我想将自定义元数据与git commit
. 专门记录代码审查中的审查 ID,但它可以是任何东西。标签似乎是一种自然的方式来做到这一点,但我希望对每一次提交都有一个审查,我不想被gitk
大量的标签弄得乱七八糟。是否有其他机制可以添加自定义元数据?我可以使某些标签不可见吗?如果我可以告诉gitk
不显示与某些模式或 RE 匹配的标签,那可能会起作用,但我看不到这样做的方法。
2 回答
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 注释只是一个可变文件,因此您可能会遇到合并冲突。为了降低这种可能性,您可以:
- 坚持使用像上面这样的简单数据(每行一个键值)。
- 使用特殊的合并策略;请参阅
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=issues
给git 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
、 或选项时。” --oneline
― man 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 页面列出了各种项目中使用的各种尾行(通常是键值对)。
这正是git notes的用途。