51

我想将自定义元数据与git commit. 专门记录代码审查中的审查 ID,但它可以是任何东西。标签似乎是一种自然的方式来做到这一点,但我希望对每一次提交都有一个审查,我不想被gitk大量的标签弄得乱七八糟。是否有其他机制可以添加自定义元数据?我可以使某些标签不可见吗?如果我可以告诉gitk不显示与某些模式或 RE 匹配的标签,那可能会起作用,但我看不到这样做的方法。

4

2 回答 2

54

Git 笔记

您可以在git notes提交中添加“注释”。您也可以将它们添加到其他 Git 对象,但让我们只关注提交,因为这就是问题所在。

笔记是一个 Git 对象,原则上可以是“任意”(任意数据)。但是为了我们的目的,我们将专注于一些简单的文本。

示例:评论 ID

该问题提到了评论 ID,所以让我们编造一些方法来表示这样的事情。我不知道评论 ID 的真正样子,但希望以下内容是明智的:

Review-id: 42

所以这实际上是一个键值对。让我们将上面的字符串添加到当前提交中:

git notes add -m "Review-id: 42"

如果您运行git log该注释将内联显示:(†1)

Author: Victor Version Control <vvc@vcs.org>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes:
    Review-id: 42

另一个例子

当然,您可以在此注释中添加更多“子注释”(我们将坚持使用简单的key: value语法,每行一个值)。例如,如果您在三个月后发现提交消息有问题,只需将更正附加到注释中:

git notes append -m "Errata: It was actually feature y."

git log

Author: Victor Version Control <vvc@vcs.org>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes:
    Review-id: 42

    Errata: It was actually feature y.

我们使用git notes append以便轻松地将这些额外数据添加到注释中。您也可以使用git notes edit以直接编辑文件。

当然,由于 Git 注释只是一个可变文件,因此您可能会遇到合并冲突。为了降低这种可能性,您可以:

  1. 坚持使用像上面这样的简单数据(每行一个键值)。
  2. 使用特殊的合并策略;请参阅man git-notes“Notes 合并策略”部分。

能见度

OP问:

> 我可以让某些标签不可见吗?

默认git log只显示一个音符,即 .git/refs/notes/commits. commits只是命名空间中的一个音符。也许您希望问题位于它们自己的命名空间中:

git notes --ref=issues add -m "Fixes: #32"

由于它存储在.git/refs/notes/issues而不是 存储在 中.git/refs/notes/commits,因此“修复:#32”不会在您运行时显示 git log。因此,默认情况下,您有效地使此类注释不可见。

如果要显示它,请传递--notes=issuesgit log

$ git log --notes=issues
Author: Victor Version Control <vvc@vcs.org>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes (issues):
    Fixes: #32

但现在.git/refs/notes/commits都隐藏了。那个也可以很容易地包括在内:

$ git log --notes=issues --notes=commits
Author: Victor Version Control <vvc@vcs.org>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes (issues):
    Fixes: #32

Notes:
    Review-id: 42

    Errata: It was actually feature y.

有一些变量可以配置默认显示哪些注释;见 man git-config

与提交消息相比的好处

元数据当然可以直接记录在提交消息中。(†2)但是提交消息是不可变的,因此更改它们实际上意味着进行全新的提交,并带来所有的涟漪后果。另一方面,Git-notes 是可变的,所以你总是可以修改它们。当然,每条笔记的修改都是版本控制的。在我们的例子中,对于.git/refs/notes/commits

$ git log refs/notes/commits
Author: Victor Version Control <vvc@vcs.org>
commit 9f0697c6bbbc6a97ecce9834d4c9afa0d668bcad
Date:   Tue Nov 8 21:13:52 2016 +0100

    Notes added by 'git notes append'

commit b60997e49444732ed2defc8a6ca88e9e21001a1d
Author: Victor Version Control <vvc@vcs.org>
Date:   Tue Nov 8 21:10:38 2016 +0100

    Notes added by 'git notes add'

分享笔记

您的笔记默认不共享;你必须明确地这样做。与其他参考相比,共享笔记不是很友好。我们必须使用refspec语法:

git push refs/notes/*

以上将把你所有的笔记推送到你的遥控器。

似乎提取笔记有点复杂。如果您指定 refspec 的两侧,则可以这样做:

git fetch origin refs/notes/*:refs/notes/*

所以这绝对不方便。如果您打算定期使用 Git-notes,您可能需要将 gitconfig 设置为始终获取笔记:

[remote "origin"]
    …
    fetch = +refs/notes/*:refs/notes/*

在重写时结转笔记

Git 有一个不方便的默认设置,即在重写提交时不会保留注释。因此,例如,如果您对一系列提交进行 rebase,则注释将不会延续到新的提交中。

默认情况下,该变量notes.rewrite.<command>设置为true,因此可能会假设笔记结转。但问题是 notes.rewriteRef决定哪些票据将被结转的变量没有默认值。要设置此值以匹配所有音符,请执行以下命令:

git config --global notes.rewriteRef "refs/notes/*"

现在,在进行诸如git rebase.

通过电子邮件补丁传递笔记

如果您使用git format-patch将更改格式化为电子邮件发送,并且您将一些元数据存储为 Git 注释,则可以传递--notes 选项以git format-patch将注释附加到电子邮件草稿中。


† 1:“这是 [...] 的默认值,当命令行上git log没有给出--pretty--format、 或选项时。” --onelineman git-log, git 版本 2.10.2

† 2:在 Git 和 Linux 内核等项目中使用的 metadata-in-commit-messages 的一种做法/约定是在提交消息的“预告片”中添加键值对,即在底部。例如,参见Linus Torvalds 的这个提交

 mm: remove gup_flags FOLL_WRITE games from __get_user_pages()
 This is an ancient bug that was actually attempted to be fixed once
 (badly) by me eleven years ago in commit 4ceb5db9757a ("Fix
 get_user_pages() race for write access") but that was then undone due to
 problems on s390 by commit f33ea7f404e5 ("fix get_user_pages bug").

 In the meantime, the s390 situation has long been fixed, and we can now
 fix it by checking the pte_dirty() bit properly (and do it better).  The
 s390 dirty bit was implemented in abf09bed3cce ("s390/mm: implement
 software dirty bits") which made it into v3.9.  Earlier kernels will
 have to look at the page state itself.

 Also, the VM has become more scalable, and what used a purely
 theoretical race back then has become easier to trigger.

 To fix it, we introduce a new internal FOLL_COW flag to mark the "yes,
 we already did a COW" rather than play racy games with FOLL_WRITE that
 is very fundamental, and then use the pte dirty flag to validate that
 the FOLL_COW flag is still valid.

 Reported-and-tested-by: Phil "not Paul" Oester <kernel@linuxace.com>
 Acked-by: Hugh Dickins <hughd@google.com>
 Reviewed-by: Michal Hocko <mhocko@suse.com>
 Cc: Andy Lutomirski <luto@kernel.org>
 Cc: Kees Cook <keescook@chromium.org>
 Cc: Oleg Nesterov <oleg@redhat.com>
 Cc: Willy Tarreau <w@1wt.eu>
 Cc: Nick Piggin <npiggin@gmail.com>
 Cc: Greg Thelen <gthelen@google.com>
 Cc: stable@vger.kernel.org
 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

看:

  • man git-interpret-trailers
  • 这个内核 Wiki 页面列出了各种项目中使用的各种尾行(通常是键值对)。
于 2016-11-08T21:31:46.580 回答
43

这正是git notes的用途。

于 2010-04-21T13:52:02.463 回答