我正在编写一个用于验证url的钩子,它在git log的notes部分输入。我遍历每个提交以获取该特定提交的注释,并对该URL进行字符串比较。如果提交是新提交,则会弹出问题,因为新提交不包含注释。
例如: -
git add sample
git commit -m "added sample"
git notes add -m "sample note" <commitID-of-sample>
git push origin master
git push origin refs/notes/*
以上示例的问题是,首先我推送提交但是提交没有注释,因为git push origin refs / notes / *在master之后被推送。我基本上想要在预接收挂钩中访问提交的注释。
有什么建议吗?
答案 0 :(得分:10)
你实际上不能按照你展示的方式做到这一点。问题归结为笔记的工作方式。正如mart1n在评论中建议的那样,您需要先按或同时按下音符。原因如下:
存在“附加到”提交的注释(因此可以通过git log
和git show
显示)“现在”如果:
1234567...
。refs/notes/commits
存在,refs/notes/commits
指向的提交进行阅读,其中有一个文件名与1234567...
匹配的“文件”。该注释是具有有趣名称的文件的内容。
让我们探索寻找笔记的过程。
大部分仓库的最低级访问命令是git cat-file
。这使您可以查看存储库中任何对象的类型(git cat-file -t sha1
)和内容(git cat-file -p sha1
)。这里的 sha1 部分可以是任何git引用名称,只要它解析为这些40个字符的十六进制SHA-1值之一即可。注释的默认引用名称为refs/notes/commits
,并且(如果存在)它应始终指向commit
对象。因此:
$ git cat-file -p refs/notes/commits
tree 28db2757c2b7c6e4bbfef35e61e8bd7c698626dc
parent ce97e80bfbdab9bc163ecb93779d071d7ed8c739
author A U Thor <author@example.example> 1376652910 -0600
committer A U Thor <author@example.example> 1376652910 -0600
Notes added by 'git notes edit'
我们的下一步是查看此处命名的tree
:
$ git cat-file -p 28db2757c2b7c6e4bbfef35e61e8bd7c698626dc
对于一小段笔记,这产生了几乎相同的东西,我们将在下面看到。如果有很多笔记,这会导致更多tree
s,这反过来可能会有更多的子树,所以这很痛苦。有一种更简单的方法。
要查看当前的音符(如果有),请使用git notes list
:
$ git notes list
b9458a531c3f93bd36af0025d56029ef58cf8d00 5e013711f5d6eb3f643ef562d49a131852aa4aa1
1c716d4d58325651ceecba14ce8974b0ac6d13e9 a546ad9299465c9cf304fecf01d1514337419e2f
“注释内容”使用每行左侧的SHA-1,每个note-content-file附加到其右侧为SHA-1的commit 1 。让我们使用第一行来看看它是如何工作的:
$ git cat-file -t 5e013711f5d6eb3f643ef562d49a131852aa4aa1
commit
$ git cat-file -p 5e013711f5d6eb3f643ef562d49a131852aa4aa1
tree ead5cc295ae64c9186f392b80ca4ed10888f20d9
parent 309b36c8166f5ff330a6e8a0a674ed161d45b5f4
author ...[line snipped]
committer ...[line snipped]
add ast ... [rest snipped]
您当然可以git show 5e0137
或git log -1 5e0137
等来查看该提交,它还会向您显示注释内容。但是,要查看只是原始注释内容,请使用左侧的SHA-1:
$ git cat-file -p b9458a531c3f93bd36af0025d56029ef58cf8d00
experiment: add a note
this is the text I put in the note
让我们做一个git notes edit 5e0137
并更改提交的注释,然后再次git notes list
:
$ git notes edit 5e0137
[editor session snipped]
$ git notes list
d87650a968ff684e69175eacde0880595f9f2989 5e013711f5d6eb3f643ef562d49a131852aa4aa1
1c716d4d58325651ceecba14ce8974b0ac6d13e9 a546ad9299465c9cf304fecf01d1514337419e2f
右侧的两个“文件名”仍然完全相同,但在左侧,第一个SHA1是不同的。我们来看看它:
$ git cat-file -p d87650a968ff684e69175eacde0880595f9f2989
change some stuff in the note
I edited the note attached to 5e0137.
如果您现在git show
(git log
等)提交旧笔记,则会收到新笔记。实际上,这些操作是运行git notes list
,检查右侧是否有匹配的ID,如果找到,则git cat-file -p
左侧的ID(重新格式化/缩进)。 (当然,这是一个更优化的版本。)
notes
列表中查找提交ID的机制是注释可以更改的原因。在refs/notes/commits
下添加新的提交会在“分支”下添加/更改文件(它不是真正的分支,分支以refs/heads/
开头,但它只是喜欢分店)。新文件具有适用于现有(旧)提交的新注释。这些旧提交根本没有改变,但是当git log
和git show
查看注释以查看提交ID是否在那里时,它们会获得新的,不同的注释以显示相同的旧提交
由refs/notes/commits
命名的提交对象现在必须存在,并且必须指向您要查看附加到您询问的提交的注释。如果您push
对一些远程回购提交了大量新提交,但尚未push
提交refs/notes/commits
提交,那么在远程回购上看的任何内容都无法看到您的注释,因为他们根本就不是那里。首先或同时按下音符,它们将在那里找到。
1 实际上,注释可以列出任何 SHA-1:提交对象,blob对象,带注释的标记对象,甚至是树对象。你甚至可以输入与repo中的任何对象不对应的SHA-1值,如果你愿意,也可以输入“分离的注释”。我知道没有这种用途的用途,但没有技术上的原因它无法完成。 [编辑添加:git notes
不会这样做;我的意思是你可以用git管道命令来做到这一点。我没试过。]
当然,refs/notes/commits
本身就是一个常规提交树。因此,我们可以“回到过去”并查看最近git notes edit
之前的注释。但似乎没有“前端”接口。我试过了,例如:
$ git log -1 --notes=refs/notes/commits^ 5e0137
但是这根本没有显示任何注释,这似乎很奇怪/破碎,因为--notes=refs/notes/commits
有效。
答案 1 :(得分:3)
要添加到torek&#39; answer(这说明了为什么需要push notes并提交,以便pre-receive
挂钩工作),这是进化论。
问题是:
当然,
refs/notes/commits
本身就是一个常规的提交树 因此,我们可以及时回到过去。并在最近的git笔记编辑之前查看笔记的样子。但似乎没有&#34;前端&#34;这个界面。我试过了,例如:
$ git log -1 --notes=refs/notes/commits^ 5e0137
但是这根本没有显示任何注释,这似乎很奇怪/破碎,因为
--notes=refs/notes/commits
有效。
这将适用于commits@{1}
,位于git 2。8(2016年3月)。
commit ee76f92见Mike Hommey (glandium
)(2015年10月8日)
(由Junio C Hamano -- gitster
--合并于commit b4e8e0e,2016年1月20日)
一些&#34;
git notes
&#34;操作,例如&#34;git log --notes=<note>
&#34;,应该 能够阅读形状像笔记的任何tree-ish的笔记 树,但注释基础结构要求参数必须 是refs/notes/
下的参考文献 只有在操作更新注释时才会将其松开以要求有效的ref(在这种情况下,我们必须有一个存储更新的注释树的位置,iow,ref
)。通过此更改,可以任意使用以只读方式使用笔记的操作 可以使用音符形tree-ish ,例如git log --notes = notes @ {1}。
(在树上,见gitrevisions
)
如果你创建了两个音符(b4
,那么b3
):
MSG=b4 git notes add
MSG=b3 git notes add
然后,您可以看到与提交树关联的最新注释(b3
):
test "b3" = "$(git notes --ref commits^{tree} show)"
后缀
^
后跟括号对中的对象类型名称意味着递归地取消引用<rev>
处的对象,直到找到<type>
类型的对象。
<rev>^{tree}
描述了相应的树对象。
之前的说明确实是b4
:
test "b4" = "$(git notes --ref commits@{1} show)"
使用:
<refname>@\{<n>\}, e.g. commits@{1}
ref后跟后缀
@
,括号对中包含序数规范(例如{1}
,{15}
)指定该ref的第n个先前值。 /> 例如,commits@{1}
是commits
的直接先前值。