Teilklon mit Git und Mercurial

74

Ist es möglich, nur einen Zweig (oder einen bestimmten Commit) in Git und Mercurial zu klonen? Ich meine, ich möchte ein zentrales Repo klonen, aber da es riesig ist, möchte ich nur einen Teil davon bekommen und trotzdem in der Lage sein, meine Änderungen zurückzugeben. Ist es möglich? Ich möchte nur ab Tag 130 oder so?

Wenn das so ist, wie?

Pablo
quelle
1
Siehe auch Git 2.17 Partial Clone (oder "Narrow Clone") stackoverflow.com/a/48852630/6309
VonC

Antworten:

76

In Git Land sprechen Sie über drei verschiedene Arten von Teilklonen:

  • flache Klone: Ich möchte die Geschichte ab Revisionspunkt X.

    Verwenden Sie diesgit clone --depth <n> <url> , aber bitte denken Sie daran, dass flache Klone bei der Interaktion mit anderen Repositorys etwas eingeschränkt sind. Sie können Patches generieren und per E-Mail senden.

  • Teilklon nach Dateipfad: Ich möchte den gesamten Revisionsverlauf in einem Verzeichnis haben/path.

    In Git nicht möglich . Mit modernem Git können Sie zwar nur spärlich auschecken , dh Sie haben den gesamten Verlauf, aber Sie checken (nur im Arbeitsbereich) nur eine Teilmenge aller Dateien aus.

  • Nur ausgewählten Zweig klonen : Ich möchte nur einen Zweig (oder eine ausgewählte Teilmenge von Zweigen) klonen.

    Möglich und

    vor git 1.7.10 nicht einfach: Sie müssten tun , was Klon manuell tut, das heißt git init [<directory>], dann git remote add origin <url>, bearbeiten .git/configersetzen *in remote.origin.fetch(wahrscheinlich ‚Master‘) von angeforderten Zweig, dann git fetch.

    Ab Git 1.7.10 git clone gibt es die --single-branchOption, die anscheinend nur für diesen Zweck hinzugefügt wurde und ziemlich einfach zu sein scheint.

    Beachten Sie jedoch, dass der Gewinn durch das Klonen nur einer Teilmenge von Zweigen möglicherweise geringer ist, als Sie denken, da Zweige normalerweise den größten Teil ihres Verlaufs gemeinsam haben.

Sie können auch einen flachen Klon nur einer ausgewählten Teilmenge von Zweigen erstellen.

Wenn Sie wissen, wie Benutzer die Dinge nach Dateipfad aufteilen möchten (mehrere Projekte im selben Repository), können Sie das Repo mithilfe von Submodulen (ähnlich wie svn: externals) in separat klonbare Teile aufteilen.

Jakub Narębski
quelle
Wenn ich also den Zweig "XX" klone, werden alle übergeordneten Commits von "master" abgerufen, oder? Oder nur das einzelne Commit, das ich für diesen Zweig gemacht habe?
Pablo
1
Wenn Sie nur den Zweig "XX" klonen (abrufen), erhalten Sie alle seine Commits, einschließlich der Commits, die der Zweig "XX" mit dem Zweig "master" gemeinsam hat. In Git Commits nicht ‚ gehört ‘ zu einem Zweig.
Jakub Narębski
Ok, dann ist es sowieso kein Teilklon, da Sie alle Eltern und damit die gesamten Repos bekommen (ok, der größte Teil, der auf Master ist)
Pablo
1
In 1.8.0 (oder etwas früher) Herstellung einzelnen Zweig Klon ist jetzt viel einfacher.
Jakub Narębski
1
Sie können dieser Liste mit Git 2.17 (Q2 2018) " Teilklon
VonC
51

Im Quecksilberland sprechen Sie von drei verschiedenen Arten von Teilklonen:

  • flache Klone: ​​Ich möchte, dass der Verlauf ab Revisionspunkt X die Remotefilelog-Erweiterung verwendet
  • Teilklone nach Dateipfad: Ich möchte den gesamten Revisionsverlauf in Verzeichnis / Pfad mit der Erweiterung " Experimental Narrowhg" oder nur Dateien in Verzeichnis / Pfad in meinem Arbeitsverzeichnis mit der Erweiterung "Experiment Sparse" (ausgeliefert seit Version 4.3, siehe hg help sparse).
  • Teilklone nach Zweig: Ich möchte den gesamten Revisionsverlauf für Zweig Y: Verwenden Sie Klon -r

Wenn Sie wissen, wie die Leute die Dinge nach Dateipfad aufteilen möchten (mehrere Projekte im selben Repo (Schande über Sie)), können Sie Unterrepositorys (ähnlich wie svn externals) verwenden, um das Repo in separat klonbare Teile aufzuteilen

Auch in Bezug auf das "so groß, dass ich nur einen Teil davon bekommen möchte": Das muss man wirklich nur einmal tun. Klonen Sie es einfach, während Sie zu Mittag essen, und dann haben Sie es für immer mehr. Anschließend können pullSie Deltas effizient in Zukunft erhalten. Und wenn Sie einen weiteren Klon davon möchten, klonen Sie einfach Ihren ersten Klon. Wo Sie einen Klon haben, spielt keine Rolle (und lokale Klone belegen keinen zusätzlichen Speicherplatz, da es sich um feste Links unter der Decke handelt).

Ry4an Brase
quelle
1
Auch Tags sind im Gegensatz zu einigen VCS nicht mit Zweigen identisch, daher fällt dies unter den ersten Punkt
jk.
Es gibt die Trimmverlaufs- Plugins ( mercurial.selenic.com/wiki/TrimmingHistory ) und die Plugins für flache Klone ( mercurial.selenic.com/wiki/ShallowClone ) für mercurial. Ich weiß allerdings nicht, wie gut sie sind.
Panzi
8
Beides sind abgelehnte Vorschläge ohne Umsetzung.
Ry4an Brase
4
* Flache Klone sind jetzt mit 'remotefilelog' möglich: bitbucket.org/facebook/remotefilelog * Teilklone nach Dateipfad sind möglich (aber immer noch experimentell), siehe Kommentare.gmane.org/gmane.comp.version-control.mercurial.devel/ …
Mathiasdm
1
Anfang 2017: Teilklone nach Dateipfad (auch bekannt als schmaler Klon) befinden sich noch nicht in Mercurial, sind jedoch mit einer Erweiterung von Google möglich - bitbucket.org/Google/narrowhg . Ähnlich spärliches Auschecken (auch bekannt als schmales Auschecken) ist nicht in Mercurial enthalten, sondern ist mit der sparse.pyMercurial-Erweiterung von Facebook möglich - bitbucket.org/facebook/hg-experimental .
Anon
9

Die ausgewählte Antwort bietet einen guten Überblick, es fehlt jedoch ein vollständiges Beispiel.

Minimieren Sie Ihren Download- und Checkout-Footprint (a) , (b) :

git clone --no-checkout --depth 1 --single-branch --branch (name) (repo) (folder)
cd (folder)
git config core.sparseCheckout true
echo "target/path/1" >>.git/info/sparse-checkout
echo "target/path/2" >>.git/info/sparse-checkout
git checkout

Optimieren Sie regelmäßig Ihren lokalen Repository-Footprint (c) (optional, mit Vorsicht verwenden):

git clean --dry-run # consider and tweak results then switch to --force
git gc
git repack -Ad
git prune

Siehe auch: Umgang mit großen Repositorys mit git

Brent Bradburn
quelle
5

Diese Methode erstellt ein nicht versioniertes Archiv ohne Unterrepositorys:

hg clone -U ssh://machine//directory/path/to/repo/project projecttemp

cd projecttemp

hg archive -r tip ../project-no-subrepos

Der nicht versionierte Quellcode ohne die Subrepositoies befindet sich im Verzeichnis project-no-subrepos

rossmic
quelle
2

In Bezug auf Git könnte es von historischer Bedeutung sein, dass Linus Torvalds diese Frage 2007 aus konzeptioneller Sicht in einem Vortrag beantwortete, der aufgezeichnet wurde und online verfügbar ist.

Die Frage ist, ob es möglich ist, nur einige Dateien aus einem Git-Repository auszuchecken.

Tech Talk: Linus Torvalds über Git t = 43: 10

Zusammenfassend sagte er, dass eine der Entwurfsentscheidungen von Git, die es von anderen Quellverwaltungssystemen unterscheidet (er zitiert BitKeeper und SVN), darin besteht, dass Git Inhalte und keine Dateien verwaltet. Die Implikationen sind, dass z. B. ein Diff einer Teilmenge von Dateien in zwei Revisionen berechnet wird, indem zuerst das gesamte Diff genommen und dann nur auf die angeforderten Dateien beschnitten wird. Ein weiterer Grund ist, dass Sie die gesamte Geschichte überprüfen müssen. alles oder nichts. Aus diesem Grund schlägt er vor, lose verwandte Komponenten auf mehrere Repositorys aufzuteilen, und erwähnt die laufenden Bemühungen, eine Benutzeroberfläche für die Verwaltung eines Repositorys zu implementieren, das als Superprojekt mit kleineren Repositorys strukturiert ist.

Soweit ich weiß, ist diese grundlegende Designentscheidung auch heute noch gültig. Das Superprojekt-Ding wurde wahrscheinlich zu dem, was jetzt Submodule sind .

user7610
quelle
1
Ich kenne den Beitrag ... Ich habe ihn ursprünglich bei slashdot eingereicht: P
pablo
-1

In mercurial sollten Sie in der Lage sein, einige davon zu verwenden, indem Sie:

hg convert --banchmap FILE SOURCEDEST REVMAP

Vielleicht möchten Sie auch:

--config convert.hg.startrev=REV

Die Quelle kann Git, Quecksilber oder eine Vielzahl anderer Systeme sein.

Ich habe es nicht ausprobiert, aber konvertieren ist ziemlich reich.

Dan Christian
quelle
4
Die Konvertierungserweiterung schreibt die Hashes neu, sodass dies kein Teilklon des vorhandenen Repos ist, sondern ein neuer. Dies bedeutet, dass es sich um ein separates Repository handelt, das nicht vom ursprünglichen Repository abgerufen oder verschoben werden kann.
Priit