11

假设下图:

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' -- -- -- -- -- -- -

换句话说,我想通过主题分支上的交互式变基将提交压缩为一个,但仍保留分支并使用常规合并将主题分支的更改集成到主分支中。

4

3 回答 3

15

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`^
于 2013-04-11T13:22:06.020 回答
7

你会得到 B 与git merge-base

git merge-base F I

或者更简单地说

git merge-base my_branch my_other_branch

然后,您可以使用结果变基

git rebase -i B

并且只保留第一个提交 G,同时压缩所有其他提交。

于 2013-04-11T12:46:02.887 回答
1

git merge-base会给你 B。你想要 B 的所有直接孩子也是 I 的祖先。这与我如何在 git 中找到下一个提交有关?在 Git 中引用提交的子项。尝试类似:

root=$(git merge-base master topic-branch)

git rev-list --parents ^$root topic-branch | grep " $root" | cut -f1 -d' '

这将列出从根到顶端的所有提交及其父项topic-branch,并显示父项是merge-base根的提交。

因为主题分支可能包含合并,所以从拓扑上来说,分支中可能有多个“第一次”提交。

于 2013-04-11T13:15:53.123 回答