Git 2.5 schlägt seit Juli 2015 einen Ersatz für contrib/workdir/git-new-workdir
: git worktree vor
Siehe Commit 68a2e6a von Junio C Hamano ( gitster
) .
In der Pressemitteilung wird Folgendes erwähnt :
Ein Ersatz dafür contrib/workdir/git-new-workdir
beruht nicht auf symbolischen Verknüpfungen und macht das Teilen von Objekten und Refs sicherer, indem der Kreditnehmer und die Kreditnehmer aufeinander aufmerksam gemacht werden.
Siehe Commit 799767cc9 (Git 2.5rc2)
Das heißt, Sie können jetzt einegit worktree add <path> [<branch>]
Erstellen <path>
und auschecken <branch>
. Das neue Arbeitsverzeichnis ist mit dem aktuellen Repository verknüpft und teilt alles außer arbeitsverzeichnisspezifischen Dateien wie HEAD, Index usw. Der git worktree
Abschnitt fügt hinzu:
Ein Git-Repository kann mehrere Arbeitsbäume unterstützen , sodass Sie mehr als einen Zweig gleichzeitig auschecken können .
Mit git worktree add
wird dem Repository ein neuer Arbeitsbaum zugeordnet.
Dieser neue Arbeitsbaum wird als "verknüpfter Arbeitsbaum" bezeichnet, im Gegensatz zum "Hauptarbeitsbaum", der von " git init
" oder " git clone
" erstellt wurde .
Ein Repository hat einen Hauptarbeitsbaum (wenn es kein nacktes Repository ist) und null oder mehr verknüpfte Arbeitsbäume.
Einzelheiten:
Jeder verknüpfte Arbeitsbaum verfügt über ein privates Unterverzeichnis im Verzeichnis des Repositorys
$GIT_DIR/worktrees
.
Der Name des privaten Unterverzeichnisses ist normalerweise der Basisname des Pfads des verknüpften Arbeitsbaums, möglicherweise mit einer Nummer versehen, um ihn eindeutig zu machen.
Zum Beispiel, wenn $GIT_DIR=/path/main/.git
der Befehl git worktree add /path/other/test-next next
Folgendes erstellt:
- der verknüpfte Arbeitsbaum in
/path/other/test-next
und
- erstellt auch ein
$GIT_DIR/worktrees/test-next
Verzeichnis (oder $GIT_DIR/worktrees/test-next1
wenn test-next
bereits vergeben).
Innerhalb eines verknüpften Arbeitsbaums:
$GIT_DIR
ist so eingestellt, dass es auf dieses private Verzeichnis verweist (z. B. /path/main/.git/worktrees/test-next
im Beispiel) und
$GIT_COMMON_DIR
ist so eingestellt, dass es zurück auf den Hauptarbeitsbaum zeigt $GIT_DIR
(z /path/main/.git
. B. ).
Diese Einstellungen werden in einer .git
Datei vorgenommen, die sich im obersten Verzeichnis des verknüpften Arbeitsbaums befindet.
Wenn Sie mit einem verknüpften Arbeitsbaum fertig sind, können Sie ihn einfach löschen.
Die Verwaltungsdateien des Arbeitsbaums im Repository werden schließlich automatisch entfernt (siehe gc.pruneworktreesexpire
in git config
), oder Sie können sie git worktree prune
im Hauptbaum oder in einem verknüpften Arbeitsbaum ausführen , um veraltete Verwaltungsdateien zu bereinigen.
Warnung: Es gibt noch einen Abschnitt git worktree
"BUGS" , den Sie beachten müssen.
Die Unterstützung für Submodule ist unvollständig .
Es wird NICHT empfohlen, ein Superprojekt mehrfach auszuchecken.
Hinweis: mit git 2.7rc1 (Nov 2015) Sie sind in der Lage Liste Ihre worktrees.
Sehen Sie verpflichten bb9c03b , begehen 92718b7 , begehen 5.193.490 , begehen 1ceb7f9 , begehen 1ceb7f9 , begehen 5.193.490 , begehen 1ceb7f9 , begehen 1ceb7f9 (8. Oktober 2015), begehen 92718b7 , begehen 5.193.490 , begehen 1ceb7f9 , begehen 1ceb7f9 (8. Oktober 2015), verpflichten 5.193.490 , Commit 1ceb7f9 (08. Oktober 2015), Commit 1ceb7f9 (08. Oktober 2015) festschreiben und ac6c561 festschreiben(02. Oktober 2015) von Michael Rappazzo ( rappazzo
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit a46dcfb , 26. Oktober 2015)
worktree
: list
Befehl ' ' hinzufügen
' git worktree list
' durchläuft die Arbeitsbaumliste und gibt Details des Arbeitsbaums aus, einschließlich des Pfads zum Arbeitsbaum, der aktuell ausgecheckten Revision und Verzweigung und ob der Arbeitsbaum leer ist.
$ git worktree list
/path/to/bare-source (bare)
/path/to/linked-worktree abcd1234 [master]
/path/to/other-linked-worktree 1234abc (detached HEAD)
Es gibt auch eine Porzellanformatoption.
Das Porzellanformat hat eine Linie pro Attribut.
- Attribute werden mit einer Bezeichnung und einem Wert aufgelistet, die durch ein einzelnes Leerzeichen getrennt sind.
- Boolesche Attribute (wie "nackt" und "getrennt") werden nur als Bezeichnung aufgeführt und sind nur dann vorhanden, wenn der Wert wahr ist.
- Eine leere Zeile zeigt das Ende eines Arbeitsbaums an
Zum Beispiel:
$ git worktree list --porcelain
worktree /path/to/bare-source
bare
worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master
worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached
Hinweis: Wenn Sie einen Arbeitsbaumordner verschieben, müssen Sie den manuell aktualisierengitdir
Datei .
Siehe Commit 618244e (22. Januar 2016) und Commit d4cddd6 (18. Januar 2016) von Nguyễn Thái Ngọc Duy ( pclouds
) .
Mit freundlicher Unterstützung von Eric Sunshine ( sunshineco
) .
(Zusammengeführt von Junio C Hamano -gitster
- in Commit d0a1cbc , 10. Februar 2016)
Das neue Dokument in Git 2.8 (März 2016) enthält:
Wenn Sie einen verknüpften Arbeitsbaum verschieben, müssen Sie die gitdir
Datei ' ' im Verzeichnis des Eintrags aktualisieren .
Wenn beispielsweise ein verknüpfter Arbeitsbaum verschoben wird /newpath/test-next
und seine .git
Datei auf zeigt /path/main/.git/worktrees/test-next
, aktualisieren Sie
stattdessen /path/main/.git/worktrees/test-next/gitdir
auf Referenz /newpath/test-next
.
Seien Sie vorsichtig beim Löschen eines Zweigs: Vor Git 2.9 (Juni 2016) können Sie einen in einem anderen Arbeitsbaum verwendeten löschen .
Wenn die Funktion " git worktree
" verwendet wird, " git branch -d
" konnte ein Zweig gelöscht werden, der in einem anderen Arbeitsbaum ausgecheckt ist.
Siehe Commit f292244 (29. März 2016) von Kazuki Yamaguchi ( rhenium
) .
Geholfen von: Eric Sunshine ( sunshineco
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 4fca4e3 , 13. April 2016)
branch -d
: das Löschen eines aktuell ausgecheckten Zweigs ablehnen
Wenn ein Zweig vom aktuellen Arbeitsbaum ausgecheckt wird, ist das Löschen des Zweigs verboten.
Wenn der Zweig jedoch nur von anderen Arbeitsbäumen ausgecheckt wird, ist das Löschen falsch erfolgreich.
Verwenden Sie find_shared_symref()
diese Option , um zu überprüfen, ob der Zweig verwendet wird, und nicht nur, um ihn mit dem HEAD des aktuellen Arbeitsbaums zu vergleichen.
In ähnlicher Weise wurde vor Git 2.9 (Juni 2016) beim Umbenennen eines in einem anderen Arbeitsbaum ausgecheckten Zweigs der symbolische KOPF in diesem anderen Arbeitsbaum nicht angepasst.
Siehe Commit 18eb3a9 (08. April 2016) und Commit 70999e9 , Commit 2233066 (27. März 2016) von Kazuki Yamaguchi ( rhenium
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 741a694 , 18. April 2016)
branch -m
: Aktualisieren Sie alle Arbeitsbaumköpfe
Beim Umbenennen eines Zweigs wird derzeit nur der KOPF des aktuellen Arbeitsbaums aktualisiert, es müssen jedoch die KÖPFE aller Arbeitsbäume aktualisiert werden, die auf den alten Zweig verweisen.
Dies ist das aktuelle Verhalten. Der Pfad von / path / to / wt wird nicht aktualisiert:
% git worktree list
/path/to 2c3c5f2 [master]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m master master2
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m oldname newname
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 0000000 [oldname]
Dieser Patch behebt dieses Problem, indem alle relevanten Arbeitsbaumköpfe beim Umbenennen eines Zweigs aktualisiert werden.
Der Verriegelungsmechanismus wird offiziell mit Git 2.10 (Q3 2016) unterstützt.
Siehe Commit 080739b , Commit 6d30862 , Commit 58142c0 , Commit 346ef53 , Commit 346ef53 , Commit 58142c0 , Commit 346ef53 , Commit 346ef53 (13. Juni 2016) und Commit 984ad9e , Commit 6835314 (03. Juni 2016) von Nguyễn Thái Ngọc Duy ( pclouds
) .
Vorgeschlagen von: Eric Sunshine ( sunshineco
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 2c608e0 , 28. Juli 2016)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
Wenn ein verknüpfter Arbeitsbaum auf einem tragbaren Gerät oder einer Netzwerkfreigabe gespeichert ist, die nicht immer bereitgestellt ist, können Sie verhindern, dass die Verwaltungsdateien gelöscht werden, indem Sie die ausgeben git worktree lock
Befehl und optional angeben--reason
, warum der Arbeitsbaum gesperrt ist.
<worktree>
: Wenn die letzten Pfadkomponenten im Pfad des Arbeitsbaums unter den Arbeitsbäumen eindeutig sind, können damit Arbeitsbäume identifiziert werden.
Zum Beispiel, wenn Sie nur Bäume bei " /abc/def/ghi
" und " bearbeiten müssen./abc/def/ggg
" , dann " ghi
" oder "def/ghi
" aus, um auf den früheren Arbeitsbaum zu verweisen.
Git 2.13 (Q2 2017) fügt eine lock
Option in Commit 507e6e9 (12. April 2017) von Nguyễn Thái Ngọc Duy ( pclouds
) hinzu .
Vorgeschlagen von: David Taylor ( dt
) .
Mit freundlicher Unterstützung von Jeff King ( peff
) .
(Zusammengeführt von Junio C Hamano -gitster
- in Commit e311597 , 26. April 2017)
Ermöglichen Sie das Sperren eines Arbeitsbaums unmittelbar nach seiner Erstellung.
Dies hilft, ein Rennen zwischen "git worktree add; git worktree lock
" und " git worktree prune
" zu verhindern.
So git worktree add' --lock
ist das Äquivalent vongit worktree lock
nach git worktree add
, aber ohne Rennbedingung.
Git 2.17+ (Q2 2018) fügt hinzu git worktree move
/ git worktree remove
: siehe diese Antwort .
Git 2.19 (Q3 2018) füge ein "--quiet
" Option hinzu "git worktree add
" weniger ausführlich .
Siehe Commit 371979c (15. August 2018) von Elia Pinto ( devzero2000
) .
Unterstützt von: Martin Ågren, Duy Nguyen ( pclouds
) und Eric Sunshine ( sunshineco
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit a988ce9 , 27. August 2018)
worktree
: hinzufügen --quiet
Option
Fügen Sie wie bei den anderen Befehlen --quiet
die Option ' ' hinzu .
' ' ist der einzige Befehl, der davon betroffen ist, da alle anderen Befehle außer 'git worktree
git
add
list
' derzeit standardmäßig stumm geschaltet sind.
Beachten Sie, dass " git worktree add
" verwendet wurde, um "einen verfügbaren Namen mit stat und dann zu finden mkdir
", was rassenanfällig ist.
Dies wurde mit Git 2.22 (Q2 2019) durch Verwendung mkdir
und Reaktion auf behobenEEXIST
in einer Schleife .
Siehe Commit 7af01f2 (20. Februar 2019) von Michal Suchanek ( hramrach
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 20fe798 , 09. April 2019)
worktree
: beheben worktree add
Rennen
Git führt eine stat-Schleife aus, um einen verfügbaren Arbeitsbaumnamen zu finden, und führt dann mkdir
den gefundenen Namen aus.
Drehen Sie es in eine mkdir
Schleife, um einen erneuten Aufruf von worktree add zu vermeiden. Fügen Sie denselben freien Namen hinzu und erstellen Sie zuerst das Verzeichnis.
Git 2.22 (Q2 2019) korrigiert die Logik, um festzustellen, ob ein Git-Repository über einen funktionierenden Baum verfügt. "git branch -D
" vor dem Entfernen des Zweigs , der derzeit versehentlich ausgecheckt wurde.
Die Implementierung dieser Logik wurde für Repositorys mit ungewöhnlichem Namen unterbrochen, was heutzutage leider die Norm für Submodule ist.
Siehe Commit f3534c9 (19. April 2019) von Jonathan Tan ( jhowtan
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit ec2642a , 08. Mai 2019)
Code Pull-Anfragen 178 Einblicke
worktree
: Update is_bare
Heuristiken
Wenn " git branch -D <name>
" ausgeführt wird, prüft Git normalerweise zuerst, ob dieser Zweig gerade ausgecheckt ist.
Diese Überprüfung wird jedoch nicht durchgeführt, wenn sich das Git-Verzeichnis dieses Repositorys nicht auf " <repo>/.git
" befindet. Dies ist der Fall, wenn dieses Repository ein Submodul ist, dessen Git-Verzeichnis beispielsweise als " super/.git/modules/<repo>
" gespeichert ist .
Dies führt dazu, dass der Zweig gelöscht wird, obwohl er ausgecheckt ist.
Dies liegt daran, dass get_main_worktree()
in worktree.c
Sets is_bare
auf einem Arbeitsbaum nur unter Verwendung der Heuristik ein Repo leer ist, wenn der Pfad des Arbeitsbaums nicht mit " /.git
" endet , und ansonsten nicht nackt.
Dieser is_bare
Code wurde in 92718b7 (" worktree
: Details zur Arbeitsbaumstruktur hinzufügen", 08.10.2015, Git v2.7.0-rc0) nach einer pre-core.bare
Heuristik eingeführt.
Dieser Patch macht zwei Dinge:
- Teach
get_main_worktree()
verwenden is_bare_repository()
stattdessen in eingeführt 7d1864c ( "Einführung is_bare_repository () und core.bare Konfigurationsvariable", 2007-01-07, Git v1.5.0-rc1) und aktualisiert in e90fdc3 ( "Clean up Arbeit Baum Handhabung", 2007 -08-01, Git v1.5.3-rc4).
Dies löst das git branch -D <name>
oben beschriebene Problem.
Jedoch ... Wenn ein Repository core.bare=1
nur den git
Befehl " " hat , der von einem seiner sekundären Arbeitsbäume ausgeführt wird, wird is_bare_repository()
false zurückgegeben (was in Ordnung ist, da ein Arbeitsbaum verfügbar ist).
Und die Behandlung des Hauptarbeitsbaums als nicht nackt, wenn er nackt ist, verursacht Probleme:
Beispiel: Fehler beim Löschen eines Zweigs aus einem sekundären Arbeitsbaum, auf den der HEAD eines Hauptarbeitsbaums verweist, selbst wenn dieser Hauptarbeitsbaum leer ist.
Um dies zu vermeiden, überprüfen Sie dies auch core.bare
bei der Einstellung is_bare
.
Wenn core.bare=1
, vertrauen Sie ihm und verwenden Sie ihn anderweitig is_bare_repository()
.
git-new-workdir
wird durchgit checkout --to=<path>
in Git 2.5 ersetzt. Siehe meine Antwort unten