【问题标题】:Show unique changes to topic branch (even if it's already been merged to master)显示对主题分支的独特更改(即使它已经合并到主分支)
【发布时间】:2015-03-19 13:33:18
【问题描述】:

如果有一个主题分支,有没有办法显示对该分支所做的独特更改?

主题分支可能已经合并到主分支。

用例是如果有人想在该主题分支被合并 6 个月后查看它的独特更改。

【问题讨论】:

  • 您没有说明合并是快进合并还是生成合并提交,所以我在下面的回答涵盖了这两种情况,而您的回答仅适用于快进合并情况,正如我反复解释的那样。
  • 如果您决定不记录合并,则没有合并记录。对于记录的合并,它只是合并提示与合并基础的 git diff。分支标签指向现在的位置,甚至它是否存在都无关紧要 - 像每个提交一样的合并提交是永久且不可变的。
  • @jthill 你是对的,虽然如果快进合并是不可能的,那么不记录合并的决定是不可用的:要么你合并一个合并提交,要么你不能合并全部。

标签: git


【解决方案1】:

如果主题分支被合并为fast-forward merge,则无法执行此操作,因为无法判断主题分支的开始位置。

但是在许多情况下,合并不会是快进合并,因为在主题分支正在开发时在主干上进行了提交。在这种情况下,会有一个合并提交,这使我们能够实现您的要求:

如果合并主题分支的提交由commit-ish$topic_merge表示,那么你可以这样做:

git log $topic_merge --not $topic_merge^

这不包括合并之前主干中的所有提交(即合并提交的第一个父级)及其所有祖先。

注意,这也可以写成

git log $topic_merge ^$topic_merge^

git log $topic_merge^..$topic_merge

虽然在使用zsh 时,您可能不得不在第一种情况下避免文件名生成扩展:

git log $topic_merge \^$topic_merge^

这甚至适用于octopus merges,因为它会显示来自合并带来的任何分支中尚未在主干中的所有更改。

唯一的缺点是它可以包含合并到主题分支中的任何其他提交。如果您不想包含这些,那么您需要再次依赖合并提交的存在,以便区分主题分支提交和合并到主题中的提交。这需要递归完成,并从上面给出的结果中减去结果。

【讨论】:

  • 是否由用户来创建 $topic_merge 提交方式?还是 git 会自动将其存储在某个地方?
  • 如果在开发主题分支的过程中在主分支上进行了提交,那么合并将自动导致合并提交,否则git将默认进行快进合并,除非@987654331使用git merge 的@ 选项。我会更新答案以澄清这一点。
  • 有用的信息,但我不认为我可以做我最初打算做的事情......能够识别已经合并到 master 的主题分支的唯一提交(确定唯一的事后提交)
  • @Jonathan.Brink 为什么你不能?您是说您对主题的合并是快进合并吗?这是唯一会阻止它成为可能的事情。
  • 请仔细阅读我的回答。正如我已经反复解释的那样,它涵盖了快进合并(在第一句话中)和非快进合并(在答案的其余部分)。相比之下,您的答案仅涵盖快进合并,因此“它对最初不存在的问题施加了约束”的说法适用于您的答案,而不是我的答案。
【解决方案2】:

我遇到了处理cherry-pick{able,ed}提交的各种日志选项,我很确定

git log --decorate --oneline --cherry   master...topic

将在此处投放(注意三个点)。

供参考,git loggit revisions(指定修订和修订集的方法)文档。

要查找topicmaster 的最新记录合并,无论topic 引用是否已被删除,

git log --oneline -1 --first-parent --merges --grep="^Merge branch 'topic'" master

并记住它以供以后使用,例如

merge=$(git log --pretty=%H -1 --first-parent --merges --grep="^Merge branch 'topic'")

这样你就可以了

git log --decorate --oneline --cherry   $merge^...$merge^2

其他选项:

在普通情况下,topic 仍然处于活动状态,您只关心合并正在处理的更改:

git diff master...topic

如果 topic 引用已被删除,即如果您正在处理这里的考古案例,则要查找 topicmaster 的最新记录合并:

git log --oneline -1 --first-parent --merges --grep="^Merge branch 'topic'" master

您可以使用

为合并和合并提示提交 ID 设置一个变量
merge=$(git log --pretty=%H -1 --first-parent --merges \
              --grep="^Merge branch 'topic'"   master)
topic=$(git rev-parse -q --verify $merge^2)

edit:我保证有一天我会停止提供键盘到编辑框的命令。上面的工作现在。

如果您决定不记录合并,那么当然没有合并记录。

已记录的合并可能会使提交图变得混乱,如果它们中有很多,它们可能会使其难以遵循;此外,提交消息主题旨在足以确定其中完成的工作范围。所以 git 通常在可能的情况下更喜欢线性历史。为了避免依赖于提交主题,确保在祖先链中记录管理上重要的边界(对于大型项目,这通常是一个非常好的主意),进行合并并指定--no-ff

要获取当前的topic 提示或获取其最近合并的提示:

topic=$( git rev-parse -q --verify refs/heads/topic \
         || git rev-parse -q --verify $( git log --pretty=%H \
                            -1 --first-parent --merges  \
                            --grep="^Merge branch 'topic'"   master)^2 )

$topic 的分支中的第一次从 master 提交:

first=`git rev-list master..$topic --reverse --first-parent | sed q`

该提交的第一个父节点是来自 master 的分支点:

branchbase=`git rev-parse $first^`

显示自从历史第一次分歧以来关于 $topic 的所有变化:

git diff $branchbase..$topic

【讨论】:

  • 1) 跳过这些rev-parse / log / rev-list 箍,与我回答中的方法相比有优势吗? 2)为什么不用git merge-base来确定分支点呢? 3)你如何处理包含合并提交的主题分支,例如如this gist?所示
  • @AdamSpiers 我们都给出了部分答案,在我看来,它们之间几乎没有重叠。 rev-parse 和 rev-list 和 log 命令找到主题提示“即使它已经被合并到 master”,你的任务完全留给 OP,将结果称为$topic_merge --not $topic_merge^first 的分配找到了分支基础,而不是最新的合并基础,这也是您的答案甚至没有提到的任务。这说明了所有的“箍”。
  • 感谢您的解释。是的,我假设 OP 已经可以在历史中找到主题分支,并且超出了问题的范围;毕竟,人们同样可以使用gitk 或IDE 来grep/浏览历史并找到它,我认为答案不应该太固执己见。但是我可以看到您的命令对某些人有用。但是我仍然不明白需要计算分支基数。也许您担心包含主干合并的主题分支?但我的回答处理得很好。
  • @AdamSpiers 对于合并,我们的答案都忽略了除了最新的 - 你的,通过(a)忽略它们的存在以及所有 topic 在其提示之前提交(并且,如果 @ 987654353@ 仍然处于活动状态,已部分合并,并且具有未合并的提交,自上次合并以来的所有提交),但包括从其他分支合并的所有合并和提交,无法区分哪个提交来自哪个分支——我的,通过包括all 更改对主题分支的影响,无论是通过合并还是普通工作合并。
  • 不管怎样,OP 将不得不对我们所说的话进行抨击,并且可能会就他无法弄清楚的任何问题提出更多问题。
【解决方案3】:

我相信这里的答案是这是不可能的。

原因是 git 不跟踪最初创建分支的位置。分支只是一个指向分支尖端的指针。

因此,如果自主题分支最初创建以来已对其进行了合并提交,则无法确定是哪个提交启动了该分支。

【讨论】:

  • 不正确 - 您不需要 git 来跟踪分支的创建位置。
  • 澄清一下,只要有合并提交就可以。在没有合并提交的快进合并的情况下,你是对的,在某些情况下,这是一个很好的论据,可以将--no-ff 选项用于git merge
  • 很抱歉,这个答案是错误的,所以你不应该接受它。您最初的问题没有说明合并是否是快进合并,所以正如我所解释的,在某些情况下它可能的。
  • 在某些情况下是可能的,但最初的问题不够清楚,无法解释尝试它的场景,所以这个答案在技术上是不正确的。
  • @Ikke 嗯?我从来没有声称我有一个通用的编程解决方案,而且 OP 也没有要求一个。这些都不妨碍我的回答是 a)正确和 b)有用,所以我不知道你的意思是什么。我也很难看出你的第二句话有什么意义;最初的问题要求一种显示更改的方法,而不是一种“了解”它们的方法(无论您是什么意思)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-22
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
相关资源
最近更新 更多