如何使用Git将多个提交合并成一个提交

12

我的历史大致如此,但是要乘以10:

                i - j - e'- k - h'- l - m  feature-branch
              /
    a - b - c - d - e - f - g - h  master

(撇号表示挑选)我想要变基到这个提交:

                                  i - j - k - l - m  feature-branch
                                 / 
    a - b - c - d - e - f - g - h  master

我不介意将该功能压缩到一个提交中。常规变基的主要问题在于它尝试逐个提交地变基,我不得不一遍又一遍地修复类似的冲突。

我想做的就是获取我的分支尖端和主分支尖端之间的差异,并将其应用于主分支之上。


这将会比常规的变基容易得多,而不是常规的合并。此外,使用合并,历史记录将是准确和真实的,而不是包含谎言。 - Dietrich Epp
等一下...你是不是在从master分支挑选提交记录然后放到feature-branch分支上? - Dietrich Epp
“e'” 是从 “e” 和 “h'” 是从 “h” 挑选出来的吗? - Richard Hansen
2
@DietrichEpp:重置本地历史记录没有问题,问题在于公共历史记录。相关链接:http://programmers.stackexchange.com/questions/255165/is-using-git-stash-as-a-workflow-an-antipattern/255174#255174 - Greg Burghardt
@GregBurghardt:“没有问题”是不正确的说法,只是在将公共历史记录变基时存在特定的问题,而这些问题并不适用于私有历史记录。这绝不意味着在将私有历史记录变基时没有其他问题,例如,您的私有历史记录可能包含单元测试,在重新变基后现在会失败,从而破坏未来使用git bisect的努力。 - Dietrich Epp
显示剩余4条评论
2个回答

11

这其实很容易。

  1. master合并到feature-branch。你将解决所有合并冲突。(我强烈建议在这里停顿。)

            i - j - e'- k - h'- l - m - n    feature-branch
          /                           /
a - b - c - d - e - f - g - h --------       master
然后执行 git reset --soft master 命令。这将使得feature-branch指向master,但是它会保留所有已修改的文件在index中,准备提交的状态。
            i - j - e'- k - h'- l - m - n    (orphaned)
          /                           /
a - b - c - d - e - f - g - h --------       master, feature-branch
                              \
                                (index)
  • git commit

  •             i - j - e'- k - h'- l - m - n    (orphaned)
              /                           /
    a - b - c - d - e - f - g - h --------       master
                                  \
                                    n'           feature-branch
    
    #2和#3的唯一目的是销毁feature-branch的历史记录。如果您确定永远不会需要那个历史记录,那就没问题了。但这样做似乎浪费了去删除实际发生情况的准确记录的所有额外麻烦。

    这不是我要求的确切行为,但我最终只完成了第一步。它允许一个大而可管理的冲突解决阶段,而不是成千上万个阶段。希望它没有被重新设置为线性外观不会在未来引起任何问题。 - ZMitton

    3
    我假设e'h'是对应于eh的特定版本。我同时也假设冲突出现在Git尝试应用e'h',但没有应用其他提交记录时。如果我理解有误,请指正。
    您有几个选择:
    • When git rebase drops to a prompt saying that it couldn't apply e' or h', run git rebase --skip to tell Git to skip that commit.

      Once the rebase is done, if you then want to squash the commits together into one:

      git reset --soft master
      git commit
      
    • Do an interactive rebase and tell Git to not apply e' and h':

      git checkout feature-branch
      git rebase -i master
      # Git will launch an editor containing an interactive rebase recipe:
      #   1. Delete the e' and h' lines.
      #   2. Optionally change the j through m lines to 'squash' if you
      #      want to squash all of those commits into one.
      #   3. Save the recipe and exit.
      
    • git rebase is an easier way to do a series of git cherry-pick commands. You can do these commands manually yourself:

      git checkout -b temp-branch master
      git cherry-pick i j k l m
      # optionally, if you want to squash i through m into a single commit:
      #   git reset --soft master
      #   git commit
      git checkout feature-branch
      git reset --hard temp-branch
      git branch -D temp-branch
      

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接