停止在git中使用一系列提交
以下是发生的事情:
git checkout a
并做了一些改变,这些改动都起作用。 现在,我们需要提交代码来掌握,有效地删除,忽略或跳过提交bf。
我怎么告诉git:“是的,我知道我回去提交一个,然后做了修改,我不想再提交任何提交b,c,d,e和f的东西了,只需要提交代码就可以了就像我现在拥有它。“?
如果你把所有使用过你的推主的人都搞砸了,那么就使用Mureinik的建议,只是为了git push --force origin
。
但是,如果您有其他使用主分支的人,并且希望他们不要在睡梦中谋杀你,那么:
首先,创建一个新的分支。 我们称之为“temp_work”:
git checkout -b temp_work
这将保持您当前的提交。
然后,结帐主人:
git checkout master
恢复提交b,c,d,e和f:
git revert f e d c b
(这是以相反的顺序来避免潜在的冲突。最先恢复最新的提交应该给你冲突的可能性最低。)
您将得到一个编辑器屏幕,以便每次提交恢复。
最后,将temp_work合并到master中:
git merge temp_work
您现在可以删除temp_work分支:
git branch -d temp_work
但是,下一次,避免检查旧的提交并在那里进行更改。 恢复您不希望的提交,然后继续正常,因为它可以节省一些工作量。 但否则,仍然没有大问题。
有多种方式可以做到这一点。 你应该使用哪一个取决于(a)你希望历史的样子,以及可能(b)“历史重写”的成本是否合理;(c)你对(a)或(b)的回答是对你更重要。 所以让我们看看一些选项...
无论你做了什么,你都可能想要开始提交新的更改。 这确保了不会有太多的摆弄会让你失去它们。
git checkout -b temp
git commit
现在这些新的变化变成了G
,而你已经变成了G
A -- B -- C -- D -- E -- F <--(master)(origin/master)
G <--(temp)
完成后,您将删除temp
,并且如果G
不是实际解决方案状态的一部分,那么它最终会被清理干净,因此将第一步作为安全网络没有任何坏处。
现在,如果你知道你永远也不会在乎B
通过F
一遍,然后用干净的结果,最简单的解决方案是简单移动master
到G
。 这是历史重写,因为它从参考历史记录中删除提交。 在进行历史重写时,必须与使用回购的其他人协调/可能在“已删除”提交处于其历史记录中时提取了参考。 事情会让历史重写更加难以执行:
F
之上” 如果你有任何这些条件,你可能想要解决一个不同的解决方案。 历史重写的理想情况是,您可以协调所有回购用户
如果你决定重写历史是正确的事情:
首先将指向F
任何参考(例如上例中的master
)移至G
git checkout temp
git branch -f master
如果其他分支已经基于F
,则需要重新分配给G
例如,如果你有
A -- B -- C -- D -- E -- F <--(origin/master)
G <--(temp)(master) H <--(feature_b)
那么你可以说
git rebase --onto temp origin/master feature_b
生产
A -- B -- C -- D -- E -- F <--(origin/master)
G <--(temp)(master)
H' <--(feature_b)
如果你有基于B
, D
或E
(但不是F
)的工作,那可能会更具挑战性,尽管重组也可能是好的。
最后,你“推动”你移动或重新设计的任何分支。 例如
git checkout master
git push -f
此时,所有其他用户需要重新同步。 如果像我上面提到的那样,每个人都扔掉了他们的本地回购,他们可以重新克隆,并且他们恢复同步。 否则,根据您更换的任何提交进行的任何本地更改都需要重新分配; 他们的参考文献必须更新。 有关更多详细信息,请参阅git rebase
文档中的“从上游rebase”恢复。
请注意,如果所有这些听起来都不错,除了要将原始提交B
到F
“保留在旁边”以备将来参考,那么在移动上述过程中的master
之前,您可以标记F
git checkout master
git tag old_master
(事实上,你可以在移动master
之后做到这一点,但是在那个时候找到F
。)
如果历史重写对您的情况不利,那么B
到F
必须留在历史中。 然后,您可以添加一个或多个提交以通过F
“撤消” B
并应用G
如果没有大量已经基于F
的分支,这仍然是最简单的。 在最简单的情况下,你可以
git checkout master
git revert HEAD~4..HEAD
git rebase master temp
git checkout master
git merge temp
给你类似的东西
A -- B -- C -- D -- E -- F -- ~F -- ~E -- ~D -- ~C -- ~B -- G' <--(master)
如果你想直接从F
跳转到G'
(没有显式的提交来恢复更改),你可以改为将G
重新保存到F
(参见git filter-branch
docs)。 或另一种方式来做同样的事情
git checkout temp
git reset --soft master
git commit
git checkout master
git merge temp
有了这些解决方案, B
到F
仍然会出现在历史记录中(例如git log
)。 在回购回购的基础上,如果开发人员想隐藏它,他们可以提供A
作为G'
之前的提交的“替代”(即G'^
)。 有关详细信息,请参阅git replace
文档。
另外一个选择是将G
合并到master
(大概在恢复提交之后)。 这产生类似的东西
A -- B -- C -- D -- E -- F -- ~FEDCB -- M <--(master)
/
---------------- G ------------------
这是可以的,但更难以用替代品“覆盖”历史。 请注意,在这种情况下,您不应该将恢复提交(S)与合并提交结合起来,因为这会产生“恶意合并”并可能导致问题。
链接地址: http://www.djcxy.com/p/49843.html上一篇: Stop using a series of commits in git
下一篇: Best way to recover after creating branch from wrong branch and merging