繁体   English   中英

无意中合并了大师进入开发和推动

[英]Accidentally merged master into develop and pushed

我在一个git仓库工作,我们维护一个主人和一个开发分支。 在开发之前进行更改并在发布之前合并到master中。 今天我不小心把大师合并到了开发中并推动了结果的发展。 现在开发的git log显示merge develop into master提交。 我需要以某种方式解决这个问题。 我使用git reflog找到了最近的好提交。 恢复它的正确方法是什么?

由于我已经推,我想避免重写历史。 但是,我不确定我是否可以使用git revert 我不相信“恢复错误的合并”howto和其他SO问题适用,因为我想要恢复的提交是自己合并的( https://www.kernel.org/pub/software/scm/git/docs /howto/revert-a-faulty-merge.txt )。

可以使用git revert还原合并。 请注意,当您这样做时,您将使未来“重新合并”变得更加困难。 阅读你密切关注的那条消息 - 它说了很多关于如何使未来“重新合并”的工作 - 但要注意它正在谈论将develop合并到master ,你说你做了相反的,合并的master进入develop

A -- B -- C -- D -- E          <-- master
      \          \
       F - G - H - M           <-- develop

在这种情况下(将master合并为develop而不是相反)你可以选择许多不同的选项,所有选项都有优点和缺点......

最简单的方法,如果它是一个选项,我更喜欢

(0)什么都不做。 如果在CD中合并不会破坏develop分支,那么就这样离开。 后来,有人会git checkout mastergit merge --no-ff develop并得到这个(假设I再加入一个提交以进行develop ):

A -- B -- C -- D -- E -- M2    <-- master
      \          \      /
       F - G - H - M - I       <-- develop

这里merge找到了develop已经完成的工作,因为它从master处分离出来,这是在B 所以它把在FG ,而H ,跳过的任何部分M是来到了master (可能是所有的话),最后提出在I ,使合并提交M2 (因为提交的E ;但如果E不存在,那是因为我使用了--no-ff )。

一些简单的方法有明显的缺点

(1)只是“重写历史”:从分支develop擦除提交M 警告使用该分支即将发生的所有其他人:提交M即将离开,他们应该采取他们必须采取的任何措施来处理这个问题。

(2)停止使用旧名称develop ,创建一个新的分支名称develop1或者其他:

A -- B -- C -- D -- E          <-- master
     |           \
     |             M           <-- develop
      \          /
       F - G - H               <-- develop1

这与选项(1)相同,除了提交M仍然存在,连同其上的分支标签,并且您有一个指向提交H的新/不同分支标签。 您仍需要提醒所有人,但这可能会使他们的工作更轻松。 您可以稍后删除develop ,当每个人都很好。

还原及其缺点

(3)恢复合并。 与链接文章一样,让我们​​使用W来表示新的还原提交:

A -- B -- C -- D -- E          <-- master
      \          \
       F - G - H - M - W       <-- develop

什么在W 无论如何“消除合并的效果”。 在这种情况下,这意味着,在CD执行的任何操作均无法执行。 到目前为止, develop只有FGH的变化。 如果/有人这样做,问题会在以后发生:

git checkout master
git merge develop

第二个命令根深蒂固地查找masterdevelop被拆分的位置,即提交B ,因此它会从那时起获取所有更改。 在这一点上,包括W那些,它们将取消 CD ,而不是你想要的。 它可以在之后修复,但是合并的人必须知道这个“删除CD ”定时炸弹等待它们。

请注意,这与“不执行任何操作”选项(0)中的合并相同。 这里的问题是W内容 在case(0)中,你想要 commit I的内容,但是在这里你不需要 W的内容。

还有一个选择

考虑到上面显示的内容,这可以说是最糟糕的选择,但无论如何我都会列出它:

(4)创建一个包含您要保留的提交副本的全新分支,并将其命名为develop (或者将其命名为其他内容,但之后我们又回到了develop1的情况,你应该只使用那个。)无论你是保留old-develop分支,还是放弃它(通过不标记它) ,由你决定,但我会把它画进去:

       F' - G' - H'            <-- develop
      /
A -- B -- C -- D -- E          <-- master
      \          \
       F - G - H - M           <-- old-develop

这包含在您包含的链接中。 它只适用于更复杂的情况。

您可以通过将本地分支重置为上一次良好提交来解决此问题,然后推送:

git checkout develop
git reset --hard lastgoodcommit
git push origin develop

请注意,默认情况下,您的上游存储库可能会禁止非快进合并。 如果是这样,您将需要在上游修改该选项,执行上述操作,然后恢复原始设置。

我使用GIT Extensions。 有一个功能可以右键单击UI中的修订并还原为它。

是的,您可以还原合并,但您需要指定哪个父级是主线。 既然你将开发合并为master,那么这应该可以解决问题:

git revert --mainline 1 HEAD

为了确保你有你想要的东西,你应该用$ lastgoodcommit做差异,但是,$ lastgoodcommit应该是HEAD ^。 这当然是,如果你没有在合并之上进行提交,如果你有,那么你需要用合并提交替换HEAD。

最后,您还可以通过检查当前提交之上的代码来手动还原:

git checkout $lastgoodcommit -- .

' - 。' 有没有区别于正常结账,其中HEAD切换到指定的提交,在此处的命令中,工作目录中的所有文件和暂存区域将与$ lastgoodcommit中的完全相同。 如果你用$ lastgoodcommit做差异,你应该再次看到没有变化。 基本上它是一个恢复。

您还可以尝试' git checkout --patch '来有选择地还原代码块。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM