07 · Branch Management¶
← Overview · Prev: Stash · Next: Hooks →
Create, switch, rename¶
git switch <branch> # old: git checkout <branch>
git switch -c <new-branch> # create and switch (from current HEAD)
git switch -c <new-branch> origin/<branch> # start from a remote branch
git branch -m <old> <new> # rename local branch
git branch -vv # branches with upstream and ahead/behind
git branch --merged main # already merged into main (safe to delete)
git branch --no-merged main # still has unmerged work
Renaming a branch that is already on the remote:
git branch -m <old> <new>
git push origin --delete <old>
git push -u origin <new>
git-adm: git-adm branch rename does all three steps.
Naming¶
Put the ticket key first so tooling can extract it, then a short kebab-case description:
PROJ-1234-fix-login-redirect. git-adm branch create builds the name that way and sanitises the suffix.
Delete branches (local and remote)¶
git branch -d <branch> # safe: refuses if unmerged
git branch -D <branch> # force
git push origin --delete <branch> # remote
# several at once
for b in <branch1> <branch2>; do git branch -d "$b"; git push origin --delete "$b"; done
# everything already merged into main (skips main/master and the current branch)
git branch --merged main | grep -vE '^\*|main|master' | xargs -r git branch -d
# clean up stale remote-tracking refs
git fetch --prune
git-adm:
* git-adm branch delete [name] — -d first, asks before forcing.
* git-adm branch nuke <name> — local and remote, typed confirmation.
* git-adm branch prune — delete local branches already merged into the base.
Reading: https://www.freecodecamp.org/news/how-to-delete-a-git-branch-both-locally-and-remotely
Protect the default branch¶
- Server-side: enable branch protection (required reviews, required CI, no force-push).
- Client-side:
git-admrefuses destructive operations onmain/master, and apre-pushhook can too:
#!/usr/bin/env bash
# pre-push: refuse to push directly to main/master
while read -r local_ref _ remote_ref _; do
case "$remote_ref" in refs/heads/main|refs/heads/master)
echo "Direct pushes to ${remote_ref#refs/heads/} are blocked. Use a PR." >&2; exit 1;;
esac
done
Worktrees: several branches checked out at once¶
git worktree add ../hotfix hotfix-branch # second working directory sharing the same repo
git worktree list
git worktree remove ../hotfix
Faster and safer than stashing when you need to jump to a hotfix and back.
Cherry-pick¶
git cherry-pick <sha> # copy one commit onto the current branch
git cherry-pick A^..B # a range, inclusive
git cherry-pick -x <sha> # record the original SHA in the message
git cherry-pick --continue | --abort