Wofür würde ich git-worktree verwenden?

210

Ich habe Githubs Beitrag über Git-Worktree gelesen . Sie schreiben:

Angenommen, Sie arbeiten in einem Git-Repository in einem Zweig namens " feature, wenn ein Benutzer einen Fehler mit hoher Dringlichkeit meldet master." Zuerst erstellen Sie einen verknüpften Arbeitsbaum mit einem neuen Zweig, der hotfixrelativ zum Master ausgecheckt ist. […] Sie können den Fehler beheben, einen Hotfix drücken und eine Pull-Anforderung erstellen.

Wenn ich an einem Zweig namens "Feature" arbeite und ein Fehler mit hoher Dringlichkeit im Master gemeldet wird, verstecke ich normalerweise alles, woran ich arbeite, und erstelle einen neuen Zweig. Wenn ich fertig bin, kann ich weiterarbeiten. Dies ist ein sehr einfaches Modell, ich arbeite seit Jahren so.

Auf der anderen Seite hat die Verwendung von git-worktree seine eigenen Einschränkungen:

Beispielsweise darf nicht derselbe Zweig gleichzeitig in zwei verknüpften Arbeitsbäumen ausgecheckt werden, da dadurch Änderungen an einem Arbeitsbaum vorgenommen werden können, um den anderen Zweig nicht mehr synchron zu halten.

Warum sollte ich für ein bereits gelöstes Problem einen komplizierteren Workflow wählen?

Gibt es etwas git-worktree, das nicht im Voraus getan werden konnte und das diese ganz neue, komplexe Funktion rechtfertigt?

awendt
quelle
12
Eine Sache, die Sie nicht verstauen können, sind nicht zusammengeführte Pfade nach einer Zusammenführung oder einer erneuten Basis mit Konflikten.
Chirlu
11
Wenn Sie mit kompilierten Sprachen arbeiten, bedeutet Stashing, dass Sie beim Entstapeln alles neu kompilieren müssen.
mb14
Wir haben mehrere verschiedene Produkte, die auf demselben Quellcode (300 MB) basieren, und ich plane, sie alle in einem großen Repo zu kombinieren und mithilfe des Arbeitsbaums jedes Produkt in einem anderen Ordner auszuchecken, anstatt eine Menge riesiger Produkte zu haben Klone, die nicht synchron bleiben
Endolith

Antworten:

195

Git Worktree ist für mich die größte Verbesserung seit langer Zeit. Ich arbeite in der Entwicklung von Unternehmenssoftware. Dort ist es sehr häufig, dass Sie alte Versionen beibehalten müssen, wie Sie sie vor 3 Jahren veröffentlicht haben. Natürlich haben Sie für jede Version einen Zweig, damit Sie einfach darauf wechseln und einen Fehler beheben können. Das Wechseln ist jedoch teuer, da Sie in der Zwischenzeit das Repository vollständig umstrukturiert und möglicherweise ein System erstellt haben. Wenn Sie wechseln, wird Ihre IDE verrückt und versucht, die Projekteinstellungen anzupassen.

Mit worktree können Sie diese ständige Neukonfiguration vermeiden. Überprüfen Sie diese alten Zweige mithilfe von Arbeitsbaum in separaten Ordnern. Für jeden Zweig haben Sie ein unabhängiges IDE-Projekt.

Natürlich hätte dies in der Vergangenheit durch mehrmaliges Klonen des Repos geschehen können, und dies war bisher mein Ansatz. Dies bedeutete jedoch auch, Platz auf der Festplatte zu verschwenden und noch schlimmer, die gleichen Änderungen mehrmals aus dem Repo abzurufen.

Sebi
quelle
4
Sie mussten nicht mehrmals dieselben Änderungen aus dem Repo abrufen. Sie hätten einfach das .git-Verzeichnis des ersten Klons kopieren können.
misiu_mp
1
@ jdk1.0 Entschuldigung für die Verwirrung, der Kommentar war an misiu_mp gerichtet
mxttie
2
Als jemand, der 2-3 hochreplizierte Repos verwendet hat, damit ich einen Feature-Zweig erstellen kann, während ich auf einem anderen entwickle, hatte ich jedes lokale Repo als Fernbedienung der anderen und stimme voll und ganz mit Sebis Charakterisierungen der Nachteile überein (viel Abrufen und Schieben! ) Sobald ich zu Arbeitsbaum wechsle, muss ich mir keine Sorgen mehr machen, dass lokale, gleichnamige Zweige auseinander gehen (was etwa alle 6-10 Monate passiert, wenn ich über einen Zeitraum von Tagen mehrmals unterbrochen werde und am Ende bin Arbeiten Sie den gleichen Feature-Zweig aus mehreren Repos heraus, aber vergessen Sie, sie wieder zu synchronisieren ...)
Salbei
3
@iheanyi - (1). Es ist schneller, wenn die IDE externe Datendateien (z. B. Indizierungsdatenbanken) verwaltet, die einem bestimmten Verzeichnis zugeordnet sind. Wenn Sie den Inhalt im selben Verzeichnis verprügeln, werden in der Regel alle IDE-Datencaches ungültig und müssen neu indiziert werden.
Steve Hollasch
5
@iheanyi - (2) Mit der Zeit wird der Verlauf von allem zu einem bestimmten Zeitpunkt viel größer als die Arbeitsbaumdateien. Die Geschichte von allem == das .gitVerzeichnis. Mit vielen lokalen Klonen aus dem Upstream haben Sie viele lokale Kopien derselben Datenbank, da jeder Klon eine eigene .gitDatenbank hat. Bei vielen lokalen Arbeitsbäumen verwendet jeder Baum dieselbe .gitDatenbank. Ja, wenn Sie lokale Klone Ihres lokalen Arbeitsbaums haben, verknüpft Git viele der .git-Inhalte fest, jedoch nicht unter Windows.
Steve Hollasch
70

Ich kann einige Verwendungszwecke dafür sehen.

Wenn Sie eine Testsuite haben, die lange läuft, stellen Sie sich Stunden vor, und Sie starten sie. Sie blockiert diese Arbeitskopie effektiv, bis die Tests abgeschlossen sind. Das Wechseln der Zweige während dieser Tests würde sie auf eine Weise zerstören, die schwer zu verstehen wäre.

Mit git-worktreekönnte ich also eine zweite Idee für eine andere Niederlassung haben, die dort arbeitet.

Wenn ich zu einem anderen Zweig wechsle, um eine schnelle Untersuchung durchzuführen, glaubt meine IDE, dass sich viele Dateien plötzlich geändert haben, und indiziert alle diese Änderungen, nur um sie beim Zurückschalten erneut indizieren zu müssen.

Ein dritter Anwendungsfall wäre der Dateivergleich mit anderen Tools als git-diffnormal diffzwischen zwei Verzeichnissen, wenn zwei Zweige vorhanden sind.

Andreas Wederbrand
quelle
6
Würde das nicht git clonefür alle gut funktionieren?
Bis zum
12
Das Klonen eines großen Repositorys von der Fernbedienung kann jedoch lange dauern. Ich arbeite gegen ein Repository, dessen Klonen einige Minuten dauert. Ich denke, dass du es damit machen könntest git clone --reference. Die Verwaltung aller anderen Zweige erfolgt nur einmal statt einmal pro Arbeitsverzeichnis.
Andreas Wederbrand
6
Klonen Sie nicht von der Fernbedienung, sondern von Ihrer lokalen. Ich verstehe das Problem der Filialverwaltung nicht. Können Sie das klären?
Bis zum
14
Ich habe versucht, Klone zu verwenden, und es gibt wirklich ein Verwaltungsproblem. Anstelle eines einzelnen Satzes von Zweigen habe ich einen Satz von Klonen, die ich nicht alle zusammen in einer einzigen Benutzeroberfläche sehen kann. Wenn ich einige Änderungen auswählen muss, muss ich sie abrufen oder herumschieben. Es fügt allen Aktionen zusätzliche Schritte hinzu. Alles ist machbar, aber es gibt immer etwas Reibung.
max630
2
Und wenn es darum geht, ein Backup einzurichten, ist ein einzelnes Repository viel einfacher.
max630
64

Eine naheliegende Verwendung besteht darin, gleichzeitig das Verhalten (nicht die Quelle) verschiedener Versionen zu vergleichen - beispielsweise verschiedene Versionen einer Website oder nur einer Webseite.

Ich habe das vor Ort ausprobiert.

  • Erstellen Sie ein Verzeichnis page1.

  • innerhalb erstellen Sie das Verzeichnis srcund git inites.

  • in srcerstellenpage1.html mit ein wenig Inhalt und festschreiben.

  • $ git branch ver0

  • $ git worktree add ../V0 ver0

  • Fügen Sie im srcMaster mehr Text hinzu page1.htmlund schreiben Sie ihn fest.

  • $ git branch sty1

  • bearbeiten page1.html in der sty1Verzweigung (fügen Sie einen bestimmten CSS-Stil hinzu) und fügen Sie Commit hinzu.

  • $ git worktree add ../S1 sty1

Sie können jetzt einen Webbrowser verwenden, um diese drei Versionen gleichzeitig zu öffnen und anzuzeigen:

  • ..\page1\src\page1.html // was auch immer git als aktuell hat

  • ..\page1\V0\page1.html // die ursprüngliche Version

  • ..\page1\S1\page1.html // die experimentell gestaltete Version

RodMcGuire
quelle
2
Ich verstehe nicht, wie dies den Vorteil der Verwendung von Arbeitsbaum für diesen Zweck gegenüber einem Klon erklärt.
Iheanyi
@iheanyi Man könnte das gleiche über sagen branch; Die Antwort ist auch die gleiche: Es ist leichter und für den Job gebaut.
OJFord
1
@OJFord das ist irgendwie der Punkt. Diese Antwort erklärt mir nicht, was der Arbeitsbaum anders macht. Es ist offensichtlich kein Alias ​​für Zweig oder Klon, aber der Effekt, den ich hier sehe, scheint der gleiche zu sein. Ich sehe nicht, dass dies leichter ist als nur die Verwendung von Zweig oder Klon.
Iheanyi
@iheanyi Es ist anders als die Verwendung von Verzweigungen - Sie können Verzweigungen nicht alleine verwenden, um mehrere Arbeitsbaumzustände gleichzeitig zu erhalten - und leichter als ein zweiter (.., n-ter) Klon. Was ich damit meinte war, dass man auch von Zweig sagen kann: "Warum nicht einfach klonen und Änderungen vornehmen?", Aber mehrere Zweige in einem einzigen Repo sind leichter und einfacher zu handhaben, um dieses Verhalten zu erreichen.
OJFord
@OJFord Ich glaube nicht, dass dies meine Verwechslung mit dem Arbeitsbaum löst. Lassen Sie es mich so sagen, egal ob Sie Branch oder Clone oder etwas anderes verwenden. Das Endziel des hier beschriebenen Prozesses besteht darin, drei verschiedene Versionen von etwas gleichzeitig zu vergleichen. Aufgrund der Antwort verstehe ich nicht, warum ich Arbeitsbaum anstelle einer Alternative verwenden würde. Die Antwort erklärt nicht, was der Arbeitsbaum tut, was Alternativen nicht tun. Sie behaupten, etwas sei leicht (oder leichter), aber ich sehe nicht, wie der Arbeitsbaum die Zweige weniger "schwer" macht.
Iheanyi
29
  1. Es gibt legitime Gründe, warum Sie möglicherweise mehrere Arbeitsbäume gleichzeitig im Dateisystem haben möchten / müssen.

    • Bearbeiten der ausgecheckten Dateien, während Änderungen an einer anderen Stelle vorgenommen werden müssen (z. B. Kompilieren / Testen)

    • Differenzieren der Dateien über normale Diff-Tools

    • Während Zusammenführungskonflikten möchte ich häufig durch den Quellcode navigieren, da er sich auf der Quellseite befindet, während Konflikte in den Dateien gelöst werden.

    • Wenn Sie häufig hin und her wechseln müssen, wird Zeit für das Auschecken und erneute Auschecken verschwendet, sodass Sie nicht mit mehreren Arbeitsbäumen arbeiten müssen.

    • Die mentalen Kosten des mentalen Kontextwechsels zwischen Zweigen durch Git-Stashing sind nicht wirklich messbar. Einige Leute stellen fest, dass das Verstecken mentale Kosten verursacht, die nicht vorhanden sind, indem sie einfach Dateien aus einem anderen Verzeichnis öffnen.

  2. Einige Leute fragen "warum nicht mehrere lokale Klone machen". Es ist richtig, dass Sie sich mit dem Flag "--local" keine Gedanken über die zusätzliche Nutzung des Speicherplatzes machen müssen. Dies (oder ähnliche Ideen) habe ich bis jetzt getan. Funktionale Vorteile verknüpfter Arbeitsbäume gegenüber lokalen Klonen sind:

    1. Bei lokalen Klonen haben Ihre zusätzlichen Arbeitsbäume (die sich in den lokalen Klonen befinden) einfach keinen Zugriff auf den Ursprung oder die vorgelagerten Zweige. Der 'Ursprung' im Klon ist nicht der gleiche wie der 'Ursprung' im ersten Klon.

      • Laufen git log @{u}..oder git diff origin/feature/other-featurekann sehr hilfreich sein und diese sind entweder nicht mehr möglich oder schwieriger. Diese Ideen sind mit lokalen Klonen über eine Reihe von Workarouns technisch möglich, aber jede Workaround, die Sie durchführen können, wird durch verknüpfte Arbeitsbäume besser und / oder einfacher.
    2. Sie können Refs zwischen Arbeitsbäumen teilen. Wenn Sie Änderungen von einer anderen lokalen Niederlassung vergleichen oder ausleihen möchten, können Sie dies jetzt tun.

Alexander Bird
quelle
11
Sie können auch alle Arbeitsbäume mit einem einzigen Befehl auflisten. Mit Klonen müssen Sie diese selbst verfolgen.
Ian Ringrose
hmm. Ab Git 2.7.0 scheint dies der Fall zu sein. Gut zu wissen.
Alexander Bird
9

tl; dr: Jedes Mal, wenn Sie aus irgendeinem Grund zwei Arbeitsbäume gleichzeitig auschecken lassen möchten, git-worktreeist dies eine schnelle und platzsparende Möglichkeit.

Wenn Sie einen anderen Arbeitsbaum erstellen, werden die meisten Teile des Repos (dh .git) gemeinsam genutzt. Wenn Sie also einen Zweig erstellen oder Daten abrufen, während Sie sich in einem Arbeitsbaum befinden, können Sie auch von anderen Arbeitsbäumen darauf zugreifen. Angenommen, Sie möchten Ihre Testsuite auf Branch Foo ausführen, ohne sie irgendwohin verschieben zu müssen, um sie zu klonen, und Sie möchten den Aufwand vermeiden, Ihr Repo lokal zu klonen. Dies git-worktreeist eine gute Möglichkeit, nur eine neue Kasse eines bestimmten Status in einem zu erstellen vorübergehender Ort, entweder vorübergehend oder dauerhaft. Genau wie bei einem Klon müssen Sie ihn nur löschen, wenn Sie damit fertig sind, und der Verweis darauf wird nach einiger Zeit durch Müll gesammelt.

jsageryd
quelle
2
Ärzte sagen, dass Sie nicht in beiden Arbeitskopien denselben Zweig haben können, was eine schwerwiegende Einschränkung darstellt. Mit Mercurial funktionierte es nur mit kleinen Problemen.
Hypersw
Sicher kannst du. Die Manpage sagt wie; suche nach --force. Es ist jedoch unpraktisch, wenn Sie den Zweig an einer Stelle aktualisieren und damit rechnen, an einer anderen Stelle daran zu arbeiten, da der Arbeitsbaum nicht aktualisiert wird.
jsageryd
Ja, Filialen in Mercurial sind in dieser Hinsicht ein transparenteres Konzept. Wie erscheinen Zweige von einem Arbeitsbaum im anderen? Gleich wie bei mehreren Uplinks? Meine ersten Experimente mit Arbeitsbäumen, bei denen Fetch in beiden ausgeführt wurde, endeten mit zwei (!) Unterschiedlichen (!) Zeigern origin/master.
Hypersw
Ein Arbeitsbaum ist (wie der Name schon sagt) nur ein Arbeitsbaum mit einigen zusätzlichen Funktionen. Das Repository wird von allen Arbeitsbäumen gemeinsam genutzt. Der einzige Unterschied zwischen zwei Arbeitsbäumen besteht darin, dass der ausgecheckte Zweig unterschiedlich sein kann (und für gesunde Workflows unterschiedlich ist). Es ist möglich, in einem separaten Arbeitsbaum festzuschreiben, daher verfügt es auch über einen eigenen Index (auch als Staging-Bereich bezeichnet), damit dies funktioniert. Die .gitDatei im separaten Arbeitsbaum ist eine Textdatei, die den Pfad zu ihrer Konfiguration enthält, die sich im ursprünglichen Repository befindet.
jsageryd
2
@ WilsonF: git checkout --ignore-other-worktrees <branch> git-scm.com/docs/git-checkout/…
jsageryd
7

Ich bin ursprünglich auf diese Frage gestoßen, nachdem ich mich gefragt hatte, wofür diese ausgefallenen Arbeitsbäume verwendet werden könnten. Seitdem habe ich sie in meinen Workflow integriert und finde sie trotz meiner anfänglichen Skepsis sehr nützlich.

Ich arbeite an einer ziemlich großen Codebasis, deren Kompilierung einige Zeit in Anspruch nimmt. Normalerweise habe ich den aktuellen Entwicklungszweig auf meinem Computer zusammen mit dem Feature-Zweig, an dem ich gerade arbeite, sowie dem Hauptzweig, der den aktuellen Status des Live-Systems darstellt.

Einer der größten Vorteile für mich ist natürlich, dass ich nicht jedes Mal, wenn ich die Zweige wechsle (dh Arbeitsbäume), das Ganze neu kompilieren muss. Ein netter Nebeneffekt ist, dass ich zum Entwicklungs-Arbeitsbaum gehen, dort Dinge erledigen, das Verzeichnis für meinen aktuellen Feature-Zweig in den Arbeitsbaum ändern und ihn dann neu starten kann, ohne vorher ziehen zu müssen.

rethab
quelle
4

Ich habe eine ziemlich ungewöhnliche: Ich mache Windows- und Linux-Entwicklung auf demselben Computer . Ich habe eine VirtualBox unter Linux in meiner Windows-Box. Die VirtualBox stellt einige Windows-Verzeichnisse bereit und verwendet sie direkt im Linux-Computer. Auf diese Weise kann ich Windows zum Verwalten von Dateien verwenden, aber unter Linux erstellen. Dies ist ein plattformübergreifendes Projekt, das sowohl auf Windows als auch auf Linux aus derselben Verzeichnisstruktur aufbaut.

Das Problem ist, dass die Linux- und Windows-Build-Systeme bei Verwendung im selben Verzeichnis ineinander stoßen. Es gibt einige komplizierte Erstellungsschritte zum Herunterladen von Bibliotheken usw., die dieselben Verzeichnisnamen verwenden. Die Windows-Version des Build-Systems lädt die Windows-spezifischen Bibliotheken herunter, und die Linux-Version des Build-Systems lädt die Linux-spezifischen Bibliotheken herunter.

In einer idealen Welt würde das Build-System so modifiziert, dass Windows und Linux innerhalb des Verzeichnisses nebeneinander existieren können. Derzeit wird das Problem jedoch mit Arbeitsbäumen behoben. Der Ordner "Linux" kann Linux-spezifische Build-Artefakte generieren, und der Ordner "Windows" kann Windows-spezifische Build-Artefakte generieren. Dies ist zwar kaum eine ideale Lösung, bietet jedoch eine gute Lücke, während darauf gewartet wird, dass die Fehler im Build-System behoben werden.

Zugegeben, der Arbeitsbaum war nicht dafür ausgelegt; Ich muss die Windows-Version und die Linux-Version in getrennten Zweigen aufbewahren, obwohl ich es wirklich vorziehen würde, wenn sie sich in demselben Zweig befinden. Trotzdem macht es den Job und ist ein etwas unkonventioneller Fall von Arbeitsbaum, der den Tag rettet.

AHelps
quelle
+1 Dies scheint eine sehr effektive Problemumgehung zu sein, damit Make keine Konfigurationsausgabeverzeichnisse pro Konfiguration erstellt. Ich habe ein ähnliches VMware Workstation-Setup mit Ubuntu- und MacOS-Gästen.
Tanz87
1

In einem neuen Projekt für mich habe ich eine Funktion erstellt. Einige Spezifikationen sind jedoch fehlgeschlagen. Um die Ergebnisse mit zu vergleichen, habe masterich ein work-treeRepo erstellt. Ich habe die Ergebnisse Schritt für Schritt im Ausführungscode verglichen, bis ich verstanden habe, was schief gelaufen ist.

itsnikolay
quelle
Wie macht ein Arbeitsbaum dies jedoch einfacher als ein Klon? Die Frage fragt nicht nach persönlichen Vorlieben, sondern nach konkreten Unterschieden.
Unsichtbarer
1

Ich benutze git worktreefür die Entwicklung des maschinellen Lernens.

Ich habe einen Hauptfunktionscode und möchte dann Zweige verschiedener Experimente (verschiedene Algorithmen und verschiedene Hyperparameter) aufteilen. git worktreeermöglicht es mir, dvc neben verschiedenen Versionen meines Codes zu integrieren, die auf verschiedene Algorithmen spezialisiert sind. Nachdem ich alle Schulungsjobs ausgeführt habe, bewerte ich die endgültigen Metriken und füge sie zusammen, um den besten Zweig / das beste Modell zu meistern.

Ricardo MS
quelle