繁体   English   中英

合并时避免在另一个Git分支中恢复提交的影响

[英]Avoid the effects of a revert commit in another Git branch while merging

使用git流程。 我们有一个不熟悉Git的同事昨天意外地合并了发展成师。

开发有很多功能,我们的下一个版本将启动,需要恢复合并。 这创建了一个撤消所有更改的提交。 当我们将master合并回develop时,revert commit会删除我们的功能生成的代码。

在保留新功能的同时,能够与master的修补程序同步开发的最佳方法是什么?

- 编辑 - 只是为了澄清,恢复是一个恢复 IE git revert -m 1 <sha> ,因为提交已经被推送到远程存储库。

发布之后,我已经提出了一个可能的解决方案,通过分支主控并恢复还原,但是我很好奇是否有其他可能性可以最小化冲突。

选项1:硬重置和强制推动

如果这是可以做到的非快进强制更新到你的master分支在上游资源库,然后代替恢复的合并develop成为master ,你可以简单地做一个硬复位master

# On master branch, do a hard reset back to the commit before the merge
git reset --hard <commit of master before the merge>

# Force push to upstream ONLY IF IT'S OK WITH OTHER DEVELOPERS
git push <remote> master --force

执行硬重置和强制推送的一个可能的缺点是,如果其他开发人员已经完成了合并提交的工作(即已经在其上进行了提交),那么他们将需要在顶部重做相同的工作master的重置头。 这可能是也可能不是他们的困难/昂贵的任务。

选项2:还原还原

我用快速测试回购测试了这个。 我必须强调它可能会起作用 ,我并非100%确信没有任何我不考虑的情况。 因此,请务必先在本地使用您的repo的备份克隆进行测试。 如果您选择在实际回购中使用此产品,请自行承担风险。

此外,这可能不是最简单/最简单的解决方案。 然而,它优于硬重置选项的优点是它不会迫使开发人员必须在重置master分支之上重做工作。

好了,所有这一切的出路,有一两件事你可以尝试做的是合并masterdevelop ,然后恢复从合并的复归developmaster ,然后合并developmaster ,当你准备好了。 在命令中:

# Coworker accidentally merges develop into master before it's ready
git merge --no-ff develop

# You revert the merge in the master branch (this creates commit "ABCDEFG"
git revert -m 1 <sha of merge commit>

# You want to merge fixes from master into develop
git checkout develop
git merge --no-ff master

# But now all that work in develop is reverted, so revert the revert "ABCDEFG"
git revert ABCDEFG

# When you're ready to merge develop into master...
git checkout master
git merge --no-ff develop

这是我用来在测试仓库中测试它的一系列命令:

mkdir practice
cd practice/
git init

touch readme.txt
git add practice.txt
git commit -m "Add practice.txt"

git checkout -b develop

touch feature1.txt
git add feature1.txt
git commit -m "Add feature 1"

touch feature2.txt
git add feature2.txt
git commit -m "Add feature 2"

git checkout master

touch hotfix1.txt
git add hotfix1.txt
git commit -m "Fix issue 1"

git merge --no-ff develop

# Creates commit "ABCDEFG" that reverts the merge
git revert -m 1 head
git checkout develop
git merge --no-ff master
git revert ABCDEFG
git checkout master
git merge --no-ff develop

您可以在git revert官方Linux Kernel Git文档中阅读有关“还原恢复”技术的更多信息:

-m parent-number

--mainline parent-number

通常,您无法还原合并,因为您不知道合并的哪一侧应被视为主线。 此选项指定主线的父编号(从1开始),并允许恢复相对于指定父级的更改。

还原合并提交声明您永远不会希望合并带来的树更改。 因此,以后的合并只会带来由不是先前还原的合并的祖先的提交引入的树更改。 这可能是也可能不是你想要的。

有关详细信息,请参阅revert-a-faulty-merge How-To

如果您完全想要了解这种技术是如何工作的,那么强烈建议如何恢复错误合并的链接,这并不难理解,实际上它有点有趣且令人着迷。

我的团队发生了类似的事情。 我实际上已经有一个相对简单的解决方案,我只找到了这个帖子,因为我正在研究防止这种情况发生的方法(仍然没有解决方案)。

这是我如何修复它,假设子分支(“develop”)在与master“bad”merge(commit M2)之前被更新(commit M1):

问题状态

           ... <-- Work after revert that needs merged to develop
            |
            R  <-- Revert Bad Merge
            |
            A  <-- Commits after merge,
            |    /   but before revert 
           ... </    and needs merged to develop
            |
           M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

步骤1

# Get latest from both parent and child branches locally

git checkout master
git pull
git checkout develop
git pull


# Merge all code from before revert in master branch to develop
# (not necessary if "bad" merge into master was immediately reverted)

git merge A

第1步之后的状态:

           ... <-- Work after revert that needs merged to develop
   M3       |
   | \____  R  <-- Revert Bad Merge
   |      \ |
   |        A  <-- Commits after merge,
   |        |    /   but before revert
   |       ... </    and needs merged to develop
   |        |
   |       M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

第2步 - 重要部分!

# Use "ours" strategy to merge revert commit to develop.
# This doesn't change any files in develop. 
# It simplly tells git that we've already accounted for that change.

git merge R -s ours

在第2步之后说明

   M4
   | \____  ... <-- Work after revert that needs merged to develop
   M3     \ |
   | \____  R  <-- Revert Bad Merge
   |      \ |
   |        A  <-- Commits after merge,
   |        |    /   but before revert
   |       ... </    and needs merged to develop
   |        |
   |       M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

第3步

# Merge as normal, from the tip of master to develop.
# This should now be an "easy" merge, with only "real" conflicts.
#  (Those that have changed in both branches)
#
# Note: I've had issues using origin master to merge from latest on remote, 
#   so instead I just ensure I've pulled the latest from master locally and 
#   merge from there

git merge master

在第3步之后说明

   M5
   | \_____
   M4      \
   | \____  ... <-- Work after revert that needs merged to develop
   M3     \ |
   | \____  R  <-- Revert Bad Merge
   |      \ |
   |        A  <-- Commits after merge,
   |        |    /   but before revert
   |       ... </    and needs merged to develop
   |        |
   |       M2  <-"bad" merge
  ... ____/ |
   | /      |
   M1       |
   | \____  |
  ...     \...
develop   master 

现在,使用最新的master更新了develop ,而无需解决重复或无意义的合并冲突。 未来的合并也将表现得正常。

暂无
暂无

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

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