以下是发生的事情:
git checkout a
并进行了更改,这些都有效。现在,我们需要提交代码 as-is 来掌握,有效地删除,忽略或跳过提交b-f。
我如何告诉git:"是的,我知道我回去犯了一个,然后做出了改变。我不再需要提交b,c,d,e和f中的任何内容。只需像现在一样完全提交代码。"?
答案 0 :(得分:2)
如果你可以搞砸使用推送大师的每个人,那么请使用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
但是,下次,请避免签出旧提交并在那里进行更改。恢复您不想要的提交,然后从那里继续正常,因为它可以为您节省一些工作。但除此之外,仍然没有大问题。
答案 1 :(得分:1)
有多种方法可以做到这一点。您应该使用哪种方法取决于(a)您希望历史记录的样子,以及可能(b)历史记录的成本是否重写"有意义的,(c)你对(a)或(b)的回答对你来说是否更重要。那么让我们看看一些选项......
无论您做什么,您都可以从提交新更改开始。这样可以确保不会有任何摆弄会导致您失去它们。
git checkout -b temp
git commit
现在,这些新的更改变为G
,而您已
A -- B -- C -- D -- E -- F <--(master)(origin/master)
\
G <--(temp)
当您完成后,您将删除temp
,如果G
不是实际解决方案状态的一部分,那么它最终会被清除,所以作为安全网迈出第一步并没有害处。
现在,如果您知道自己再也不关心B
到F
,那么最简单的解决方案是将master
移至G
}。这是一个历史重写,因为它从ref的历史中删除了提交。在进行历史记录重写时,您必须与使用回购的其他人协调/可能在删除&#34;删除&#34;承诺是其历史。导致历史重写的事情更难以执行:
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
),那可能会更具挑战性,但是变基也可能没问题
最后,你强迫推动&#34;您移动或重新分配的任何分支机构。 e.g。
git checkout master
git push -f
此时,所有其他用户需要恢复同步。如果,正如我上面所建议的,每个人都扔掉了他们的本地回购,他们可以重新克隆,他们会重新同步。否则,根据您已更换的任何提交,他们所拥有的任何本地更改都需要重新设置;他们的参考文献必须更新。请参阅&#34;从上游rebase恢复&#34;在git rebase
文档中了解更多详情。
请注意,如果所有这些听起来都不错,那么您希望保留原始提交B
到F
&#34;关闭到&#34;为了将来参考,然后在上述过程中移动master
之前 ,您可以标记F
。
git checkout master
git tag old_master
(事实上你可以在移动master
之后做到这一点,但此时找到F
会更难。)
如果历史记录重写不适合您的情况,那么B
到F
必须保留在历史记录中。然后,您可以添加一个或多个提交到&#34;撤消&#34; B
到F
并申请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
作为替换&#34;用于G'
之前的提交(即G'^
)。有关详细信息,请参阅git replace
文档。
另一个选项是将G
合并到master
(可能是在还原提交之后)。产生类似
A -- B -- C -- D -- E -- F -- ~FEDCB -- M <--(master)
\ /
---------------- G ------------------
这没关系,但是更难以#34;纸张超过&#34;有替代的历史。请注意,在这种情况下,你应该不将恢复提交(S)与合并提交相结合,因为这会产生一个&#34;邪恶的合并&#34;并可能导致麻烦。