我想在我的项目的第一次提交中改变一些东西,而不丢失所有后续提交。有什么办法可以做到吗?

我不小心在源代码内的评论中列出了我的原始电子邮件,我想改变它,因为我从索引GitHub的机器人收到垃圾邮件。


当前回答

如1.7.12版本说明中所述,您可以使用

$ git rebase -i --root

其他回答

正如下面ecdpalma所提到的,git 1.7.12+(2012年8月)增强了git rebase的root选项:

"git rebase [-i]——root $tip"现在可以用来重写从"$tip"到根提交的所有历史记录。

这个新行为最初的讨论如下:

我个人认为“git rebase -i -root”应该在不需要“-onto”的情况下工作,并让你“编辑”甚至是历史上的第一个。 没有人费心是可以理解的,因为人们很少在历史开始的时候重写。

补丁紧随其后。


(原答案,2010年2月)

正如Git常见问题(以及这个SO问题)中提到的,这个想法是:

创建新的临时分支 使用git reset将它倒回到你想要更改的提交——很难 更改提交(它将是当前HEAD的顶部,您可以修改任何文件的内容) 在变更提交的基础上重新创建分支,使用: Git rebase - to <tmp branch> <commit after change > <branch> '

诀窍在于确保您想要删除的信息不会在以后的文件其他地方提交时重新引入。如果您怀疑这一点,那么您必须使用filter-branch -tree-filter来确保该文件的内容不包含任何提交的合理信息。

在这两种情况下,您最终都要重写每次提交的SHA1,因此如果您已经发布了要修改内容的分支,请小心。除非您的项目尚未公开,其他人还没有基于您即将重写的提交进行工作,否则您可能不应该这样做。

Git rebase -i允许您方便地编辑任何以前的提交,除了根提交。下面的命令向您展示如何手动执行此操作。

# 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

如果你只想修改第一次提交,你可以尝试git rebase并修改提交,类似于这篇文章: 如何在git中修改指定的提交?

如果你想修改所有包含原始邮件的提交,filter-branch是最好的选择。在Pro Git这本书中有一个如何在全球范围内更改电子邮件地址的例子,你可能会发现这个链接很有用http://git-scm.com/book/en/Git-Tools-Rewriting-History

如1.7.12版本说明中所述,您可以使用

$ git rebase -i --root