使用git,如何将主(上游)分支合并到主题分支中,但是看到差异就好像我将主题分支合并到主分支一样?

时间:2018-01-17 10:10:05

标签: git git-merge

使用git,如何将主(上游)分支合并到主题分支中,但是看到差异就好像我将主题分支合并到主分支一样?

当主题分支准备就绪时,我们的习惯是将主要分支(使用git)合并为两个阶段:

  1. 将主分支合并到主题分支中。推送主题分支,触发外部测试系统上的测试,以检查应用程序功能是否仍按预期工作。
  2. 将主题分支合并到主分支中。推动主分支,再次触发测试。
  3. 这样做的好处是,如果合并版本存在任何问题,那么它们很可能已经出现在主题分支中,他们不会打扰其他开发者。

    缺点是在将主分支合并到主题分支时,报告的差异是由其他开发人员引入主分支的差异。其中可能有很多,而且我没有参与其中任何一项,因此我很难确认合并没有出错。

    如果我立即将主题分支合并到主分支中,而不首先将主分支合并到主题分支中,那么报告的差异仅是我为主题分支引入的差异。那些数量较少,而且我对它们非常熟悉,因此我更容易验证合并没有出错,但是我们没有获得首先测试组合的优势。主题分支的背景。

    我无法在推送之前在本地运行测试,因此不能将主题分支合并到主分支,然后测试,解决任何问题,然后才推送主分支。

    假设合并进展顺利,无论是将主题分支合并到主分支还是将主分支合并到主题分支中,最终代码都无关紧要:在这两种情况下,我最终得到相同的代码,但与不同的分支相关联。

    我想要的是在主题分支中包含合并的代码,但要查看差异,就像我将主题分支合并到主分支一样。最方便的方法是什么?

    笨重的方法是拥有两个本地存储库副本,其中一个主分支签出,另一个签出主题分支。将主题分支合并到第一个存储库副本的主分支中(仅查看我自己的差异 - 非常好!),然后将源代码而不是.git目录复制到其他存储库副本,并提交到主题分支。这很麻烦,浪费了磁盘空间。

    我还尝试将主题分支合并到主分支(但不推送!)然后将主题分支硬重置到主分支中的合并提交,但这只是移动主题分支标记,丢失了与主题分支中先前提交的连接。

    第一部分解决方案,增加2018-01-19

    我找到了解决问题的部分方法。当我正在将主分支合并到主题分支中时,那么

    git diff --stat MERGE_HEAD...
    

    (注意末尾的三个点)显示自主要分支以来最近共同祖先以来主题分支中文件已更改的行数。如果我将主题分支合并到主分支中,那些文件将被报告为已更改;那些是我改变的文件。

    在我将主分支合并到主题分支中时,我可以忽略git diff中该列表中的所有文件。我忽略了那些被忽略的文件,所以我不需要仔细检查它们是否存在git无法检测到的合并问题。

    第二部分解决方案,增加2018-01-23

    此解决方案基于史蒂夫在此问题下面添加的评论,并添加了一些内容。

    1. 在master上创建一个新的临时分支并将主题分支合并到此分支中。将提交消息更改为"将主分支合并到主题分支",类似于将主分支直接合并到主题分支中的情况。 (默认提交消息提到临时分支,我们很快就要删除它,因此如果提交消息引用它将会令人困惑。此外,有效合并方向将与默认方向相反提交消息说。)
    2. 切换到主题分支并将临时分支合并(快进)到此。删除临时分支。然后按主题分支以触发测试。
    3. 合并(可能与--no-ff?)现在测试的主题分支到master。
    4. 第三方解决方案

      我的一位同事提出了减少痛苦的第三种方法:使用工作树获得主分支的廉价第二副本,而无需再次克隆整个存储库。假设您已进入主存储库目录" repo"检查主题分支:

      # create worktree and check out main-branch in it:
      git worktree add ../repo-worktree main-branch
      cd ../repo-worktree
      git merge topic-branch
      # (resolve any merge conflicts)
      # copy changed files to the main repository:
      cp <changed-files> ../repo
      cd ../repo    # go to main repository
      git add -u    # stage copied files (no new ones!)
      git commit -m "merged main branch into topic branch"
      
      # when you don't need the worktree anymore, then
      rm -rf ../repo-worktree  # removes worktree
      git worktree prune       # removes obsolete worktree administrative files
      

1 个答案:

答案 0 :(得分:0)

第一部分解决方案,于2018年1月19日添加

我已经找到部分解决方案来解决我的问题。当我正在将主分支合并到主题分支中时,然后

git diff --stat MERGE_HEAD...

(请注意末尾的三个点)显示自从最近的主要祖先与主分支以来,主题分支中文件已更改的行数。如果我改为将主题分支合并到主分支,这些文件将被报告为已更改。这些是我更改的文件。

在将主分支合并到主题分支中时,我可以忽略git diff中不在该列表中的所有文件。这些要忽略的文件没有被我更改,因此我不需要再次检查它们以查看git无法检测到的合并问题。

第二部分解决方案,于2018年1月23日添加

此解决方案基于Steve在此问题下方添加的评论,并添加了一些内容。

  1. 在master上创建一个新的临时分支,并将主题分支合并到其中。将提交消息更改为“将主分支合并到主题分支”之类的内容,类似于将主分支直接合并到主题分支中的情况。 (默认的提交消息提到了临时分支,我们将在短期内删除它,因此,如果提交消息引用了它,将会造成混乱。此外,有效的合并方向将与默认的提交消息相反说。)
  2. 切换到主题分支并将临时分支合并(快进)到该分支。删除临时分支。然后按下主题分支以触发测试。
  3. 将(可能是--no-ff?)合并到现在已测试的主题分支中。

第三部分解决方案

我的一位同事提出了减轻痛苦的第三种方法:使用工作树获取主分支的廉价第二个副本,而不必再次克隆整个存储库。假设您位于主存储库目录“ repo”中,并且主题分支已检出:

# create worktree and check out main-branch in it:
git worktree add ../repo-worktree main-branch
cd ../repo-worktree
git merge topic-branch
# (resolve any merge conflicts)
# copy changed files to the main repository:
cp <changed-files> ../repo
cd ../repo    # go to main repository
git add -u    # stage copied files (no new ones!)
git commit -m "merged main branch into topic branch"

# when you don't need the worktree anymore, then
rm -rf ../repo-worktree  # removes worktree
git worktree prune       # removes obsolete worktree administrative files