デフォルトで 0 に設定されている git のデフォルト オプションに気付きましたcore.repositoryFormatVersion
が、「リポジトリ フォーマット バージョン」とは何ですか。
2 に答える
これは将来の互換性のためです。新しい機能を有効にするためにリポジトリをディスクに保存する方法を変更する必要があると Git 開発者が判断した場合、アップグレードされたリポジトリにcore.repositoryformatversion
of を持たせることができ1
ます。次に、その新しい形式を認識している git の新しいバージョンはコードをトリガーしてそれを処理し、そうでない古いバージョンの git は"Expected git repo version <= 0, found 1. Please upgrade Git"
.
現在のところ、定義または認識されているリポジトリ形式のバージョンは のみです0
。これは、git のすべての公開リリースで使用されている形式を示します。
git 2.7 (2015 年 11 月) では、新しい .xml ファイルにさらに多くの情報が追加されていDocumentation/technical/repository-version.txt
ます。commit 067fbd4、commit 00a09d5 (2015 年 6 月 23 日) by Jeff King ( )
を参照してください。( 2015 年 10 月 26 日にコミット fa46579でJunio C Hamanoによってマージされました)peff
gitster
「拡張機能」を定義core.repositoryformatversion
し、「マーカー」として使用して、Git のバージョン番号自体を変更する代わりに、拡張機能の存在を知らせることができるようになりました。
そのような変更ごとにリポジトリのバージョンを上げなければならない場合、非互換性がシステムの直交部分にある可能性があるとしても、バージョン
X
を理解する実装はX-1
、なども理解X-2
する必要があり、そうでなければできない理由はありません。一方を他方なしで実装します (さらに重要なことは、ユーザーが特定の機能のみの互換性のトレードオフを考慮して、一方の機能を他方なしで使用することを選択できないことです)。このパッチは、既存の戦略を文書化し
repositoryformatversion
、新しい形式「1」を導入します。これにより、リポジトリは、任意の拡張セットで実行する必要があることを指定できます。
ドキュメントからの抜粋:
すべての git リポジトリは 、そのファイルの
core.repositoryformatversion
キーに数値バージョンでマークされています。config
このバージョンは、ディスク上のリポジトリ データを操作するためのルールを指定します。これは、リポジトリのディスク コンテンツに直接アクセスする場合にのみ適用されることに注意してください。
format のみを理解する古いクライアントは、サーバー プロセスが format を理解する限り、format を使用してリポジトリに0
接続できます。git://
1
1
バージョン
0
これは、git の初期バージョンで定義された形式であり、リポジトリ ディレクトリ、リポジトリ構成ファイル、オブジェクトおよび参照ストレージの形式を含みますが、これらに限定されません。
バージョン
1
この形式は version と同じですが
0
、次の例外があります。
変数を読み取るとき、
core.repositoryformatversion
バージョン 1 をサポートする git 実装extensions
は、構成ファイルのセクションにある構成キーも読み取る必要があります。バージョン 1 のリポジトリ
extensions.*
が、実行中の git が実装していないキーを指定している場合、操作を続行してはなりません。
同様に、既知のキーの値が実装によって理解されない場合、操作を続行してはなりません。これは、たとえば次のように使用できます。
ref ヒントの到達可能性のみに基づいてオブジェクトをプルーニングすべきではないことを git に通知します (たとえば、「clone --shared」子があるため)。
通常の「refs」および「packed-refs」ディレクトリ以外の形式で参照が保存されていること
これは、すべてのリリース バージョン番号ポリシーとそのサーバー ポリシーに対する独自のアプローチです。
フォーマット "1" にぶつかり、フォーマット "1" では実行中の git が言及されている拡張機能を認識している必要があるため、古いバージョンのコードはこれらの新しいフォーマットに直面しても危険なことをしないことがわかっています。
たとえば、ユーザーが参照にデータベース ストレージを使用することを選択した場合、"extensions.refbackend" 構成を "db" に設定できます。
古いバージョンの git は、フォーマット "1" と bail を理解できません。
"1" は理解できるが "refbackend" については知らないバージョン、または "refbackend" については知っているが "db" バックエンドについては知らないバージョンの git は、実行を拒否します。
もちろん、これは面倒ですが、リポジトリに参照がないと主張したり、他の実装が読み取らない場所に書き込んだりするよりははるかに優れています。ここでは、形式 1 のルールのみを定義していることに注意してください。
フォーマット 1 を自分で作成することはありません。これは、古い実装で安全性を提供するために、ユーザーおよび将来の拡張機能によって使用されることを意図したツールです。
最初の拡張機能として、 git 2.7 を使用しますpreciousObjects
。
この拡張機能がリポジトリで使用されている場合、オブジェクト ストレージからオブジェクトをドロップする可能性がある操作は実行されません。これは、参照が表示されない他のリポジトリとそのストレージを共有している場合に役立ちます。
ドキュメントには次のように記載されています。
config キー
extensions.preciousObjects
が に設定されてtrue
いる場合、リポジトリ内のオブジェクトを削除してはなりません (たとえば、git-prune
またはによってgit repack -d
)。
あれは:
たとえば、次のようにします。
$ git clone -s parent child $ git -C parent config extensions.preciousObjects true $ git -C parent config core.repositoryformatversion 1
親リポジトリで git を実行する際の安全性が向上しました。
Prunes と repacks はエラーで保釈され、git gc
それらの操作をスキップします (ref の pack と他の非オブジェクト操作を続けます)。
古いバージョンの Git をリポジトリで実行すると、すべての操作で失敗します。
preciousObjects
" " を実行する場合、デフォルトでは拡張子を設定しないことに注意してください。これを行うclone -s
と、後方互換性が失われるためです。これは、ユーザーが明示的に行う必要がある決定です。
このcore.repositoryformatversion
ビジネスは古いことに注意してください。本当に古い。commit ab9cb76、2005 年 11 月、Git 0.99.9l。最初はdbバージョン
で行われました:
これにより、
init-db
リポジトリのバージョンが認識されます。既存の構成ファイルが、再初期化されているリポジトリのバージョンが間違っていることを示しているかどうかを確認し、さらに害を及ぼす前に中止します。
repository_format
Git 2.22 (2019 年第 2 四半期) では、構造に関するリークが回避され
ます。
commit e8805af (2019 年 2 月 28 日) およびMartin Ågren (``)によるcommit 1301997 (2019 年 1 月 22 日)を参照してください。( 2019 年 3 月 20 日、コミット 6b5688bでJunio C Hamanoによってマージされました)
gitster
setup
: でメモリリークを修正struct repository_format
を設定すると
struct repository_format
、割り当てられたメモリのさまざまな部分が所有されます。次に、「候補」リポジトリ形式を使用することを決定したため、これらのメンバーを使用するか、候補/スクラッチ スペースを破棄します。
最初のケースでは、メモリの所有権をいくつかのグローバル変数に移します。後者の場合、黙って構造体を削除するだけで、メモリ リークが発生します。の両側で使用される 初期化マクロ
REPOSITORY_FORMAT_INIT
と関数を導入します。メモリの所有権を明確かつ単純にするには、ポインタを盗むのではなく、すべてのユーザが取得した文字列を複製できるようにします。clear_repository_format()
read_repository_format()
struct repository_format
関数を複数回入力することがあるため、構造体を単にゼロにするの
clear_...()
ではなく、最初に呼び出します。 したがって、 を呼び出す前に構造体を初期化することが重要なので、それを文書化してください。を呼び出す前に呼び出す ことすらできないため、これも重要です。たとえば、 を参照してください。read_...()
read_...()
read_...()
clear_...()
builtin/init-db.c
read_...()
安全な状態にリセットされるように、エラー時に構造体をクリアするように教え、これを文書化します。( ではsetup_git_directory_gently()
、 -1 でrepo_fmt.hash_algo
あっても調べますrepo_fmt.version
が、これは実際には API ごとに行うべきではありませんでした。このコミットの後は、問題ありません。)
Git 2.28 (2020 年第 3 四半期) では、ランタイム自体がリポジトリ形式のバージョンを自動的にアップグレードできます (たとえば、unshallow fetch など)。
commit 14c7fa2、commit 98564d8、commit 01bbbbd、commit 16af5f1 (2020 年 6 月 5 日) by Xin Li ( livid
)を参照してください。
( 2020 年 6 月 29 日、コミット 1033b98でJunio C Hamanoによってマージされました)gitster
fetch
: 初期クローンの後にフィルターを追加できるようにします署名者: Xin Li
--unshallow
フィルターをさかのぼって追加すると、ユーザーは通常のフェッチですべての git オブジェクトをダウンロードしなくても、以前の変更履歴を確認できるため、既存の浅いクローンに役立ちます。このパッチがないと、ユーザーはリポジトリ構成を編集してリモートを promisor に変換することで、クローンを部分的に作成できます。
git config core.repositoryFormatVersion 1 git config extensions.partialClone origin git fetch --unshallow --filter=blob:none origin
この作業を行うための難しい部分は既に整っており、そのような編集はエラーが発生しやすいため、代わりに必要な構成変更を自動的に実行するように Git に教えてください。
この変更は、変更せずに設定を認識する既存の Git の動作を変更しないことに注意して
extensions.partialClone
くださいrepositoryFormatVersion
。
警告: 2.28-rc0 では、バージョン 0 のリポジトリでも一部のリポジトリ拡張が誤って受け入れられるというバグを修正しました (extensions.*
名前空間のこれらの構成変数は、バージョン番号が 1 以上のリポジトリでは特別な意味を持つはずでした)。少し大きすぎる変更でした。
コミット 62f2eca、コミット 1166419 (2020 年 7 月 15 日) by Jonathan Nieder ( artagnon
)を参照してください。
( 2020 年 7 月 16 日にコミット d13b7f2でJunio C Hamanoによってマージされました)gitster
Revert "check_repository_format_gently()
: 古いリポジトリの拡張を拒否します"報告者: Johannes Schindelin
署名者: Jonathan Nieder
これにより、コミット 14c7fa269e42df4133edd9ae7763b678ed6594cdが元に戻ります。
この
core.repositoryFormatVersion
フィールドはab9cb76f661 ("Repository format version check.", 2005-11-25, Git v0.99.9l -- merge ) で導入され、Martin Atukunda によるいくつかの歓迎すべき分析のおかげで、歓迎すべき少しの前方互換性が提供されました。セマンティクスは単純です
core.repositoryFormatVersion
。0 に設定されたリポジトリは、アクティブに使用されているすべての Git 実装で理解できる必要があります。また、Git の実装は、Git リポジトリがcore.repositoryFormatVersion
理解できない新しい形式を表す高い値を使用して動作を試みるのではなく、早期にエラーを発生させる必要があります。00a09d57eb8 (2015-06-23 の「拡張」形式を導入)まで、新しいリポジトリ形式を定義する必要はありませんでした
core.repositoryformatversion
。これにより、Git リポジトリのよりきめ細かい拡張メカニズムが提供されました。
1 に設定されたリポジトリでは
core.repositoryFormatVersion
、Git 実装はextensions.*
、リポジトリの解釈方法を変更する " " 設定に基づいて動作できます。リポジトリ形式バージョン 1 では、拡張機能の設定が認識されないため、Git でエラーが発生します。
ユーザーが拡張機能を設定したが、リポジトリ形式のバージョンを 1 に上げるのを忘れた場合はどうなりますか?
その場合でも拡張機能の設定は認識されました。さらに悪いことに、拡張機能の設定が認識されていなくても、Git でエラーが発生することはありません。そのため、リポジトリ形式のバージョン 0 と拡張機能の設定を組み合わせると、ある意味で、両方の世界で最悪の事態が発生します。
その状況を改善するために、14c7fa269e4
(check_repository_format_gently()
以降: 古いリポジトリの拡張機能を拒否、2020-06-05) Git は代わりに v0 モードの拡張機能を無視します。このようにして、v0 リポジトリは履歴 (2015 年より前) の動作を取得し、v1 形式を認識しない Git 実装との互換性を維持します。残念ながら、ユーザーはこの種の構成を使用しており、この動作の変更は多くの人を驚かせました。
- 「 」のユーザーは、 (リポジトリ形式のバージョンを上げずに)
git config --worktree
有効にするというアドバイスに従っていましたが、自分のワークツリー構成が有効にならないことに気付くでしょう。extensions.worktreeConfig
- 既存のリポジトリに設定されていた(リポジトリ形式のバージョンも上げずに) copybaraなどのツール
extensions.partialClone
は、その設定が有効でなくなったことを検出します。14c7fa269e4で導入された動作は、2015 年にさかのぼる場合は良い動作かもしれませんが、手遅れです。
どういうわけか、それはもともと実装されていたものであり、後退していると思いました。
14c7fa269e4が開発中であったときに、私の調査を行わなかったことをお詫びします。
2015 年以降の動作に戻りましょう:
extensions.*
リポジトリ形式のバージョンに関係なく、常に設定に従って動作します。ここでは、「リポジトリ バージョンのアップグレード」コード パスへの影響を説明するテストをいくつか含めます。