Git 压扁树枝的分枝

Git 压扁树枝的分枝,git,pull-request,git-squash,Git,Pull Request,Git Squash,假设我有以下git历史记录:一个以commita开始的主分支,一个以commitB和C从a分支的feature-1分支,以及第二个功能分支feature-2,它是在commitC的基础上构建的,带有commitD和E master A \ feature-1 B--C \ feature-2 D--E 现在假设commitC已经过测试并准备好合并,所以我们使用git开关主机;git合并功能-1——挤压 ma

假设我有以下git历史记录:一个以commit
a
开始的主分支,一个以commit
B
C
a
分支的
feature-1
分支,以及第二个功能分支
feature-2
,它是在commit
C
的基础上构建的,带有commit
D
E

master     A
            \
feature-1    B--C
                 \
feature-2         D--E
现在假设commit
C
已经过测试并准备好合并,所以我们使用
git开关主机;git合并功能-1——挤压

master     A------C'
            \    /
feature-1    B--C
                 \
feature-2         D--E
master     A------C'
            \    /
feature-1    B--C
                 \
feature-2         D--E
master的历史记录非常清晰,只提交了
A
C'
,但是如果我们现在想比较
master
feature-2
(例如,
git log master..feature-2
),我们最终会看到已经合并到中的
feature-1
的所有提交

问题1:是否有一种简单的方法来挤压
功能-2
的历史以匹配挤压的合并?如果历史记录稍微复杂一点,并且在
feature-1
上的分支点
C
之后有更多提交被挤压合并到master中,该怎么办


问题2:假设重写历史很困难(或者只能用
git-rebase-i
繁琐地完成;我在每个分支上有两个以上的提交),有没有办法只查看
feature-2
中没有挤压合并到master中的提交?在GitHub或Bitbucket上为
feature-2->master
执行拉取请求时,有没有办法只列出那些真正的新提交?

在简单场景中,如果您在
master
上简单地
rebase
您的
feature-2
,您将只有非空提交

在更复杂的场景中,我建议执行以下操作:

git switch feature-2
git merge origin/master
git reset --soft origin/master
git commit -m 'feature 2'
这将导致一个单一的提交,其中包含来自
feature-2
的所有更改,这些更改有效地压缩在
master

现在假设commit
C
已经过测试并准备好合并,所以我们使用
git开关主机;git合并功能-1——挤压

master     A------C'
            \    /
feature-1    B--C
                 \
feature-2         D--E
master     A------C'
            \    /
feature-1    B--C
                 \
feature-2         D--E
这幅画不太正确:它应该像我下面画的那样。注意,我也把名字移到了右边,原因过一会儿就会更清楚。我还称之为挤压提交
BC
,这是为了清楚地表明,有一个单一的提交完成了B和C一起完成的工作

您绘制的是一个真正的合并(尽管您称为合并提交
C'
)。因此,“挤压合并”根本不是合并

A--BC master
,有没有办法只列出那些真正的新提交

不,因为这些系统没有等效的语法。但是,一旦您使用rebase只复制所需的提交,并强制推送以使GitHub或Bitbucket存储库匹配,它们就会显示您想要的内容


2上面没有提到的是,
git-rebase
在默认情况下故意省略步骤1中的某些提交。在您的情况下,此处不应省略任何提交,因此这并不真正相关,但值得一提:

  • 默认情况下,
    git-rebase
    忽略所有合并提交
  • 通过设计(并且没有停止此操作的选项),
    git-rebase
    也使用与
    git-cherry
    git-log相同的计算——cherry-pick
    将用于从复制中消除与上游提交集中的提交匹配的任何提交。(如果不深入了解
    A…B
    symmetric difference notation的工作原理,就很难定义此集合。)在您的情况下,这也不重要,因为这种补丁ID匹配在这里非常不可能。对于上游有人故意使用
    git cherry pick
    将您的一个或多个提交复制到要重设基础的分支的情况,这意味着更多
  • 在某些情况下,但同样不是您的-
    git-rebase
    默认运行
    git-merge--fork-point
    来查找要忽略的提交,这会产生令人惊讶的结果

从历史上看,rebase文档在提及这些方面一直比较松懈,可能是因为它们并不经常出现。在你的情况下,他们不应该出现。最新的rebase文档有了很大的改进。

只需将master合并到feature-2分支中即可。这两个功能分支在master中共享一个共同的祖先。只需将feature-2中的压缩合并到master中,就可以了。不需要花哨,这是非常彻底和有益的。谢谢
git switch feature-2 && git rebase --onto master feature-1
git log feature-1..feature-2