🚀

Gitで出来るだけ無駄なくリモートリポジトリの特定のファイルをダウンロードする

2025/02/10に公開

目的

Gitのリモートリポジトリ内の特定のファイルをダウンロードしたいのですが、普通にgit cloneするとリポジトリ全体を落として来ちゃうのでできるだけ無駄なくできないかと調べました

ブラウザからダウンロードしたりwgetなどで直接URLを叩く方法もありそうですが、今回は認証をgitコマンド任せにして処理はプログラムで書くようにしたかったのでgit cloneでどうにかするようにしました

コマンド

git clone --filter=tree:0 --no-tags --no-checkout --sparse <url> <dir>
cd <dir>
git sparse-checkout set --no-cone <file_path>
git checkout <commit>

いろいろ調べた結果、こんな感じになりました

環境

Windows 11 23H2
git version 2.47.1.windows.2

git clone

できるだけ無駄なデータを取得せずにクローンします

git clone --filter=tree:0 --no-tags --no-checkout --sparse <url> <dir>

--filter=tree:0

ツリーレスクローンにすることで履歴データの大部分を取得しないようしています

こちらの記事がわかりやすかったです
https://github.blog/jp/2021-01-13-get-up-to-speed-with-partial-clone-and-shallow-clone/

--no-tags

タグ情報をダウンロードしないようにしています

--no-checkout

この時点ではまだチェックアウトを行わないようにしています

--sparse

後述のsparse-checkoutの機能を有効化しています

git sparse-checkout

リポジトリから必要なファイルのみをチェックアウトして作業ツリーを最適化するためのコマンドです

目的のファイルのパスを登録します

git sparse-checkout set --no-cone <file_path>

--no-cone

sparse-checkoutにはコーンモードと非コーンモードがあり、
コーンモードではルート直下とパス上の兄弟ファイルもチェックアウトする挙動になります

if you specified the directory Documentation/technical/ then your sparse checkout would contain:

  • all files in the toplevel-directory
  • all files immediately under Documentation/
  • all files at any depth under Documentation/technical/

https://git-scm.com/docs/git-sparse-checkout#_internalscone_mode_handling

コーンモードの方が新しい方式でパフォーマンスも良さそうなのですが、今回は対象のファイルをダウンロードしたいだけなので無駄なファイルをダウンロードしない非コーンモード--no-coneを指定します

git checkout

git checkout <commit>

最後にチェックアウトするとsparse-checkoutで指定したファイルのみが作業ディレクトリに生成されます
このタイミングで必要なデータがリモートリポジトリからダウンロードされます

ちなみにgit clone--no-checkoutのオプションをつけていないとsparse-checkout設定前のクローン時にチェックアウトが走り不要なファイルまでダウンロードしてしまいます

ダメだった方法

git archive

git archive --remote=<repo>がまさに今回のような用途の機能っぽいのですがGitHubでは非対応みたいです[1]
今回はGitHubも対象にしたいので他の方法にしました

参照

https://github.blog/jp/2021-01-13-get-up-to-speed-with-partial-clone-and-shallow-clone/
https://git-scm.com/docs/git-clone/ja

脚注
  1. https://stackoverflow.com/questions/9609835/git-export-from-github-remote-repository ↩︎

Discussion