更改 任何提交在技术上是不可能的。但这并不是真正的问题,因为用新的和改进的替换替换一个提交,甚至整个提交链在技术上是简单和容易的。这里的问题不是替换提交,而是因为 Git 是分布式,更新存储库的每个副本,包括其他人制作的所有克隆 em>。
在你做任何其他事情之前,你必须首先回答的问题是:还有谁有这个提交?要进行你所做的提交,你必须有给了别人。一旦其他人拥有它,他们可能会告诉他们的朋友,他们会告诉他们的朋友,并且在几毫秒内,您所做的一次提交就会通过一万个克隆传播。
通常,您会使用 git push 向 GitHub 提交新的提交。如果你已经提交了git push,那么至少 GitHub 上的 Git 存储库有你的提交。 可以在那里访问您的存储库的任何其他人也可能从那里复制了它。他们都会从你之前的提交切换到你新的和改进的提交吗?如果是这样,请随意用新的和改进的提交替换你的错误提交。或者,如果其他人不应该拥有它,或者您不在乎他们是否拥有,那么您可以继续。
因此有两个步骤:在本地替换提交,然后说服其他 Git 也这样做
要在本地替换提交,您可以:
- 使用
git commit --amend(最后一个最简单)
- 使用
git reset,正如刚刚发布的另一个答案中所述
- 使用
git rebase -i,如 cmets 和链接的几乎重复项中所建议的那样
- 做任何你喜欢的事情:这个存储库是你的克隆,你可以做任何你想做的事!但以上三种方法可能是最简单的。
一旦你完成了本地替换,你必须说服另一个 Git——GitHub 上的那个或者你git push 所在的任何地方——他们应该抛弃旧的提交,转而使用新的和改进的替换提交。为此,您通常需要使用git push --force 或git push --force-with-lease。
两个操作都告诉另一个 Git:是的,我知道这个操作会丢弃一些旧的提交。无论如何都要这样做!他们把原本礼貌的请求变成了一个礼貌的要求,请,如果没问题,请将您的分支名称设置为一个强有力的命令:设置您的分支名称! 只要你有权提出这样的要求,其他 Git 就会服从你的 Git 的强制推送。
普通的git push --force 和git push --force-with-lease 之间的区别在于,使用--force-with-lease,你的Git 会发送一个更复杂的命令,格式如下:我认为你的分支_____ 指向提交_____。如果我是对的,请将其设置为 _____。无论哪种方式,如果我是对的,请告诉我。(你的 Git 用你希望 他们的 Git 更改的分支名称填充这些空白 - 即你在 @987654332 中使用的名称@——以及两个提交哈希 ID。)
这意味着--force-with-lease 选项可让您更新共享 GitHub 存储库,同时检查您所做的是否只是 替换您的错误。如果您的 GitHub 存储库未共享,则不需要更高级的选项。
使用git commit --amend 很容易
在你提交之后,如果你意识到它有一些小问题,你只需:
- 修复任何需要的文件,如果需要,
git add 他们
- 然后运行
git commit --amend
--amend 选项告诉你的 Git:把最后一个提交推开,让这个新的提交替换它而不是添加它。你有机会编辑提交消息再一次——你可以使用--no-edit 来抑制它,如果提交 message 是好的——当你完成后,旧的提交就看不到了。它仍然存在于您的存储库中,只是您再也无法看到了。旧的提交会保留一段时间——默认情况下至少 30 天——如果需要,你可以取回它,但大多数情况下,它已被新的替换;新的就是你将看到的。
将旧的提交推开并用一个新的和改进的提交替换它,您现在可能需要使用 git push --force 或 git push --force-with-lease 来说服另一个 Git 存储库也推旧的承诺不妨碍新的承诺。请记住,这个 other Git 存储库如果是共享的,现在可能会在 your 提交之上构建多个贡献者的 新 提交:推你的除此之外,您还必须将所有他们的都推到一边!