【发布时间】:2011-01-15 19:34:29
【问题描述】:
我想在项目的第一次提交中更改某些内容,而不会丢失所有后续提交。有没有办法做到这一点?
我不小心在源代码的评论中列出了我的原始电子邮件,我想更改它,因为我收到了来自索引 GitHub 的机器人的垃圾邮件。
【问题讨论】:
标签: git rebase git-filter-branch
我想在项目的第一次提交中更改某些内容,而不会丢失所有后续提交。有没有办法做到这一点?
我不小心在源代码的评论中列出了我的原始电子邮件,我想更改它,因为我收到了来自索引 GitHub 的机器人的垃圾邮件。
【问题讨论】:
标签: git rebase git-filter-branch
正如ecdpalma below 所述,git 1.7.12+(2012 年 8 月)增强了 --root 的选项 git rebase:
“git rebase [-i] --root $tip”现在可用于将导致“$tip”的所有历史记录重写为根提交。
这个新行为最初是discussed here:
我个人认为应该让“
git rebase -i --root”在不需要“--onto”的情况下直接工作,让你“编辑”甚至是历史上的第一个。
没有人打扰是可以理解的,因为人们在历史开始时重写的频率要低得多。
(原始答案,2010 年 2 月)
正如Git FAQ(和这个SO question)中提到的,这个想法是:
git reset --hard 将其倒回到您要更改的提交
在更改的提交之上重新设置分支,使用:
git rebase --onto <tmp branch> <commit after changed> <branch>`
诀窍是确保您要删除的信息不会被文件中其他地方的稍后提交重新引入。如果您怀疑,那么您必须使用filter-branch --tree-filter 来确保该文件的内容不包含任何提交中的敏感信息。
在这两种情况下,您最终都会重写每次提交的 SHA1,因此如果您已经发布了要修改其内容的分支,请小心。你可能不应该这样做,除非你的项目还没有公开并且其他人还没有基于你将要重写的提交的工作。
【讨论】:
<commit after changed> 设置为我在 git reset --hard 命令中使用的相同哈希值。除了一个小的更改之外,这可以很好地更新 repo 中所有提交的作者信息。
git rebase -i --root 为我工作。
如1.7.12 Release Notes 中所述,您可以使用
$ git rebase -i --root
【讨论】:
如果你只想修改第一次提交,你可以尝试 git rebase 并修改提交,类似于这篇文章: How to modify a specified commit in git?
如果你想修改所有包含原始电子邮件的提交,filter-branch 是最好的选择。 Pro Git 一书中有一个如何全局更改电子邮件地址的示例,您可能会发现此链接很有用http://git-scm.com/book/en/Git-Tools-Rewriting-History
【讨论】:
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
【讨论】:
-a 添加到git commit --amend 或使用git add,因为我第一次忘记了!