Questions tagged [git-rewrite-history]

Rewriting the history of a Git repository, for example to edit old commits, remove unwanted data (e.g. private data or large files), rearrange file structure, fix commit metadata, etc.

There are many motivations for wanting to rewrite Git history:

  • Fixing up an old commit
  • Reducing repository size by removing large files previously checked into the repo - they still take up disk space even if removed from later commits
  • Removing sensitive data (passwords, credentials, etc) which you wouldn't want to share when sharing the repo, or even just moving a repo to an external hosting provider
  • Re-arranging or removing entire folders to reflect the splitting up of many sub-projects from one repo to many, or vice-versa

Git repositories store the whole of project history, and by design Git commits are immutable (their id changes completely if even a small part of their content or history is changed) - so how can you remove unwanted data stored deep in your repository’s past?

Tools for rewriting history

Changing history in a Git repository means rewriting all of the subsequent commit history from that point. There are several tools available to let you do this:

  • git commit --amend - for fixing the most recent commit you just made.
  • git rebase to rebase a branch's history, replaying it to look as though it was all based on a different (often newer) point in the repository's history. Used with the -i flag, can be used to interactively re-order history.
  • git filter-branch - an automated tool to rewrite many commits (on many branches) using one or more shell-scripts to make the alterations, which gives it great flexibility.
  • The BFG Repo-Cleaner - an alternative to git-filter-branch which achieves greater speed & usability by restricting itself to common use-cases around the task of removing unwanted data.

Sharing the rewritten history

If a repository has been shared prior to the rewrite, it's necessary to afterwards push the rewritten version to the main server with a --force or --mirror flag, and then request other users to re-clone the repository.

321 questions
7650
votes
27 answers

How to modify existing, unpushed commit messages?

I wrote the wrong thing in a commit message. How can I change the message? The commit has not been pushed yet.
Laurie Young
  • 136,234
  • 13
  • 47
  • 54
3127
votes
19 answers

How do I modify a specific commit?

I have the following commit history: HEAD HEAD~ HEAD~2 HEAD~3 git commit --amend modifies the current HEAD commit. But how do I modify HEAD~3?
Sam Liao
  • 43,637
  • 15
  • 53
  • 61
2974
votes
41 answers

How do I change the author and committer name/email for multiple commits?

How do I change the author for a range of commits?
1085
votes
30 answers

How can one change the timestamp of an old commit in Git?

The answers to How to modify existing, unpushed commits? describe a way to amend previous commit messages that haven't yet been pushed upstream. The new messages inherit the timestamps of the original commits. This seems logical, but is there a…
Dhskjlkakdh
  • 11,341
  • 5
  • 22
  • 17
1062
votes
23 answers

How to remove/delete a large file from commit history in the Git repository?

I accidentally dropped a DVD-rip into a website project, then carelessly git commit -a -m ..., and, zap, the repo was bloated by 2.2 gigs. Next time I made some edits, deleted the video file, and committed everything, but the compressed file is…
culebrón
  • 34,265
  • 20
  • 72
  • 110
736
votes
24 answers

How to squash all git commits into one?

How do you squash your entire repository down to the first commit? I can rebase to the first commit, but that would leave me with 2 commits. Is there a way to reference the commit before the first one?
Verhogen
  • 27,221
  • 34
  • 90
  • 109
506
votes
12 answers

Remove sensitive files and their commits from Git history

I would like to put a Git project on GitHub but it contains certain files with sensitive data (usernames and passwords, like /config/deploy.rb for capistrano). I know I can add these filenames to .gitignore, but this would not remove their history…
Stefan
  • 9,289
  • 7
  • 38
  • 46
434
votes
12 answers

How do you fix a bad merge, and replay your good commits onto a fixed merge?

I accidentally committed an unwanted file (filename.orig while resolving a merge) to my repository several commits ago, without me noticing it until now. I want to completely delete the file from the repository history. Is it possible to rewrite…
Grant Limberg
  • 20,913
  • 11
  • 63
  • 84
403
votes
5 answers

Edit the root commit in Git?

There's ways to change the message from later commits: git commit --amend # for the most recent commit git rebase --interactive master~2 # but requires *parent* How can you change the commit message of the very first commit…
13ren
  • 11,887
  • 9
  • 47
  • 64
299
votes
8 answers

How to amend several commits in Git to change author

I have made a series of commits in Git and I realise now that I forgot to set my user name and user email properties correctly (new machine). I have not yet pushed these commits to my repository, so how can I correct these commits before I do so…
pauldoo
  • 18,087
  • 20
  • 94
  • 116
257
votes
5 answers

Rebasing a Git merge commit

Take the following case: I have some work in a topic branch and now I'm ready to merge back to master: * eb3b733 3 [master] [origin/master] | * b62cae6 2 [topic] |/ * 38abeae 1 I perform the merge from master, resolve the conflicts and now…
jipumarino
  • 2,573
  • 2
  • 15
  • 5
237
votes
6 answers

How to amend older Git commit?

I have made 3 git commits, but have not been pushed. How can I amend the older one (ddc6859af44) and (47175e84c) which is not the most recent one? $git log commit f4074f289b8a49250b15a4f25ca4b46017454781 Date: Tue Jan 10 10:57:27 2012…
michael
  • 106,540
  • 116
  • 246
  • 346
230
votes
9 answers

Combine the first two commits of a Git repository?

Suppose you have a history containing the three commits A, B and C: A-B-C I would like to combine the two commits A and B to one commit AB: AB-C I tried git rebase -i A which opens up my editor with the following contents: pick e97a17b B pick…
Christian
  • 9,914
  • 6
  • 45
  • 52
202
votes
3 answers

Remove refs/original/heads/master from git repo after filter-branch --tree-filter?

I had the same question as asked here: New git repository in root directory to subsume an exist repository in a sub-directory I followed this answer here: New git repository in root directory to subsume an exist repository in a sub-directory Now,…
goofeedude
  • 2,123
  • 2
  • 13
  • 4
151
votes
4 answers

Purging file from Git repo failed, unable to create new backup

I tried to remove a file from my remote repo by running: git filter-branch --index-filter 'git rm --cached --ignore-unmatch Rakefile' HEAD But Git complains that Cannot create new backup. A previous backup already exists in refs/original/ Force…
Cardin
  • 5,148
  • 5
  • 36
  • 37
1
2 3
21 22