【问题标题】:git log --cherry-pick A..B - what am I doing wrong?git log --cherry-pick A..B - 我做错了什么?
【发布时间】:2021-03-26 21:57:57
【问题描述】:

为了在分支 working 上找到未合并/选择到 master 的提交,但我正在运行

git log --format="%h %aN %ai %f" --cherry-pick --no-merges master..working

据悉here

但正如here 所述,我发现master 上的提交 working 上的提交ID 仅因采摘樱桃而有所不同。

working 均未合并到 master,反之亦然。

即使我手动选择从 workingmaster 的提交,它也会显示运行上述命令。

实际上--cherry-pick 似乎完全没有效果,正如|wc 所示。

我做错了什么?

更新

实际上,ElpieKay 和 torek 都是正确的,我的初始命令也会起作用。不幸的是,我不知道我们正在使用一些“樱桃采摘”魔法,我不知道在樱桃采摘后哪些改变了提交

.

【问题讨论】:

  • 试试master...working。恐怕你漏了一个点。
  • A..B^A B 的简写(参见git-scm.com/docs/git-log)-... 似乎是用于对称差异,即它还显示master 上的提交,而working 上没有.尽管如此,它也显示了精心挑选的提交。
  • @ElpieKay:奇怪的是,当我尝试提出一个可重现的最小示例时,unsing ...cherry-picked 提交确实没有出现。但不幸的是,master 上的那些也只会出现。尽管如此,在我的实际项目结帐中,即使git patch-id 告诉我,樱桃挑选的提交 do 也会出现(使用...),它们是相同的..
  • FWIW:我发现我可以更好地了解标记为可挑选或不使用的内容:git log --graph --cherry-mark --boundary --format="..." A...Bcherry-mark 仍会提到 are 樱桃的提交-picked,并用= 表示它们,--graph --boundary 对可以更清楚地了解图表哪一侧的提交)

标签: git branch commit git-log


【解决方案1】:

在 Git 2.30.1(2021 年第一季度)之前,当一侧出现多个具有相同补丁 ID 的提交时,“git log --cherry-pick A...B(man) 并未将它们全部排除当另一侧出现具有相同补丁 ID 的提交时。
现在可以了(再次使用 Git 2.31,2021 年第一季度)。

参见Jeff King (peff)commit c9e3a4e(2021 年 1 月 12 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit b69bed2,2021 年 1 月 25 日)

patch-ids: 处理重复的 hashmap 条目

报告人:Arnaud Morin
签字人:Jeff King

这修复了dfb7a1b(“patch-ids:停止使用手动哈希图实现”,2016-07-29,Git v2.10.0-rc0 -- merge)中引入的一个错误,其中

git rev-list --cherry-pick A...B

即使在 B 中出现了具有匹配补丁 ID 的提交,也无法抑制可从 A 访问的提交。

在那次提交的时候,“--cherry-pick”的算法看起来像这样: 0. 遍历所有的commit,将它们标记为在对称差的左侧或右侧。

  1. 遍历左侧提交,将每个提交的 patch-id 结构插入到 hashmap 中,并将 commit->util 指向 patch-id 结构。
  2. 遍历右侧提交,检查哈希图中存在的提交。
    如果是这样,我们从输出中排除提交并且我们将补丁 ID 标记为“seen”。
  3. 再次遍历左侧提交,检查是否设置了commit->util->seen;如果是这样,请将它们从输出中排除。

最后,我们将消除双方在另一侧具有匹配补丁 ID 的提交。
但是这里有一个微妙的假设:对于任何给定的补丁 ID,我们必须只有一个结构来表示它。
如果来自A 的两次提交都具有相同的patch-id,并且我们允许在hashmap 中重复,那么我们就会遇到问题:

  • 一个。在第 1 步中,我们将两个 patch-id 结构插入到 hashmap 中。

  • b.在第 2 步中,我们的查找将只找到这些结构中的一个,因此只有 标记了一个“可见”标志。

  • c。在第 3 步中,A 中的一个提交将具有其 commit->util->seen 设置,但其他不会。我们会错误地输出后者。

dfb7a1b 之前,我们的哈希图不允许重复。
之后,它使用了hashmap_add(),它明确允许重复。

那时,解决方案很简单:当我们要添加副本时,跳过此操作并返回匹配的现有条目。
但它变得更加复杂。

683f17e(“patch-ids:用提交指针替换所见指标”,2016-07-29,Git v2.10.0-rc0 -- merge)中,我们的第 3 步完全消失了。 相反,在第2步中,当右侧从左侧找到匹配的patch_id时,我们可以直接将左侧的patch_id->commit标记为省略。
解决这个问题也很容易;补丁 ID 与提交之间存在一对多的关系,因此我们只需要保留一个列表即可。

但还有更多。
提交b3dfeeb(“rebase:避免计算不必要的补丁ID”,2016-07-29,Git v2.10.0-rc0 -- merge)通过懒惰地计算完整的补丁ID。
所以我们甚至不知道在添加到 hashmap 时,两个提交是否真的具有相同的 id。
我们必须暂时为它们分配一个列表,然后在我们计算真正的补丁 ID 时可能将它们分开(可能分成 N 个新结构)。
这可以工作,但它很复杂且容易出错。

相反,让我们接受我们可能会存储重复项,并让查找端变得更聪明。
它需要遍历所有匹配的补丁 ID,而不是要求单个匹配的补丁 ID。
这确实意味着检查单个哈希桶中的每个条目,但哈希查找的最坏情况已经在这样做了。

我们将通过提供一个简单的迭代接口将哈希图的详细信息隐藏在调用者之外。
我们可以为其他调用者保留简单的has_commit_patch_id() 接口,但我们会将其返回值简化为整数,而不是返回patch_id 结构。
这样他们就不会在不迭代的情况下查看返回值的“提交”字段。

【讨论】:

    【解决方案2】:

    作为ElpieKay mentioned in a comment,您需要三点符号。但是,仅添加三点符号是不够的:您还需要添加 --left-only--right-only (取决于您放置 AB 部分的对称差异的哪一侧,@987654326 @,开)。

    注意:

    为了找到分支working 上的提交,尚未合并/选择到master [我使用] master..working

    所以在这里,您需要--right-only master...working。您也可以保留--no-merges。如果合并只显示在 master 上,您实际上并不需要 --no-merges,但它可能是无害的。但是请注意,--no-merges 完全消除了 所有 合并,无论它们的补丁 ID 是什么。

    【讨论】:

      猜你喜欢
      • 2023-02-02
      • 2013-03-26
      • 2019-04-06
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 2012-10-16
      • 2011-07-06
      相关资源
      最近更新 更多