Ist es möglich, eine spärliche Prüfung durchzuführen, ohne zuerst das gesamte Repository auszuchecken?


170

Ich arbeite mit einem Repository mit einer sehr großen Anzahl von Dateien, deren Auschecken Stunden dauert. Ich prüfe die Möglichkeit, ob Git jetzt mit dieser Art von Repository gut funktioniert, da es spärliche Checkouts unterstützt, aber jedes Beispiel, das ich finden kann, führt Folgendes aus:

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

Das Problem bei dieser Befehlsfolge ist, dass der ursprüngliche Klon auch eine Prüfung durchführt. Wenn Sie dem ursprünglichen Klonbefehl -n hinzufügen, führt der Befehl read-tree zu folgendem Fehler:

Fehler: Beim spärlichen Auschecken bleibt kein Eintrag im Arbeitsverzeichnis

Wie kann das spärliche Auschecken durchgeführt werden, ohne zuerst alle Dateien auszuchecken?



Hinweis: Funktioniert git worktree add --no-checkoutauch (nicht nur git clone --no-checkout) mit Git 2.9 (nur 2016). Siehe meine Antwort unten
VonC

Nach dem Versuch , hier alle Lösungen, die einzige, die nur das Verzeichnis herunterlädt (kein Stoßen danach!) Ist dies .
LondonRob

Antworten:


23

Im Jahr 2020 gibt es eine einfachere Möglichkeit, mit Sparse-Checkout umzugehen, ohne sich um .git-Dateien kümmern zu müssen. So habe ich es gemacht:

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

Beachten Sie, dass Git Version 2.25 installiert sein muss. Lesen Sie hier mehr darüber: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

AKTUALISIEREN:

Der obige git cloneBefehl klont das Repo weiterhin mit seinem vollständigen Verlauf, ohne jedoch die Dateien auszuchecken. Wenn Sie nicht den vollständigen Verlauf benötigen, können Sie dem Befehl den Parameter --depth wie folgt hinzufügen :

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

1
Das ist wahr, guter Punkt. Upvoted. Ich folgte der sparse-checkout --coneFunktion in stackoverflow.com/a/59515426/6309
VonC

Es lohnt sich --filter, Ihrer Antwort hier einen Teilklon ( ) hinzuzufügen .
Tao

@ alexey-grinko, der erste Befehl musste immer noch das gesamte fragliche Repo klonen, auch wenn es nicht überprüft wurde ... Ich wollte die Zeit sparen, nicht alle Dinge zu klonen, die ich nicht brauche. .
mropp

1
@mropp, ich habe die Antwort durch Hinzufügen eines --depthParameters aktualisiert, mit dem wir einen flachen Klon erstellen können . Wird das helfen? @Tao, nicht sicher, wie man --filterin diesem Fall verwendet, ich habe es nicht versucht. Könnten Sie ein Beispiel geben oder eine andere Antwort auf dieses Thema posten?
Alexey Grinko

3
Beachten Sie, dass es in Version 2.27 nicht genauso funktioniert - ich weiß nicht warum.
Blazes

162

Bitte beachten Sie, dass diese Antwort eine vollständige Kopie der Daten aus einem Repository herunterlädt. Dasgit remote add -f Befehl klont das gesamte Repository. Aus der Manpage vongit-remote :

Mit -f Option git fetch <name>wird sofort ausgeführt, nachdem die Remote-Informationen eingerichtet wurden.


Versuche dies:

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

Jetzt werden Sie feststellen, dass Sie eine "beschnittene" Kasse haben, bei der nur Dateien vom Pfad / inside_repo / zum / gewünschten_subdir (und in diesem Pfad) vorhanden sind.

Beachten Sie, dass Sie in der Windows-Befehlszeile den Pfad nicht angeben dürfen, dh Sie müssen den 6. Befehl mit diesem ändern:

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

Wenn Sie dies nicht tun, erhalten Sie die Anführungszeichen in der Sparse-Checkout-Datei, und es wird nicht funktionieren


3
Ich kann den Befehl "git checkout [branchname]" nicht verwenden (auch Fehler gefunden: Sparse checkout hinterlässt keinen Eintrag im Arbeitsverzeichnis). Ich habe "Git Pull Origin Master" verwendet und es funktioniert richtig.
Natty

2
Mit Git Version 1.7.2.5 unter Linux habe ich die folgenden Ergebnisse erhalten: echo 'dir / *' überprüft nur die Dateien in dir /, aber nicht in seinen Unterverzeichnissen; echo 'dir /' (kein Sternchen!) überprüft den gesamten Baum unter dir / korrekt. HTH
Pavek

37
Das hat bei mir einfach nicht funktioniert - der Befehl "git remote" hat dazu geführt, dass das gesamte Repo ausgecheckt wurde - bam! - Also gut; Daher hatten die "git config ..." und die Angabe eines Unterverzeichnisses von Interesse in den folgenden Befehlen keine Auswirkung. Ist die im Befehl "git remote" angegebene Repo-URL nur der Pfad zur .git-Datei der obersten Ebene? Oder sollte es ein Weg zum Unterverzeichnis von Interesse sein?
Rob Cranfill

10
Hier ist eine optimierte Version (keine Notwendigkeit, das Verzeichnis manuell zu erstellen, einen Init und ein Remote-Add durchzuführen, führen Sie einfach den normalen Git-Klon + Checkout-Zyklus mit der Option --no-checkout aus, wie von @onionjake erwähnt): git-Klon --no-checkout <Projekt> CD <Projekt> Echo <Verzeichnis> .git / info / sparse-checkout git checkout <branch>
Gregor

22
Der git remote addBefehl lädt alles herunter, weil er -fgenau das tut - er fordert ihn auf, sofort abzurufen, bevor Sie die Optionen für das spärliche Auschecken definiert haben. Aber das Weglassen oder Neuanordnen hilft nicht weiter. Sparse Checkouts wirken sich nur auf den Arbeitsbaum aus, nicht auf das Repository. Wenn Sie möchten, dass Ihr Repository stattdessen eine Diät macht, müssen Sie stattdessen die Optionen --depthoder --single-branchprüfen.
Miral

43

Git-Klon hat eine Option ( --no-checkoutoder -n), die macht, was Sie wollen.

Ändern Sie in Ihrer Befehlsliste einfach:

git clone <path>

Dazu:

git clone --no-checkout <path>

Sie können dann die spärliche Kaufabwicklung wie in der Frage angegeben verwenden.


7
Ja, es wird nicht ausgecheckt, aber es wird immer noch ein Abruf durchgeführt, um den gesamten Repo-Verlauf herunterzuladen
Jason S

9
@ JasonS die Frage war speziell, keine Kasse zu machen. Wenn Sie nicht möchten, verwenden Sie die --depth <depth>Option für den Git-Klon. Dadurch werden nur die letzten <depth>Commits aus dem Verlauf heruntergeladen . Derzeit gibt es keine Möglichkeit, ein einzelnes Commit mit git teilweise herunterzuladen. Wenn Ihre Fernbedienung dies jedoch unterstützt, können Sie git archive --remoteteilweise Dateigruppen herunterladen.
Zwiebeljake

Sie können jetzt auch ein Commit " auschecken ", ohne Dateien mit vfsforgit.org herunterladen zu müssen . Dies kann nützlich sein, wenn jemand versucht, nur eine kleine Teilmenge eines einzelnen Commits auszuchecken.
Zwiebeljake

22

Ich hatte einen ähnlichen Anwendungsfall, außer dass ich nur das Commit für ein Tag auschecken und die Verzeichnisse bereinigen wollte. Die Verwendung --depth 1macht es sehr spärlich und kann die Dinge wirklich beschleunigen.

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
--depth 1 wird als flacher Klon bezeichnet, nur zu Ihrer Information.
Mark Allison

1
Das hat geholfen! Vielen Dank
kp123

1
Danke dafür. Nachdem ich viele andere Möglichkeiten ausprobiert habe, um das Herunterladen des gesamten Repos zu verhindern, habe ich es richtig gemacht.
J ... S

12

Ich habe die gesuchte Antwort von dem Einzeiler gefunden, den pavek zuvor gepostet hat (danke!), Daher wollte ich eine vollständige Antwort in einer einzigen Antwort geben, die unter Linux (GIT 1.7.1) funktioniert :

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

Ich habe die Reihenfolge der Befehle ein wenig geändert, aber das scheint keine Auswirkungen zu haben. Der Schlüssel ist das Vorhandensein des abschließenden Schrägstrichs "/" am Ende des Pfades in Schritt 5.


3
Bist du sicher, dass du das willst? Das -f bedeutet, dass alle Daten abgerufen werden. Sie erhalten trotzdem alle anderen Informationen, die Sie nicht möchten, und es ist langsam. (Dies ist immer noch "Auschecken des gesamten Repository")
Shuman

1
Ich habe die obigen Schritte in Windows versucht, aber das Auschecken von Ersatzdaten funktioniert nicht in der Eingabeaufforderung, also habe ich die Git Bash-Shell ausprobiert und es hat funktioniert !! Die Eingabeaufforderung kann alle Git-Befehle wie Push, Pull usw. ausführen, aber wenn es um das Auschecken mit geringer Dichte geht, schlägt dies fehl.
user593029

So machen Sie nur Dateien des Unterverzeichnisses. Ich möchte nur die Dateien in einem bestimmten Unterverzeichnis abrufen.
Babish Shrestha

@BabishShrestha siehe Kommentar von onionjake zu anderer Antwort FWIW: |
Rogerdpack

9

Leider hat keines der oben genannten Verfahren für mich funktioniert, so dass ich sehr lange Zeit damit verbracht habe, verschiedene Dateikombinationen sparse-checkoutauszuprobieren.

In meinem Fall wollte ich Ordner mit IntelliJ IDEA-Konfigurationen überspringen.

Folgendes habe ich getan:


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

Lauf git config core.sparsecheckout true

Erstellt .git\info\sparse-checkoutmit folgenden Inhalten

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

Führen Sie 'git checkout -' aus, um alle Dateien abzurufen.


Entscheidend dafür war, dass /*der Name des Ordners hinzugefügt wurde .

Ich habe Git 1.9


3
Nein, es lädt immer noch alles herunter, alle Commits und alle Dateien, Git 2.3.2
Tyguy7

6
Sparsame Kassen betreffen nur den Arbeitsbaum. Sie haben keinen Einfluss auf die Größe des Repositorys oder darauf, was abgerufen wird. Sie benötigen verschiedene Optionen, wenn Sie das möchten.
Miral

Probieren Sie Git Bash Shell das nächste Mal aus, wenn Sie unter Windows arbeiten und die obigen Schritte von 'pbetkier' ausführen. Es funktioniert einwandfrei
einwandfrei

6

Ja, es ist möglich, einen Ordner herunterzuladen, anstatt das gesamte Repository herunterzuladen. Sogar irgendein / letztes Commit

Gute Möglichkeit, dies zu tun

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
  1. -r HEAD lädt nur die letzte Revision herunter, ignoriert den gesamten Verlauf.

  2. Beachten Sie den Trunk und / bestimmten Ordner

Kopieren und ändern Sie die URL vorher und nachher /trunk/. Ich hoffe das hilft jemandem. Genießen :)

Aktualisiert am 26. September 2019


gilt nur für diejenigen, die von svn kommen oder svn verwenden. Ich werde diesen nicht positiv bewerten.
C Johnson

@CJohnson Wie Sie sehen können, klone ich Git Repo Ordner. Funktioniert gut
Qamar

1
Beachten Sie, dass dies kein Standardangebot von Git ist, sondern etwas, das Git Hub neben dem regulären Git-Angebot anbietet. Es funktioniert jedoch wunderbar, wenn Sie es verwenden können. Vielen Dank!
Qix - MONICA wurde

1
Von den unzähligen Vorschlägen zu SO ist Ihr Vorschlag die präziseste und klarste.
Boardrider

4

git 2.9 (Juni 2016) verallgemeinert die --no-checkoutOption auf git worktree add(den Befehl, der es ermöglicht, mit mehreren Arbeitsbäumen für ein Repo zu arbeiten )

Siehe Commit ef2a0ac (29. März 2016) von Ray Zhang ( OneRaynyDay) .
Unterstützt von: Eric Sunshine ( sunshineco) und Junio ​​C Hamano ( gitster) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 0d8683c , 13. April 2016)

Die git worktreeManpage enthält jetzt:

--[no-]checkout:

Standardmäßig addKontrollen <branch>jedoch --no-checkoutkönnen zur Unterdrückung der Kasse , um verwendet werden , um Anpassungen, wie zum Beispiel der Konfiguration spärlich-Kasse .


4

Schritte zum spärlichen Auschecken nur bestimmter Ordner:

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]

Zu Ihrer Information, im ersten (1) Schritt müssen Sie --no-checkout nicht verwenden. Klonen Sie einfach das gesamte Repo und führen Sie dann alle folgenden Schritte 2-5 (oben erwähnt) aus. Sie erhalten die gewünschte Ausgabe. Lassen Sie mich wissen, wenn Sie es nicht verstanden haben.
SANDEEP MACHIRAJU

4

Basierend auf dieser Antwort von apenwarr und diesem Kommentar von Miral habe ich die folgende Lösung gefunden, mit der ich beim lokalen Klonen des Linux-Git-Repositorys fast 94% des Speicherplatzes gespart habe, während nur ein Dokumentations-Unterverzeichnis benötigt wurde:

$ 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    .

Also bin ich von 2,9 GB auf 182 MB runtergekommen, was schon ganz nett ist.

Ich habe dies jedoch nicht zum Laufen gebracht git clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-test( hier angedeutet ), da dann alle fehlenden Dateien als entfernte Dateien zum Index hinzugefügt wurden. Wenn also jemand das Äquivalent von git clone --filter=blob:nonefor kennt git fetch, können wir wahrscheinlich noch ein paar Megabyte sparen. (Das Lesen der Manpage von git-rev-listweist auch darauf hin, dass es so etwas gibt --filter=sparse:path=…, aber ich habe das auch nicht zum Laufen gebracht.

(Alle haben es mit Git 2.20.1 von Debian Buster versucht.)


1
Interessantes Feedback. Upvoted. Das weiß ich auch nicht --filter=sparse:path=….
VonC

3

Ich bin neu in Git, aber es scheint, dass es funktioniert, wenn ich Git-Checkout für jedes Verzeichnis mache. Außerdem muss die Sparse-Checkout-Datei nach jedem Verzeichnis wie angegeben einen abschließenden Schrägstrich enthalten. Jemand mehr Erfahrung bitte bestätigen, dass dies funktionieren wird.

Interessanterweise scheint es keinen Unterschied zu machen, wenn Sie ein Verzeichnis auschecken, das sich nicht in der Sparse-Checkout-Datei befindet. Sie werden nicht im Git-Status angezeigt und der Git-Lesebaum -m -u HEAD bewirkt nicht, dass er entfernt wird. git reset --hard bewirkt auch nicht, dass das Verzeichnis entfernt wird. Hat jemand mehr Erfahrung damit, zu kommentieren, was Git von Verzeichnissen hält, die ausgecheckt sind, aber nicht in der spärlichen Checkout-Datei enthalten sind?


0

In meinem Fall möchte ich den PodsOrdner beim Klonen des Projekts überspringen . Ich habe Schritt für Schritt wie unten und es funktioniert für mich. Ich hoffe es hilft.

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

Anmerkung: Wenn Sie mehr Ordner überspringen möchten, fügen Sie einfach mehr Zeilen in die Sparse-Checkout-Datei ein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.