563

I want to change something in the first commit of my project with out losing all subsequent commits. Is there any way to do this?

I accidentally listed my raw email in a comment within the source code, and I'd like to change it as I'm getting spammed from bots indexing GitHub.

VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
Michael
  • 10,456
  • 9
  • 36
  • 42

4 Answers4

862

As mentioned by ecdpalma below, git 1.7.12+ (August 2012) has enhanced the option --root for git rebase:

"git rebase [-i] --root $tip" can now be used to rewrite all the history leading to "$tip" down to the root commit.

That new behavior was initially discussed here:

I personally think "git rebase -i --root" should be made to just work without requiring "--onto" and let you "edit" even the first one in the history.
It is understandable that nobody bothered, as people are a lot less often rewriting near the very beginning of the history than otherwise.

The patch followed.


(original answer, February 2010)

As mentioned in the Git FAQ (and this SO question), the idea is:

  1. Create new temporary branch
  2. Rewind it to the commit you want to change using git reset --hard
  3. Change that commit (it would be top of current HEAD, and you can modify the content of any file)
  4. Rebase branch on top of changed commit, using:

    git rebase --onto <tmp branch> <commit after changed> <branch>`
    

The trick is to be sure the information you want to remove is not reintroduced by a later commit somewhere else in your file. If you suspect that, then you have to use filter-branch --tree-filter to make sure the content of that file does not contain in any commit the sensible information.

In both cases, you end up rewriting the SHA1 of every commit, so be careful if you have already published the branch you are modifying the contents of. You probably shouldn’t do it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.

VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • 6
    On OS X Mountain Lion with system-installed git 1.7.9.6 (Apple Git-31.1) I set `` to be the same hash I used in the `git reset --hard` command. Aside from that one minor change, this works beautifully to update the author information across all commits in a repo. – berto Dec 30 '12 at 01:28
  • 4
    can you provide example of what should be $tip. `git rebase -i --root` worked for me. – Rémi Benoit Jun 04 '15 at 17:12
  • @RémiBenoit yes, `$tip` can be any commit you want. `master` (meaning `master HEAD` commit) is fine. – VonC Jun 04 '15 at 17:13
  • @VonC the step 3 needs to edit the commit content. I try to do that using `git reser --soft HEAD~1` but it's not possible because it's an ambiguous argument `HEAD~1` or path not in the working tree. – Francis Rodrigues Aug 26 '18 at 01:44
  • @FrancisRodrigues I believe step 3 was about modifying files, adding and committing – VonC Aug 26 '18 at 11:18
  • I think `Change first commit of project with git` it's possible but we don't mentioned that here. – Francis Rodrigues Aug 26 '18 at 20:56
  • The patch URL is broken. Please update when possible. – code_dredd Nov 16 '18 at 18:23
  • 1
    @code_dredd Thank you. I have restored that link. – VonC Nov 16 '18 at 19:22
  • @VonC Are you sure? The URL I'm referring to is the one that says: "The [patch followed](http://comments.gmane.org/gmane.comp.version-control.git/200687)". It results in a blank page with the following message: "ArchivedAt Nothing found - bye". – code_dredd Nov 16 '18 at 20:02
  • 1
    @code_dredd Sorry, I modified the wrong link. I have fixed my previous "fix". – VonC Nov 16 '18 at 20:13
  • @VonC Looks good. Thanks for the quick fix! – code_dredd Nov 16 '18 at 20:26
  • 1
    The most Epic answer and solution. Amazing! – Rambou Nov 20 '20 at 17:47
263

As stated in 1.7.12 Release Notes, you may use

$ git rebase -i --root
ecdpalma
  • 9,399
  • 3
  • 19
  • 24
90

git rebase -i allows you to conveniently edit any previous commits, except for the root commit. The following commands show you how to do this manually.

# tag the old root, "git rev-list ..." will return the hash of first commit
git tag root `git rev-list HEAD | tail -1`

# switch to a new branch pointing at the first commit
git checkout -b new-root root

# make any edits and then commit them with:
git commit --amend

# check out the previous branch (i.e. master)
git checkout @{-1}

# replace old root with amended version
git rebase --onto new-root root

# you might encounter merge conflicts, fix any conflicts and continue with:
# git rebase --continue

# delete the branch "new-root"
git branch -d new-root

# delete the tag "root"
git tag -d root
Alexsander Akers
  • 15,763
  • 12
  • 55
  • 81
cmcginty
  • 101,562
  • 37
  • 148
  • 155
  • 12
    I followed these instructions like a n00b and they worked perfectly - thanks! You might want to mention adding `-a` to `git commit --amend` or using `git add` because I forgot that first time! – Nick Craig-Wood Nov 11 '12 at 14:42
  • 2
    This is no longer true, please refer to the accepted answer – Robin Kanters May 10 '16 at 12:41
  • 1
    Thanks a lot for your answer. I'm using a Centos 7 and the git version is 1.7.1 with a lot of limitations on commands. The accepted answer did not work for me and this _**how to**_ worked like a charm to rebuild the repository history from _**initial commit**_ – Marcos Regis Jul 04 '16 at 21:25
-2

If you want to modify only the first commit, you may try git rebase and amend the commit, which is similar to this post: How to modify a specified commit in git?

And if you want to modify all the commits which contain the raw email, filter-branch is the best choice. There is an example of how to change email address globally on the book Pro Git, and you may find this link useful http://git-scm.com/book/en/Git-Tools-Rewriting-History

Community
  • 1
  • 1
ZelluX
  • 57,940
  • 18
  • 67
  • 104