Rewriting History

Rewriting Git history to tidy up commits before they are shared with anyone else.

Once a commit is pushed, its hash is part of what everyone else has. Rewriting history means giving a commit a new hash, which is why the tools here are for fixing history before it is shared, or in a repository you alone control.

The smallest tool is git commit --amend, which replaces the most recent commit. That handles a bad message or a forgotten file, and nothing more.

For older commits, git rebase -i opens a list of the commits on your branch and lets you choose what happens to each one: keep it, squash it into the one below, reword it, drop it, or reorder it.

git rebase -i HEAD~5

Squashing a run of "fix typo" commits into one is the everyday use. Reordering commits so they build is the other.

git filter-branch and its modern replacement git filter-repo rewrite history across many commits at once, changing file contents or paths throughout. Reach for them when a secret was committed and needs removing, or when a file has to be renamed in every commit that touched it. Both rewrite every affected hash.

If a rebase goes wrong before it finishes, git rebase --abort puts you back. After it finishes, Git Reflog still has the original commits.

None of this is safe on a shared branch once others have pulled. If in doubt, make a backup branch before you start.

Free Resources

official: