Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Git & GitHub - Rewriting History

How to rewrite history in Git

Rewriting history in Git involves modifying commits that have already been recorded in a repository. This can be useful for cleaning up commit messages, combining commits, or removing sensitive information. This guide covers various techniques for safely rewriting Git history.

Key Points:

  • Rewriting history can change the commit history of a repository, which can affect collaborators.
  • Common methods for rewriting history include amending commits, interactive rebase, and filter-branch.
  • Use caution when rewriting history on shared branches to avoid disrupting the workflow of others.

Amending Commits

Amend the Most Recent Commit

Use git commit --amend to modify the most recent commit. This is useful for correcting commit messages or adding changes:


# Amend the most recent commit
$ git commit --amend
                

This command opens the default text editor, allowing you to change the commit message. To add changes, stage the changes first, then use --amend:


# Stage the changes
$ git add file.txt

# Amend the most recent commit to include the staged changes
$ git commit --amend --no-edit
                

Interactive Rebase

Rewriting Multiple Commits

Interactive rebase allows you to edit, reorder, and combine commits. Use git rebase -i followed by the commit hash or HEAD~n to specify the range of commits:


# Start an interactive rebase for the last 3 commits
$ git rebase -i HEAD~3
                

Editing Commit Messages

In the interactive rebase editor, replace pick with reword to change commit messages:


# Interactive rebase editor example
reword abc123 First commit
reword def456 Second commit
reword ghi789 Third commit
                

Squashing Commits

To combine commits, replace pick with squash or fixup for the commits you want to combine:


# Interactive rebase editor example
pick abc123 First commit
squash def456 Second commit
squash ghi789 Third commit
                

Using Filter-Branch

git filter-branch is a powerful tool for rewriting history across all commits. It can be used to remove sensitive data or modify file paths:


# Example: Removing sensitive data from history
$ git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch path/to/sensitive/file' \
  --prune-empty --tag-name-filter cat -- --all
                

Note: filter-branch is powerful but can be slow for large repositories. Consider using git filter-repo for faster performance.

Best Practices

Follow these best practices when rewriting Git history:

  • Communicate with Your Team: Inform your team before rewriting shared history to avoid disruptions.
  • Backup Your Repository: Make a backup of your repository before performing significant history rewrites.
  • Use Interactive Rebase for Small Changes: Interactive rebase is ideal for small changes like editing commit messages or combining commits.
  • Use Filter-Branch for Large Changes: Use filter-branch or filter-repo for large-scale history rewriting, such as removing files or sensitive data.
  • Force Push with Caution: If rewriting history on a shared branch, use git push --force with caution and ensure team members are aware.

Summary

This guide covered how to rewrite history in Git, including amending commits, interactive rebase, and using filter-branch. Rewriting history can help you clean up your commit history and remove sensitive information, but it should be done carefully to avoid disrupting your team's workflow.