Best Practices
Backup Before Rewriting
Establish a safety net before executing history-rewriting operations like rebase or filter-repo so mistakes are recoverable.
- Individuals or teams who want more predictable Git habits
- Maintainers setting collaboration expectations
- At least one real collaboration loop
- Basic command familiarity without a stable routine yet
- Treating guidance as absolute law without context
- Memorizing process without understanding team boundaries
The short version
History-rewriting operations (rebase, amend, filter-repo, reset, etc.) are high-risk. Before executing them, create a named branch or tag as a safety net — essentially taking a snapshot of the current state so you can return to the origin at any time if something goes wrong.
Create branch backupAdd tagPush to remote
Fast recovery possibleHistory not lostTeam can sync
Pre-rewrite backup is insurance, not paranoia. Whenever you think 'this time nothing will go wrong' is exactly when you need it most.
Why backup is essential
# Rebase without backup
git rebase -i HEAD~10
# Errors during the operation, conflict resolution mistakes, accidental commit deletion...
# Too late; the original commit positions are already lost
# Rebase with backup
git branch backup-before-rebase # Backup first
git rebase -i HEAD~10
# Made a mistake? No problem; return to the backup at any time
git reset --hard backup-before-rebase
Backup strategies
Strategy 1: Backup branch (most common)
# Create a backup branch before starting the rewrite
git branch backup/main-$(date +%Y%m%d-%H%M%S)
# Or more semantic naming
git branch backup/before-rebase-sprint-2024
git branch backup/before-filter-repo-cleanup
# After completion, if everything went well, delete the backup
git branch -d backup/main-20240115-143022
Strategy 2: Backup tag (more durable)
# Tags are not affected by regular branch cleanup; they are more durable
git tag backup/before-rebase-$(date +%Y%m%d)
# Delete after completion
git tag -d backup/before-rebase-20240115
Strategy 3: Remote backup (highest security)
# Push the current state to the remote
git push origin main:backup/main-$(date +%Y%m%d)
# Even if the local repository is corrupted, the remote still has a backup
Backup checklist for common rewrite scenarios
Interactive rebase
# 1. Backup
git branch backup/before-rebase
# 2. Run rebase
git rebase -i HEAD~5
# 3. If satisfied, delete backup
git branch -d backup/before-rebase
# 4. If not satisfied, restore
git reset --hard backup/before-rebase
Amend commit
# Even for a simple amend, it is recommended to mark the position first
git tag backup/before-amend
git commit --amend
# If you regret it, come back
git reset --hard backup/before-amend
Filter-repo (cleaning history)
# filter-repo is an extremely destructive operation; multiple backups are required
# 1. Local backup branch
git branch backup/before-filter-repo
# 2. Remote backup
git push origin main:backup/main-before-cleanup
# 3. Filesystem backup (clone --mirror)
git clone --mirror . ../repo-backup.git
# 4. Run filter-repo
git filter-repo --path src/old-module/ --invert-paths
# 5. Verify results are correct before cleaning up backups
Batch cherry-pick
# Cherry-picking multiple commits is error-prone
git branch backup/before-cherry-pick
git cherry-pick abc1234 def5678 ghi9012
# If there are too many conflicts, just abort
git cherry-pick --abort
git reset --hard backup/before-cherry-pick
Automated backup script
# scripts/git-backup.sh
#!/bin/sh
action="$1"
branch=$(git branch --show-current)
timestamp=$(date +%Y%m%d-%H%M%S)
backup_name="backup/${branch}-${action}-${timestamp}"
git branch "$backup_name"
echo "Created backup branch: $backup_name"
echo "If something goes wrong, run:"
echo " git reset --hard $backup_name"
Backup naming conventions
# Recommended format
backup/<branch>-<action>-<YYYYMMDD-HHMMSS>
# Examples
backup/main-rebase-20240115-143022
backup/feature-auth-filter-repo-20240115-160000
backup/main-before-amend-20240115-102030
# Avoid
backup1 # No idea what was backed up
old-main # No idea from what point in time
tmp # Easily cleaned up
Cleaning up backups
# View all backup branches
git branch | grep backup/
# Delete backups that are confirmed safe
git branch -d backup/main-rebase-20240115-143022
# Bulk cleanup of backups older than one week (use with caution)
git branch | grep "backup/" | while read branch; do
# Check backup branch dates, delete old ones
# ...
done
Team policy recommendations
# Document clearly in team documentation:
#
# The following operations must create a backup:
# - Any interactive rebase (git rebase -i)
# - Modifying already-pushed commits (git commit --amend + force push)
# - History cleaning (git filter-repo, BFG)
# - Batch cherry-pick (more than 3 commits)
# - Any unfamiliar operation attempted for the first time
#
# The following operations are recommended to create a backup:
# - Ordinary rebase
# - reset --hard
# - Complex merge conflict resolution
Best practices summary
- Backup before operating: Make creating a backup muscle memory; do not ask "do I need one this time?"
- Semantic naming: Backup names include branch, operation, and time; clear at a glance
- Keep a remote copy: Push to the remote for important operations
- Verify before cleaning: Do not rush to delete backups; ensure the rewrite result is correct and has been stable for some time
- Team-wide policy: Write "backup before operating" into onboarding docs and team policies
- Leverage reflog: Even without a backup, the reflog can usually rescue you, but do not rely on it
- Practice recovery periodically: Occasionally use a backup branch to do a recovery drill to ensure the process works
Key takeaways
git branch backupcreates a lightweight reference that takes almost no space; do not hesitate- Backup branches do not auto-update; they are just snapshots of a point in time
- After rewriting shared branch history, collaborators need to resync; backup branches can help coordinate
- For operations like filter-repo that completely rewrite history, a filesystem-level
--mirrorclone is the safest - Do not push backup branches to the shared repository's default namespace; isolate them with a
backup/prefix
Previous / Next
PreviousBisect-Friendly CommitsBest Practices
NextNo more reads in this direction