假设如下图:
A -- B -- C -- D -- E -- F
\
G -- H -- I
我想找到G
以便能够使用交互式rebase来压缩提交(但仍然在主题分支上保留一个提交),稍后将对其进行审核和合并。我不想仅仅修改整个分支,因为我想保留有分支的信息并将其合并。
(我知道我可以查看历史记录并只使用提交的SHA校验和,但我正在寻找一种方法来实现它,而无需手动挖掘信息或计算提交的数量并使用〜来自HEAD的那个号码)。
编辑:澄清我想要实现的目标:
我想避免这种情况:
A -- B -- C -- D -- E -- F -- J
\ /
G -- H -- I -- -- -- -
而是有这样的事情:
A -- B -- C -- D -- E -- F -- J
\ /
G' -- -- -- -- -- -- -
换句话说,我想将主题分支上的交互式rebase压缩为一个,但仍保留分支并使用常规合并将主题分支中的更改集成到主分支中。
答案 0 :(得分:11)
git中没有“在分支上”的提交。分支中只有提交可到达。而且这些信息并不是一个非常好的指标,表明最初提交的分支属于哪个分支。所以我认为有两种方法可以解释你的问题:
branch
和master
的合并基础之后找到第一个提交。branch
访问的第一个提交,但不能从master
找到。我会假设你的意思是第二个。这个命令返回的答案是:
git rev-list ^master mybranch | tail -n 1
注意:如果您分支主题分支,这将会非常失败。
我对你想要达到的目标感到有点困惑。如果您希望整个分支由一个提交表示,但仍然得到合并,您应该这样做:
git checkout mybranch
git reset --soft `git merge-base mybranch master`
git commit -m 'All of Mybranch'
git checkout master
git merge --no-ff mybranch
请注意,这将在第一个合并基础上开始压缩。如果您之前将master
合并到mybranch
,那么这可能不是您想要的。您可以将此修改为从mybranch上的第一次提交开始,而不是在master上(可能在复杂历史记录中可能有奇怪且意外的结果)通过将第二个命令替换为:
git reset --soft `git rev-list ^master mybranch | tail -n 1`^
答案 1 :(得分:6)
您将获得带有git merge-base
的Bgit merge-base F I
或者更简单地用
git merge-base my_branch my_other_branch
然后您可以使用结果
进行变基git rebase -i B
只需保留第一个提交G,同时压缩所有其他提交。
答案 2 :(得分:1)
git merge-base
会给你B.你想要B的所有直系孩子也是我的祖先。这与How do I find the next commit in git?和Referencing the child of a commit in Git有关。尝试类似:
root=$(git merge-base master topic-branch)
git rev-list --parents ^$root topic-branch | grep " $root" | cut -f1 -d' '
这将列出从topic-branch
及其父级的根到提示的所有提交,并显示父级为merge-base
根的提交。
因为主题分支可能包含合并,所以拓扑中的分支中可能会有多个“第一个”提交。