1. ホーム
  2. git

[解決済み] 浅いgitサブモジュールの作り方は?

2022-04-23 09:22:07

質問

浅いサブモジュールを持つことは可能ですか?スーパープロジェクトにいくつかのサブモジュールがあり、それぞれが長い履歴を持つので、その履歴をすべて引きずると不必要に大きくなってしまうのです。

私が見つけたのは この未回答のスレッド .

を実行すればよいのでしょうか? git-submoduleをハックする を実装することはできますか?

どのように解決するのですか?

今後の新機能 git1.8.4 (2013年7月) :

<ブロッククオート

" git submodule update "は、オプションでサブモジュールリポジトリを浅くクローンすることができます。

(そして、git 2.10 Q3 2016では、それを記録するために git config -f .gitmodules submodule.<name>.shallow true .

この回答の最後を参照)

参照 commit 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f :

<ブロッククオート

を追加します。 --depth オプションを "git submodule" の追加コマンドと更新コマンドに追加し、それを clone コマンドに渡します。これは、サブモジュールが巨大で、最新のコミット以外にはあまり興味がないような場合に便利です。

<ブロッククオート

テストが追加され、"submodule update can handle symbolic links in pwd"のテストファイルの残りの部分に適合するようにいくつかのインデントの調整が行われました。

<ブロッククオート

サインオフバイ: Fredrik Gustafsson <[email protected]>

Acked-by: Jens Lehmann(イェンス・レーマン <[email protected]>

これが効くということですね。

# add shallow submodule
git submodule add --depth 1 <repo-url> <path>
git config -f .gitmodules submodule.<path>.shallow true

# later unshallow
git config -f .gitmodules submodule.<path>.shallow false
git submodule update <path>

コマンドはどのような順番で実行してもかまいません。そのため git submodule コマンドは、実際のクローンを実行します(今回は深度1を使用)。そして git config コマンドは、後で再帰的にレポをクローンする他の人のために、このオプションを永続的にします。

例として、レポがあるとします。 https://github.com/foo/bar を追加したい場合 https://github.com/lorem/ipsum をサブモジュールとして、自分のレポで path/to/submodule . コマンドは以下のような感じでしょうか。

git submodule add --depth 1 [email protected]:lorem/ipsum.git path/to/submodule
git config -f .gitmodules submodule.path/to/submodule.shallow true

次の結果も同じです(順序が逆)。

git config -f .gitmodules submodule.path/to/submodule.shallow true
git submodule add --depth 1 [email protected]:lorem/ipsum.git path/to/submodule

次に誰かが git clone --recursive [email protected]:foo/bar.git の全履歴を取り込みます。 https://github.com/foo/bar しかし、期待通りにサブモジュールを浅くクローンするだけです。

で。

--depth

このオプションは、以下の場合に有効です。 addupdate コマンドを使用します。

指定したリビジョン数まで切り詰めた履歴を持つ、「浅い」クローンを作成します。


アトワイマン が追加されました。 コメント欄 :

私の知る限りでは、このオプションは master 非常に密接に。深度1を設定した場合 submodule update は、指定したサブモジュールのコミットが最新のマスターである場合にのみ成功します。 そうでない場合は、" が表示されます。 fatal: reference is not a tree " .

その通りです。

それは、git 2.8(2016年3月)までの話です。2.8では submodule update --depth は、SHA1 がリモートリポジトリの HEAD の 1 つから直接到達可能であっても、成功するチャンスが 1 つ増えます。

参照 コミット fb43e31 (2016年2月24日)によるものです。 ステファン・ベラー( stefanbeller ) .

ヘルプドバイ ジュニオ・C・ハマノ( gitster ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- コミット9671a76 , 2016年2月26日)

<ブロッククオート

submodule: sha1 を直接取得することで、必要な sha1 をより多く取得できるようにする。

<ブロッククオート

Gerritでサブモジュールを更新するような変更をレビューするとき、一般的なレビューのやり方は、ローカルにパッチをダウンロードしてチェリーピックしてテストすることです。

しかし、ローカルでテストする場合、' git submodule update というのは、サブモジュールの対応するコミットはまだプロジェクトの歴史に含まれておらず、単なる変更案でもあるからです。

<ブロッククオート

もし $sha1 がデフォルトのフェッチに含まれていなかった場合、そのフェッチを試みます。 $sha1 直接 . しかし、一部のサーバは sha1 による直接取得をサポートしておらず、そのため git-fetch をすぐに失敗してしまう。

sha1がまだないため、どのみちチェックアウトの段階で失敗することになるので、ここで失敗するのが一番いいのです。


MVG ポイント コメントで になります。 コミット fb43e31 (git 2.9、2016年2月)

<ブロッククオート

と思われるでしょう。 コミット fb43e31 は、SHA1 IDで欠落しているコミットを要求しているので uploadpack.allowReachableSHA1InWantuploadpack.allowTipSHA1InWant の設定は、おそらく動作の可否に影響します。

を書きました。 今日、git listに投稿した 浅いサブモジュールの使用は、いくつかのシナリオ、すなわちコミットがタグでもある場合に、よりうまく機能させることができることを指摘しました。

期待して待ちましょう。

<ブロッククオート

fb43e31が特定のSHA1に対するフェッチをデフォルトブランチに対するフェッチの後にフォールバックするようにしたのは、このためだと思います。

とはいえ、「-depth 1」の場合、早期に中止するのが理にかなっていると思います。リストアップされた参照に要求されたものがなく、SHA1による問い合わせがサーバーでサポートされていない場合、どちらにしてもサブモジュールの要件を満たすことができないので、何も取得する意味がありません。


2016年8月更新(3年後)

Git 2.10 (2016年第3四半期) では、以下のことができるようになります。

 git config -f .gitmodules submodule.<name>.shallow true

"をご覧ください。 余計な重量のない Git サブモジュール "を参照してください。


Git 2.13 (Q2 2017)で追加してください。 コミット 8d3047c (2017年4月19日)による セバスチャン・シューベルト( sschuberth ) .

(によって統合されました。 セバスチャン・シューベルト -- sschuberth -- コミット 8d3047c , 2017年4月20日)

<ブロッククオート

このサブモジュールのクローンは、浅いクローンとして実行されます。 (歴史の深さは1)

しかし チロ・サンティリ が追加されます。 コメント欄 (そして詳細 回答 )

shallow = true オン .gitmodules を使用した場合、リモートの HEAD で追跡される参照にのみ影響します。 --recurse-submodules ターゲットコミットがブランチで指されている場合でも、また branch = mybranch の上に .gitmodules にも対応しています。


Git 2.20(2018年第4四半期)では、サブモジュールのサポートが改善され、以下の箇所でblobから読み取るように更新されました。 HEAD:.gitmodules のときに .gitmodules ファイルが作業ツリーから欠落している場合。

参照 コミット 2b1257e , コミット 76e9bdc (2018年10月25日)、および コミットb5c259f , コミット 23dd8f5 , コミットb2faad4 , コミット 2502ffc , コミット 996df4d , コミットd1b13df , コミット 45f5ef3 , コミットbcbc780 (2018年10月05日)によるものです。 アントニオ・オスピテ ( ao2 ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- commit abb4824 , 2018年11月13日)

<ブロッククオート

submodule : 読書をサポート .gitmodules 作業ツリーにない場合

<ブロッククオート

のときは .gitmodules ファイルが作業ツリーに存在しない場合、次のようにします。 インデックスと現在のブランチの内容を使用します。

これは、ファイルがリポジトリの一部であるにもかかわらず、何らかの理由で 例えば、疎なチェックアウトのため、チェックアウトされていません。

<ブロッククオート

これにより、少なくとも' git submodule コマンド どの 読む その gitmodules を完全に入力することなく、設定ファイルを 作業ツリー

<ブロッククオート

への書き込み .gitmodules は、ファイルがチェックアウトされていることを要求します。 を呼び出す前に、そのことを確認してください。 config_set_in_gitmodules_file_gently .

にも同様のチェックを追加します。 git-submodule.sh::cmd_add() が最終的に失敗することを想定して、" git submodule add のとき、コマンド .gitmodules が安全に書き込み可能でない場合、このコマンドはリポジトリを偽の状態(例えば、サブモジュールのリポジトリはクローンされたが .gitmodules が更新されなかったのは config_set_in_gitmodules_file_gently に失敗しました)。

さらに config_from_gitmodules() がグローバルオブジェクト この関数を呼び出すすべてのコードパスを保護する必要があります。 は、グローバル・オブジェクト・ストアへの同時アクセスから保護されます。

現在、このようなことが起こるのは builtin/grep.c::grep_submodules() ということで grep_read_lock() を含むコードを呼び出す前に config_from_gitmodules() .

注意:この新機能が動作しないケースが稀にあります。 のないネストしたサブモジュールは、まだ正常に動作していません。 .gitmodules を作業ツリーに追加しました。


注:Git 2.24 (Q4 2019) では、サブモジュールの浅いクローン作成時に発生する可能性のあるセグメンテーションフォールトが修正されました。

参照 コミットddb3c85 (2019年9月30日)によるものです。 アリ・ウトゥク・セレン ( auselen ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- コミット 678a9ca , 2019年10月09日)


Git 2.25 (2020年第1四半期)では、以下の点が明確になりました。 git submodule update のドキュメントを参照してください。

参照 コミットf0e58b3 (2019年11月24日)によるものです。 フィリップ・ブレーン ( phil-blain ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- コミット ef61045 , 2019年12月05日)

<ブロッククオート

doc : 'git submodule update' が見つからないコミットを取得することについて言及します。

協力者:Junio C Hamano

協力:Johannes Schindelin(ヨハネス・シンデリン

サインオフ:Philippe Blain

<ブロッククオート

' git submodule アップデート' は、スーパープロジェクトに記録された SHA-1 が見つからない場合、サブモジュールのリモートから新しいコミットを取得します。 . これはドキュメントに記載されていませんでした。


警告 Git 2.25 (2020 年第 1 四半期) では、" git clone --recurse-submodules "と代替オブジェクト ストアの設計が不適切でした。

<ブロッククオート

ドキュメントとコードは、ユーザーが失敗を見たときに、より明確な勧告をするように指導されました。

参照 コミット 4f3e57e , コミット 10c64a0 (2019年12月02日) によるものです。 ジョナサン・タン ( jhowtan ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- コミット5dd1d59 , 2019年12月10日)

<ブロッククオート

submodule--helper : 致命的な代替エラーに関するアドバイス

署名:ジョナサン・タン

Acked-by: ジェフ・キング

<ブロッククオート

スーパープロジェクトで定義されたシャローモジュールを再帰的にクローンする場合、その .gitmodules で再クローンし、" --reference=<path> "の場合、エラーが発生します。例えば

<ブロッククオート
git clone --recurse-submodules --branch=master -j8 \

  https://android.googlesource.com/platform/superproject \
  master
git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  --reference master master2

で失敗します。

fatal: submodule '<snip>' cannot add alternate: reference repository

'<snip>' is shallow

スーパープロジェクトの代替から計算された代替が追加できない場合、今回のケースに限らず、"の設定についてアドバイスしてください。 submodule.alternateErrorStrategy という設定オプションを使用し、quot; --reference-if-able の代わりに "を使用します。 --reference クローンを作成する場合は、" を使用します。

に詳しく書かれていますね。

Git 2.25 (Q1 2020) では、"git clone --recurse-submodules" と代替オブジェクトストアとの間の相互作用が不適切に設計されていました。

<ブロッククオート

Doc : submodule.alternateErrorStrategyを説明します。

署名: Jonathan Tan

Acked-by: ジェフ・キング

<ブロッククオート

コミットメント 31224cbdc7 (" clone : recursive and reference option triggers submodule alternates", 2016-08-17, Git v2.11.0-rc0 --。 マージ に記載されている バッチ1号 ) は、Git に設定オプション " をサポートするように教えました。 submodule.alternateLocation "と" submodule.alternateErrorStrategy "スーパープロジェクトで。

<ブロッククオート

もし、" submodule.alternateLocation が設定されている場合、「" superproject スーパープロジェクトでは、そのスーパープロジェクトのサブモジュールがクローンされると、そのサブモジュールの代替パスを $GIT_DIR/objects/info/alternates を作成し、それを参照する。

<ブロッククオート

は、" submodule.alternateErrorStrategy "オプションは、その代替物が参照できない場合にどうするかを決定します。

しかし、このオプションが "die" に設定されていない場合、代替物が指定されていないかのようにクローンが進行することは明らかではありません(以下のテストに見られるとおりです)。 31224cbdc7 ).

したがって、それに応じて文書化する。

は、その config サブモジュールのドキュメント が含まれるようになりました。

submodule.alternateErrorStrategy::

<ブロッククオート

で計算されたサブモジュールのオルタネートで発生したエラーをどのように扱うかを指定します。 submodule.alternateLocation .

可能な値は次のとおりです。 ignore , info , die .

デフォルトは die .

に設定されている場合は注意が必要です。 ignore または info および 計算された代替にエラーがある場合、代替が指定されていないかのようにクローンが進められます。 .


注:"です。 git submodule update --quiet " ( 男性 ) は、quiet オプションを下層に伝搬させませんでした。 git fetch ( 男性 ) というメッセージが表示されますが、Git 2.32 (2021 年第2四半期) で修正されました。

参照 コミット 62af4bd (2021年4月30日)によるものです。 ニコラス・クラーク( nwc10 ) .

(によって統合されました。 ジュニオ・C・ハマノ--。 gitster -- コミット 74339f8 2021年5月11日)

<ブロッククオート

submodule update : フェッチに " を使用することで、無音にすることができます。 --quiet "

署名:ニコラス・クラーク

<ブロッククオート

などのコマンドがあります。

$ git submodule update --quiet --init --depth=1

浅いクローンを含む、シェル関数 fetch_in_submodule, を起動し、さらに git fetch .

を渡す。 --quiet オプションは、そこから先に進みます。