All checks were successful
Build, test and publish / verify (push) Successful in 6m57s
50 lines
2.6 KiB
Markdown
50 lines
2.6 KiB
Markdown
# Local branch cleanup
|
|
|
|
MIT licensed. See [LICENSE.wanjakrah](LICENSE.wanjakrah) and
|
|
[ATTRIBUTION.md](ATTRIBUTION.md).
|
|
|
|
Requires Git, JDK 25 on `PATH`, and a Unix-like system with `env -S`.
|
|
Run from the repository you want to clean (including any subdirectory):
|
|
|
|
```sh
|
|
./git-tools/pruneLocalBranches --check
|
|
./git-tools/pruneLocalBranches -d feature/example
|
|
./git-tools/pruneLocalBranches -d '*'
|
|
./git-tools/pruneLocalBranches --help
|
|
```
|
|
|
|
From another repository, use the absolute path to this script. Its location does
|
|
not select the repository; the current working directory does. Always quote `'*'`.
|
|
Alternatively launch with `java --source 25 /path/to/pruneLocalBranches ...`.
|
|
|
|
The script fetches all origin branches and prunes stale **local** origin tracking
|
|
references. A failed fetch stops the operation. It never pushes, deletes remote
|
|
branches, removes folders, or changes working files.
|
|
|
|
A local branch is eligible only when no same-name branch exists on origin, it is
|
|
not checked out in any worktree, and all its commits are reachable from the current
|
|
`HEAD` or local `main`. Configured upstream names do not affect this decision:
|
|
`S6-deployment` tracking `origin/main` is not protected by that mapping. If local
|
|
`main` is missing, only `HEAD` counts. Neither local branch is updated by fetching.
|
|
Squash/rebase merges can leave different commit identities, so these branches may
|
|
be refused even when their changes were merged. The refusal lists the commits.
|
|
Checked-out branches are always refused, protecting their uncommitted work too.
|
|
|
|
`--check` prints eligibility and protection reasons. Deletion prints the candidates
|
|
and requires exactly `DELETE`; any other response or end of input cancels. Bulk
|
|
deletion skips protected branches and reports why. Before each deletion the script
|
|
rechecks eligibility and verifies that the branch still points to the displayed
|
|
commit. Avoid concurrent Git operations while running it; bulk deletion is not
|
|
atomic, so an error can leave earlier candidates already deleted.
|
|
|
|
Implementation: a Java 25 compact source file runs Git through `ProcessBuilder`
|
|
without a shell. After the explicit safety checks, `git branch -D` removes the local
|
|
ref, bypassing Git's separate upstream-based merge check. No build or dependencies
|
|
are needed. Exit codes: `0` success or cancellation, `1` error/blocked deletion,
|
|
`2` invalid arguments.
|
|
|
|
Run the isolated integration checks with
|
|
`python3 git-tools/test-prune-local-branches.py`. They create temporary repositories
|
|
under the system temporary directory, print their location for inspection, and
|
|
exercise single/bulk deletion, protection rules, cancellation and fetch failures.
|