Git¶
Convenience recipes for inspecting, working with, and cleaning up git repositories. All recipes run in the current
directory ([no-cd]).
Info¶
log shows a compact graph of the last 30 commits — useful for orienting yourself on a branch. branches lists all
branches (local and remote) sorted by most recent commit, so stale branches sink to the bottom. recent filters to
commits from the last 7 days. stats gives a per-author commit count. stashes lists the stash stack.
inspect [branch] (defaults to current; -i for fzf picker) shows enough about a branch to decide whether it's safe to
delete: tip (sha + date + author + subject), upstream state, and which other refs (local + remote) also contain the tip.
The "Contained in" line is the key fact — if it's empty AND upstream is gone or absent, deleting the branch will orphan
its unique commits (recoverable via reflog for ~90 days, or until git gc --prune=now runs).
leak-check runs betterleaks against unpushed commits (@{u}..HEAD) — the same scan the pre-push hook performs, but on
demand. Useful before a push when you want manual confirmation a stack is clean. --full / -f widens to every
reachable object (branches, tags, stashes, reflog) — findings inside stashes are usually safe (stashes don't push) but
worth knowing about if you intend to share the .git/ or unstash old work.
Upstream-state shorthand (from git status / git for-each-ref):
| Display | Meaning |
|---|---|
up-to-date |
local matches upstream |
[ahead N] |
local has N commits upstream doesn't — git push to publish |
[behind N] |
upstream has N you don't — git pull (or rebase) to catch up |
[ahead N, behind M] |
diverged, both sides have unique commits — rebase or merge to reconcile |
[gone] |
upstream ref deleted (e.g. PR merged + branch removed on the remote) |
none (never tracked) |
branch has no upstream tracking ref configured |
Config¶
get-identity shows the current repo's user.name and user.email — quick check before pushing under the wrong
identity. set-identity sets them (defaults to the dotfiles identity). Useful when cloning into a fresh repo that
doesn't yet have an identity, or when switching between work and personal repos. The dotfiles config has
useConfigOnly = true, which refuses commits without an explicit per-repo identity.
Workflow¶
undo soft-resets the last commit — changes stay staged. Use this when you committed too early or with the wrong
message. Follow up with git commit to redo it. Always asks for confirmation; if the commit has been pushed you get a
second confirmation about rewriting shared history (you will need to force-push afterwards).
amend folds staged changes into the last commit. Default opens $EDITOR on the commit message (matching
git commit --amend); pass -n / --no-edit to keep the existing message. Always asks for confirmation; if the commit
has been pushed you get a second confirmation about rewriting shared history (force-push afterwards).
unstage removes everything from the staging area without touching the working tree. Equivalent to git reset HEAD.
checkpoint creates a stash backup of all changes (including untracked files), verifies the working tree is clean, then
restores your working tree. The stash entry remains as a safety net. Does nothing if the tree is already clean. The
default message includes a timestamp but you can override it: just git checkpoint "before big refactor".
wip / unwip are a paired workflow. wip stages everything (including untracked files) and commits with the message
chore: wip checkpoint — it shows what was staged so you can spot surprises. The conventional-commits prefix (chore:)
is required because the commit-msg hook enforces format. unwip reverses it by matching the exact subject string, so
you won't accidentally undo real work.
move-to-branch rescues commits made on the wrong branch ("I committed to main by mistake"). Moves the last N commits
from the current branch to a new (or fork-aligned) target via ref shuffling — original commit SHAs preserved, no replay,
no merge conflicts mid-operation. Target must be new or already at the fork point (HEAD~N); for other target states
(divergent, behind, unrelated) the recipe refuses and prints exact copy-pasteable cherry-pick / rebase commands.
just git move-to-branch feature/my-fix # move last commit
just git move-to-branch feature/my-fix 3 # move last 3 commits
Design rationale, primitive comparison table, refusal reasons, and manual workflows for each primitive live in the
DESIGN NOTES block at the top of ~/.local/bin/git-move-to-branch.sh.
Cleanup¶
prune [branch] deletes a single local branch with informed confirmation:
- No arg: picks from branches merged into current (fzf if available, numeric menu fallback). Protected branches and the current branch are never offered.
- Named: skips the picker, goes straight to inspect + confirm. Protected branches are refused before deletion (the picker filter doesn't apply on this path).
Protected patterns live in home/.chezmoidata/data.yaml under git.protected_branches — bash regex, not auto-anchored.
Defaults match exact main/master/develop and any branch with release in the name (e.g. release/v1,
pre-release). Edit the data file to add patterns.
Always shows inspect output for the branch first so you see the tip, upstream state, and which other refs also contain
the commits — then asks to confirm. Uses git branch -d (safe delete); refuses unmerged branches. "Merged" here is
relative to your current branch — a branch may show as merged into feature/A while never reaching main. The inspect
output's "Contained in" line tells you which other refs hold the commits.
gc runs git gc by default — compacts the object database, prunes unreachable objects older than 2 weeks
(gc.pruneExpire). Recent orphaned commits/stashes stay recoverable via git fsck --lost-found. Pass
-p/--prune-now to purge unreachable objects immediately — destructive, inline danger confirmation, no recovery
after.
nuke is a destructive reset: discards all uncommitted changes and removes untracked files. Two confirmations (one for
the recipe, one for _ensure-really-sure) because there's no recovery. Use to get back to a known clean state.