◐ Off-By-One · answer catalog

so-git-branch-rename

1 answer(s)shellbash

./git-rename-branch.sh --current

📦 Source in repository (JSON)

Answer

File: /tmp/git-rename-branch.sh — a comprehensive script demonstrating all 5 Git branch rename scenarios with full edge-case handling.

1) Rename current branch

git branch -m <new-name>
# or via the script:
./git-rename-branch.sh --current <new-name>

2) Rename any branch (not checked out)

git branch -m <old-name> <new-name>
# or:
./git-rename-branch.sh <old-name> <new-name>

The script auto-detects if old-name == current branch and uses the single-arg form.

3) Rename + push + set upstream + delete old remote

# Manual:
git branch -m <new-name>
git push -u origin <new-name>
git push origin --delete <old-name>

# Script (one command):
./git-rename-branch.sh --push <old> <new> [remote]

4) Delete stale remote branch after local rename

git push origin --delete <old-name>
git remote prune origin           # clean up local tracking refs

# Script:
./git-rename-branch.sh --delete-remote <old> [remote]

5) Master → Main migration (industry-wide)

# Full sequence:
git branch -m master main
git push -u origin main
git push origin --delete master
# Then in GitHub/GitLab: Settings → Branches → change default to "main"
git remote prune origin

# Script (one command):
./git-rename-branch.sh --master-to-main [remote]

The script also handles git check-ref-format validation, detached HEAD detection, same-name no-ops, non-existent branches, and already-on-main scenarios.


Evidence & signatures

All **23 tests pass** across 10 test suites covering every edge case:

| # | Test | Result |
|---|------|--------|
| 1 | Rename current branch | ✓ old branch gone, new exists, on new branch |
| 2 | Rename non-current branch | ✓ old gone, new exists, stayed on original |
| 3 | Rename + push + set upstream + delete remote | ✓ local, remote, and upstream all correct |
| 4 | Delete stale remote branch | ✓ remote ref removed |
| 5 | Master → Main migration (with remote) | ✓ master gone, main exists, remote master deleted, upstream set |
| 6 | Rename to same name | ✓ graceful no-op |
| 7 | Detached HEAD | ✓ prevented with clear error |
| 8 | Non-existent branch | ✓ fails gracefully |
| 9 | Invalid branch name (`.lock`) | ✓ rejected by `git check-ref-format` |
| 10 | Already on main before migration | ✓ no-op detected |

Edge cases verified:
- **Bare remote refuses to delete HEAD branch**: handled with `receive.denyDeleteCurrent` config note in script output
- **Branch name validation**: uses `git check-ref-format` — catches `..`, spaces, `~^:?*[\`, leading `.`, trailing `.lock`, `@{`
- **Tracking branch format**: upstream stored as `origin/branch` not `refs/remotes/origin/branch`
- **Remote doesn't exist**: skipped gracefully
- **Already on target name**: early return with no-op

---
{"model": "deepseek-v4-flash", "problem_class": "so-git-branch-rename", "result": "passed", "tests": 23}
Generated from the verified corpus · MIT licensedBack to the catalog