最初にリポジトリ全体をチェックアウトせずに、まばらなチェックアウトを行うことは可能ですか?


170

チェックアウトに何時間もかかる非常に多数のファイルを含むリポジトリを使用しています。Gitがスパースチェックアウトをサポートするようになったため、Gitがこの種のリポジトリでうまく機能するかどうかを調べていますが、見つけることができるすべての例では次のことを行います。

git clone <path>
git config core.sparsecheckout true
echo <dir> > .git/info/sparse-checkout
git read-tree -m -u HEAD

このコマンドシーケンスの問題は、元のクローンもチェックアウトを行うことです。元のcloneコマンドに-nを追加すると、read-treeコマンドで次のエラーが発生します。

エラー:スパースチェックアウトで作業ディレクトリにエントリがありません

最初にすべてのファイルをチェックアウトせずに、スパースチェックアウトを実行するにはどうすればよいですか?



注:git 2.9(2016年git worktree add --no-checkoutだけgit clone --no-checkout)でも(だけでなく)機能します。下記の私の回答を
VonC

ここにすべてのソリューションを試した後、唯一のディレクトリだけをダウンロードするには、(無その後プッシュ!)で、この
LondonRob 2018年

回答:


23

2020年には、.gitファイルを気にすることなく、スパースチェックアウトを処理する簡単な方法があります。ここに私がそれをした方法があります:

git clone <URL> --no-checkout <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout set apps/my_app libs/my_lib # etc, to list sub-folders to checkout
# they are checked out immediately after this command, no need to run git pull

gitバージョン2.25がインストールされている必要があることに注意してください。詳しくは、https//github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/をご覧ください。

更新:

上記のgit cloneコマンドは、ファイルをチェックアウトしなくても、完全な履歴でリポジトリを複製します。完全な履歴が必要ない場合は、次のようにコマンドに--depthパラメータを追加できます。

# create a shallow clone,
# with only 1 (since depth equals 1) latest commit in history
git clone <URL> --no-checkout <directory> --depth 1

1
それは事実です。賛成。私sparse-checkout --conestackoverflow.com/a/59515426/6309
VonC

--filterここでの回答に部分的なクローン()を追加する価値があります。
タオ

@ alexey-grinko、最初のコマンドは、チェックアウトしなくても、問題のリポジトリ全体を複製する必要がありました...不要なものすべてを複製しない時間を節約するために探していました。 。
mropp

1
@mropp、--depth浅いクローンを作成できるようにするパラメーターを追加して、回答を更新しました。それは役に立ちますか?@Tao、--filterこの場合の使い方がわからないので、試しませんでした。例を提供したり、このトピックに別の回答を投稿したりできますか?
Alexey Grinko

3
2.27リリースでは同じように機能しないことに注意してください。理由はわかりません。
Blazes

162

この回答では、リポジトリからデータの完全なコピーがダウンロードされることに注意してください。このgit remote add -fコマンドは、リポジトリ全体を複製します。のマニュアルページからgit-remote

では-fオプション、git fetch <name>遠隔情報が設定された直後に実行されます。


これを試して:

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add -f origin git://...
echo "path/within_repo/to/desired_subdir/*" > .git/info/sparse-checkout
git checkout [branchname] # ex: master

これで、path / within_repo / to / desired_subdirからのファイルのみ(およびそのパス内)の「プルーニング」チェックアウトがあることがわかります。

Windowsコマンドラインでは、パスを引用符で囲まないでください。つまり、6番目のコマンドを次のように変更する必要があります。

echo path/within_repo/to/desired_subdir/* > .git/info/sparse-checkout

そうしないと、疎チェックアウトファイルで引用符が表示され、機能しません。


3
「git checkout [branchname]」というコマンドは使用できません(エラーも検出:スパースチェックアウトで作業ディレクトリにエントリが残りません)。「git pull origin master」を使用しましたが、正しく動作します。
Natty、

2
エコー「DIR / *」チェックアウト:Linux上でgitのバージョン1.7.2.5で、私は以下の結果を得た唯一のディレクトリにある/ではなく、そのサブディレクトリ内のファイル。echo 'dir /'(アスタリスクなし!)は、dir /の下のツリー全体を正しくチェックアウトします。HTH
2013年

37
これだけでは機能しませんでした。「git remote」コマンドを実行すると、リポジトリ全体がチェックアウトされました-bam!-その時; そのため、「git config ...」と次のコマンドで対象となるサブディレクトリを指定しても効果はありませんでした。「git remote」コマンドで指定されたリポジトリURLは、最上位の.gitファイルへのパスにすぎませんか?それとも、対象のサブディレクトリへのパスにする必要がありますか?
Rob Cranfill 2013年

10
これは合理化されたバージョンです(手動でディレクトリを作成する必要はなく、initとリモート追加を実行します。@ onionjakeで言及されているように--no-checkoutオプションで通常のgit clone + checkoutサイクルを実行します):git clone --no-checkout <project> cd <project> echo <dir>> .git / info / sparse-checkout git checkout <branch>
Gregor

22
git remote addコマンドのダウンロードはすべてそれが何だから-fない-あなたがまばらなチェックアウトオプションを定義した前に、すぐにフェッチするように指示します。ただし、省略または並べ替えを行っても効果はありません。スパースチェックアウトは、リポジトリではなく作業ツリーにのみ影響します。代わりにリポジトリをダイエットさせたい場合は、代わりに--depthまたは--single-branchオプションを確認する必要があります。
Miral

43

Gitクローンには、必要な処理を実行するオプション(--no-checkoutまたは-n)があります。

コマンドのリストで、次のように変更します。

git clone <path>

これに:

git clone --no-checkout <path>

その後、質問に記載されているように、スパースチェックアウトを使用できます。


7
ええ、チェックアウトはしませんが、それでもフェッチを行ってレポ履歴全体をダウンロードします
Jason S

9
@JasonS問題は、特にチェックアウトを行わないことに関するものでした。履歴全体--depth <depth>が不要な場合は、git cloneのオプションを使用してください。これは<depth>、履歴から最後のコミットのみをダウンロードします。現在、gitで単一のコミットを部分的にダウンロードする方法はありませんが、リモートがサポートしている場合git archive --remoteは、ファイルの部分的なセットをダウンロードするために使用できます。
オニオンジェイク2016

vfsforgit.orgを使用してファイルをダウンロードせずにコミットを「チェックアウト」できるようになりました。これは、誰かが単一のコミットの小さなサブセットのみをチェックアウトしようとしている場合に役立ちます。
onionjake

22

タグのコミットのみをチェックアウトし、ディレクトリをプルーニングしたいと思ったことを除いて、私は同様のユースケースを持っていました。を使用--depth 1すると、非常にまばらになり、速度を上げることができます。

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add origin <url>  # Note: no -f option
echo "path/within_repo/to/subdir/" > .git/info/sparse-checkout
git fetch --depth 1 origin tag <tagname>
git checkout <tagname>

3
-深さ1は、浅いクローン、FYIと呼ばれます。
マークアリソン

1
これは役に立ちました!ありがとう
kp123

1
これをありがとう。リポジトリ全体のダウンロードを防ぐために他の多くの方法を試した後、これでうまくいきました。
J ... S

12

以前にpavekが投稿したワンライナー(ありがとう!)から探していた答えを見つけたので、Linux(GIT 1.7.1)で機能する単一の返信で完全な答えを提供したいと思いました。

1--> mkdir myrepo
2--> cd myrepo
3--> git init
4--> git config core.sparseCheckout true
5--> echo 'path/to/subdir/' > .git/info/sparse-checkout
6--> git remote add -f origin ssh://...
7--> git pull origin master

コマンドの順序を少し変更しましたが、影響がないようです。重要なのは、手順5でパスの末尾にスラッシュ "/"が存在することです。


3
これでいいですか?-fはすべてのデータをフェッチすることを意味しますが、不要な他のすべての情報を取得し、速度が低下します。(これはまだ「リポジトリ全体をチェックアウトしている」)
Shuman

1
上記の手順をWindowsで試しましたが、コマンドプロンプトでスペアチェックアウトが機能しないため、Git Bashシェルを試してみましたが、うまくいきませんでした。コマンドプロンプトは、push、pullなどのすべてのgitコマンドを実行できますが、スパースチェックアウトになると失敗します。
user593029

サブディレクトリのファイルのみを行う方法。特定のサブディレクトリ内のファイルのみをフェッチしたい。
バビッシュシュレスタ2016

@BabishShrestha他の回答FWIWでonionjakeのコメントを参照してください:|
rogerdpack 2016

9

残念ながら、上記のどれもうまくいかなかったので、さまざまなsparse-checkoutファイルの組み合わせを試すのに非常に長い時間を費やしました。

私の場合、IntelliJ IDEA構成のフォルダーをスキップしたいと思いました。

これが私がしたことです:


走る git clone https://github.com/myaccount/myrepo.git --no-checkout

走る git config core.sparsecheckout true

.git\info\sparse-checkout次のコンテンツで作成

!.idea/*
!.idea_modules/*
/*

「git checkout-」を実行して、すべてのファイルを取得します。


それを機能させるための重要なことは/*、フォルダ名の後に追加することでした。

私はgit 1.9を持っています


3
いいえ、まだすべて、すべてのコミット、すべてのファイルをダウンロードしています
。git2.3.2

6
スパースチェックアウトは作業ツリーにのみ影響します。リポジトリのサイズや取得される内容には影響しません。必要な場合は、さまざまなオプションが必要です。
Miral

Windowsで作業していて、上記の「pbetkier」の手順を使用する場合は、次回Git Bash Shellを試してみてください
user593029

6

はい、リポジトリ全体をダウンロードする代わりにフォルダをダウンロードすることは可能です。いずれか/最後のコミット

これを行う良い方法

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
  1. -r HEADは最後のリビジョンのみをダウンロードし、すべての履歴を無視します。

  2. トランクと/ specific-folderに注意してください

の前後にURLをコピーして変更します/trunk/。これが誰かの役に立つことを願っています。楽しい :)

2019年9月26日に更新


svnからの、またはsvnを使用している人にのみ適用されます。これには賛成しません。
Cジョンソン

@CJohnsonご覧のとおり、git repoフォルダーのクローンを作成しています。正常に動作しています
カマール、

1
これはgitがそのまま提供するものではなく、Git ハブが通常のGitオファリングに隣接して提供するものであることに注意してください。しかし、それを活用できれば美しく機能します。ありがとう!
Qix-モニカは

1
SOに関する無数の提案のうち、あなたの提案が最も簡潔で明確な解決策です。
ボードライダー

4

git 2.9(2016年6月)は、--no-checkoutオプションを一般化しますgit worktree add1つのリポジトリー複数の作業ツリーを操作できるようにするコマンド)。

Ray Zhang()によるcommit ef2a0ac(29 Mar 2016)を参照してください。 協力者:Eric Sunshine(Junio C Hamano((合併によりJunio C浜野- -コミット0d8683c、2016年4月13日)OneRaynyDay
sunshinecogitster
gitster

git worktreemanページには今含まれています:

--[no-]checkout:

ただし、デフォルトでは、addチェックアウトを使用して、sparse-checkoutの構成などのカスタマイズを行うためにチェックアウトを抑制することができます<branch>--no-checkout


4

特定のフォルダのみをスパースチェックアウトする手順:

1) git clone --no-checkout  <project clone url>  
2) cd <project folder>
3) git config core.sparsecheckout true   [You must do this]
4) echo "<path you want to sparce>/*" > .git/info/sparse-checkout
    [You must enter /* at the end of the path such that it will take all contents of that folder]
5) git checkout <branch name> [Ex: master]

参考までに、最初の(1)ステップでは、-no-checkoutを使用する必要はありません。リポジトリ全体のクローンを作成し、以下のステップ2〜5(上記)をすべて実行するだけで、必要な出力が得られます。届かない場合はお知らせください。
SANDEEP MACHIRAJU

4

apenwarrによるこの回答Miralによるこのコメントに基づいて、Linux gitリポジトリをローカルに複製するときに、ドキュメントサブディレクトリを1つだけ必要とするときに、ディスク領域の約94%を節約する次の解決策を思いつきました。

$ cd linux
$ du -sh .git .
2.1G    .git
894M    .
$ du -sh 
2.9G    .
$ mkdir ../linux-sparse-test
$ cd ../linux-sparse-test
$ git init
Initialized empty Git repository in /…/linux-sparse-test/.git/
$ git config core.sparseCheckout true
$ git remote add origin ../linux
# Parameter "origin master" saves a tiny bit if there are other branches
$ git fetch --depth=1 origin master
remote: Enumerating objects: 65839, done.
remote: Counting objects: 100% (65839/65839), done.
remote: Compressing objects: 100% (61140/61140), done.
remote: Total 65839 (delta 6202), reused 22590 (delta 3703)
Receiving objects: 100% (65839/65839), 173.09 MiB | 10.05 MiB/s, done.
Resolving deltas: 100% (6202/6202), done.
From ../linux
 * branch              master     -> FETCH_HEAD
 * [new branch]        master     -> origin/master
$ echo "Documentation/hid/*" > .git/info/sparse-checkout
$ git checkout master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'
$ ls -l
total 4
drwxr-xr-x 3 abe abe 4096 May  3 14:12 Documentation/
$  du -sh .git .
181M    .git
100K    .
$  du -sh
182M    .

それで、2.9GBから182MBに下がりました。

私はこれを動作させることはできませんでしたがgit clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-testここで示唆されました)、不足しているファイルはすべて削除されたファイルとしてインデックスに追加されました。したがって、git clone --filter=blob:nonefor の同等物を誰かが知っている場合git fetch、おそらくさらに数メガバイトを節約できます。(のmanページを読むと、のgit-rev-listようなものがあることが示唆されますが--filter=sparse:path=…、それも機能しませんでした。

(Debian Busterのgit 2.20.1ですべて試しました。)


1
興味深いフィードバック。賛成。--filter=sparse:path=…どちらかわかりません。
VonC、

3

私はgitは初めてですが、ディレクトリごとにgit checkoutを実行すると、動作するようです。また、sparse-checkoutファイルでは、示されているように、すべてのディレクトリの後にスラッシュを付ける必要があります。これ以上の経験があれば、これが機能することを確認してください。

興味深いことに、疎チェックアウトファイルにないディレクトリをチェックアウトしても、違いはないようです。それらはgitステータスでは表示されず、git read-tree -m -u HEADによって削除されることはありません。git reset --hardを実行しても、ディレクトリは削除されません。チェックアウトされているが、まばらなチェックアウトファイルにはないディレクトリについてgitがどのように考えているかについてコメントする、より経験豊富な人はいますか?


0

私の場合、Podsプロジェクトを複製するときにフォルダをスキップしたいと思います。私は以下のように段階的に行いましたが、それは私にとってはうまくいきます。それが役に立てば幸い。

mkdir my_folder
cd my_folder
git init
git remote add origin -f <URL>
git config core.sparseCheckout true 
echo '!Pods/*\n/*' > .git/info/sparse-checkout
git pull origin master

メモ、さらにフォルダをスキップしたい場合は、スパースチェックアウトファイルに行を追加してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.