git:获取提交id和提交注释

git:获取提交id和提交注释,git,Git,我正在编写一个钩子,用于验证在git日志的notes部分中输入的url。我循环每次提交,以获取特定提交的注释,并对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/note

我正在编写一个钩子,用于验证在git日志的notes部分中输入的url。我循环每次提交,以获取特定提交的注释,并对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添加示例
git提交-m“添加了示例”
git注释添加-m“示例注释”
git推送源主机
git推送原点参考/注释/*
上面示例的问题是,首先我推送提交,但提交没有注释,因为git push origin refs/notes/*是在master之后推送的。我基本上希望访问pre-receive钩子中的commit注释


有什么建议吗

你真的不能用你表现出来的方式来做这件事。问题归结为笔记的工作方式。正如mart1n在评论中所建议的,您需要先推送注释,或者同时推送注释。原因如下:

笔记的工作原理 “附加到”提交的注释存在(因此可以通过
git log
git show
显示),如果:

  • 假设这次提交的SHA1(我们正在尝试查找其注释)是
    1234567…
  • refs/notes/committes
    存在,并且
  • 通过
    refs/notes/commits
    指向的提交读取,有一个文件名与
    1234567…
    匹配的“文件”
  • 注释是具有有趣名称的文件内容

    让我们来探索查找注释的过程

    后台,使用低级“raw”git命令 大多数repo的最低级别访问命令是
    git cat file
    。这使您可以查看存储库中任何对象的类型(
    git cat file-t sha1
    )和内容(
    git cat file-p sha1
    )。这里的sha1部分可以是任何git引用名称,只要它解析为40个字符的十六进制SHA-1值之一。notes的默认引用名称是
    refs/notes/committes
    ,并且(如果存在)它应该始终指向
    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'
    
    对于一组简短的注释,这会产生几乎相同的结果,我们将在下面看到。如果有很多注释,这会导致更多的
    树,而这些树又会有更多的子树,所以这是一件痛苦的事情。有一个更简单的方法

    获取笔记 要查看当前注释是什么(如果有),请使用
    git notes list

    $ git notes list
    b9458a531c3f93bd36af0025d56029ef58cf8d00 5e013711f5d6eb3f643ef562d49a131852aa4aa1
    1c716d4d58325651ceecba14ce8974b0ac6d13e9 a546ad9299465c9cf304fecf01d1514337419e2f
    
    “注释内容”使用每行左侧的SHA-1,每个注释内容文件都附加到委员会1,其SHA-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,如果找到,则检查左侧的ID(重新格式化/缩进)。(当然,这是一个更优化的版本。)

    这种在
    notes
    列表中查找提交ID的机制就是notes可以更改的原因。 在
    refs/notes/commits
    下添加新提交将在该“分支”下添加/更改文件(它不是真正的分支,分支以
    refs/heads/
    开头,但在其他方面与分支类似)。新文件具有适用于现有(旧)提交的新注释。那些旧的提交根本没有改变,但是当
    git log
    git show
    查看注释以查看提交ID是否在其中时,它们会为相同的旧提交显示新的、不同的注释

    但是,名为
    refs/notes/commits
    的commit对象现在必须存在,并且必须指向您要查看的附加到您所询问的提交的注释。如果您
    push
    向某个远程回购提交一组新的提交,并且还没有
    push
    提交
    refs/notes/commits
    提交,那么任何查看远程回购的内容都看不到您的笔记,因为它们根本不在那里。先按一下笔记,或者同时按一下,笔记就会在那里找到


    1实际上,注释可以列出任何SHA-1:提交对象、blob对象、带注释的标记对象,甚至树对象。您甚至可以输入SHA-1值,这些值与回购协议中的任何对象都不对应,如果您愿意,可以使用“分离注释”。我知道这样的事情没有任何用处,但没有技术上的理由不能做到。[编辑以添加:
    git notes
    无法完成此操作;我的意思是您可以使用git管道命令完成此操作。不过我还没有尝试过。]

    怪事 当然,
    refs/notes/commits
    本身就是一个常规的提交树。因此,我们可以“回到过去”,看看在最新的
    git notes edit
    之前notes是什么样子。但似乎没有“前端”接口。我试过了,例如:

    $ git log -1 --notes=refs/notes/commits^ 5e0137
    
    但是这根本没有显示任何注释,这看起来很奇怪/不完整,因为
    --notes=refs/notes/committes
    可以工作。

    要添加到的(这说明了为什么需要进行和提交,以便
    预接收
    钩子可以工作),这里有一个演变


    问题是:

    当然,
    refs/notes/commits
    本身就是一个常规的提交树。
    因此,我们可以“回到过去”,看看在最新的git notes编辑之前,notes是什么样子的。但似乎没有“前端”接口。我试过了,例如:

    $ git log -1 --notes=refs/notes/commits^ 5e0137
    
    但这只是表明没有
    $ git log -1 --notes=refs/notes/commits^ 5e0137
    
    MSG=b4 git notes add
    MSG=b3 git notes add
    
    test "b3" = "$(git notes --ref commits^{tree} show)"
    
    test "b4" = "$(git notes --ref commits@{1} show)"
    
    <refname>@\{<n>\}, e.g. commits@{1}