Git で shallow clone するときに全ブランチの最新履歴を取得する

2020/10/10に公開

shallow clone とは

直近の履歴だけを取得することができます。
過去の履歴が多くリポジトリを丸ごと clone すると重い場合などに重宝します。

具体的には git clone のオプションで --depth <depth> を付けます。
最新だけを取得する場合は 1 です。

git clone --depth 1 <repository>

後から git fetch --unshallow することで解除もできます。

課題

ただし --depth 1 だけで実行してしまうと .git/config が以下のようになり main (master) ブランチの fetch しかできなくなるので注意が必要です。
unshallow してもここは変わりません。

[remote "origin"]
	url = <repository>
	fetch = +refs/heads/main:refs/remotes/origin/main

これを直すためには手動で config を修正するか、以下のコマンドを実行します。

git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'

ただ .git 配下のファイルを直接編集するのは怖いですし、コマンドで実行するにしても refs を正しく書くのは難しいです。そして何より手間です。

--no-single-branch

--depth の説明にはこのような記述があります。

--depth <depth>
Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches.

--no-single-branch というオプションを併せて指定することで全てのブランチの最新の履歴を取得することができます。

git clone --depth 1 --no-single-branch <repository>

これですぐに git switch <branch> することができます。
.git/config も fetch = +refs/heads/*:refs/remotes/origin/* になっています。
当然 git fetch --depth <depth>git fetch --unshallow で過去の履歴も取得できます。

git fetch --depth 10
git fetch --depth 20
..
..
git fetch --unshallow

おまけ

shallow clone のその他オプション

--shallow-since--shallow-exclude といったオプションもあるようです。

shallow clone 以外でも使えるオプション

--branch

clone 後に switch (checkout) したいブランチが決まっていれば --branch を付けます。

git clone --depth 1 --no-single-branch --branch <branch> <repository>

--no-checkout

ファイルを取得しません。
履歴だけを見たいときには便利かもしれません。

git clone --depth 1 --no-single-branch --no-checkout <repository>

ファイルを取得する際は git switch <branch> します。

git switch main

Discussion