是否有一种简单的方法可以检索某个提交的所有注释,包括有关注释作者和注释提交者的信息?
使用git show --notes=refs/notes/* <commit_hash>
我能够获得所有笔记。但是我没有找到如何使用管道命令获取笔记的作者和提交者。
答案 0 :(得分:2)
虽然git notes
实际上通过提交某些内容而起作用,但附加到git notes
提交的作者和/或提交者名称不被认为有用,因此无法使用。这有一些很好的理由。
让我们快速浏览一下有备注的存储库。在这里,我将使用GitHub上的freebsd存储库,因为它有refs/notes/commits
(由于$ $我已映射到refs/notes/origin/commits
)。目前,我们有:
$ git rev-parse refs/notes/origin/commits
af51c6d65d574faa11ab8026398e045e5f584040
$ git show af51c6d65d574faa11ab8026398e045e5f584040 | sed 's/@/ /'
commit af51c6d65d574faa11ab8026398e045e5f584040
Author: hselasky <hselasky FreeBSD.org>
Date: Mon Aug 14 12:59:14 2017 +0000
Adding Git note for current refs/heads/stable/10
diff --git a/13/06/ece6bde0e4291eaf08139085990e5f55a622 b/13/06/ece6bde0e4291eaf08139085990e5f55a622
new file mode 100644
index 000000000000..3d1ba58d02fa
--- /dev/null
+++ b/13/06/ece6bde0e4291eaf08139085990e5f55a622
@ -0,0 +1 @@
+svn path=/stable/10/; revision=322500
查看此提交中发生了什么:它添加了一个名为13/06/ece6bde0e4291eaf08139085990e5f55a622
的文件。此文件包含ID为1306ece6bde0e4291eaf08139085990e5f55a622
的对象的注释:
$ git show --decorate 1306ece6bde0e4291eaf08139085990e5f55a622 | sed 's/@/ /'
commit 1306ece6bde0e4291eaf08139085990e5f55a622 (origin/stable/10)
Author: hselasky <hselasky FreeBSD.org>
Date: Mon Aug 14 12:59:14 2017 +0000
MFC r314878:
Add support for constant pointer constructs to READ_ONCE() in the
LinuxKPI. When the type of the argument is constant the temporary
variable cannot be assigned after the barrier. Instead assign the
temporary variable by initialization.
Approved by: re (kib)
Sponsored by: Mellanox Technologies
Notes (origin/commits):
svn path=/stable/10/; revision=322500
[diff snipped]
(我已将此存储库配置为使用refs/notes/origin/commits
,因此这里会显示注释。)在这种情况下 - 这是典型的 - 注释本身的作者和提交者是相同的作为该笔记所附的提交者的作者和提交者。
但是,如果我们仔细观察对象af51c6d65d574faa11ab8026398e045e5f584040
,我们会发现它有许多具有这些奇怪名称的文件:
$ git ls-tree af51c6d65d574faa11ab8026398e045e5f584040
040000 tree 598b9e08b0138536da55f5ef55868b2a3a607194 00
040000 tree 5101bb91ab93102057e242b41e19c55fdf3314e7 01
040000 tree 2105ada31d9191d03b50a7ad5c97471c0b531283 02
040000 tree 3e42537c937f0f36cff65b7b19570d2e301a17d2 03
[and so on for 256 names]
如果我们查看598b9e08b0138536da55f5ef55868b2a3a607194
,我们会发现另外253个子树名为00
,01
,02
,....最重要的是:
$ git ls-tree 598b9e08b0138536da55f5ef55868b2a3a607194 | head -1
040000 tree 825029e67b3e99c8c9f36c68c26c57b7f4c2edb4 00
和825029e67b3e99c8c9f36c68c26c57b7f4c2edb4
本身只有7个条目:
$ git ls-tree 825029e67b3e99c8c9f36c68c26c57b7f4c2edb4
100644 blob 47efcb375199433eaff1932ab03ff51ffbc0f4b2 067319a197c517553b4bd00eeca22fbbb7bb
100644 blob a6aa47f5b27bc95afedb4178da68958d10c0665a 252549bd16445f7a9c45ff41b295a8bc653d
100644 blob b892978bc9120fe06997841b48e6cc05027234db a5b6354a4d39247d26563c2cf96ea644af63
100644 blob b50a07b6e41e178bc374ab25e860a33560929801 b2ecb7b200786a0a17d90036510a2aa4fa86
100644 blob 5725ea47215dd0697cb4510c53b63c49f6285a1b d86e693087beab26f4d49d7e3eb86a611efb
100644 blob 86754af5a4c9077db1e0bc52952823b3012278b4 e846eae3e7cb94a93496931c64d69682818f
100644 blob 8798a0048bf97bce373e24f0fb0456544c127406 fe19d1123431f6cbad809f708ab744b4d02c
左侧的名称是文件名:这些是存储在提交的00
树的00
子树中的文件。因此,这个由hselasky制作的“顶级”笔记提交包含数十万个文件(目前为332,670个),所有文件的名称都是这些时髦的哈希ID,分成目录目录,因此没有一个子目录文件太多了。
git show
对真实提交的作用,例如1306ece6bde0e4291eaf08139085990e5f55a622
(refs/heads/stable/10
的当前提示),是查看提交af51c6d65d574faa11ab8026398e045e5f584040
以查看它是否有名称为1306ece6bde0e4291eaf08139085990e5f55a622
的文件,或其目录名以13
开头的文件。如果找到目录,则会在其中检查是否存在名称以06ece6bde0e4291eaf08139085990e5f55a622
开头的文件或名称以06
开头的目录。如果找到一个目录,它会剥离接下来的两个字符,依此类推。最终,它要么找到文件,要么找不到。
如果Git 找到一个名称与提交的哈希匹配的文件,那么该文件包含该提交的注释。
如果Git 没有找到这样的文件,那么该提交没有备注。
现在,可以更新一个音符。更新注释只是意味着我们创建一个新提交,其内容与之前的notes-commit相同,但一个文件除外。假设我们决定更新提交1306ece6bde0e4291eaf08139085990e5f55a622
的注释。我们发现它已被放入13/06/ec...
,因此我们将notes-commit af51c6d6...
提取到树中,编辑文件13/06/ec...
,更改注释,编写文件,然后编写新提交其父提交为af51c6d6...
。我们将这个新提交的新哈希填充到refs/notes/origin/commits
或refs/notes/commits
...现在我们已经替换了该注释。
替换这样的注释是我们可以获得与原始提交1306ec...
一致的注释的不同作者和提交者的一种方式。
但是让我们来看看早先的提交。 stable/10
上的下一次提交是8f2e6e2e028ef61fd105967432ff2838153110f7
。我们通过查看refs/notes/origin/commits
点的提交来找到它的注释:再次af51c6...
。它有一个名为8f
的目录吗?为什么是,确实如此。该目录是否有名为2e
的子目录?果然,确实如此。那有一个名为6e2e...
的文件吗?
$ git rev-parse refs/notes/origin/commits:8f/2e/6e2e028ef61fd105967432ff2838153110f7
46fa8873ffcf4c9e0d0270b02a3e2abcdf10e31e
确实如此,这是我们可以看到的一个blob:
$ git cat-file -p 46fa8873ffcf4c9e0d0270b02a3e2abcdf10e31e
svn path=/stable/10/; revision=322462
这是提交8f2e74c5...
的注释。但是我们所看到的地方的作者和提交者 - refs/notes/origin/commits
又名af51c6...
- 是hselasky,而8f2e6e2e028ef61fd105967432ff2838153110f7
的作者和提交者是avos。
要找到最近更改 8f2e6e2e028ef61fd105967432ff2838153110f7
注释的作者和提交者,我们必须从顶级refs/notes/origin/commits
提交开始,看看谁触摸了文件这个名字看起来像那样。实际上,名称本身是8f/2e/6e2e...
;但是在某些早期,名称将是8f/2e6e2e...
,随着存储库的不断增长,名称将在某个时刻突然变为8f/2e/6e/2e...
。因此,我们需要一种工具,它不仅能够识别时髦的hash-ID-as-file-name,而且还知道拆分到包含包含文件的子目录的目录中,随着时间的推移而发展。这使得当音符改变时很难找到它,如果有的话。
如果注释从不更改,则第一次将其添加到存储库通常是“创建提交本身时”,因此其作者和提交者将匹配提交的作者和提交者。所以这通常足够好。如果它对你的用例不够好,你将不得不编写自己的工具。