git-worktrees 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/AGENTS.md +8 -4
  2. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/CHANGELOG.md +59 -0
  3. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/PKG-INFO +48 -11
  4. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/README.md +47 -10
  5. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/docs/DEVELOPMENT.md +3 -1
  6. git_worktrees-0.4.0/docs/REFERENCE.md +438 -0
  7. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/pyproject.toml +1 -1
  8. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/cli.py +75 -21
  9. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/forge.py +9 -0
  10. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/layout.py +37 -0
  11. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/new_branch.py +4 -1
  12. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/pick.py +17 -1
  13. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/prune.py +6 -1
  14. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/verdicts.py +23 -1
  15. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/conftest.py +16 -0
  16. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_cli.py +185 -11
  17. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_completions.py +45 -0
  18. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_forge.py +114 -0
  19. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_gates.py +31 -0
  20. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_shims.py +28 -0
  21. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_worktree.py +40 -0
  22. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/uv.lock +1 -1
  23. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.agents/skills/release/SKILL.md +0 -0
  24. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.claude/settings.json +0 -0
  25. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.github/workflows/publish.yml +0 -0
  26. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.github/workflows/testpypi.yml +0 -0
  27. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.github/workflows/tests.yml +0 -0
  28. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.gitignore +0 -0
  29. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.pre-commit-config.yaml +0 -0
  30. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/.python-version +0 -0
  31. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/LICENSE +0 -0
  32. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gw.fish +0 -0
  33. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwa.fish +0 -0
  34. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwh.fish +0 -0
  35. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwl.fish +0 -0
  36. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwm.fish +0 -0
  37. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwnb.fish +0 -0
  38. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwp.fish +0 -0
  39. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwr.fish +0 -0
  40. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gwrot.fish +0 -0
  41. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/completions/gws.fish +0 -0
  42. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/conf.d/worktrees.fish +0 -0
  43. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/docs/BENCHMARK.md +0 -0
  44. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/functions/gwa.fish +0 -0
  45. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/functions/gwl.fish +0 -0
  46. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/functions/gwm.fish +0 -0
  47. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/functions/gwr.fish +0 -0
  48. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/hatch_build.py +0 -0
  49. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/renovate.json +0 -0
  50. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/scripts/README.md +0 -0
  51. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/scripts/benchmark.py +0 -0
  52. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/scripts/verify-publish.bash +0 -0
  53. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/__init__.py +0 -0
  54. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/errors.py +0 -0
  55. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/git.py +0 -0
  56. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/merged.py +0 -0
  57. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/render.py +0 -0
  58. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/repo.py +0 -0
  59. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/rotate.py +0 -0
  60. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/src/worktrees/worktree.py +0 -0
  61. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_benchmark.py +0 -0
  62. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_fixture.py +0 -0
  63. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_new_branch.py +0 -0
  64. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_render.py +0 -0
  65. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_rotate.py +0 -0
  66. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_spec.py +0 -0
  67. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/tests/test_version.py +0 -0
  68. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gw +0 -0
  69. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwa +0 -0
  70. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwh +0 -0
  71. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwl +0 -0
  72. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwm +0 -0
  73. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwnb +0 -0
  74. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwp +0 -0
  75. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwr +0 -0
  76. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gwrot +0 -0
  77. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/completions/_gws +0 -0
  78. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/functions/gwa +0 -0
  79. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/functions/gwl +0 -0
  80. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/functions/gwm +0 -0
  81. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/functions/gwr +0 -0
  82. {git_worktrees-0.3.0 → git_worktrees-0.4.0}/zsh/plugins/worktrees/worktrees.plugin.zsh +0 -0
@@ -156,10 +156,14 @@ Two more about what is in the list at all:
156
156
  the one a finished branch leaves you in, so leaving it out leaves out the
157
157
  only answer that is always right. `main` finds it whatever branch it stands
158
158
  on, because its label carries the word, once.
159
- - The worktree you are standing in is listed and never offered. Picking it is
160
- the one answer that takes you nowhere, and a picker whose single candidate
161
- is where you already are prints nothing at all, which reads as a broken
162
- command.
159
+ - The worktree you are standing in is shown and never offered. It carries a
160
+ `*` rather than a number, because picking it is the one answer that takes
161
+ you nowhere. Leaving it out of the list entirely is worse: the list then
162
+ shows fewer rows than `git worktree list` does, and reads as though
163
+ something went missing rather than as where you already are. The main
164
+ checkout is in `gws` and `gwp` for the same reason, kept and never
165
+ proposed, and out of `gwr`'s candidates because `git worktree remove`
166
+ refuses it whatever flag it is given.
163
167
 
164
168
  `--json` and `--list` answer the same question without any of this, and an
165
169
  agent uses those.
@@ -17,6 +17,65 @@ not in here, whatever it cost to build.
17
17
  A release closes with a `### Choices` section when a decision in it is worth
18
18
  the reader's time: what was chosen, and what the alternative failed to do.
19
19
 
20
+ ## 0.4.0 - 2026-09-21
21
+
22
+ ### Security
23
+
24
+ Forge queries ignore `GH_REPO` and `GITLAB_REPO`, so a merged request in
25
+ another repository cannot authorize removal here.
26
+
27
+ Printed branch restoration commands and `gwnb` checkout hints quote branch
28
+ names so shell metacharacters are treated as part of the name.
29
+
30
+ ### Added
31
+
32
+ `gws` reports how many worktrees under the shared `.worktrees` directory
33
+ belong to other repositories, with the count in `gws --json` as `neighbours`.
34
+
35
+ ### Fixed
36
+
37
+ After a failed fetch, worktree assessments use local refs and skip forge
38
+ queries.
39
+
40
+ `gwl` and `gwr` shell completions omit paths containing newlines, which
41
+ cannot fit their one-row-per-line format; those worktrees remain reachable
42
+ by name or path.
43
+
44
+ Pressing Ctrl-C at a worktree selection or removal prompt exits with code
45
+ 130 and no traceback. No worktree is selected or removed.
46
+
47
+ ## 0.3.1 - 2026-09-20
48
+
49
+ `gws` and `gwp` list the main checkout, and `gwl`'s picker shows the
50
+ worktree you are standing in. Both listings used to leave those rows out, so
51
+ a repository with the main checkout and one worktree showed one row where
52
+ `git worktree list` shows two, which reads as though something went missing
53
+ rather than as where you already are.
54
+
55
+ The main checkout is `keep`, with `it is the main checkout, and never
56
+ removable`. Nothing proposes it, and `git worktree remove` answers
57
+ `fatal: '<path>' is a main working tree` whatever flag it is given, so `gwr`
58
+ still does not offer it.
59
+
60
+ The one you are standing in carries a `*` rather than a number:
61
+
62
+ ```
63
+ * cleanup /home/you/git/.worktrees/cleanup/repo
64
+ 1 docs-ship-with-the-change (main) /home/you/git/repo
65
+ which? [1-1, or blank to cancel]
66
+ ```
67
+
68
+ Two things move with those rows. The counts include the main checkout, so a
69
+ repository with one linked worktree reads `1 removable, 1 kept, 0 unclear`
70
+ where it read `1 removable, 0 kept, 0 unclear`, and `gws --json` and
71
+ `gwp --json` carry the extra verdict. A caller filtering on
72
+ `verdict == "remove"` is unaffected; one reading `verdicts[0]` gets the main
73
+ checkout now.
74
+
75
+ `no worktrees besides the main checkout` is on stderr rather than stdout, and
76
+ says `; gwa NAME makes one`. The table is always on stdout now, so stdout is
77
+ never that sentence instead.
78
+
20
79
  ## 0.3.0 - 2026-09-20
21
80
 
22
81
  `gwl` with no query asks which worktree rather than moving you to one.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: git-worktrees
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Git worktree commands that refuse to lose work.
5
5
  Project-URL: Bug reports, https://github.com/MihaiBojin/worktrees/issues/new
6
6
  Project-URL: Source, https://github.com/MihaiBojin/worktrees
@@ -64,6 +64,10 @@ function, because a binary cannot change its caller's directory.
64
64
 
65
65
  `worktrees` is the same program under its long name.
66
66
 
67
+ Ctrl-C interrupts a running command with exit code 130 and no traceback.
68
+ At a selection or removal prompt, it cancels without choosing or removing
69
+ a worktree.
70
+
67
71
  `gws` and `gwp` are what this tool is for and their behaviour is settled.
68
72
 
69
73
  **`gwnb` and `gwrot` are alpha and may go.** They start branches rather than
@@ -160,6 +164,12 @@ subcommand and shorthand, `gwl --complete` prints every worktree, and both
160
164
  shells narrow what those return, so the matching stays in one place and a
161
165
  command added to the table needs no edit in either shell.
162
166
 
167
+ One row a line, `label<TAB>path`. A worktree whose path holds a newline is
168
+ left out of that listing, because both shells would read it as two rows and
169
+ offer the tail as a worktree of its own. `gwa` cannot make such a path, since
170
+ it derives from a branch name and git refuses a newline in a ref, and the
171
+ worktree is still reachable by name or path.
172
+
163
173
  Neither manager puts a binary on `$PATH`, which is why the two installs stay
164
174
  separate.
165
175
 
@@ -168,19 +178,30 @@ separate.
168
178
  ```console
169
179
  $ gws
170
180
  VERDICT BRANCH WHY PATH
181
+ keep main it is the main checkout, and never removable /home/you/git/repo
171
182
  keep dirty-work it has uncommitted changes /home/you/git/.worktrees/dirty-work/repo
172
183
  keep holds-secrets merged, but holds 2 ignored path(s); pass --delete-ignored /home/you/git/.worktrees/holds-secrets/repo
173
184
  unknown never-pushed not merged into origin/main, and no upstream says whether its commits were pushed /home/you/git/.worktrees/never-pushed/repo
174
185
  remove squash-merged squash-merged /home/you/git/.worktrees/squash-merged/repo
175
186
 
176
- 1 removable, 2 kept, 1 unclear
187
+ 1 removable, 3 kept, 1 unclear
188
+ 2 worktree(s) under /home/you/git/.worktrees belong to another repository
177
189
  unclear, and gwp does not touch these: never-pushed
178
190
  gwp removes the 1 marked removable
179
191
  ```
180
192
 
181
- Rows come in `git worktree list` order. Paths are absolute wherever this
193
+ Rows come in `git worktree list` order, the main checkout first. It is there
194
+ so the table shows what `git worktree list` shows; nothing proposes it, and
195
+ `git worktree remove` answers `fatal: '<path>' is a main working tree`
196
+ whatever flag it is given. Paths are absolute wherever this
182
197
  prints one, so a row can be pasted into the next command. The table and the
183
- count are on stdout; the two lines after them are on stderr.
198
+ count are on stdout; everything after them is on stderr.
199
+
200
+ Every repository in the same parent directory keeps its worktrees under that
201
+ one `.worktrees` root, so some of the directories in there are a sibling's.
202
+ `gws` counts those and says so, because nothing else does, and `--json`
203
+ carries the same count as `neighbours`. No command here reads or removes
204
+ them, and the count comes from walking the root rather than from asking git.
184
205
 
185
206
  On a terminal the verdict carries its own colour, `remove` green, `keep` blue
186
207
  and `unknown` yellow, with the branch in bold and the path dimmed. That
@@ -204,7 +225,13 @@ squashes, so the intermediate state it holds differs from the final one in
204
225
  the same regions, and a diff cannot separate a stale branch from one with
205
226
  work left. A merged pull request settles it, cross-checked against the
206
227
  commits an upstream has not got, because a request speaks for what reached
207
- it and nothing about what never did. `--no-forge` decides from git alone.
228
+ it and nothing about what never did. `--no-forge` decides from git alone, and
229
+ so does a run whose fetch just failed.
230
+
231
+ The question goes to the repository the command is standing in and nowhere
232
+ else. `GH_REPO` and `GITLAB_REPO` beat that directory, so both are dropped
233
+ before `gh` or `glab` runs; everything else in the environment, the token
234
+ included, is passed through.
208
235
 
209
236
  A record left behind by a directory somebody deleted by hand is nobody's
210
237
  verdict. `gws` names how many there are; clearing them is `git worktree prune`,
@@ -326,13 +353,18 @@ show me the options, and being moved without being asked is not that. So it
326
353
  asks, numbered, however many there are:
327
354
 
328
355
  ```console
329
- $ gwl # standing in the main checkout
330
- 1 dirty-work /home/you/git/.worktrees/dirty-work/repo
331
- 2 holds-secrets /home/you/git/.worktrees/holds-secrets/repo
332
- 3 never-pushed /home/you/git/.worktrees/never-pushed/repo
356
+ $ gwl # standing in never-pushed
357
+ * never-pushed /home/you/git/.worktrees/never-pushed/repo
358
+ 1 main /home/you/git/repo
359
+ 2 dirty-work /home/you/git/.worktrees/dirty-work/repo
360
+ 3 holds-secrets /home/you/git/.worktrees/holds-secrets/repo
333
361
  which? [1-3, or blank to cancel]
334
362
  ```
335
363
 
364
+ The one you are standing in is marked `*` and carries no number. It is where
365
+ you are rather than somewhere to go, and a list without it shows three rows
366
+ where `git worktree list` shows four.
367
+
336
368
  Matching is substring first and then subsequence, so `tst` finds `add-tests`,
337
369
  and a substring hit always outranks a loose one. Without a terminal `gwl`
338
370
  refuses at exit 3 and names `--list` and `--json`.
@@ -443,7 +475,10 @@ print one thing each and have nothing to be quiet about, takes `--json`, `-q`,
443
475
 
444
476
  A remote that cannot be reached is not fatal anywhere. The fetch fails, the
445
477
  command says so on stderr, and it answers from the refs already here, which is
446
- where `--no-fetch` sends it on request.
478
+ where `--no-fetch` sends it on request. The forge is not asked either: it is
479
+ over the same network, and `gh` waits 30 seconds before saying so, once per
480
+ branch. `--no-fetch` alone says nothing about the network, so it leaves the
481
+ forge asked.
447
482
 
448
483
  Data goes to stdout and diagnostics to stderr, the prompt included, so `--json`
449
484
  is parseable in every mode. Colour is decided per stream and only for a
@@ -498,7 +533,9 @@ is refused with them: it deletes refs without `-d` appearing at all.
498
533
  The Python, the tests and the release procedure are in
499
534
  [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md). The rules the code follows are in
500
535
  [AGENTS.md](AGENTS.md). What changed in each release is in
501
- [CHANGELOG.md](CHANGELOG.md).
536
+ [CHANGELOG.md](CHANGELOG.md). What was decided and what must not break,
537
+ including the alternatives that were closed, is in
538
+ [docs/REFERENCE.md](docs/REFERENCE.md).
502
539
 
503
540
  ## Licence
504
541
 
@@ -38,6 +38,10 @@ function, because a binary cannot change its caller's directory.
38
38
 
39
39
  `worktrees` is the same program under its long name.
40
40
 
41
+ Ctrl-C interrupts a running command with exit code 130 and no traceback.
42
+ At a selection or removal prompt, it cancels without choosing or removing
43
+ a worktree.
44
+
41
45
  `gws` and `gwp` are what this tool is for and their behaviour is settled.
42
46
 
43
47
  **`gwnb` and `gwrot` are alpha and may go.** They start branches rather than
@@ -134,6 +138,12 @@ subcommand and shorthand, `gwl --complete` prints every worktree, and both
134
138
  shells narrow what those return, so the matching stays in one place and a
135
139
  command added to the table needs no edit in either shell.
136
140
 
141
+ One row a line, `label<TAB>path`. A worktree whose path holds a newline is
142
+ left out of that listing, because both shells would read it as two rows and
143
+ offer the tail as a worktree of its own. `gwa` cannot make such a path, since
144
+ it derives from a branch name and git refuses a newline in a ref, and the
145
+ worktree is still reachable by name or path.
146
+
137
147
  Neither manager puts a binary on `$PATH`, which is why the two installs stay
138
148
  separate.
139
149
 
@@ -142,19 +152,30 @@ separate.
142
152
  ```console
143
153
  $ gws
144
154
  VERDICT BRANCH WHY PATH
155
+ keep main it is the main checkout, and never removable /home/you/git/repo
145
156
  keep dirty-work it has uncommitted changes /home/you/git/.worktrees/dirty-work/repo
146
157
  keep holds-secrets merged, but holds 2 ignored path(s); pass --delete-ignored /home/you/git/.worktrees/holds-secrets/repo
147
158
  unknown never-pushed not merged into origin/main, and no upstream says whether its commits were pushed /home/you/git/.worktrees/never-pushed/repo
148
159
  remove squash-merged squash-merged /home/you/git/.worktrees/squash-merged/repo
149
160
 
150
- 1 removable, 2 kept, 1 unclear
161
+ 1 removable, 3 kept, 1 unclear
162
+ 2 worktree(s) under /home/you/git/.worktrees belong to another repository
151
163
  unclear, and gwp does not touch these: never-pushed
152
164
  gwp removes the 1 marked removable
153
165
  ```
154
166
 
155
- Rows come in `git worktree list` order. Paths are absolute wherever this
167
+ Rows come in `git worktree list` order, the main checkout first. It is there
168
+ so the table shows what `git worktree list` shows; nothing proposes it, and
169
+ `git worktree remove` answers `fatal: '<path>' is a main working tree`
170
+ whatever flag it is given. Paths are absolute wherever this
156
171
  prints one, so a row can be pasted into the next command. The table and the
157
- count are on stdout; the two lines after them are on stderr.
172
+ count are on stdout; everything after them is on stderr.
173
+
174
+ Every repository in the same parent directory keeps its worktrees under that
175
+ one `.worktrees` root, so some of the directories in there are a sibling's.
176
+ `gws` counts those and says so, because nothing else does, and `--json`
177
+ carries the same count as `neighbours`. No command here reads or removes
178
+ them, and the count comes from walking the root rather than from asking git.
158
179
 
159
180
  On a terminal the verdict carries its own colour, `remove` green, `keep` blue
160
181
  and `unknown` yellow, with the branch in bold and the path dimmed. That
@@ -178,7 +199,13 @@ squashes, so the intermediate state it holds differs from the final one in
178
199
  the same regions, and a diff cannot separate a stale branch from one with
179
200
  work left. A merged pull request settles it, cross-checked against the
180
201
  commits an upstream has not got, because a request speaks for what reached
181
- it and nothing about what never did. `--no-forge` decides from git alone.
202
+ it and nothing about what never did. `--no-forge` decides from git alone, and
203
+ so does a run whose fetch just failed.
204
+
205
+ The question goes to the repository the command is standing in and nowhere
206
+ else. `GH_REPO` and `GITLAB_REPO` beat that directory, so both are dropped
207
+ before `gh` or `glab` runs; everything else in the environment, the token
208
+ included, is passed through.
182
209
 
183
210
  A record left behind by a directory somebody deleted by hand is nobody's
184
211
  verdict. `gws` names how many there are; clearing them is `git worktree prune`,
@@ -300,13 +327,18 @@ show me the options, and being moved without being asked is not that. So it
300
327
  asks, numbered, however many there are:
301
328
 
302
329
  ```console
303
- $ gwl # standing in the main checkout
304
- 1 dirty-work /home/you/git/.worktrees/dirty-work/repo
305
- 2 holds-secrets /home/you/git/.worktrees/holds-secrets/repo
306
- 3 never-pushed /home/you/git/.worktrees/never-pushed/repo
330
+ $ gwl # standing in never-pushed
331
+ * never-pushed /home/you/git/.worktrees/never-pushed/repo
332
+ 1 main /home/you/git/repo
333
+ 2 dirty-work /home/you/git/.worktrees/dirty-work/repo
334
+ 3 holds-secrets /home/you/git/.worktrees/holds-secrets/repo
307
335
  which? [1-3, or blank to cancel]
308
336
  ```
309
337
 
338
+ The one you are standing in is marked `*` and carries no number. It is where
339
+ you are rather than somewhere to go, and a list without it shows three rows
340
+ where `git worktree list` shows four.
341
+
310
342
  Matching is substring first and then subsequence, so `tst` finds `add-tests`,
311
343
  and a substring hit always outranks a loose one. Without a terminal `gwl`
312
344
  refuses at exit 3 and names `--list` and `--json`.
@@ -417,7 +449,10 @@ print one thing each and have nothing to be quiet about, takes `--json`, `-q`,
417
449
 
418
450
  A remote that cannot be reached is not fatal anywhere. The fetch fails, the
419
451
  command says so on stderr, and it answers from the refs already here, which is
420
- where `--no-fetch` sends it on request.
452
+ where `--no-fetch` sends it on request. The forge is not asked either: it is
453
+ over the same network, and `gh` waits 30 seconds before saying so, once per
454
+ branch. `--no-fetch` alone says nothing about the network, so it leaves the
455
+ forge asked.
421
456
 
422
457
  Data goes to stdout and diagnostics to stderr, the prompt included, so `--json`
423
458
  is parseable in every mode. Colour is decided per stream and only for a
@@ -472,7 +507,9 @@ is refused with them: it deletes refs without `-d` appearing at all.
472
507
  The Python, the tests and the release procedure are in
473
508
  [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md). The rules the code follows are in
474
509
  [AGENTS.md](AGENTS.md). What changed in each release is in
475
- [CHANGELOG.md](CHANGELOG.md).
510
+ [CHANGELOG.md](CHANGELOG.md). What was decided and what must not break,
511
+ including the alternatives that were closed, is in
512
+ [docs/REFERENCE.md](docs/REFERENCE.md).
476
513
 
477
514
  ## Licence
478
515
 
@@ -24,7 +24,9 @@ invisible to it, so CI is the first thing to format a file you just wrote.
24
24
 
25
25
 
26
26
  The rules this code follows, and the reasoning behind them, are in
27
- [AGENTS.md](../AGENTS.md). This file is what to run.
27
+ [AGENTS.md](../AGENTS.md). What was decided, what must not break and which
28
+ failure classes have a test are in [REFERENCE.md](REFERENCE.md). This file is
29
+ what to run.
28
30
 
29
31
  ## Layout
30
32