- Git
git cloneの使い方|ブランチ指定とshallow clone
git cloneとは、リモートにあるリポジトリを履歴ごと手元に複製し、すぐ作業できる状態(リモート設定・ブランチのチェックアウトまで済んだ状態)にするコマンドです。 基本は git clone <URL> の1行ですが、-b でブランチを指定したり、--depth 1 で履歴を浅く取ったり(shallow clone)、--filter で必要になるまで中身を取らない(partial clone)といった取り方を選べます。
この記事では、通常clone・--depth 1・--single-branch・--filter=blob:none・--filter=tree:0 を同じリポジトリに対して実行し、所要時間と .git のサイズを実測しました。さらに、shallow cloneのあとで「他のブランチが見えない」「git log が1件しか出ない」「pushが拒否される」という場面を再現し、git fetch --unshallow や git remote set-branches で元に戻すところまで、すべて実際の出力つきで紹介します。検証は git 2.43.0(Linux)で行い、オプションの仕様は公式ドキュメント(git-clone、今回開いた時点の表示は 2.54.0 更新版)で確認しています。
git cloneの早見表
まずは「やりたいこと」からコマンドを引ける表です。URLは自分のリポジトリに読み替えてください。
| やりたいこと | コマンド | ポイント |
|---|---|---|
| ふつうに複製する | git clone <URL> |
全ブランチ・全履歴を取得 |
| フォルダ名を決めて複製する | git clone <URL> myapp |
第2引数が作成先フォルダ |
| いまのフォルダに展開する | git clone <URL> . |
空のフォルダで実行する |
| ブランチを指定する | git clone -b develop <URL> |
取得後に develop をチェックアウト |
| タグを指定する | git clone -b v1.0 <URL> |
detached HEAD(ブランチなし)になる |
| 最新の1コミットだけ取る | git clone --depth 1 <URL> |
shallow clone。既定で1ブランチのみ |
| ブランチ指定+最新だけ | git clone --depth 1 -b develop <URL> |
CIや動作確認向け |
| 浅く、全ブランチの先端を取る | git clone --depth 1 --no-single-branch <URL> |
各ブランチの最新1件ずつ |
| 1ブランチの全履歴だけ取る | git clone --single-branch -b main <URL> |
履歴は全部、ブランチは1つ |
| 履歴は全部、ファイルの中身は後から | git clone --filter=blob:none <URL> |
blobless clone(partial clone) |
| コミットだけ先に取る | git clone --filter=tree:0 <URL> |
treeless clone。使い捨て向け |
| 一部のフォルダだけ展開する | git clone --filter=blob:none --sparse <URL> → git sparse-checkout set docs |
大きなモノレポ向け |
| サブモジュールも一緒に取る | git clone --recurse-submodules <URL> |
浅くするなら --shallow-submodules も |
| shallowを通常に戻す | git fetch --unshallow |
全履歴を取り直す |
| 見えないブランチを見えるようにする | git remote set-branches origin '*' → git fetch |
fetch対象を全ブランチに広げる |
| 履歴を少しだけ深くする | git fetch --deepen=10 |
いまより10コミット分さかのぼる |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「git cloneの使い方|ブランチ指定とshallow clone」
git cloneの基本の使い方
書式とURLの種類
git clone [オプション] <リポジトリURL> [作成先フォルダ]
作成先フォルダを省略すると、URLの末尾(.git を除いた名前)がフォルダ名になります。URLの書き方は主に次の3種類です。
| 種類 | 例 | 認証 | 向いている場面 |
|---|---|---|---|
| HTTPS | https://github.com/example/myapp.git |
アクセストークン(資格情報マネージャーに保存) | 初めての環境、プロキシ越し |
| SSH | git@github.com:example/myapp.git |
SSH鍵 | 毎日使う開発用PC |
| ローカル/file | /srv/git/myapp.git、file:///srv/git/myapp.git |
なし | 社内サーバーや検証 |
cloneが内部でやっていること
git clone は、次の操作をまとめて行うコマンドです。「cloneしたのにブランチが1つしか無い」という疑問は、4番を知っておくと解けます。
| 順番 | 内容 | 相当するコマンド |
|---|---|---|
| 1 | フォルダと空のリポジトリを作る | git init |
| 2 | リモートを origin という名前で登録する |
git remote add origin <URL> |
| 3 | オブジェクト(コミット・ツリー・ファイル)を取得する | git fetch |
| 4 | リモート追跡ブランチ(origin/main など)を作る |
(fetchの結果) |
| 5 | 既定のブランチをローカルに作ってチェックアウトする | git switch main |
通常のcloneでは、ローカルブランチは既定の1つ(多くは main)だけ作られ、ほかのブランチは origin/develop のようなリモート追跡ブランチとして存在します。git branch -a で確認でき、git switch develop と打てば追跡ブランチ付きのローカルブランチが自動で作られます。
$ git clone file:///srv/origin.git myapp
Cloning into 'myapp'...
$ cd myapp
$ git branch -a
* main
remotes/origin/HEAD -> origin/main
remotes/origin/develop
remotes/origin/feature/login
remotes/origin/main
ブランチを指定してcloneする(-b)
-b <ブランチ名>(--branch)を付けると、clone直後にそのブランチがチェックアウトされます。-b だけでは取得量は減りません。 全ブランチを取ったうえで、最初に開くブランチを変えるオプションです。
# developを開いた状態でclone(全ブランチ・全履歴を取得)
git clone -b develop https://github.com/example/myapp.git
# developの最新1コミットだけ(取得量も最小)
git clone --depth 1 -b develop https://github.com/example/myapp.git
# developの全履歴だけ(ほかのブランチは取らない)
git clone --single-branch -b develop https://github.com/example/myapp.git
| 書き方 | 開くブランチ | 取るブランチ | 取る履歴 |
|---|---|---|---|
-b develop |
develop | 全部 | 全部 |
-b develop --single-branch |
develop | developのみ | developの全履歴 |
-b develop --depth 1 |
develop | developのみ | 最新1コミット |
-b develop --depth 1 --no-single-branch |
develop | 全部 | 各ブランチの最新1コミット |
タグを指定した場合はdetached HEADになる
-b にはタグ名も渡せます。その場合はブランチではなくコミットを直接開いた状態(detached HEAD)になります。次は実行した出力です。
$ git clone -b v1.0 --depth 1 file:///srv/origin.git c_tag
Cloning into 'c_tag'...
Note: switching to 'afe87a515b9aeff90879280aa836f8cb9e7ad337'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
(以下略)
$ git -C c_tag status
Not currently on any branch.
nothing to commit, working tree clean
特定のリリース版をビルドするだけならこのままで問題ありません。そこから変更を積みたいときは git switch -c fix-from-v1.0 でブランチを作ってから作業します。
存在しないブランチ名を指定したとき
$ git clone -b nobranch file:///srv/origin.git c_e1
Cloning into 'c_e1'...
fatal: Remote branch nobranch not found in upstream origin
ブランチ名の打ち間違いが多い原因です。cloneの前に git ls-remote --heads <URL> を実行すると、リモートにあるブランチ名の一覧を取得せずに確認できます。
5つのclone方式を同じリポジトリで実測
検証に使ったリポジトリと条件
取り方による差を数字で見るために、検証用のリポジトリを用意して5方式(+組み合わせ3つ)でcloneしました。
| 項目 | 内容 |
|---|---|
| Gitのバージョン | 2.43.0(Linux) |
| リポジトリ | コミット440件(main 400件、develop +30件、feature/login +10件)、タグ1つ |
| 中身 | テキスト約40ファイル+150KBのバイナリ10個を毎コミット1つずつ更新(圧縮が効きにくいデータ) |
サーバー側の .git |
73MB(bareリポジトリ) |
| 取得経路 | 同じマシン内の file://(ネットワーク転送なし) |
| 計測 | git clone -q の開始から終了まで。各1回 |
ネットワークを通していないので、秒数は「方式ごとの比率」を見るための値です。 実際の回線越しでは転送量の差がそのまま時間差として大きく出ます。サーバー側では partial clone を受け付けるために uploadpack.allowFilter=true を設定しています(GitHubなど主要なホスティングでは既定で使えます)。
実測結果の比較表
| 方式 | コマンド | 所要時間 | .git サイズ |
git log の件数 |
見えるリモートブランチ |
|---|---|---|---|---|---|
| 通常clone | git clone <URL> |
11.23秒 | 59MB | 400 | 3つ全部 |
| shallow clone | git clone --depth 1 <URL> |
0.50秒 | 1.7MB | 1 | mainのみ |
| single-branch | git clone --single-branch <URL> |
10.24秒 | 59MB | 400 | mainのみ |
| blobless | git clone --filter=blob:none <URL> |
0.88秒 | 2.0MB | 400 | 3つ全部 |
| treeless | git clone --filter=tree:0 <URL> |
0.47秒 | 1.8MB | 400 | 3つ全部 |
| shallow+全ブランチ | git clone --depth 1 --no-single-branch <URL> |
0.84秒 | 4.7MB | 1 | 3つ全部 |
| shallow+ブランチ指定 | git clone --depth 1 -b develop <URL> |
0.32秒 | 1.7MB | 1 | developのみ |
| blobless+sparse | git clone --filter=blob:none --sparse <URL> |
0.33秒 | 464KB | 400 | 3つ全部 |
結果から読み取れること
--depth 1は通常cloneの約22分の1の時間、.gitは約35分の1になりました。履歴を持たないぶん軽くなります。--single-branchだけではほとんど軽くなりませんでした(59MBのまま)。今回のリポジトリは develop と feature/login が main から分かれて数十コミットしか進んでおらず、履歴の大半を共有しているためです。ブランチごとに中身が大きく違うリポジトリでは差が出ます。--filter=blob:noneは、400件の履歴をすべて持ったまま 2.0MB に収まりました。コミットとツリー(フォルダ構成)は全部取り、ファイルの中身(blob)は最新のチェックアウトに必要なものだけ取るためです。--filter=tree:0はさらに小さく速い一方、あとで履歴を調べる操作に時間がかかります(次の項で実測)。--sparseを組み合わせると 464KB まで小さくなりました。最上位フォルダ直下のファイルだけを展開するため、チェックアウトに必要なblobも減るからです。
bloblessとtreelessは「あとで調べるとき」に差が出る
partial cloneは、足りないオブジェクトを必要になった時点でサーバーから取りに行きます。同じ「特定ファイルの履歴を見る」操作を2つの方式で比べました。
# どちらも clone 直後に実行
git log --oneline -5 -- docs/note1.md
| 方式 | 上のコマンドの所要時間 | 理由 |
|---|---|---|
--filter=blob:none |
0.006秒 | ツリーは手元にあるので、追加の取得なしで履歴をたどれる |
--filter=tree:0 |
4.67秒 | 過去コミットのツリーをその都度サーバーへ取りに行く |
treelessは「cloneは最速、履歴調査は遅い」という性質です。ビルドして捨てるCIジョブには向き、手元で git log -- <パス> や git blame を使う開発用にはbloblessが向いています。
どの方式を選ぶかの判断表
| 目的 | おすすめ | 理由 |
|---|---|---|
| 日常の開発用(履歴も見る・pushもする) | 通常clone、大きければ --filter=blob:none |
履歴・ブランチがすべて使える |
| CIでビルド・テストするだけ | --depth 1(必要なら -b) |
最小の転送量。使い捨てなので履歴が不要 |
| CIでタグ間の差分や変更履歴も必要 | --filter=blob:none または --depth 50 など |
git describe や差分計算に履歴が要る |
| コードを読むだけ・試しに動かすだけ | --depth 1 |
すぐ取れる。必要になれば --unshallow |
| 巨大なモノレポの一部だけ触る | --filter=blob:none --sparse + sparse-checkout |
展開するフォルダを絞れる |
| 特定ブランチしか使わない | --single-branch -b <名前> |
fetch対象も1ブランチに固定される |
shallow clone(--depth)の仕組みと使い方
shallow cloneは、指定した深さより前の履歴を持たないcloneです。--depth 1 なら各ブランチ先端の1コミットだけを取得します。公式ドキュメントにあるとおり、--depth を付けると --single-branch も自動で付きます(--no-single-branch を指定しない限り)。この「1ブランチだけになる」動作が、あとで紹介する「ブランチが見えない」の理由です。
| オプション | 意味 | 例 |
|---|---|---|
--depth <n> |
先端からn件だけ取る | --depth 1、--depth 50 |
--shallow-since=<日付> |
指定日より後の履歴だけ取る | --shallow-since=2026-01-01 |
--shallow-exclude=<ref> |
指定したブランチ・タグから届く履歴を除く | --shallow-exclude=v1.0 |
--no-single-branch |
浅いまま全ブランチの先端を取る | --depth 1 --no-single-branch |
--shallow-submodules |
サブモジュールも深さ1で取る | --recurse-submodules --shallow-submodules |
shallowかどうかは次のコマンドで確認できます。
$ git rev-parse --is-shallow-repository
true
$ cat .git/shallow
aa5a3ed28de0c5344e1d4b909c38a8ced9ae893c
.git/shallow には「ここより前の履歴は持っていない」という境界のコミットIDが記録されています。
shallow clone後に困る場面を再現して直す
ここからは git clone --depth 1 <URL> で作ったリポジトリで、よく出会う3つの場面を再現します。
場面1:git logが1件しか出ない
$ git log --oneline
aa5a3ed commit 400
リモートには400件ありますが、手元には先端の1件だけです。git blame や git bisect、過去のタグとの比較もこの範囲でしか動きません。
直し方A:全履歴を取り直す(通常のリポジトリに戻す)
$ git fetch --unshallow
$ git rev-parse --is-shallow-repository
false
$ git rev-list --count HEAD
400
直し方B:必要なぶんだけ深くする
$ git fetch --deepen=10
$ git rev-list --count HEAD
11
--deepen=10 は「いまの深さからさらに10件」、--depth=50 は「先端から50件に揃える」という違いがあります。すでに完全なリポジトリで --unshallow を実行すると、次のメッセージが出て何も起きません。
$ git fetch --unshallow
fatal: --unshallow on a complete repository does not make sense
なお、今回の検証では --unshallow 後の .git が 103MB になり、通常clone(59MB)より大きくなりました。あとから取得したオブジェクトが別のパックに分かれて格納されるためで、git gc を実行すると整理されます。
場面2:ほかのブランチが見えない・切り替えられない
$ git branch -a
* main
remotes/origin/HEAD -> origin/main
remotes/origin/main
$ git switch develop
fatal: invalid reference: develop
リモートには develop があるのに、手元には origin/develop がありません。原因は fetch の設定(refspec)が main だけになっていることです。
$ git config --get remote.origin.fetch
+refs/heads/main:refs/remotes/origin/main
通常cloneなら +refs/heads/*:refs/remotes/origin/*(全ブランチ)になる箇所です。この状態で git fetch origin develop を実行しても、取得結果は FETCH_HEAD に入るだけで origin/develop は作られません。
$ git fetch origin develop
From file:///srv/origin
* branch develop -> FETCH_HEAD
$ git branch -a
* main
remotes/origin/HEAD -> origin/main
remotes/origin/main
直し方:fetch対象を広げてから取り直す
# 全ブランチを対象にする
$ git remote set-branches origin '*'
$ git config --get remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
# 浅いまま各ブランチの先端を取得
$ git fetch --depth 1
From file:///srv/origin
* [new branch] develop -> origin/develop
* [new branch] feature/login -> origin/feature/login
* [new tag] v1.0 -> v1.0
$ git switch develop
Switched to a new branch 'develop'
branch 'develop' set up to track 'origin/develop'.
特定のブランチだけ追加したい場合は --add を使います。
$ git remote set-branches --add origin main
$ git config --get-all remote.origin.fetch
+refs/heads/develop:refs/remotes/origin/develop
+refs/heads/main:refs/remotes/origin/main
$ git fetch --depth 1 origin main
From file:///srv/origin
* branch main -> FETCH_HEAD
* [new branch] main -> origin/main
git remote set-branches は .git/config の remote.origin.fetch を書き換えるコマンドです。--single-branch でcloneしたリポジトリ(shallowでなくても)でも同じ手順で直せます。
場面3:別のリモートへpushすると拒否される
shallowなリポジトリでも、clone元へ新しいコミットをpushすることは通常どおりできます。困るのは、履歴を持っていない別のリモート(新しく作った空のリポジトリなど)へpushするときです。
$ git push ../newremote.git main
To ../newremote.git
! [remote rejected] main -> main (shallow update not allowed)
error: failed to push some refs to '../newremote.git'
受け取る側は、途中で切れた履歴を既定では受け付けません。リポジトリの引っ越しやミラー作成のときに出会いやすいエラーです。
直し方:先に履歴をそろえてからpushする
$ git fetch --unshallow
$ git push ../newremote.git main
To ../newremote.git
* [new branch] main -> main
リポジトリを丸ごと移すことが目的なら、最初から git clone --mirror <URL> で取得するのが確実です。
shallowで困ったときの対処まとめ
いずれも今回の検証で症状と解消を確認したものです。
| 症状 | 原因 | 対処 |
|---|---|---|
git log が1件 |
履歴を深さ1で切っている | git fetch --unshallow または git fetch --deepen=<n> |
git switch develop が invalid reference |
fetch対象が1ブランチ | git remote set-branches origin '*' → git fetch |
git fetch origin develop しても origin/develop が出ない |
refspecに含まれていない | git remote set-branches --add origin develop → git fetch |
shallow update not allowed |
履歴が途中で切れたまま別リモートへpush | git fetch --unshallow してからpush |
git describe --tags が No tags can describe ... になる |
タグのあるコミットまで履歴が届いていない | git fetch --deepen=<n> または --unshallow、git fetch --tags |
浅く取った別ブランチとの git merge で refusing to merge unrelated histories |
共通の祖先が浅い範囲に入っていない | git fetch --unshallow で共通祖先まで取得 |
partial clone(--filter)の使い方
partial cloneは、履歴(コミット)は持ったまま、中身の一部を「必要になったら取る」方式です。shallow cloneが「過去を切る」のに対し、partial cloneは「過去は残して中身を後回しにする」と考えると区別しやすくなります。
| 指定 | 通称 | 最初に取るもの | 後から取るもの |
|---|---|---|---|
--filter=blob:none |
blobless clone | 全コミット+全ツリー+チェックアウトに必要なblob | 過去のファイルの中身 |
--filter=tree:0 |
treeless clone | 全コミット+チェックアウトに必要なツリーとblob | 過去のツリーとファイルの中身 |
--filter=blob:limit=1m |
サイズ制限 | 1MB未満のblobは全部 | 1MB以上のblob |
clone後の設定を見ると、リモートが「足りない分を約束してくれる相手(promisor)」として記録されています。
$ git config --get-regexp 'remote.origin.*'
remote.origin.url file:///srv/origin.git
remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
remote.origin.promisor true
remote.origin.partialclonefilter blob:none
fetch対象が *(全ブランチ)である点に注目してください。bloblessならブランチの切り替えも git log も通常cloneと同じ感覚で使え、切り替え時に足りないblobだけが自動で取得されます。オフラインで過去のファイルを開く予定がある場合は、通常cloneを選ぶと安心です。
shallowとpartialの違い
| 観点 | shallow(--depth 1) |
blobless(--filter=blob:none) |
|---|---|---|
| コミット履歴 | 先端のみ | すべて |
git log |
取得した範囲だけ | すべて表示できる |
git blame / git diff <過去> |
取得した範囲だけ | 使える(必要なblobを自動取得) |
| ブランチ | 既定で1つ | すべて |
| オフライン作業 | 取得済みの範囲で完結 | 過去の中身を開くときは接続が必要 |
| サーバー側の対応 | ほぼ必ず使える | フィルタ対応が必要(主要サービスは対応) |
| 向いている用途 | CI、試し読み | 日常の開発、大きなリポジトリ |
sparse-checkoutで必要なフォルダだけ展開する
モノレポのように大きなリポジトリでは、作業ツリーに展開するフォルダも絞れます。--sparse を付けてcloneすると、最初は最上位フォルダ直下のファイルだけが展開されます。次は実行した出力です(検証用リポジトリは最上位にファイルが無いため、最初の ls は空です)。
$ git clone --filter=blob:none --sparse file:///srv/origin.git mono
$ cd mono
$ ls
$ git sparse-checkout set docs
$ ls
docs
$ git sparse-checkout add src/app
$ ls
docs
src
$ git sparse-checkout list
docs
src/app
| コマンド | 働き |
|---|---|
git sparse-checkout set <dir>... |
展開するフォルダを指定した内容に置き換える |
git sparse-checkout add <dir>... |
展開するフォルダを追加する |
git sparse-checkout list |
いまの指定を表示する |
git sparse-checkout disable |
絞り込みをやめて全フォルダを展開する |
disable を実行すると assets docs src の全フォルダが展開され、検証では .git が 548KB から 2.0MB に増えました。展開に必要なblobがその時点で取得されたためです。「filterで取得量を減らし、sparse-checkoutで展開量を減らす」という2段構えになっています。
認証情報の管理(HTTPSとSSH)
非公開リポジトリのcloneでは認証が必要です。この項のコマンドは外部サービスへの接続が必要なため、今回の検証環境では未実行です(一般に知られた手順として紹介します)。
| 方式 | 準備 | cloneのコマンド | 管理のポイント |
|---|---|---|---|
| HTTPS+トークン | アクセストークンを発行 | git clone https://github.com/example/myapp.git |
パスワード欄にトークンを入力。資格情報ヘルパーに保存する |
| SSH鍵 | ssh-keygen -t ed25519 で作成し公開鍵を登録 |
git clone git@github.com:example/myapp.git |
秘密鍵は持ち出さない。ssh -T git@github.com で接続確認 |
| GitHub CLI | gh auth login |
gh repo clone example/myapp |
トークンの発行と保存を任せられる |
URLにトークンを直接埋め込む書き方(https://<トークン>@...)は、.git/config やシェルの履歴に残ります。 資格情報ヘルパーに保存する方法にすると、URLには秘密の値が残りません。
# 資格情報ヘルパーの確認と設定
git config --global credential.helper # いまの設定を表示
git config --global credential.helper manager # Windows(Git Credential Manager)
git config --global credential.helper osxkeychain # macOS
git config --global credential.helper 'cache --timeout=3600' # Linux:1時間メモリに保持
# clone後にHTTPSからSSHへ切り替える
git remote set-url origin git@github.com:example/myapp.git
git remote -v
SSH鍵の作り方と接続確認は別の記事で詳しく扱っているため、ここでは要点の表に留めます。
エラー別の対処早見表
「実行」欄が「再現」のものは今回の検証で実際に出力を確認したメッセージ、「未実行」のものは外部サービスやWindows環境が必要なため今回は動かしておらず、一般に知られたメッセージと対処を載せています。
| エラーメッセージ | 主な原因 | 対処 | 実行 |
|---|---|---|---|
fatal: destination path 'myapp' already exists and is not an empty directory. |
同名のフォルダが既にある | 別名を第2引数に指定するか、既存フォルダで git pull |
再現 |
fatal: Remote branch nobranch not found in upstream origin |
-b のブランチ名が違う |
git ls-remote --heads <URL> で名前を確認 |
再現 |
fatal: '...' does not appear to be a git repository / Could not read from remote repository. |
URL・パスの間違い、アクセス権なし | URLを確認。SSHなら鍵の登録を確認 | 再現 |
! [remote rejected] main -> main (shallow update not allowed) |
shallowのまま別リモートへpush | git fetch --unshallow してからpush |
再現 |
fatal: --unshallow on a complete repository does not make sense |
すでに全履歴がある | 対処不要(そのまま使える) | 再現 |
fatal: invalid reference: develop |
single-branchで取得しておりブランチが無い | git remote set-branches origin '*' → git fetch |
再現 |
git@github.com: Permission denied (publickey). |
SSH鍵が未登録、または別の鍵が使われている | ssh -T git@github.com で確認し、公開鍵を登録。ssh-add -l で読み込み済みの鍵を確認 |
未実行 |
remote: Repository not found. |
URLの打ち間違い、または権限のないアカウントで認証されている | URLとログイン中のアカウントを確認。保存済みの資格情報を入れ直す | 未実行 |
fatal: Authentication failed for 'https://...' |
トークンの期限切れ、パスワードを入力している | 新しいトークンを発行し、資格情報を更新 | 未実行 |
error: unable to create file ...: Filename too long(Windows) |
パスが260文字の上限を超えた | git config --global core.longpaths true。浅い階層(C:\src など)にcloneする |
未実行 |
warning: LF will be replaced by CRLF(Windows) |
改行コードの自動変換が有効 | 下の「改行コード」の項を参照 | 未実行 |
error: RPC failed; curl 56 ... / fatal: early EOF |
大きなリポジトリで転送が途中で切れた | --depth 1 や --filter=blob:none で取得量を減らし、あとで --unshallow |
未実行 |
SSL certificate problem: unable to get local issuer certificate |
社内プロキシなどの証明書を信頼していない | 証明書を http.sslCAInfo に設定する(検証の無効化はしない) |
未実行 |
Windows:Filename too long
Windowsでは、パスの長さに上限(260文字)があるため、深い階層を持つリポジトリでは展開が途中で止まることがあります。Git for Windows側の設定で長いパスを扱えるようにします。
# Git側で長いパスを有効にする
git config --global core.longpaths true
# すでにcloneが途中で止まったフォルダなら、設定後に作業ツリーを展開し直す
git restore --source=HEAD :/
あわせて、cloneする場所を C:\src\myapp のように浅くすると余裕ができます。OS側の「長いパスを有効にする」設定が必要な場合もあるため、管理者に確認するとスムーズです。
Windows:改行コード(CRLFとLF)の問題
Windowsでcloneした直後に「何も変更していないのに全ファイルが変更扱いになる」「シェルスクリプトが \r のせいで動かない」ときは、改行コードの自動変換が関係しています。
| 設定 | チェックアウト時 | コミット時 | 向いている環境 |
|---|---|---|---|
core.autocrlf=true |
LF → CRLF に変換 | CRLF → LF に変換 | Windowsのみで開発 |
core.autocrlf=input |
変換しない | CRLF → LF に変換 | macOS/Linux、WSL |
core.autocrlf=false |
変換しない | 変換しない | .gitattributes で管理する場合 |
チーム全員の設定をそろえるには、個人の設定に頼らず .gitattributes をリポジトリに置く方法が確実です。
# .gitattributes
* text=auto eol=lf
*.bat text eol=crlf
*.png binary
# clone時だけ設定を上書きする(-c はそのcloneで作るリポジトリに設定を書き込む)
git clone -c core.autocrlf=input https://github.com/example/myapp.git
clone後に確認しておくと安心なコマンド
cloneが終わったら、次の4つを実行すると状態が一目でわかります。
git remote -v # 取得元URL(HTTPSかSSHか)
git branch -a # ローカル/リモート追跡ブランチ
git rev-parse --is-shallow-repository # shallowなら true
git config --get remote.origin.fetch # fetch対象(* なら全ブランチ)
| 確認項目 | 期待する状態 | 違っていたら |
|---|---|---|
| リモートURL | 意図した方式(SSH/HTTPS) | git remote set-url origin <URL> |
| ブランチ | 必要なブランチが origin/... にある |
git remote set-branches origin '*' → git fetch |
| shallowかどうか | 開発用なら false |
git fetch --unshallow |
| ユーザー名・メール | そのリポジトリ用の値 | git config user.name / user.email を設定 |
よくある質問
Q. --depth 1 でcloneしたリポジトリで、そのまま開発を続けても大丈夫ですか?
A. コミットやclone元へのpushは通常どおり行えます。過去の履歴を調べる操作(git log、git blame、過去のタグとの比較)が取得した範囲に限られるため、開発用として長く使うなら git fetch --unshallow で全履歴を取っておくか、最初から --filter=blob:none でcloneすると快適です。
Q. -b でブランチを指定すれば、そのブランチだけ取得されますか?
A. -b だけでは全ブランチが取得されます。1ブランチに絞るには --single-branch を併用します。--depth を付けた場合は自動で --single-branch も付くため、結果として1ブランチだけになります。
Q. shallow cloneとpartial clone(--filter=blob:none)はどちらを選べばよいですか?
A. ビルドして捨てるCIのような使い捨ての用途には --depth 1、手元で履歴を見ながら開発する用途には --filter=blob:none が合います。今回の実測では、どちらも通常cloneの10分の1以下の時間で終わり、.git は2MB前後でした。
Q. cloneしたあとで、取得するブランチを追加できますか?
A. できます。git remote set-branches --add origin <ブランチ名> で対象に加えてから git fetch を実行します。全ブランチを対象に戻すなら git remote set-branches origin '*' です。
まとめ
git clone <URL>は、init・remote追加・fetch・チェックアウトをまとめて行うコマンドで、ローカルブランチは既定の1つだけ作られる-bは「最初に開くブランチ」を決めるだけで、取得量を減らすには--single-branchや--depthを組み合わせる- 実測では
--depth 1が0.50秒/1.7MB、--filter=blob:noneが0.88秒/2.0MB(通常cloneは11.23秒/59MB) --depthは自動で--single-branchになるため、ほかのブランチはgit remote set-branches origin '*'とgit fetchで見えるようにするgit fetch --unshallowで通常のリポジトリに戻せる。少しだけ深くするなら--deepen=<n>shallow update not allowedは、履歴をそろえてからpushすると解消する- Windowsの
Filename too longはcore.longpaths、改行コードは.gitattributesでそろえる
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「git cloneの使い方|ブランチ指定とshallow clone」
株式会社RJCでは、git cloneの取り方やリポジトリの扱い方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。