web-dev-qa-db-ja.com

git commitにメタデータを追加できますか?または、gitkでいくつかのタグを非表示にできますか

カスタムメタデータをgit commitに関連付けたい。具体的には、コードレビューからレビューIDを記録しますが、それは何でもかまいません。タグはそれを行うための自然な方法のようですが、コミットごとにレビューを行うことを期待しており、gitkを大量のタグで乱雑にしたくありません。カスタムメタデータを追加する他のメカニズムはありますか?特定のタグを非表示にすることはできますか? gitkに、何らかのパターンまたはREに一致するタグを表示しないように指示できれば、それは機能する可能性がありますが、その方法がわかりません。

42
Chris Nelson

それがまさに git notes の目的です。

34
Jörg W Mittag

Git-notes

git notesを使用すると、コミットに「メモ」を追加できます。それらを他のGitオブジェクトに追加することもできますが、それが問題であるため、コミットに焦点を当てましょう。

メモはGitオブジェクトであり、原則として「何でも」(任意のデータ)にすることができます。ただし、目的のために、シンプルでテキスト的なものに焦点を当てます。

例:レビューID

質問にはレビューIDが記載されているので、そのようなことを表す方法をいくつか作りましょう。レビューIDが実際にどのように見えるかはわかりませんが、次のことが賢明であることを願っています。

Review-id: 42

したがって、これは事実上キーと値のペアです。上記の文字列を現在のコミットに追加しましょう。

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

git logを実行すると、メモがインラインで表示されます:(†1)

Author: Victor Version Control <[email protected]>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes:
    Review-id: 42

もう一つの例

もちろん、このメモにさらに「サブノート」を追加することもできます(単純なkey: value構文、1行に1つの値を使用します)。たとえば、3か月後にコミットメッセージに問題があることがわかった場合は、メモに修正を追加するだけです。

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

git log

Author: Victor Version Control <[email protected]>
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. 上記のような単純なデータに固執します(1行に1つのKey-Value)。
  2. 特別なマージ戦略を使用します。 man git-notesのセクション「メモのマージ戦略」を参照してください。

可視性

OPは尋ねました:

>特定のタグを非表示にすることはできますか?

デフォルトでは、git logは1つのメモ、つまり.git/refs/notes/commitsのみを表示します。 commitsは、名前空間内の1つのメモです。 issuesを独自の名前空間に配置したい場合があります。

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

これは.git/refs/notes/issuesではなく.git/refs/notes/commitsに保存されるため、git logを実行しても「修正:#32」は表示されません。したがって、このようなメモはデフォルトで事実上非表示になっています。

表示したい場合は、--notes=issuesgit logに渡します。

$ git log --notes=issues
Author: Victor Version Control <[email protected]>
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 <[email protected]>
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-noteは変更可能であるため、いつでも修正できます。そして、ノートの各変更はもちろんバージョン管理されています。私たちの場合、.git/refs/notes/commitsの場合:

$ git log refs/notes/commits
Author: Victor Version Control <[email protected]>
commit 9f0697c6bbbc6a97ecce9834d4c9afa0d668bcad
Date:   Tue Nov 8 21:13:52 2016 +0100

    Notes added by 'git notes append'

commit b60997e49444732ed2defc8a6ca88e9e21001a1d
Author: Victor Version Control <[email protected]>
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/*

(出典: https://git-scm.com/blog/2010/08/25/notes.html

書き換えに関するメモを引き継ぐ

Gitには、コミットが書き換えられたときにメモが引き継がれないという不便なデフォルトがあります。したがって、たとえば一連のコミットをリベースした場合、メモは新しいコミットに引き継がれません。

変数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:たとえば、次のようなプロジェクトで使用される、metadata-in-commit-messagesの1つのプラクティス/規則。 GitとLinuxカーネルは、コミットメッセージの「トレーラー」、つまり下部にキーと値のペアを追加します。たとえば、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 <[email protected]>
 Acked-by: Hugh Dickins <[email protected]>
 Reviewed-by: Michal Hocko <[email protected]>
 Cc: Andy Lutomirski <[email protected]>
 Cc: Kees Cook <[email protected]>
 Cc: Oleg Nesterov <[email protected]>
 Cc: Willy Tarreau <[email protected]>
 Cc: Nick Piggin <[email protected]>
 Cc: Greg Thelen <[email protected]>
 Cc: [email protected]
 Signed-off-by: Linus Torvalds <[email protected]>

見る:

  • man git-interpret-trailers
  • このカーネルWikiページ さまざまなプロジェクトで使用されるさまざまなトレーラー行(通常はキーと値のペア)を一覧表示します。
31
Guildenstern