garden-tools 2.6.0

Garden grows and cultivates collections of Git trees Garden lets you define and run commands over collections of configuration-defined multi-worktree Git environments.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# Commands

Garden includes a set of built-in commands and can be flexibly extended
with user-defined commands. User-defined commands are one Garden's most
useful features.


## Command-Line Conventions

Run `garden help` to display usage information for garden commands.
The usage information is where the command-line options are documented.

```bash
garden help
garden help <command>
garden <command> --help
```

Built-in commands use this basic syntax:

    garden [options] <command> [command-options] [command-arguments]*

The following options come before `<command>` and are common to all commands.

    -C | --chdir <directory>

Navigate to the specified directory before searching for configuration.
This is modeled after `make -C <path> ...` or `git -C <path> ...`.

    -c | --config <filename>

Specify a garden file to use instead of searching for `garden.yaml`.
The filename can be either the path to a file or the basename of a file in the
configuration search path.

    -v | --verbose

Enable verbose debugging output.

    -D | --define name=value

Override a configured variable by passing a `name=value` string to
the `-D | --define` option.  The variable named `name` will be updated with the
garden expression `value`.  Multiple variables can be set by specifying the
flag multiple times.


## garden init

```bash
garden init [options] [<filename>]

# create a local garden config rooted at the current directory
garden init

# create a global garden config rooted at ~/src
garden init --global --root '~/src'
```

The init command will create an empty Garden YAML file with the minimal
boilerplate to start using garden. If no `<filename>` is specified,
`garden.yaml` in the current directory will be written.

The Garden file is written to the user's `~/.config/garden/` global configuration
directory when `--global` is specified.

This command is typically run without specifying a filename.
`garden init` typically creates a `garden.yaml` in the current directory:

```
current-directory/
└── garden.yaml
```

If the current directory contains a Git repository then it will be added to
the `trees` block automatically. Use `garden init --empty` to disable this behavior.


## garden plant

```bash
garden plant <tree>
```

Add a pre-existing Git worktree to `garden.yaml`.

The `trees` section in the `garden.yaml` file will be updated with details
about the new tree.

`garden plant` records the Git remotes associated with a repository.
It is safe to re-run `garden plant` in order to add new remotes to
an existing configuration.

Repositories created using `git worktree` are supported by `garden plant`.
Parent trees must be planted first before planting a child tree.

Use the `--sort` option to sort all of the `trees` entries after planting.


## garden ... [tree-query]

Garden commands accept [tree query](tree-queries.md) strings that are used to
refer to sets of trees.

Tree queries are glob string patterns that can be used to match the gardens,
groups or trees defined in "garden.yaml".


## garden grow

```bash
garden grow <tree-query>

# Example usage
garden grow cola
```

If you have a `garden.yaml` file, either one that you authored yourself or
one that was provided to you, then you will need to grow the Git trees
into existence.

The `grow` sub-command updates or creates the trees matched by the `<tree-query>`
and places them into the paths defined by the garden file.

Use the `-t | --trees` option to specify a glob pattern for filtering trees by
name post-query. This lets you filter a tree query so that only a subset of the
trees in the query are grown.

It is safe to re-run the `grow` command and re-grow a tree.  Existing trees will
have their git configuration updated to match the configured remotes.  Missing
repositories are created by cloning the configured tree URL.

### Branches

The `branch: <branch-name>` tree variable is used to specify which branch should be
cloned and checked out when the tree is grown.

```yaml
trees:
  example:
    branch: dev
    url: git@example.org:trees/example.git
```

`garden grow example` clones the repository using `git clone --branch=dev`.
The `branch` setting is a tree variable and supports `${variable}` expressions.


### Shallow Clones

The `depth: <integer>` tree parameter is used to create shallow clones.

```yaml
trees:
  example:
    depth: 42
    url: git@example.org:trees/example.git
```

`garden grow example` clones the repository using:

```bash
git clone --depth=42 --no-single-branch
```

Even though a shallow clone is created, all of the remote tracking branches
(e.g. `origin/*`) are available because we clone the repository using
the `--no-single-branch` option.

The `single-branch: true` tree parameter is used to create clones that contain
a single branch only. This is useful if you want to limit the on-disk footprint
of repositories by only having a single branch available.

This par mater is typically used in conjunction with `branch: <branch-name>` and
`depth: 1` to create a 1-commit shallow clone with a single branch.

```yaml
trees:
  example:
    branch: dev
    depth: 1
    single-branch: true
    url: git@example.org:trees/example.git
```


### Wildcards

Wildcards are supported in the trees queries supported by `garden grow`.
`garden grow 'glob*'` grows the gardens, groups or trees that start with "glob".

If `garden.yaml` contains `gardens` whose name matches the query then the trees
associated with each garden are grown.

If no gardens are found then garden will search for "groups" that match
the query. If groups are found then the trees within each group will be grown.

If no gardens and no groups are found then will garden search for trees and grow
those whose names match the query string.


### Worktrees

`garden grow` can be used to create worktrees that share their `.git` storage
using [git worktree](https://git-scm.com/docs/git-worktree).

To create shared storage, define the primary worktree where the `.git`
storage will reside and then define additional trees that reference the
worktrees.

```yaml
trees:
  example/main: git@example.org:trees/example.git

  example/dev:
    worktree: example/main
    branch: dev

  example/v2:
    worktree: example/main
    branch: v2
```

This example uses `example/main` tree for the shared storage and two additional worktrees.
`example/dev` uses the `dev` branch and `example/v2` uses the `v2` branch.


### Upstream Branches

Remote tracking branches can be configured by defining a `branches` block that maps
local branch names (the `key`) to a remote branch name expression (the `value`).

```yaml
trees:
  example/branches:
    branch: local
    branches:
      local: origin/dev
      dev: origin/dev
```

The above configuration creates local branches called `local` and `dev` and checks out
the `local` branch when `garden grow example/branches` is run.

### Git Configuration Values

The `garden grow` command will apply git configuration values that are
specified using the `gitconfig` key.

```yaml
trees:
  foo:
    gitconfig:
      # Override the submodule URL for "thirdparty/repo".
      submodule.thirdparty/repo.url: "git@private.example.com:thirdparty/repo.git"
```

Multi-valued `git config --add` values are also supported, for example
the [remote.$name.pushurl](https://git-scm.com/docs/git-config#Documentation/git-config.txt-remoteltnamegtpushurl)
value can be set to multiple values.

Use a list as the value for the key and multiple values will be added using
[git config --add $name $value](https://git-scm.com/docs/git-config#Documentation/git-config.txt---add).

```yaml
trees:
  foo:
    url: "git@example.org:trees/foo.git"
    gitconfig:
      remote.origin.pushurl:
        # Push to multiple remotes when using "git push origin"
        - "git@jupiter.example.org:trees/foo.git"
        - "git@saturn.example.org:trees/foo.git"
```

### Bare Repositories

To clone bare repositories use `bare: true` in the tree configuration.

```yaml
trees:
  example:
    bare: true
    url: url
```

Bare clones are created by default when the tree path ends in `.git`.
For example, a tree called `example.git` will be `bare: true` by default.

```yaml
trees:
  example.git: git@example.org:trees/example.git
```

Setting `bare: false` overrides the name-based detection of bare repositories.

```yaml
trees:
  example.git:
    bare: false
    url: git@example.org:tree/example.git
```

## garden cmd

```bash
garden cmd <tree-query> <command> [<command>]... [-- <arguments>..]

# Example usage
garden cmd cola build test -- V=1
```

Run one or more user-defined commands over the gardens, groups or trees
that match the specified tree query.

The example above runs the `build` and `test` commands in all of the trees
that are part of the `cola` garden.

### Commands

`garden cmd` and `garden <command>` interact with custom commands that are
configured in the `commands` section for templates, trees, gardens,
and the top-level scope.

```bash
# Example usage

# Run the test" command in the cola and vx trees
garden test git-cola vx

# Use "--" to forward arguments to the custom commands
garden test git-cola -- --verbose

# Print what would get run without running anything
garden test --dry-run -vv git-cola
```

Custom commands can be defined at either the tree or garden scope.
Commands defined at the garden scope extend commands defined on a tree.
If both a tree and the garden containing that tree defines a command called
`test` then `garden test` will first run the tree's `test` command followed
by the garden's `test` command.

Commands are executed in a shell so that shell expressions can be used in commands.
A POSIX-compatible shell must be installed in your `$PATH`.

Additional command-line `<arguments>` specified after a double-dash (`--`)
end-of-options marker are forwarded to each command.

`"$0"` in a custom command points to the current garden executable and can be
used to rerun garden from within a garden command.

Additional arguments are available to command strings by using the traditional
`"$@"` shell syntax.  When additional arguments are present `"$1"`, `"$2"`, and
subsequent variables will be set according to each argument.

The `-N | --dry-run` option performs a trial run without running any commands.
Combine this option with the `-vv` extra-verbose mode to print the commands that
would be run without running them.

```yaml
# Commands can be defined in multiple ways.
# Strings and lists of strings are both supported via "String to List Promotion".
# The YAML reader accepts multi-line strings using the "|" pipe syntax.

commands:
  one-line: echo hello "$@"
  multi-line: |
    if test "${debian}" = "yes"
    then
        sudo apt install rust-all
    fi
  multiple-commands:
    - echo a $1 ${name}
    - |
        echo b $3
        echo c $4

variables:
  debian: $ type apt-get >/dev/null && echo yes || echo no
  name: value

# Commands can also be defined at tree and garden scope
trees:
  our-tree:
    commands:
      tree-cmd: echo ${TREE_NAME}

gardens:
  all:
    trees: "*"
    commands:
      print-pwd: pwd
```

#### Forwarding arguments using the double-dash `--` end-of-options marker

Use `--` (double-dash) to forward arguments to custom commands.
Everything specified after `--` on the command-line will be present in the `"$@"` array.

```yaml
commands:
  test: cargo test -v "$@"
```

If the wrapped command also uses `--` then you have to specify `--` twice in order for
the inner command to see a `--` marker.

The `cargo test` command uses `--` in order to pass options to the inner test commands.
To pass options to the inner test command we'd have to use `--` twice.

```bash
garden test -- -- --list
# Runs "cargo test -v -- --list". The first "--" is consumed by "garden".
```

If you always pass arguments to inner commands after their `--` marker then
you can simplify the command's usage by embedding `--` into the command definition.

```yaml
commands:
  test: cargo test -v -- "$@"
```

Using `--` in the command lets us use a single `--` to pass arguments to the innermost
tests instead of two.

```bash
garden test -- --list
# Runs "cargo test -v -- --list".
```

#### Shebang (#!) Commands

Custom command shells can be used on a per-command basis by using a `#!<command>`
shebang line as the start of a multi-line command.

The command specified in the `#!` shebang line *must* accept a command string as the
next argument to the specified command.

```yaml
commands:
  python-cmd: |
    #!python3 -c
    import sys
    print(sys.implementation)
```

Using `#!python3 -c` as the shebang line, as demonstrated above in the `python-cmd`
command, will result in the remainder of the command getting passed as the next argument.

Concretely, `garden` will run `python3 -c "import sys\nprint(sys.implementation)"` when
the `garden python-cmd` command is run.

#### Parallel Execution

By default, `garden` runs commands sequentially, one command and tree after another.

`garden cmd <tree-query> <command>...` and `garden <command> [<tree-query>...]`
are able execute commands in parallel by using the `-j# | --jobs #` option.

Using the `-j# | --jobs=#` option makes `garden` use the specified number of cores when
running commands in parallel.

Passing the value zero (`-j0 | --jobs 0`) to this option tells `garden` to detect and
use all available cores. When `-j | --jobs` is the last option on the command line you
can omit the numeric value and `garden` will treat it as if `0` was specified and use
all cores.

```bash
garden test '@*' -j
garden test --jobs=0 '@*'
```

The commands above run the custom `test` command over all trees, in parallel, using all
cores as detected at runtime.

Similarly, `garden cmd '@*' test -j` has the same behavior -- all trees are visited
and operated on concurrently.

When multiple commands are specified, e.g. `garden cmd '@*' a b c -j`, then `garden`
will run commands `a`, `b` and `c` in order, one after another, over all trees in parallel.

`garden` can also be made to visit each tree sequentially while running the `a`, `b` and `c`
commands in parallel as each tree is visited.

The `-b | --breadth-first` option enables this behavior.

```bash
garden cmd -b '@*' a b c -j
```

The command above visits each tree sequentially and executes `a`, `b`, and `c`
in parallel on each tree. The next tree is visited as soon as all three `a`, `b`,
and `c` commands complete.

Parallel execution does not effect the ordering of pre and post-commands.
Pre and post-commands run sequentially, in-order, relative to their associated
command irrespective of the parallel execution mode.


### Garden Shell

The `garden.shell` configuration value controls which shell interpreter
is used to interpret custom commands.

```yaml
garden:
  shell: zsh  # zsh is used by default when available. Uses bash, dash or sh otherwise.
  shell-wordsplit: true  # Words are split by default in zsh using "zsh -o shwordsplit"
  shell-errexit: true  # Non-zero exit status stops execution using "zsh -e".
```

`garden.shell` defaults to `zsh` when `zsh` is installed but can be set to any shell
that accepts `-e` and `-c <string>` options (for example `ksh`).
If `zsh` is not installed then `bash` or `dash` will be used instead.
If neither `zsh`, `bash` nor `dash` is installed then `sh` will be used.

Each command runs under `["zsh", "-e", "-c", "<command>"]` with the resolved
environment from the corresponding garden, group, or tree.

Multi-line and multi-statement command strings will stop executing as soon as the
first non-zero exit code is encountered due to the use of the `-e` shell option.
Use the `-n | --no-errexit` option to inhibit the use of the `-e` "errexit" option.

The `--no-errexit` option causes commands with multiple statements to run to completion
even when a non-zero exit code is encountered. This is akin to a regular shell script.

Configure `garden.shell-errexit` to `false` in `garden.yaml` to opt-out of this behavior.
You can also opt-out of the `errexit` behavior on a per-command basis by using
`set +e` as the first line of a multi-line command.

When `zsh` is used it is executed with the `-o shwordsplit` option so that zsh behaves
similarly to traditional shells by splitting words in unquoted `$variable` expressions
rather than treating `$variable` like a single argument.

Configure `garden.shell-wordsplit` to `false` to opt-out of this behavior.
You can also opt-out of the `shwordsplit` behavior on a per-command basis by using
`set +o shwordsplit` as the first line of a multi-line command.

#### Builtin Shells

The following values for `garden.shell` are understood directly by `garden` and
the following commands are used when `garden` detects that these shells are
configured. Not applicable (N/A) is denoted by `-`.

| garden.shell  | Command used for running commands     | errexit=false | wordsplit=false       |
|---------------|---------------------------------------|---------------|-----------------------|
| `bun`         | `bun -e`                              | -             | -                     |
| `bash`        | `bash -e -c`                          | Omit `-e`     | -                     |
| `dash`        | `dash -e -c`                          | Omit `-e`     | -                     |
| `ksh`         | `ksh -e -c`                           | Omit `-e`     | -                     |
| `node`        | `node -e`                             | -             | -                     |
| `nodejs`      | `nodejs -e`                           | -             | -                     |
| `perl`        | `perl -e`                             | -             | -                     |
| `ruby`        | `ruby -e`                             | -             | -                     |
| `sh`          | `sh -e -c`                            | Omit `-e`     | -                     |
| `zsh`         | `zsh -o shwordsplit +o nomatch -e -c` | Omit `-e`     | Omit `-o shwordsplit` |

The following shells are not builtin, but they work as expected because they accept
`-c <string>` arguments for running command strings.

| garden.shell  | Command used for running commands |
|---------------|-----------------------------------|
| `fish`        | `fish -c`                         |
| `python3`     | `python3 -c`                      |

#### Custom Command Interpreters

The command used in `garden.shell` must specify a command that takes a string to
execute using the `-c <string>` option. Some commands take `-e <string>` instead,
namely `nodejs`, `perl` and `ruby`, which are all understood by `garden` and
are expanded into their corresponding command-line.

This allows you to specify `python3` as the shell because `garden` assumes that
it can call `python3 -c <string>` to execute commands.

```yaml
# This uses "python -c <string>" to run commands.
garden:
  shell: python3
commands:
  hello: print('hello world')
  info: |
    import platform
    print(platform.platform())

# Builtin shorthand shell values are special-cased internally.
# This uses "zsh -o shwordsplit -e -c <string>" to run commands.
garden:
  shell: zsh

# This uses "bash -e -c <string>" to run commands.
garden:
  shell: bash

# Use "#!" shebang lines to use a custom interpreters for a command.
commands:
  info: |
    #!python3 -c
    import platform
    print(platform.platform())
```

`garden.shell` also allows you to completely override the command used for interpreting
custom commands. When you specify a command line with multiple arguments then `garden`
will no longer internally manage the command-line options passed to the shell command.
The options that you specify will be used instead. You must specify `-c` or similar
arguments yourself when `garden` is configured with a custom command.
The `garden.shell-wordsplit` and `garden.shell-errexit` options have no effect
when using custom shell commands.

```yaml
# Use "zsh -c" directly without "-o shwordsplit" and "-e".
garden:
  shell: zsh -c

# Additional examples.
garden:
  shell: python3 -s -u -c
```

### Shell Syntax

User-defined Commands and Exec Expressions are evaluated by the shell configured
in the `garden.shell` configuration value.

Garden and Shells share a key piece of common syntax: the interpolated braced
`${variable}` syntax.

Garden Variables that use the `${variable}` syntax are evaluated by
`garden` first before the shell has evaluated them.

This means that the shell syntax supported by Garden's Exec Expressions is
a subset of the full syntax because shell-only variables such as `${OSTYPE}` cannot
be accessed using the braced-variable syntax.

```yaml
commands:
  example-command: |
    shell_variable=$(date +%s)
    echo hello $OSTYPE $shell_variable
```

The plain `$variable` syntax is reserved for use by the shell commands used in
user-defined Commands and Exec Expressions.

Environment Variables can be used in shell scriptlets through both the `$ENV` and
`${ENV}` braced variable syntax. Garden makes all environment variables available during
variable expansion.

The distinction between the `${garden}` and `$shell` syntax is only relevant when
using variables defined within shell command, such as `$shell_variable` above.

If the `${shell_variable}` syntax were to be used in the `example-command` then an
empty value would have been used instead of the output of `date +%s`.

Sometimes it is necessary to actually use the `${...}` braced literal syntax
in shell commands. The `$${...}` braced double-dollar syntax can be used to
escape a braced value and disable evaluation by `garden`.

Double-`$` can generally be used to escape literal `$` values in commands, but
escaping is handled automatically for regular `$shell` variables.

### Tree Traversal Order

Garden traverses trees in the same order that appear in the `gardens`, `groups`,
and `trees` blocks in your `garden.yaml` files. You can affect the order that trees and
commands are traversed by ordering the entries in the Garden file accordingly.

### Depth-first and Breadth-first Tree Traversal

The following two invocations run commands in a different order:

```bash
# Depth-first (default)
garden cmd treesitters build test

# Breadth-first
garden cmd --breadth-first treesitters build test
```

The default traversal order for commands is depth-first. This means that *both* the
`build` and `test` commands are run on each tree in the `treesitters` group
*before* running any commands on the next tree.

The `-b | --breadth-first` option enables a breadth-first traversal. A breadth-first
traversal runs the `build` command over *all* of the trees in the `treesitters` group
*before* the `test` command is run over all of the trees in the same group.

### Custom Commands

```bash
garden <command> <query> [<query>]* [-- <arguments>...]

# Example usage
garden status @git-cola .
garden build cola/next
```

`garden <command>` is another way to execute a user-defined `<command>`.
This form allows you to specify multiple queries rather than multiple commands.

When no builtin command exists by the specified name then garden will
use custom commands defined in a `commands` block at the corresponding
garden or tree scope.

`garden <command> [<query>...]` is complementary to `garden cmd <query> <command>...`.

`garden cmd <query> <command>...` runs multiple commands over a single query.

`garden <command> [<query>...]` runs a single command over multiple queries.

For example, `garden build treesitters catsitters` will run a user-defined `build`
command over both the `treesitters`  and `catsitters` groups.

Use the `-vv` extra-verbose option to display the commands being run.

Use the `-t | --trees` option to specify a glob pattern to filter trees by name
post-query. Commands will only be run inside trees whose names match the pattern.
This lets you activate a garden and its environment variables while only running
a commands against a subset of trees in that garden.

### Pre and Post Commands

Commands can specify references to other commands that should be run before and/or after
a command.

* Pre-commands are run before the command.

* Pre-commands use a `<` suffix with values that specify the names of other commands to
  run before the command.

* Post-commands are run after the command.

* Post-commands use a `>` suffix with values that specify the names of other commands to
  run after the command.

* Pre-commands and post-commands can only refer to other custom commands.

```yaml
commands:
  custom-cmd: echo custom-cmd
  custom-cmd<: pre
  custom-cmd>:
    - post1
    - post2
  pre: echo before
  post1: echo after1
  post2: echo after2
```

Running `garden custom-cmd` with the above configuration runs the following commands:

```
# pre
echo before

# custom-cmd
echo custom-cmd

# post1
echo after1

# post2
echo after2
```

### Missing Trees

`garden` skips missing trees when running custom commands by default.

This means that if a tree has not yet been grown then `garden` will not visit it when
running custom commands. Missing trees are silently ignored and skipped.

Use `garden --verbose <command> ...` to instruct `garden` to print information about
missing trees when it skips them. Missing trees are annotated with a `(skipped)` message.

Using `mkdir` to create the tree's directory is all that's needed to get `garden` to run
commands in those trees.

Alternatively, use the `-f | --force` option when running custom commands to get
`garden` to run custom commands on missing trees. The `--force` option only affects the
behavior of custom commands when they operate on missing trees.

Since the tree's directory does not exist the current working directory when running
commands on missing trees using `--force` will be different.

Using `garden <command> --force <query>` to run commands on missing trees will use the
`${GARDEN_ROOT}` directory (`garden.root`) instead of the tree's `${TREE_PATH}`
directory as the current working directory when commands are run.


## garden exec

```bash
garden exec <tree-query> <command> [<arguments>]*

# example
garden exec cola git status -s
garden exec -j0 cola git status -s
```

Run commands over the trees, groups or gardens matched by tree query.
When the `<tree-query>` resolves to a garden then the environment
is configured for the command using the environment variables and
custom commands from both the tree and the garden.

Use the `-vv` extra-verbose option to display the command being run.

Use the `-N | --dry-run` option to perform a trial run without running any commands.

Use the `-t | --trees` option to specify a glob pattern to filter trees by name
post-query. Commands will only be run inside trees whose names match the pattern.
This lets you activate a garden and its environment variables while only running
the `<command>` against a subset of trees in that garden.

Use the `-j# | --jobs=#` option to enable parallel execution of commands limited to
the specified number of cores. Trees will be visited in parallel and the command will be
executed concurrently in each tree.

Set the jobs value to zero `-j0 | --jobs=0` to use all available cores.


## garden eval

```bash
garden eval <expression> [<tree>] [<garden>]

# example
garden eval '${GARDEN_ROOT}'
garden eval '${TREE_PATH}' cola
```

Evaluate a Garden Expression in the specified tree context and output
the result to stdout.

Garden Expressions are `strings-with-${variables}` that get substituted
and resolved using garden's `variables` and `environment` blocks.

If no tree is given then the variable scope includes the top-level variables
block only.

When a tree is given then its variables are considered as well.

When a garden is specified then the garden's variables are also available for
evaluation.


## garden git

```bash
garden git <tree-query> <git-subcommand> [<arguments>]*

# example
garden git pull
garden git pull '@*' --ff-only
garden git -j0 pull '@*' --ff-only
```

Run Git commands over the trees, groups or gardens matched by tree query.
When the `<tree-query>` resolves to a garden then the environment
is configured for the command using the environment variables
from both the tree and the garden.

Use the `-vv` extra-verbose option to display the command being run.

Use the `-N | --dry-run` option to perform a trial run without running any commands.

Use the `-t | --trees` option to specify a glob pattern to filter trees by name
post-query. Commands will only be run inside trees whose names match the pattern.
This lets you activate a garden and its environment variables while only running
the `<command>` against a subset of trees in that garden.

Use the `-j# | --jobs=#` option to enable parallel execution of commands limited to
the specified number of cores. Trees will be visited in parallel and the command will be
executed concurrently in each tree.

Set the jobs value to zero `-j0 | --jobs=0` to use all available cores.


## garden gui

    garden gui [<query>...]

    # example
    garden gui

Garden has a graphical user interface for running command and queries.
`garden-gui` is provided by a separate crate:

```bash
cargo install garden-gui
```

The top-most search bar allows you to input Tree Queries and see the set of trees that
the query would find.

Custom commands are displayed in a grid of buttons. The contents of each command can be
seen by right-clicking a command button.

Clicking on a command button will run that command against the current query.


## garden shell

    garden shell <tree-query> [<tree>]

    # example
    garden shell cola

Launch a shell inside the environment synthesized by the tree query.
If `<tree>` is specified then the current directory will be set to the
tree's directory.

If the resolved tree query contains a tree whose name exactly matches the
query string then that tree's directory will be used when opening the shell.
The optional tree argument is not needed for the case where a garden
and tree share a name -- garden will chdir into that same-named tree when
creating the shell.

If you would like to customize the command to use for `garden shell` then
you can configure `garden.interactive-shell`. This value overrides `garden.shell`
and is only used by the `garden shell` command.

```yaml
# Launch a fish login shell for "garden shell".
garden:
  interactive-shell: fish
```

Arbitrary command interpreters can be specified.

```yaml
# Launch a python interpreter for "garden shell".
garden:
  interactive-shell: python3 -B
```


## garden ls

    garden ls [options] [<tree-query>...]

Display configured information about trees and commands.
Tree details are not displayed for missing / ungrown trees.

Use the `-a | --all` option to display details for missing trees.

If no tree-queries are specified then `garden ls` behaves as if
`garden ls '@*'` were specified, which displays all trees.

Use the `-t | --trees` option to specify a glob pattern that can be used to
filter trees by name post-query. This is useful when you want to list details
about a group or garden while only listing details about a subset of the trees.


## garden prune

    garden prune [options] [<subdirs>...]

Traverse the filesystem and interactively delete any repositories that are
not referenced by the garden file.

This command is intended to cleanup a garden-managed directory. Its intended
usage is to delete repositories that were created (e.g. via `garden grow`) and
have since been removed from your version-controlled garden configuration.

**Warning**: `garden prune` is a dangerous command and must be run with care.
`garden prune` deletes repositories and all of their files (including the `.git` storage)!

The following options are supported by `garden prune`.

## Enable deletions

    --rm

The `garden prune` command uses a no-op "safe mode" which does not actually
delete repositories by default. Deletions must be enabled by specifying the
`--rm` option.

Use the `--rm` option only after you have verified that `garden prune` is not
going to delete any unexpected repositories that you intended to keep.

## Limit concurrency

    --jobs <jobs>

The prune process runs in parallel across multiple cores. All cores are used by default.
The `--jobs` option limits the number of cores to the specified number of jobs.

## Limit filesystem traversal depth

    --min-depth <minimum-depth>
    --max-depth <maximum-depth>
    --exact-depth <exact-depth>

The cleanup process can be limited to specific traversal depths. The filesystem is
traversed with no limits by default.

Specifying a minimum depth will not remove repositories shallower than the specified
depth. For example, `--min-depth 1` will not remove repositories in the same directory
as the garden file.

Specifying a maximum depth will not remove repositories deeper than the specified
depth. For example, `--max-depth 0` will not remove repositories in subdirectories
below the directory containing the garden file.

## Enable scripted usage by answering "yes" to all prompts

    --no-prompt

The `garden prune` command interactively prompts before removing each repository.
The prompt looks like the following:

```bash
# /home/user/src/example
Delete the "example" repository?
WARNING: "all" deletes "example" and ALL subsequent repositories!
Choices: yes, no, all, quit [y,n,all,q]?
```

Entering `y` (or `yes`) at the prompt will delete the repository and all of its files.

Entering `n` (or `no`) at the prompt will skip and not remove the repository.

Entering `q` (or `quit`) will exit `garden prune` without deleting the repository.

Entering `all` will remove the repository and all subsequent repositories.
`all` is equivalent to answering `yes` to all further prompts.

Entering `all` is dangerous and proceeds without further prompts. Be careful!

`--no-prompt` is also equivalent to answering `yes` to all prompts.
`--no-prompt` is intended for use in scripts where user interaction is not desired.
Use with caution!


## garden completion

Shell completions for `garden` can be generated by running the `garden completion`
command.

`garden completion` uses [clap complete](https://crates.io/crates/clap_complete)
to generate its completions.

The `--commands` options will additionally generate completions for custom commands.

### Zsh

Ensure that your `~/.zshrc` file has completions enabled and that you have a
directory configured in your `$fpath` for `zsh` completion scripts.
Add the following snippet to your `~/.zshrc` to enable completions and
configure `~/.config/zsh/completion` for providing completion scripts.

```bash
fpath=(~/.config/zsh/completion $fpath)
autoload -U +X compinit
compinit -i
```

These settings make `zsh` look for a script called `_garden` in the directory when
tab-completing for `garden`.

Lastly, create the directory and generate the `~/.config/zsh/completion/_garden`
zsh shell completion script.

```bash
mkdir -p ~/.config/zsh/completion
garden completion zsh >~/.config/zsh/completion/_garden
```

Use `garden completion --commands zsh` instead of `garden completion zsh`
to include completions for custom commands.

*NOTE*: You should regenerate the `_garden` zsh completion script whenever `garden`
is upgraded to ensure that all of the options and commands have up to date completions.

### Bash

Add the following snippet to your `~/.bashrc` to enable `bash` tab completions.

```bash
if test -n "$PS1" && type garden >/dev/null 2>&1
then
    eval "$(garden completion bash)" 2>/dev/null
fi
```

Use `garden completion --commands bash` instead of `garden completion bash`
to include completions for custom commands.

### Future shell completion enhancements

Tab completion can only be made to include a static set of user-defined commands.
Custom commands cannot be defined dynamically, which means that the same completions
will be used irrespective of your current directory.

Improvements to the shell completions can be made once traction has been made on the
following upstream issues:

* [clap #3022]https://github.com/clap-rs/clap/issues/3022 - zsh broken with two multi length arguments

* [clap #4612]https://github.com/clap-rs/clap/pull/4612 - candidate fix for the above issue

* [clapng #92]https://github.com/epage/clapng/issues/92 - Dynamic completion support