Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用git merge,如何将错误修复合并到多个长期分支中?_Git_Merge - Fatal编程技术网

使用git merge,如何将错误修复合并到多个长期分支中?

使用git merge,如何将错误修复合并到多个长期分支中?,git,merge,Git,Merge,最近在工作中,我们已经从使用SVN切换到使用git。我们必须维护软件的多个版本,以前我们将它们设置为分支。因此,在使用了git svn clone之后,我们得到了4个分支:master、5.0、5.1和5.2 注:我们使用master作为我们的开发分支。5.0、5.1和5.2所有来自master和的分支都用作生产分支 几天过去了,大师经历了不少变化。5.2中刚发现一个bug,我们想修复它。我们已经尝试了解决方案,但运气不太好。我们总是可以很容易地合并回master,但每当我们合并回5.2时,就会

最近在工作中,我们已经从使用SVN切换到使用git。我们必须维护软件的多个版本,以前我们将它们设置为分支。因此,在使用了git svn clone之后,我们得到了4个分支:master、5.0、5.1和5.2

注:我们使用master作为我们的开发分支。5.0、5.1和5.2所有来自master和的分支都用作生产分支

几天过去了,大师经历了不少变化。5.2中刚发现一个bug,我们想修复它。我们已经尝试了解决方案,但运气不太好。我们总是可以很容易地合并回master,但每当我们合并回5.2时,就会遇到一系列冲突。我们所看到的显示此过程的一切(为bugfix创建一个新分支并将其合并回开发和生产中)都表明,它应该简单到:

(master)$ git checkout -b bugfix
# fixed bug and committed

(bugfix)$ git checkout master
(master)$ git merge bugfix
# successful merge

(master)$ git checkout 5.2
(5.2)$ git merge bugfix
# successful merge
然而,对于我们来说,当我们到达最后一行时,
git-merge-bugfix
。我们在错误修复中甚至没有涉及的文件冲突。我们做错了什么

注意:我们还尝试通过从5.2启动bugfix分支来完成这个过程。然后将错误修复合并到5.2中是很容易的,但是将错误修复合并到master中会产生冲突

显示流程的其他位置:

  • (滚动至“最终用户发现错误”)

几年前,我们将一个非常大的项目从SVN转移到git。这是我不断提出的问题

首先(这一部分不是对你问题的回答,而是对“你为什么要问这个问题?”)的回答),阅读以下内容: 暂时接受它可能是正确的,这意味着放弃一些SVN思维。这对我来说是最难的一点

现在你已经做到了,我来回答这个问题

最佳路线是:

  • 确保始终可以将任何较旧的分支合并到任何较新的分支中,而不会影响较新的分支

  • 在您希望修复的最旧分支上执行您需要修复的任何错误修复。然后按顺序将其合并到新分支中,并在执行过程中修复合并冲突

做第二件事会使第一件事始终有效(如果你仔细想想的话)

如果任何给定分支中的变更集始终包含所有旧分支中的所有变更集,则此技术可扩展到不同年龄段的许多分支

然而,上述第二点假设了一个理想世界,其中:

  • 在进行bug修复时,您确切地知道您需要在哪个分支中执行bug修复(即,没有人会对您说“嘿,我们需要将bug修复后端口,这也会给客户X带来问题”)

  • <> >对于每个分支,bug修复总是相同的(例如,对旧的分支做一个带辅助的最小熵修复)。

您可以通过使用
git cherry pick
将提交选择到较旧的分支中来解决这些问题中的第一个。但是(这是重要的一点)将修复合并到较新的分支中(即使它已经存在)。您可以明智且非常小心地使用:

git checkout newer
git merge older   # check it's all merged up
git checkout older
git cherry-pick xxxxx
... fix up cherry pick, check it works ...
git checkout newer
git merge -s ours older
请注意,这会标记合并,但实际上会忽略旧分支中已更改的所有内容,因此在更改之前检查合并非常重要


第二种情况也可以类似地处理。将真正的修复应用于较新的
。检查
较旧的
合并到较新的
中,然后将您的绷带应用于较旧的
中,然后使用
git merge-s ours older

git merge
是自公共基础以来所有更改的一部分。如果您想记录一次刚刚开始的合并e更改为多个历史,您必须使其成为所有历史中某些祖先内容的唯一更改,如下所示:

git checkout -b bugfix `git merge-base 5.0 5.1 5.2 master`
# so now bugfix is an ancestor of all of the above

# fix the bug here, then:
git commit -m 'bug fixed'

git checkout 5.0; git merge bugfix     # bugfix has just the one change
git checkout 5.1; git merge bugfix
git checkout 5.2; git merge bugfix
git checkout master; git merge bugfix

最好是一路返回,并在最初引入错误的提交后进行分支修复,但如果它已经存在足够长的时间,这并不总是能够实现干净的合并。

我们的问题源于
git svn clone
。尽管它确实给了我们一个git repo,并且似乎给了我们正确的分支,但是软管分支实际上并不像我们预期的那样来自master。这相当令人困惑,因为当我们查看日志时,我们可以看到分支创建之前的日志在两个分支上具有相同的哈希值。事实上,唯一提示我们发生这种情况的是查看来自Ortoisegit的修订图.我没有截图,但这基本上就是图表的样子:

    5.2          master
 origin/5.2   origin/master
      `-.       .-'
         `-. .-'
        a3f2d6205
因此,我们可以看到,这两个分支都源自根提交
a3f2d6205
。我们需要使其成为5.2源于master。下面是我们采取的一些步骤,这些步骤成功地实现了这一目标

(master)$ git reset --hard 0b73ab0
(master)$ git branch 5.2.new
(master)$ git merge --no-ff --log origin/master
(master)$ git push origin master
(master)$ git checkout 5.2.new
(5.2.new)$ git merge -Xtheirs --log origin/5.2
(5.2.new)$ git push -u origin 5.2.new
(5.2.new)$ git push origin --delete 5.2

# hopped on the "central" git repo
(master)$ git branch -m 5.2.new 5.2

# run these commands for all of the developers repos
(master)$ git pull
(master)$ git remote prune origin
  • (master)$git reset--hard 0b73ab0
    -
    0b73ab0
    是5.2分支的提交
  • (master)$git branch 5.2.new
    -从这一点创建一个新分支
  • (master)$git merge--no ff--log origin/master
    -我们需要将master恢复到原来的位置,但不管出于什么原因,如果它进行快进合并,它会弄乱词干,所以请将其标记为
    --no ff
    ,以确保不会发生这种情况
  • (master)$git push origin master
    -将我们的新master推送到服务器
  • (主控)$git checkout 5.2.new
    -checkout 5.2.new
  • (5.2.new)$git merge-Xtheirs-log origin/5.2
    -我们需要将5.2备份到应该的位置。使用
    -Xtheirs
    ,这样我们就不必处理冲突
  • (5.2.new)$git push-u origin 5.2.new
    -将此分支推送到“中央”git回购
  • (5.2.new)$git push origin——删除5.2
    ——删除dumb 5.2分支
<
             5.2
         origin/5.2
          .-'
       .-'
    master
origin/master
      |
      |
  a3f2d6205