Git日志列表提交不包括从第一个分支中挑选的樱桃

时间:2019-05-24 17:44:16

标签: git github

例如,我有此提交历史记录

git history enter image description here

假设某个时间点release1已发布到生产环境中,几天后,release2分支被释放了。

  • 分支relase1包含2个提交(4和5),这些提交是从主那里挑选的
  • 分支release2包含2个提交(8和9),这些提交也是从master那里挑选的。

从未使用-x自变量来完成cherry-pick。

我要获取release2的所有提交,“当时尚未发布”,这意味着以绿色圆圈标记的提交(6,7,8,9)。

最简单的方法是什么?

github中的存储库示例

更新1(git cherry)

$ git cherry -v release1 release2
- 91785f2be363244a1da4459746fce6a6ea28c2b5 4
- e88de1f8b62213089b300e3143c4caf509b5c13b 5
- 9d23e9c7e6f769c3bbb44ad42bc7b708b4b0a9e6 6
- 6fb71e4406e0b127e06f6e5b145de8a9d39db01e 7
- 6276becc413494b7724a4dd8b852234f4b71e913 8
- 6dd3b5b75222c02c921c9c20bcaee83e1c8be746 9

cherry下,看来我仍然有4和5都是表单母版

更新2(-左右-樱桃标记)

$ git log --left-right --cherry-mark --pretty=oneline --abbrev-commit  release2...release1
= 6dd3b5b 9
= 6276bec 8
> caa4e2f 5
= 0230a1f 4
= 6fb71e4 7
= 9d23e9c 6
= e88de1f 5
= 91785f2 4

除了5个标记为樱桃的标记,这给了我一切,我很难解释

使用非空提交更新3

在最初的尝试中,我使用--allow-empty创建了每个提交。如下所述,它创建了一个空树的哈希。

用真实的内容重新创建存储库后,我得到了期望的结果,答案都在git cherry--left-right --cherry-mark之下

2 个答案:

答案 0 :(得分:3)

请注意,your linked repository包含15个完全为空的提交。 “空提交”不只是表示git commit --allow-empty允许的那种无更改提交,而是完全为空:每个提交根本没有文件,只有一条提交消息。 (更确切地说,每个提交都将empty tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904作为其树。)因此,存储库中的每个提交的补丁ID等同于存储库中的其他提交

(大部分)解释了为什么update-2部分显示其所做的输出:commit 6dd3b5b与补丁6276bec9d23e9c等价于补丁。令人困惑的是为什么提交caa4e2f没有与另一个提交配对,因为它也与其他所有提交都是补丁等效的。无论如何,这几乎都是一个误报的例子,但在这里,它实际上更像是一个误报:这些提交都是相同,因此可以被丢弃而没有任何效果。


Git的修订版本遍历命令(git loggit rev-list)可以使用git patch-id来标记等效补丁提交。这不是万无一失的,但是如果在没有人工干预的情况下精心挑选了一个提交,副本和原始补丁的补丁ID将匹配。

要了解如何使用此功能,请查看the git log or git rev-list documentation(关于此内容的部分在两组文档中都是共享的-底层实现也是如此,因此我只链接了其中一个)。跳至the section on the --left-right option。请注意,--left-right 仅在与对称差异组合时才有意义,在这种情况下,这意味着使用语法release1...release2release2...release1。请注意,这里的两个名称之间有三个,而不是两个点。

使用三个点和--left-right,Git将枚举release1可以到达的提交5和4,以及release2可以到达的两个不同的提交5和4。 (当然,Git首先会枚举release2可以到达的提交9、8、7和6,然后枚举release2而不是release1可以到达的5和4。如您所见,使用相同的两个名称来调用这四个不同的提交可能是一个错误。它们具有不同的哈希ID是有原因的:它们是不同的提交。将它们分别称为5A5B和{ {1}}和4A(如果需要),或者4B5.1添加发行号,但给它们起不同的名字!)

到目前为止,这并没有太大帮助:Git显示您从5.2提交了5.1和4.1,并根据三个点的哪一侧标记为release1<名称>已打开。并且,您的Git显示了您从release1提交的9、8、7、6、5.2和4.2,并用其他标记进行了标记。但这是最重要的起点。现在,您可以从release2切换到--left-only--left-right,告诉Git 不要显示我这两个集合之一,即使您仍在枚举所有提交内容。

有或没有左或右选项,您可以添加--cherry-mark,以告知Git:在两组命令中的每次提交上运行--right-only。当左侧集合中的提交与右侧集合中的提交具有相同的补丁程序ID时,请用等号git patch-id标记该提交。否则,请用加号=标记提交。

因此,在这种情况下,如果您运行:

+

您将看到(假设提交9的哈希ID以git rev-list --left-right --cherry-mark --abbrev-commit release2...release1 开头,依此类推):

999999

因此,所需的提交正是那些标记为<9999999 <8888888 <7777777 <6666666 =5200000 =4200000 =5100000 =4100000 的提交。使用<,您想要的提交正是标记为release1...release2的提交。

假设以上所有内容都有意义,请阅读--cherry-pick section

请注意,如果您在选择樱桃时必须解决冲突,则原始提交的补丁ID及其副本不会。这样的提交不会会被该过程忽略。也可能会得到错误的匹配。这往往发生在仅由例如一些开合括号组成的修复程序中:修补程序ID是通过不仅去除行号而且去除空格而形成的。因此,减少对补丁ID的两个不同(通过缩进和行号)的大括号更改提交会使应该不同的提交折叠。因此,我在最上面的说法不是万无一失:您可以同时得到误报(解决合并冲突的樱桃选择)和误报(实际上是不同的合并提交)。

答案 1 :(得分:1)

使用git cherry命令,您可以找到尚未在上游分支中应用的提交。在man git-cherry中,内容提要如下:

git cherry [<upstream> [<head> [<limit>]]]

和说明

  

确定<head>..<upstream>中是否有等同于<limit>..<head>范围内的提交。

     

等效测试基于差异,除去空白和行号。因此,git-cherry通过git-cherry-pick(1)git-am(1)git-rebase(1)检测何时复制了提交。

     

<limit>..<head>中输出每个提交的SHA1,对于在-中具有等效值的提交,以<upstream>为前缀,对于没有+的提交,以release2为前缀。 >

因此,要查找release1中没有等效提交的git cherry release1 release2 | grep '^+' | cut -d' ' -f2 中的提交,您可以

async function uploadImageAsync(uri) {
  let apiUrl = 'upload.php';



  let uriParts = uri.split('.');
  let fileType = uriParts[uriParts.length - 1];

  let formData = new FormData();
  formData.append('photo', {
    uri: uri,
    name: `photo.${fileType}`,
    type: `image/${fileType}`,
  });

  let options = {
    method: 'POST',
    body: formData,
    headers: {
      Accept: 'application/json',
      'Content-Type': 'multipart/form-data',
    },
  };

  return fetch(apiUrl, options);
}