【问题标题】:How to achieve simplified merge-commits如何实现简化的合并提交
【发布时间】:2020-05-03 09:57:13
【问题描述】:

Rational:In out 环境审查发生在此处表示为 master> 的分支上。我想将(更好:组合)提交压缩在一起,以便对某个开发步骤进行所有更改。因此:

我如何从左到右?

                                                   master> * C <feature  
                                                           |\
            * H <feature   - just local                    | * H     (merged)
            |                                              | |
            * G     - pushed to remote          =??=>      | * G     (merged)
master> B * |       - pushed to remote                   B * |
          | * F     - pushed to remote                     | * F     (merged)
          |/                                               |/
          *                                              A *                

实际上,功能路径上的提交数量很大(10+),我想将它们全部压缩。其中一部分已发布到远程存储库(不应更改或更改)。但是我只想在主分支上创建一个提交。

git merge --squash 显然会执行此操作,但它不会将提交标记为合并。因此,如果我继续在&lt;feature-Branch 上工作,下一次调用git merge 将导致很多冲突。我发现 explanation on stackoverflow: git merge --squash 导致了一个与源提交无关的补丁。

所以,我想要实现的是从右到左的情况,并且 featurebranch 上的所有提交(FGH)将被标记为合并*) - 如果我继续工作在 Featurebranch 上下一次合并不会导致与我自己的更改发生冲突。如果 Featurebranch 上的所有更改都未发布到远程存储库(请参阅git merge --squash-Question),则此问题已解决。

PS:当然,将提交单独标记为合并就足够了,但我不知道如何做到这一点,也不知道 git 如何管理它的合并信息。

PSS:正常合并可以,但如果 master 上没有提交,它会失败。

*):“标记为合并”的意思是,在 gitk - 如果您选择提交,分支列表包括功能、遥控器/原点/功能、主控、遥控器/原点/主控。因此,在随后对git merge 的调用中不会考虑这些提交。

【问题讨论】:

  • 合并后只删除功能分支?除此之外,不清楚您的预期结果是什么?
  • 谢谢@Liam,但我应该继续在这个分支上工作。 (设置工作环境的方式使得为单个项目创建新分支的成本很高 - CICD 与我正在处理的命名分支相关联,因为与一堆其他可执行文件协作)

标签: git merge git-merge


【解决方案1】:

没有办法做你想做的事。

当 Git 进行合并时,它会计算合并基础,这大致是两个分支的共同祖先提交。在典型合并中考虑的三个(也是唯一的)三个点是合并基础和两个头部。如果您进行正常的合并,那么您将在主分支上产生一个新的提交,并且该提交或其后代之一通常将在未来用作合并基础,这意味着 Git 不会将您的更改视为第二次。

如果您进行 squash 合并,则合并基础是原始分叉点,因此后续合并会将您视为已进行多次提交且更改相同,从而导致您所看到的冲突。

除非使用自定义合并驱动,否则无法自定义合并基础检测,因此需要采用其他解决方案或学习处理冲突。

您可以做的是删除现有分支并从master 分支重新创建它(或将其重置为master 上的最新提交),这意味着未来的工作基于包括所有以前的提交工作。这样可以避免你的冲突。

您还可以使用标准合并而不是 squash 合并,这将使合并碱基检测做正确的事情。

最后,您可以编写一个自定义合并驱动程序,以某种方式直观地了解有关您的分支的信息。我不推荐这种方法,因为它涉及大量工作,而且很容易出错并弄乱所有数据。

但最终,鉴于您的工作流程限制,您可以选择的选项并不多。我个人建议采用一种不同的、更标准的、约束更少的工作流程;逻辑的、独立的提交;和标准的合并政策。

【讨论】:

    【解决方案2】:

    您的描述(图片和文字)需要定期合并:

    git checkout master
    git merge feature
    

    如果这不是您想要的,并且您坚持进行压缩提交,那么您将无法继续在分支 feature 上工作,但必须在 master 合并后立即从 master 分叉一个新功能分支旧功能分支。

    【讨论】:

    • 感谢@j6t,但这不会产生预期的结果。不幸的是,您没有弄清楚为什么 git 在进行压缩合并时无法将原始提交标记为已合并。你知道它在哪里存储合并信息吗?
    • @Xantopp:不幸的是,nothing 将导致您想要的结果。 Git 无法实现你想要的。您的 CI/CD 系统正在做出一组假设,而 Git 正在做出另一组假设,而这两者并没有很好地结合起来。
    • 以下命令强制执行压缩提交,即使如果可以快速前进:git merge --no-ff feature
    • 请直截了当。与git merge --squash 的“压缩合并”会创建单个非合并提交并丢失合并父提交的信息。 git merge --no-ff 不这样做;它创建一个常规的合并提交,而不是一个“压缩合并”提交,并保留哪些提交被合并的信息。
    【解决方案3】:

    经过一些研究,我了解到以下内容:git 将根据所涉及分支的状态选择如何合并的方法 - 在下面我的草图中的琐碎(图 b))git选择 fast-forward,即两个分支中只有一个发生变化。在这种情况下,feat-branch 的所有更改都可能会放在 master 分支的顶部。

    题外话:如果多个相关分支(图 a)从我下面的草图)git 选择一个 merge-Strategie 根据相关分支的当前状态和 git 配置。此外,您可以使用命令行来强制执行某些行为(https://git-scm.com/docs/merge-strategieshttp://gitbu.ch/ch03.html)。

    有了这些知识,我的问题就有了答案:

    答案:赞成--no-ff 而不是--squash 如果我想避免“快进”合并,您应该使用

    git merge --no-ff --no-commit feature
    

    在此之后,您应该将功能同步到 main

    git checkout feature
    git merge --ff-only master
    

    这会将您从问题中的草图从左到右带到feature-Branch 的每个提交原始文件将在master 分支上标记为存在(当您选择该信息时,此信息将显示在 gitk提交)。

    避免“快进”可能还有另一个原因:实现的情况将记录下来,最初将更改签入到功能分支中,然后对主分支进行。

    草图说明快进:

        a) real merge                          b) trivial - no chanes on master
    
                    * H <feature                           * H <feature
                    |                                      |
                    * G <feature/origin                    * G  <feature/origin
        master> B * |                                      |
                  | * F                                    * F 
                  |/                                      /
                  *                            master> A *                
    

    a) 是双方提交的常见情况,其中涉及合并策略以解决它们。 b) 是一个小例子,可以快速前进。

    总结:在任何一种情况下,给定的命令都会将feature 分支上的所有工作提交组合成master 上的单个提交,而不会丢失合并信息。

    【讨论】:

      猜你喜欢
      • 2011-09-05
      • 2014-02-07
      • 2015-02-09
      • 1970-01-01
      • 2021-03-26
      • 2011-03-03
      • 1970-01-01
      • 2021-07-31
      • 2010-12-12
      相关资源
      最近更新 更多