浅いサブモジュールを持つことは可能ですか? それぞれが長い歴史を持ついくつかのサブモジュールを含むスーパープロジェクトがあるため、そのすべての歴史を引きずって不必要に大きくなります。
私が見つけたのは、この未回答のスレッドだけです。
これを実装するにはgit-submodule をハックするだけでいいですか?
浅いサブモジュールを持つことは可能ですか? それぞれが長い歴史を持ついくつかのサブモジュールを含むスーパープロジェクトがあるため、そのすべての歴史を引きずって不必要に大きくなります。
私が見つけたのは、この未回答のスレッドだけです。
これを実装するにはgit-submodule をハックするだけでいいですか?
次のgit1.8.4 (2013 年 7 月)の新機能:
"
git submodule update
" は、サブモジュール リポジトリを浅く複製することもできます。
(そして git 2.10 Q3 2016 では、それを で記録できますgit config -f .gitmodules submodule.<name>.shallow true
。
この回答の最後を参照してください)
コミット 275cd184d52b5b81cb89e4ec33e540fb2ae61c1fを参照してください。
--depth
「git submodule」の add コマンドと update コマンドにオプションを追加し、それを clone コマンドに渡します。これは、サブモジュールが巨大で、最新のコミット以外にはあまり関心がない場合に便利です。
テストが追加され、「サブモジュールの更新で pwd のシンボリック リンクを処理できる」というテストファイルの残りの部分に準拠するために、いくつかのインデント調整が行われました。
署名者: Fredrik Gustafsson
<iveqy@iveqy.com>
承認者: Jens Lehmann<Jens.Lehmann@web.de>
つまり、これは機能します:
# 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
コマンドは、後で再帰的にレポを複製する他の人のためにオプションを永続的にします。
例として、レポがあり、レポ at にサブモジュールとしてhttps://github.com/foo/bar
追加したいとします。コマンドは次のようになります。https://github.com/lorem/ipsum
path/to/submodule
git submodule add --depth 1 git@github.com: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 git@github.com:lorem/ipsum.git path/to/submodule
次に誰かが を実行git clone --recursive git@github.com:foo/bar.git
すると、 の履歴全体https://github.com/foo/bar
が取り込まれますが、期待どおりにサブモジュールの浅いクローンしか作成されません。
と:
--depth
add
このオプションはおよびupdate
コマンドに有効です。
指定されたリビジョン数に切り捨てられた履歴を持つ「浅い」クローンを作成します。
私が知る限り、このオプションは、
master
非常に厳密に追跡しないサブモジュールには使用できません。深さ 1 を設定submodule update
すると、必要なサブモジュールのコミットが最新のマスターである場合にのみ成功します。 それ以外の場合は "fatal: reference is not a tree
"になります。
それは本当です。
つまり、git 2.8 (2016 年 3 月) までです。2.8 では、submodule update --depth
リモート リポジトリ HEAD の 1 つから SHA1 に直接到達できる場合でも、成功するチャンスがもう 1 つあります。
Stefan Beller ( )によるコミット fb43e31 (2016 年 2 月 24 日)を参照してください。
手伝い:浜野ジュニオC ( ) . ( 2016 年 2 月 26 日、コミット 9671a76でJunio C Hamanoによってマージされました)stefanbeller
gitster
gitster
サブモジュール: sha1 を直接取得することにより、必要な sha1 を取得することをより困難にします
Gerrit のサブモジュールも更新する変更をレビューする場合、一般的なレビュー方法は、パッチをローカルにダウンロードしてチェリー ピックしてテストすることです。
ただし、ローカルでテストするとgit submodule update
、サブモジュールの対応するコミットがまだプロジェクト履歴の一部ではなく、提案された変更に過ぎないため、「 」は正しいサブモジュール sha1 の取得に失敗する場合があります。
がデフォルトのフェッチに含まれていない場合は、直接
$sha1
をフェッチしようとし$sha1
ます。ただし、一部のサーバーは sha1 による直接フェッチをサポートしていないため、git-fetch
すぐに失敗します。
sha1 がまだ不足していると、後でチェックアウト段階で失敗する可能性があるため、ここで失敗する可能性があります。
MVGは、コメントで fb43e31をコミットするよう指摘しています(git 2.9、2016 年 2 月)。
コミット fb43e31が欠落しているコミットを SHA1 ID で要求しているように思われるため、サーバーのおよび
uploadpack.allowReachableSHA1InWant
設定uploadpack.allowTipSHA1InWant
はおそらくこれが機能するかどうかに影響します。私は今日 git list に投稿
を書き、いくつかのシナリオ、つまりコミットもタグである場合に、浅いサブモジュールの使用がどのようにうまく機能するかを指摘しました。 待って見てみましょう。
これが、fb43e31 がデフォルト ブランチのフェッチ後に特定の SHA1 のフェッチをフォールバックにした理由だと思います。
それにもかかわらず、「--depth 1」の場合は、早期に中止するのが理にかなっていると思います: リストされた ref のいずれも要求されたものと一致せず、SHA1 による要求がサーバーでサポートされていない場合は、意味がありません。どちらの方法でもサブモジュールの要件を満たすことができないため、何かをフェッチします。
2016 年 8 月更新 (3 年後)
Git 2.10 (2016 年第 3 四半期) では、次のことが可能になります。
git config -f .gitmodules submodule.<name>.shallow true
詳細については、「余分な重みのない Git サブモジュール」を参照してください。
Git 2.13 (2017 年第 2 四半期) は、 Sebastian Schuberth ( )によるcommit 8d3047c (2017 年 4 月 19 日) を追加します。( 2017 年 4 月 20 日、コミット 8d3047cでSebastian Schuberthによってマージされました)sschuberth
sschuberth
このサブモジュールのクローンは、浅いクローン(履歴の深さ 1)として実行されます。
ただし、Ciro Santilliはコメントに追加します(詳細は彼の回答に記載されています) 。
shallow = true
on.gitmodules
を使用すると、リモートの HEAD によって追跡される参照にのみ影響します--recurse-submodules
。ターゲットのコミットがブランチによって指されている場合でも、 を配置branch = mybranch
した場合でも.gitmodules
同様です。
Git 2.20 (2018 年第 4 四半期) ではサブモジュールのサポートが改善されており、ファイルが作業ツリーにないHEAD:.gitmodules
場合にBLOB から読み取るように更新されています。.gitmodules
commit 2b1257e、commit 76e9bdc (2018 年 10 月 25 日)、およびcommit b5c259f、commit 23dd8f5、commit b2faad4、commit 2502ffc、commit 996df4d、commit d1b13df、commit 45f5ef3、commit bcbc780 (05 Oct 2018) by Antonio Ospite ( ao2
)を参照してください。
( 2018 年 11 月 13 日、コミット abb4824でJunio C Hamanoによってマージされました)gitster
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()
ください。
注: この新機能がまだ適切に動作しないまれなケースが 1 つあります:
.gitmodules
作業ツリーにないネストされたサブモジュールです。
注: Git 2.24 (2019 年第 4 四半期) では、サブモジュールの浅いクローンを作成するときに発生する可能性があった segfault が修正されています。
Ali Utku Selen ( )によるcommit ddb3c85 (2019 年 9 月 30 日)を参照してください。( 2019 年 10 月 9 日にコミット 678a9caでJunio C Hamanoによってマージされました)auselen
gitster
Git 2.25 (2020 年第 1 四半期) は、git submodule update
ドキュメントを明確にします。
Philippe Blain ( )によるコミット f0e58b3 (2019 年 11 月 24 日)を参照してください。( 2019 年 12 月 5 日にコミット ef61045でJunio C Hamanoによってマージされました)phil-blain
gitster
doc
: 'git submodule update' が欠落しているコミットをフェッチすることを述べます支援者: Junio C Hamano
支援者: Johannes Schindelin
署名者: Philippe Blain
スーパープロジェクトに記録された SHA-1 が見つからない場合、 '
git submodule
update'はサブモジュール リモートから新しいコミットを取得します。これはドキュメントには記載されていませんでした。
警告: Git 2.25 (2020 年第 1 四半期) では、" git clone --recurse-submodules
" と代替オブジェクト ストアとの間の相互作用の設計が適切ではありませんでした。
ドキュメントとコードは、ユーザーが失敗したときに、より明確な推奨事項を示すように教えられています。
コミット 4f3e57e、コミット 10c64a0 (2019 年 12 月 2 日) by Jonathan Tan ( jhowtan
)を参照してください。
( 2019 年 12 月 10 日、コミット 5dd1d59でJunio C Hamanoによってマージされました)gitster
submodule--helper
: 致命的な代替エラーについてアドバイスします署名者: ジョナサン・タン
承認者: ジェフ・キング
で定義されたいくつかの浅いモジュールを使用してスーパープロジェクトを再帰的に複製し
.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
" 構成オプションを構成し、複製時--reference-if-able
に " " の代わりに " "を使用することをお勧めします。--reference
詳細は次のとおりです。
Git 2.25 (2020 年第 1 四半期) では、「git clone --recurse-submodules」と代替オブジェクト ストアとの間の相互作用が適切に設計されていませんでした。
Doc
: submodule.alternateErrorStrategy について説明します署名者: ジョナサン・タン
承認者: ジェフ・キング
コミット31224cbdc7 ("
clone
: recursive and reference option triggers submodule alternatives"、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
" ( man )は、基になる( man )まで quiet オプションを伝播しませんでした。これは、Git 2.32 (2021 年第 2 四半期) で修正されています。git fetch
Nicholas Clark ( )によるcommit 62af4bd (2021 年 4 月 30 日)を参照してください。( 2021 年 5 月 11 日、コミット 74339f8でJunio C Hamanoによってマージされました)nwc10
gitster
submodule update
: 基礎となるフェッチを "--quiet
"で沈黙させます署名者: Nicholas Clark
などのコマンド
$ git submodule update --quiet --init --depth=1
浅いクローンを含む場合は、シェル関数
fetch_in_submodule,
を呼び出します。シェル関数は を呼び出しますgit fetch
。そこにオプションを
渡します。--quiet
Git 2.9.0はサブモジュールの浅いクローンを直接サポートしているため、次のように呼び出すことができます。
git clone url://to/source/repository --recursive --shallow-submodules
ライアンの答えに続いて、すべてのサブモジュールを反復処理し、それらを浅いクローンにするこの単純なスクリプトを思いつくことができました。
#!/bin/bash
git submodule init
for i in $(git submodule | sed -e 's/.* //'); do
spath=$(git config -f .gitmodules --get submodule.$i.path)
surl=$(git config -f .gitmodules --get submodule.$i.url)
git clone --depth 1 $surl $spath
done
git submodule update
git-submodule の「ソース」を読むとgit submodule add
、すでにリポジトリが存在するサブモジュールを処理できるようです。その場合...
$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...
必要なコミットがサブモジュール リポジトリにあることを確認する必要があるため、適切な --depth を設定してください。
編集: 複数の手動サブモジュール クローンとそれに続く単一の更新で回避できる場合があります。
$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update
サブモジュールの正規の場所は離れていますか? もしそうなら、それらを一度複製してもよろしいですか?言い換えれば、頻繁なサブモジュールの (再) クローンによる無駄な帯域幅に苦しんでいるという理由だけで、浅いクローンが必要ですか?
ローカル ディスク領域を節約するために浅いクローンが必要な場合は、Ryan Graham の回答が適切な方法のようです。リポジトリが浅くなるように、手動でクローンを作成します。それが役に立つと思うなら、それgit submodule
をサポートするように適応してください。それについて質問するリストに電子メールを送ってください(それを実装するためのアドバイス、インターフェースに関する提案など)。私の意見では、建設的な方法で Git を強化することを真剣に望んでいる潜在的な貢献者を、そこの人々は非常に支持しています。
各サブモジュールの 1 つの完全なクローンを実行することに問題がない場合 (およびそれらを最新の状態に保つために後でフェッチする)、(Git 1.6.4 以降にある)の--reference
オプションを使用して、ローカル オブジェクト ストアを参照してみてください (例:正規のサブモジュール リポジトリのクローンをgit submodule update
作成し、サブモジュールでこれらのローカル クローンを指すように使用します)。/を使用する前に、必ず/について読んでください。ミラーの参照に関する唯一の可能性のある問題は、それらが早送り以外の更新をフェッチすることになった場合です (ただし、reflog を有効にし、有効期限ウィンドウを拡張して、問題を引き起こす可能性のある放棄されたコミットを保持するのに役立てることができます)。限り、問題はないはずです。--mirror
--reference
git clone --reference
git clone --shared
--reference
このようなものを使用していて、作業ツリーでローカル サブモジュールのコミットを実行する可能性がある場合は、チェックアウトされたサブモジュールによって参照される重要なオブジェクトがコミットされていないことを確認する自動化されたシステムを作成することをお勧めします。ミラーリポジトリにぶら下がったままにします(見つかった場合は、それらを必要とするリポジトリにコピーします)。
また、マンページにあるように、これらの意味を理解していない場合git clone
は使用しないでください。--reference
# Full clone (mirror), done once.
git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git
git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git
# Reference the full clones any time you initialize a submodule
git clone $super_url super
cd super
git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super
git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super
# To avoid extra packs in each of the superprojects' submodules,
# update the mirror clones before any pull/merge in super-projects.
for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done
cd super
git pull # merges in new versions of submodules
git submodule update # update sub refs, checkout new versions,
# but no download since they reference the updated mirrors
または、 の代わりに、ローカル ミラーをサブモジュールのソースとして--reference
使用することにより、ミラー クローンをデフォルトのハードリンク機能と組み合わせて使用することもできます。git clone
新しいスーパー プロジェクトのクローンで、ローカル ミラーを指すようにgit submodule init
サブモジュールの URL を編集してから、.git/config
git submodule update
. ハードリンクを取得するには、既存のチェックアウトされたサブモジュールを再クローン化する必要があります。ミラーに一度ダウンロードするだけで帯域幅を節約し、それらからチェックアウトしたサブモジュールにローカルにフェッチします。ハード リンクはディスク スペースを節約します (ただし、フェッチは蓄積され、チェックアウトされたサブモジュールのオブジェクト ストアの複数のインスタンス間で複製される傾向があります。ミラーからチェックアウトされたサブモジュールを定期的に再クローン化して、ディスク スペースの節約を取り戻すことができます。ハードリンク)。