586

我想在项目的第一次提交中更改某些内容,而不会丢失所有后续提交。有没有办法做到这一点?

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

4

4 回答 4

895

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

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

最初在这里讨论了这种新行为:

我个人认为git rebase -i --root应该让“”在不需要“ --onto”的情况下直接工作,让你“编辑”甚至是历史上的第一个。
没有人打扰是可以理解的,因为人们在历史开始时重写的频率要低得多。

补丁紧随其后。


(原始答案,2010 年 2 月)

正如Git FAQ(和这个SO question)中提到的那样,这个想法是:

  1. 创建新的临时分支
  2. 将其倒回到您想要更改的提交git reset --hard
  3. 更改该提交(它将是当前 HEAD 的顶部,您可以修改任何文件的内容)
  4. 在更改的提交之上重新设置分支,使用:

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

诀窍是确保您要删除的信息不会被文件中其他地方的稍后提交重新引入。如果您怀疑,那么您必须使用filter-branch --tree-filter以确保该文件的内容不包含在任何提交中的敏感信息。

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

于 2010-02-22T07:20:36.677 回答
281

1.7.12 发行说明中所述,您可以使用

$ git rebase -i --root
于 2013-01-31T15:27:14.847 回答
91

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
于 2010-02-24T00:15:34.563 回答
-2

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

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

于 2010-02-11T17:32:59.180 回答