次のようなケースではgit clone時にdepthオプションを付与すると、履歴を削減して高速クローンが可能です。
- 最新ソースでビルドなどをしたい。
- 最新ソースの指定ブランチをチョロっと変更してCommit & Pushしたい。
以下、本ページの目次です。depth関連で少し書いてみました。
git clone –depth
基本的にいつものgit cloneに–depthオプションを付与すればOKです。
git clone --depth N <url>
例:git clone --depth 1 https://github.com/microsoft/vscode.git
depth=1の場合、git logで確認可能な履歴数は1個となります。該当履歴には「grafted」(日本語訳で接木)という単語が付与されます。
ブランチがmainしかない・・・。checkout/switch出来ない・・・。
そうなのよ。関連オプションを紹介するね。
- mainではなく指定ブランチを最小履歴で取得したい。
⇒ -b <branchName>オプションを付ける。
例:git clone –depth 1 -b develop <url> - 全ブランチを最小履歴で取得したい。
⇒ –no-single-branchオプションを付ける。
例:git clone –depth 1 –no-single-branch <url>
後から履歴を追加取得
やっぱりもう少しログを確認したくなった場合は、追加取得が可能です。
git fetch --depth N
例:git fetch --depth 5
やっぱりブランチや履歴を含めて全部取得したい。
git fetch --unshallow
git remote set-branches origin '*'
git fetch
※再取得だけだと関連付けがないため、リモートブランチを関連付けして再fetchする感じ。
ブランチマージは?
ブランチマージはマージ元・先の履歴を利用するものなので、履歴削減状態だと失敗します。
※ブランチがmainしかなくてもダメ。
git merge develop
→ fatal: refusing to merge unrelated histories
通常のcloneをやり直しかな?
そうだね、素直にやり直しが無難かな。けど履歴の追加取得でも可能だった。
git fetch –depth N によってブランチの分岐点までの履歴を再取得しところ、git mergeは動作しました。
→ ブランチの分岐点 = 例えばmain, developであれば派生元の履歴まで再取得。
実施の効果はどの程度?
10万越えの履歴をもつ「vscode.git」で試してみます。
# 通常のclone(depth未指定)
$ time git clone https://github.com/microsoft/vscode.git vscodeFull.git
Cloning into 'vscodeFull.git'...
remote: Enumerating objects: 1581743, done.
remote: Counting objects: 100% (1575/1575), done.
remote: Compressing objects: 100% (951/951), done.
remote: Total 1581743 (delta 910), reused 1165 (delta 600), pack-reused 1580168
Receiving objects: 100% (1581743/1581743), 892.72 MiB | 15.46 MiB/s, done.
Resolving deltas: 100% (1012724/1012724), done.
Updating files: 100% (7324/7324), done.
real 1m21.519s
user 0m0.000s
sys 0m0.000s
# 履歴1のclone(depth=1指定)
$ time git clone --depth 1 https://github.com/microsoft/vscode.git vscodeDepth1.git
Cloning into 'vscodeDepth1.git'...
remote: Enumerating objects: 9234, done.
remote: Counting objects: 100% (9234/9234), done.
remote: Compressing objects: 100% (7790/7790), done.
remote: Total 9234 (delta 1335), reused 4296 (delta 717), pack-reused 0
Receiving objects: 100% (9234/9234), 19.31 MiB | 15.13 MiB/s, done.
Resolving deltas: 100% (1335/1335), done.
Updating files: 100% (7324/7324), done.
real 0m8.138s
user 0m0.000s
sys 0m0.015s
結果を表でまとめます。
clone depth | Clone時間 | .gitの容量 |
---|---|---|
未指定 | 1分21秒 | 942 MB |
1指定 | 8秒 | 20 MB |
- 処理時間は約10倍早くなりました。
- リポジトリの管理フォルダである「.git」の容量は約1/47のサイズになりました。
- 履歴数の多さにもよりますが、肥大化したリポジトリに対しては予想以上の効果を発揮します。
最後に
最新ソースを利用したビルドなどに活用できそうなgit clone –depthについて書きました。
- git clone時にdepthを指定すると高速clone出来ます。
⇒ リポジトリの履歴数に依存しますが、10倍以上早くなることもあります。 - ブランチマージは出来ません。
⇒ けど、再fetchして履歴を追加取得すれば可能になります。
# clone時にdepth指定
git clone --depth N <url>
# clone時にdepth指定&対象ブランチ指定
git clone --depth N -b <branchName> <url>
# clone時にdepth指定&全ブランチ指定
git clone --depth N --no-single-branch <url>
# 履歴を追加取得
git fetch --depth N
最後までごらんいただき、ありがとうございました!
コメント