停止在git中使用一系列提交
发生的事情如下:停止在git中使用一系列提交,git,Git,发生的事情如下: 编写代码 提交(提交:a) 代码起作用了。大家都很高兴 决定添加功能 编写更多代码,并创建提交b、c、d、e和f。这些被推到主回购协议中 意识到这不是最好的方法,我们需要恢复到提交a,因此,我们做了git checkout a并进行了更改,这很有效 现在,我们需要按原样提交代码以掌握它,有效地删除、忽略或跳过提交b-f 我如何告诉git:“是的,我知道我回到了提交a,然后做了一些更改。我不再需要提交b、c、d、e和f中的任何内容。只需按照我现在的方式将提交g作为代码。”?如果你
git checkout a
并进行了更改,这很有效我如何告诉git:“是的,我知道我回到了提交a,然后做了一些更改。我不再需要提交b、c、d、e和f中的任何内容。只需按照我现在的方式将提交g作为代码。”?如果你愿意把所有使用推送主控器的人都搞砸,然后使用Mureinik的建议,只需将git推送--force origin 但是,如果您有其他人使用主分支,并且您希望他们不要在您睡觉时谋杀您,那么: 首先,创建一个新分支。我们称之为“临时工作”: 这将保持您当前的提交 然后,签出主机:
git checkout master
恢复提交b、c、d、e和f:
git revert f e d c b
(这与避免潜在冲突的顺序相反。首先恢复最新的提交将使冲突的可能性降至最低。)
对于每个要还原的提交,您将获得一个编辑器屏幕
最后,将临时工作合并到主程序中:
git merge temp_work
现在可以删除临时工作分支:
git branch -d temp_work
但是,下次,请避免签出旧的提交并在那里进行更改。首先恢复不需要的提交,然后继续正常操作,因为这样可以节省一些工作。但是,除此之外,仍然没有什么大问题。如果你可以把所有使用过你的推送大师的人都搞砸,那么就用Mureinik的建议,只需
git push--force origin
但是,如果您有其他人使用主分支,并且您希望他们不要在您睡觉时谋杀您,那么:
首先,创建一个新分支。我们称之为“临时工作”:
这将保持您当前的提交
然后,签出主机:
git checkout master
恢复提交b、c、d、e和f:
git revert f e d c b
(这与避免潜在冲突的顺序相反。首先恢复最新的提交将使冲突的可能性降至最低。)
对于每个要还原的提交,您将获得一个编辑器屏幕
最后,将临时工作合并到主程序中:
git merge temp_work
现在可以删除临时工作分支:
git branch -d temp_work
但是,下次,请避免签出旧的提交并在那里进行更改。首先恢复不需要的提交,然后继续正常操作,因为这样可以节省一些工作。但除此之外,仍然没有什么大问题。有多种方法可以做到这一点。你应该使用哪一个取决于(a)你希望历史看起来像什么,可能还有(b)“重写历史”的成本是否合理,以及(c)你对(a)或(b)的回答对你来说是否更重要。让我们看看一些选项 无论您还做了什么,您都可能希望从提交新更改开始。这确保了再多的摆弄也不会让你失去它们
git checkout -b temp
git commit
现在,这些新的更改变成了G
,您已经
A -- B -- C -- D -- E -- F <--(master)(origin/master)
\
G <--(temp)
如果其他分支基于F
,则需要将其重设为G
。例如,如果你有
A -- B -- C -- D -- E -- F <--(origin/master)
\ \
G <--(temp)(master) H <--(feature_b)
屈服
A -- B -- C -- D -- E -- F <--(origin/master)
\
G <--(temp)(master)
\
H' <--(feature_b)
此时,所有其他用户都需要恢复同步。如我上面所说,如果每个人都放弃了他们的本地回购协议,他们可以重新克隆,然后重新同步。否则,基于您所替换的任何提交,他们所做的任何本地更改都需要重新设置基础;他们的参考文献必须更新。有关更多详细信息,请参阅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)
A -- B -- C -- D -- E -- F -- ~FEDCB -- M <--(master)
\ /
---------------- G ------------------
对于其中任何一种解决方案,B
到F
仍会出现在历史记录中(例如git log
)。在逐笔回购的基础上,如果开发人员想要隐藏此信息,他们可以提供a
作为G'
之前提交的“替代品”(即G'^
)。有关详细信息,请参阅git replace文档
另一个选项是将G
合并到master
(可能是在还原提交之后)。这会产生类似的结果
A -- B -- C -- D -- E -- F -- ~F -- ~E -- ~D -- ~C -- ~B -- G' <--(master)
A -- B -- C -- D -- E -- F -- ~FEDCB -- M <--(master)
\ /
---------------- G ------------------
A--B--C--D--E--F--~FEDCB--M有多种方法可以做到这一点。你应该使用哪一个取决于(a)你希望历史看起来像什么,可能还有(b)“重写历史”的成本是否合理,以及(c)你对(a)或(b)的回答对你来说是否更重要。让我们看看一些选项
无论您还做了什么,您都可能希望从提交新更改开始。这确保了再多的摆弄也不会让你失去它们
git checkout -b temp
git commit
现在,这些新的更改变成了G
,您已经
A -- B -- C -- D -- E -- F <--(master)(origin/master)
\
G <--(temp)
如果其他分支基于F
,则需要将其重设为G
。例如,如果你有
A -- B -- C -- D -- E -- F <--(origin/master)
\ \
G <--(temp)(master) H <--(feature_b)
屈服
A -- B -- C -- D -- E -- F <--(origin/master)
\
G <--(temp)(master)
\
H' <--(feature_b)
此时,所有其他用户都需要恢复同步。如我上面所说,如果每个人都放弃了他们的本地回购协议,他们可以j