Skip to content

feat(devtools): prune merged local branches after a pull - #59

Merged
davidmoralesz merged 1 commit into
mainfrom
feat/prune-merged-branches
Oct 9, 2026
Merged

davidmoralesz merged 1 commit into
mainfrom
feat/prune-merged-branches

Conversation

@davidmoralesz

Copy link
Copy Markdown
Contributor

What

Adds a shared post-merge job to lefthook/org.yml. After a git pull on the default branch it deletes local branches whose pull request has merged.

A branch is deleted only when all of these hold:

  • its remote branch is gone
  • it is not checked out in any worktree
  • its work is in the default branch: the tip is an ancestor of it, or (for a squash merge, which leaves no ancestry) gh reports a merged PR whose head is exactly the local tip

Anything else is kept and named, so commits made after the merge, or a PR closed unmerged, are never lost. Without gh, a squash-merged branch is kept rather than guessed at. The script always exits 0, and --dry-run shows what it would do.

Files

  • .devtools/prune-merged-branches.sh: the logic
  • .lefthook/post-merge/prune-branches.sh: wrapper lefthook finds, like the pre-push ones
  • lefthook/org.yml: the post-merge job
  • .devtools/test-hooks.sh: cases for ancestry merge, gh-confirmed squash, squash with a moved head, closed unmerged, live remote, worktree, non-default branch, dry run
  • README.md: short section

Testing

  • bash .devtools/test-hooks.sh: passes, with gh stubbed
  • shellcheck, prettier, gitleaks and commitlint via the repo's own hooks: pass
  • End to end: a throwaway consumer pulling lefthook/org.yml through remotes pinned to a tag, then a real git pull after a merge. The ancestry-merged branch was deleted; the squash-merged (no PR for gh to confirm), closed and live branches were kept
  • Not tested against real GitHub: the gh pr list path is covered only by the stub

Notes

  • Consumers get this once a release is cut and their lefthook.yml bumps ref and runs lefthook install. Repos still on pre-commit need the lefthook migration first.
  • While testing, ref: <branch> with refetch: true (the tip in AGENTS.md) made hooks report "script does not exist" when git ran them; a pinned tag without refetch worked. Cause not confirmed, left unchanged here.

@davidmoralesz
davidmoralesz merged commit 254b8cc into main Oct 9, 2026
6 checks passed
@davidmoralesz
davidmoralesz deleted the feat/prune-merged-branches branch October 9, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant