11

使用 git 流。我们有个不熟悉Git的同事昨天不小心把develop合并成了master。

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

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

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

自从发布此内容以来,我提出了一个可能的修复方法,即通过分支 master 并恢复还原,但是我很好奇是否还有其他可能性可以最大限度地减少冲突。

4

2 回答 2

14

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

如果可以对上游存储库中的分支进行非快进强制更新,那么您可以简单地对 进行硬重置,master而不是恢复develop into的合并:mastermaster

# 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% 确信没有任何我没有考虑过的情况。因此,请务必先使用您的存储库的备份克隆在本地对其进行测试。如果您选择在实际回购中使用它,请自行承担风险。

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

好的,除了所有这些,您可以尝试做的一件事是合并 masterdevelop,然后将合并的还原从developinto 恢复,然后在您准备好时master合并develop到。master在命令中:

# 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

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

-m parent-number

--mainline parent-number

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

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

有关更多详细信息,请参阅恢复错误合并操作方法。

如果您完全想了解此技术的工作原理,强烈建议您使用如何恢复错误合并的链接,它并不难理解,而且它实际上有点有趣和迷人。

于 2013-07-25T00:24:59.023 回答
4

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

这是我修复它的方法,假设子分支(“开发”)在与主分支“错误”合并(提交 M2)之前更新(提交 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 

Nowdevelop使用最新的 from 更新master,无需解决重复或无意义的合并冲突。未来的合并也将正常运行。

于 2017-10-09T22:00:22.903 回答