Wiele katalogów roboczych z Git?

242

Nie jestem pewien, czy jest to wspierane przez Git, ale teoretycznie wydaje mi się, że powinno to działać.

Mój przepływ pracy często obejmuje edycję plików w wielu gałęziach jednocześnie. Innymi słowy, często chcę otworzyć kilka plików w jednym oddziale podczas edycji zawartości innego pliku w innym oddziale.

Moim typowym rozwiązaniem tego jest dokonanie dwóch transakcji, ale szkoda, że ​​nie mogę udostępniać gałęzi i referencji między nimi. Chciałbym mieć tylko dwa katalogi robocze zarządzane przez ten sam folder .git.

Zdaję sobie sprawę z lokalnych rozwiązań klonowania git (domyślnie jest to hardlink udostępnionych obiektów oraz opcja --shared, która konfiguruje alternatywny magazyn obiektów z oryginalnym repo), ale rozwiązania te ograniczają tylko wykorzystanie miejsca na dysku , a zwłaszcza w przypadku opcji - share, wydają się być pełne niebezpieczeństw.

Czy istnieje sposób na użycie jednego folderu .git i utworzenie kopii zapasowej dwóch działających katalogów? A może Git jest na stałe zapisany w jednym katalogu roboczym w dowolnym momencie?

jtolds
źródło
1
git-new-workdirzostanie zastąpiony przez git checkout --to=<path>w Git 2.5. Zobacz moją odpowiedź poniżej
VonC
3
Właściwie to polecenie to git worktree add <path> [<branch>](Git 2.5 rc2). Zobacz moją zredagowaną odpowiedź poniżej
VonC
powinieneś zmienić zaakceptowaną odpowiedź Odpowiedź VonC, ponieważ rzeczy się zmieniły od czasu, kiedy pierwotnie zadałeś pytanie.
xaxxon
dzięki za zaktualizowaną odpowiedź!
jtolds

Odpowiedzi:

293

Git 2.5 proponuje od lipca 2015 r. Zamiennik contrib/workdir/git-new-workdir: git worktree

Zobacz commit 68a2e6a przez Junio ​​C Hamano ( gitster) .

Informacja o wersji wspomina :

Zamiennik dla contrib/workdir/git-new-workdir tego nie opiera się na symbolicznych linkach i sprawia, że ​​dzielenie się przedmiotami i referencjami jest bezpieczniejsze poprzez uświadomienie sobie pożyczkobiorcy i pożyczkobiorców.

Zobacz zatwierdzenie 799767cc9 (Git 2.5rc2)

Oznacza to, że teraz możesz zrobićgit worktree add <path> [<branch>]

Utwórz <path>i <branch>do kasy . Nowy katalog roboczy jest połączony z bieżącym repozytorium, współużytkując wszystko oprócz plików specyficznych dla katalogu roboczego, takich jak HEAD, indeks itp. git worktreeSekcja dodaje:

Repozytorium git może obsługiwać wiele działających drzew , umożliwiając sprawdzenie więcej niż jednej gałęzi na raz.
Z git worktree add, nowe działające drzewo jest powiązane z repozytorium.

To nowe drzewo robocze jest nazywane „połączonym drzewem roboczym” w przeciwieństwie do „głównego drzewa roboczego” przygotowanego przez „ git init” lub „ git clone .
Repozytorium ma jedno główne drzewo robocze (jeśli nie jest to samo repozytorium) i zero lub więcej powiązanych drzew roboczych.

Detale:

Każde połączone drzewo robocze ma prywatny podkatalog w katalogu repozytorium $GIT_DIR/worktrees.
Nazwa prywatnego podkatalogu jest zwykle podstawową nazwą ścieżki połączonego drzewa roboczego, ewentualnie uzupełnioną liczbą, aby uczynić go unikalnym.
Na przykład, gdy $GIT_DIR=/path/main/.gitpolecenie git worktree add /path/other/test-next nexttworzy:

  • połączone drzewo robocze w /path/other/test-next i
  • tworzy również $GIT_DIR/worktrees/test-nextkatalog (lub $GIT_DIR/worktrees/test-next1jeśli test-nextjest już zajęty).

W połączonym drzewie roboczym:

  • $GIT_DIRjest ustawiony tak, aby wskazywał na ten prywatny katalog (np. /path/main/.git/worktrees/test-nextw przykładzie) i
  • $GIT_COMMON_DIRjest ustawiony tak, aby wskazywał z powrotem na główne drzewo robocze $GIT_DIR(np /path/main/.git.).

Te ustawienia są wprowadzone w .git pliku znajdującym się w górnym katalogu połączonego drzewa roboczego.

Po zakończeniu pracy z połączonym działającym drzewem możesz je po prostu usunąć.
Pliki administracyjne drzewa roboczego w repozytorium zostaną ostatecznie automatycznie usunięte (patrz gc.pruneworktreesexpirew git config) lub można uruchomić git worktree prunew głównym lub dowolnym połączonym drzewie roboczym, aby usunąć wszelkie przestarzałe pliki administracyjne.


Ostrzeżenie: nadal istnieje sekcja git worktree„BŁĘDY”, o której należy pamiętać.

Obsługa podmodułów jest niepełna .
NIE zaleca się dokonywania wielu transakcji w superprojekcie.


Uwaga: dzięki git 2.7rc1 (listopad 2015) możesz wyświetlić swoje listy robocze.
Zobacz popełnić bb9c03b , popełnić 92718b7 , popełnić 5193490 , popełnić 1ceb7f9 , popełnić 1ceb7f9 , popełnić 5193490 , popełnić 1ceb7f9 , popełnić 1ceb7f9 (08 paź 2015), popełnić 92718b7 , popełnić 5193490 , popełnić 1ceb7f9 , popełnić 1ceb7f9 (08 paź 2015), popełnić 5193490 , zatwierdzić 1ceb7f9 (08 października 2015), zatwierdzić 1ceb7f9 (08 października 2015) i zatwierdzić ac6c561(02 października 2015) autor:Michael Rappazzo ( rappazzo) .
(Połączone przez Junio ​​C Hamano - gitster- in commit a46dcfb , 26 października 2015)

worktree: dodaj listpolecenie „ ”

' git worktree list' dokonuje iteracji przez listę drzewa roboczego i wyświetla szczegółowe informacje o nim, w tym ścieżkę do niego, aktualnie sprawdzoną wersję i gałąź oraz jeśli drzewo pracy jest puste.

$ git worktree list
/path/to/bare-source            (bare)
/path/to/linked-worktree        abcd1234 [master]
/path/to/other-linked-worktree  1234abc  (detached HEAD)

Dostępna jest również opcja formatu porcelany.

Format porcelany ma wiersz na atrybut.

  • Atrybuty są wymienione wraz z etykietą i wartością oddzieloną pojedynczą spacją.
  • Atrybuty logiczne (takie jak „goły” i „odłączony”) są wymienione tylko jako etykieta i są obecne tylko wtedy i tylko wtedy, gdy wartość jest prawdziwa.
  • Pusta linia wskazuje koniec drzewa roboczego

Na przykład:

$ 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

Uwaga: jeśli PRZESUŃ folder folderu roboczego, musisz ręcznie zaktualizować gitdirplik.

Zobacz commit 618244e (22 stycznia 2016 r.) I commit d4cddd6 (18 stycznia 2016 r.) Autor: Nguyễn Thái Ngọc Duy ( pclouds) .
Pomógł: Eric Sunshine ( sunshineco) .
(Połączone przez Junio ​​C Hamano - gitster- w commit d0a1cbc , 10 lutego 2016)

Nowy dokument w git 2.8 (marzec 2016) będzie zawierać:

Jeśli przeniesiesz połączone drzewo robocze, musisz zaktualizować gitdirplik „ ” w katalogu pozycji.
Na przykład, jeśli połączone drzewo robocze zostanie przeniesione do, /newpath/test-nexta jego .gitplik wskazuje /path/main/.git/worktrees/test-next, należy zaktualizować, /path/main/.git/worktrees/test-next/gitdiraby odwołać się do /newpath/test-nextniego.


Zachowaj ostrożność podczas usuwania gałęzi: przed git 2.9 (czerwiec 2016 r.) Możesz usunąć jedną używaną w innym działającym drzewie.

Gdy git worktreeużywana jest funkcja „ git branch -d”, dozwolone jest „ ” usunięcie gałęzi, która jest wyewidencjonowana w innym drzewie roboczym.

Zobacz commit f292244 (29 marca 2016) autor: Kazuki Yamaguchi ( rhenium) .
Pomógł: Eric Sunshine ( sunshineco) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 4fca4e3 , 13 kwietnia 2016)

branch -d: odmowa usunięcia oddziału, który jest obecnie wyewidencjonowany

Kiedy gałąź jest wyewidencjonowana przez bieżące działające drzewo, usuwanie gałęzi jest zabronione.
Jednak gdy gałąź jest wyewidencjonowana tylko przez inne działające drzewa, niepoprawne usunięcie kończy się powodzeniem.
Służy find_shared_symref()do sprawdzania, czy gałąź jest w użyciu, a nie tylko do porównywania z HEAD bieżącego drzewa roboczego.


Podobnie przed wersją 2.9 (czerwiec 2016 r.) Zmiana nazwy oddziału wyewidencjonowanego w innym drzewie roboczym nie zmieniła symbolicznej HEAD we wspomnianym innym drzewie roboczym.

Zobacz zatwierdzenie 18eb3a9 (08 kwietnia 2016) i zatwierdzenie 70999e9 , zatwierdzenie 2233066 (27 marca 2016) przez Kazuki Yamaguchi ( rhenium) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 741a694 , 18 kwietnia 2016)

branch -m: zaktualizuj wszystkie HEADs dla poszczególnych stanowisk roboczych

Podczas zmiany nazwy gałęzi obecnie aktualizowany jest tylko HEAD bieżącego drzewa roboczego, ale musi aktualizować HEAD wszystkich pracujących drzew, które wskazują na starą gałąź.

To jest obecne zachowanie, HEAD / path / to / wt's HEAD nie jest aktualizowany:

  % 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]

Ta poprawka rozwiązuje ten problem, aktualizując wszystkie odpowiednie HEAD z drzewa roboczego podczas zmiany nazwy gałęzi.


Mechanizm blokujący jest oficjalnie obsługiwany przez git 2.10 (III kwartał 2016)

Zobacz zatwierdzenie 080739b , zatwierdzenie 6d30862 , zatwierdzenie 58142c0 , zatwierdzenie 346ef53 , zatwierdzenie 346ef53 , zatwierdzenie 58142c0 , zatwierdzenie 346ef53 , zatwierdzenie 346ef53 (13 czerwca 2016 r.) I zatwierdzenie 984ad9e , zatwierdzenie 6835314 (03 czerwca 2016 r.) Autor: Nguyễn Thái Ngọc Duy ( pclouds) .
Sugerowane przez: Eric Sunshine ( sunshineco) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 2c608e0 , 28 lipca 2016)

git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>

Jeśli połączone drzewo robocze jest przechowywane na urządzeniu przenośnym lub udziale sieciowym, który nie zawsze jest zamontowany, można zapobiec przycinaniu jego plików administracyjnych, wydając git worktree lockpolecenie, opcjonalnie określając, --reasondlaczego drzewo robocze jest zablokowane.

<worktree>: Jeśli ostatnie komponenty ścieżki na ścieżce drzewa roboczego są unikalne wśród drzew roboczych, można ich użyć do identyfikacji drzew roboczych.
Na przykład, jeśli musisz pracować tylko z drzewami „ /abc/def/ghi” i „ /abc/def/ggg”, wówczas „ ghi” lub „ def/ghi” wystarczy, aby wskazać poprzednie działające drzewo.


Git 2.13 (Q2 2017) dodaje lockopcję w zatwierdzeniu 507e6e9 (12 kwietnia 2017 r.) Autor: Nguyễn Thái Ngọc Duy ( pclouds) .
Sugerowane przez: David Taylor ( dt) .
Pomoc: Jeff King ( peff) .
(Połączone przez Junio ​​C Hamano - gitster- w commit e311597 , 26 kwietnia 2017)

Pozwól zablokować drzewo robocze natychmiast po jego utworzeniu.
Pomaga to zapobiec wyścigowi między „ git worktree add; git worktree lock” i „ git worktree prune”.

Podobnie git worktree add' --lock jest git worktree lockpo git worktree add, ale bez warunków wyścigu.


Git 2.17+ (Q2 2018) dodaje git worktree move/ git worktree remove: zobacz tę odpowiedź .


Git 2.19 (III kwartał 2018 r.) Dodaje --quietopcję „ git worktree add”, dzięki której „ ” jest mniej gadatliwy.

Zobacz commit 371979c (15 sierpnia 2018) autor: Elia Pinto ( devzero2000) .
Pomagają: Martin Ågren, Duy Nguyen ( pclouds) i Eric Sunshine ( sunshineco) .
(Połączone przez Junio ​​C Hamano - gitster- w commit a988ce9 , 27 sierpnia 2018)

worktree: dodaj --quietopcję

Dodaj --quietopcję „ ” do git worktree, tak jak w przypadku innych gitpoleceń.
add” to jedyne polecenie, którego dotyczy, ponieważ wszystkie inne polecenia, z wyjątkiem „ list”, są obecnie domyślnie ciche.


Zauważ, że „ git worktree add” kiedyś „znajdował dostępną nazwę ze stat, a następnie mkdir”, która jest podatna na rasę.
Zostało to naprawione w Git 2.22 (Q2 2019) przy użyciu mkdiri reakcji EEXISTw pętli.

Zobacz commit 7af01f2 (20 lutego 2019) autorstwa Michała Suchanka ( hramrach) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 20fe798 , 09 kwi 2019)

worktree: napraw worktree addwyścig

Git uruchamia pętlę statystyk, aby znaleźć nazwę drzewa roboczego, która jest dostępna, a następnie wyszukuje nazwę mkdirznalezioną.
Zamień go w mkdirpętlę, aby uniknąć kolejnej inwokacji dodawania drzewa roboczego, znajdując tę ​​samą wolną nazwę i tworząc najpierw katalog.


Git 2.22 (drugi kwartał 2019 r.) Naprawia logikę, aby stwierdzić, czy repozytorium Git ma działające drzewo, chroni git branch -Dprzed usunięciem gałęzi, która jest obecnie wypisana przez pomyłkę.
Implementacja tej logiki została zepsuta dla repozytoriów o nietypowej nazwie, co niestety jest obecnie normą dla podmodułów.

Zobacz zatwierdzenie f3534c9 (19 kwietnia 2019 r.) Autor: Jonathan Tan ( jhowtan) .
(Połączone przez Junio ​​C Hamano - gitster- w commit ec2642a , 08 maja 2019)

Code Pull wymaga 178 wglądów

worktree: aktualizacja is_bareheurystyki

Po git branch -D <name>uruchomieniu „ ” Git zwykle najpierw sprawdza, czy gałąź jest obecnie wyewidencjonowana.
Ale ta kontrola nie jest przeprowadzana, jeśli katalog Git tego repozytorium nie znajduje się w „ <repo>/.git”, co ma miejsce, jeśli to repozytorium jest podmodułem, którego katalog Git jest zapisany super/.git/modules/<repo>na przykład jako „ ”.
Powoduje to usunięcie gałęzi, nawet jeśli jest ona wyewidencjonowana.

Wynika to z tego, że get_main_worktree()w worktree.czestawach is_barew środowisku roboczym wykorzystujących heurystykę repo jest nagie, jeśli ścieżka nie kończy się na „ /.git”, a nie inaczej.
Ten is_barekod został wprowadzony w 92718b7 („ worktree: dodaj szczegóły do ​​struktury drzewa roboczego”, 08.10.2015, Git v2.7.0-rc0), zgodnie z pre-core.bareheurystyką.

Ta łatka robi 2 rzeczy:

  • Naucz get_main_worktree()się używać is_bare_repository()zamiast tego wprowadzono 7d1864c ( "Przedstaw is_bare_repository () i zmienna konfiguracja core.bare", 2007-01-07, Git v1.5.0-rc1) i zaktualizowane w e90fdc3 ( "Clean up obchodzenia praca drzewa", 2007 -08-01, Git v1.5.3-rc4).
    Rozwiązuje to git branch -D <name>problem opisany powyżej.

Jednak ... Jeśli repozytorium ma, core.bare=1ale gitpolecenie jest uruchamiane z jednego z drugorzędnych drzew roboczych, is_bare_repository()zwraca false (co jest w porządku, ponieważ jest dostępne drzewko robocze).

I traktowanie głównego stołu roboczego jako nieogołego, gdy jest goły, powoduje problemy:

Na przykład brak usunięcia gałęzi z pomocniczego drzewa roboczego, do którego odwołuje się HEAD głównego drzewa roboczego, nawet jeśli ten główny stół roboczy jest pusty.

Aby tego uniknąć, sprawdź także core.barepodczas ustawiania is_bare.
Jeśli core.bare=1zaufaj, a w przeciwnym razie użyj is_bare_repository().

VonC
źródło
1
To jest najfajniejsza rzecz, którą stworzyli, właśnie tego szukałem. Dziękuję za to!
Jak usunąć tylko działające drzewo i nadal utrzymywać gałąź
Randeep Singh,
@DotnetRocks możesz usunąć dowolne działające drzewo (folder lokalny na twoim komputerze): nie będzie to miało żadnego wpływu na gałąź: główne repozytorium .git nadal będzie zawierać pełną zatwierdzoną historię ze wszystkimi jej gałęziami, niezależnie od tego, czy drzewo robocze zostało usunięte.
VonC
Tak, ale jeśli po prostu usuniesz działające drzewo, przechodząc do tego folderu w moim systemie i usuniesz go, git nie pozwala mi na dokonanie płatności do tej gałęzi i mówi, że już kasuje na <ścieżka> (<ścieżka> ścieżka drzewa roboczego). Ale wygląda na to, że jeśli wykonam następujące polecenia: rm -rf <ścieżka> git worktree prune, to zadziała. Czy to prawda?
Randeep Singh,
1
@Jayan Dziękuję. Wyjaśniłem, że 2.5 i 2.7 są już dostępne.
VonC
113

gitDystrybucja przychodzi z pomocą przyczyniła skrypt o nazwie git-new-workdir. Użyłbyś tego w następujący sposób:

git-new-workdir project-dir new-workdir branch

gdzie katalog-projektu to nazwa katalogu zawierającego twoje .gitrepozytorium. Skrypty tworzą kolejny .gitkatalog z wieloma dowiązaniami symbolicznymi do oryginalnego, z wyjątkiem plików, których nie można udostępnić (jak bieżąca gałąź), umożliwiając pracę w dwóch różnych gałęziach.

Brzmi to trochę krucho, ale jest to opcja.

adl
źródło
3
+1 Poprawiłem się, to jest niesamowite. Wydaje się, że natychmiast dzieli historię i gałęzie między dwoma różnymi sprawdzonymi repozytoriami bez pchania / ciągnięcia, tylko symlinkowanie. Byłem zupełnie nieświadomy, że git sobie z tym poradzi. Niestety, nie ma go w mojej dystrybucji.
meagar
2
Dla tych, którzy używają msysgit (Windows), możesz użyć tej wersji skryptu: github.com/joero74/git-new-workdir
amos
9
Zwykle działa dobrze, ale jeśli przypadkowo edytowałeś ten sam oddział w różnych lokalizacjach, nie jest to łatwe do naprawienia.
grep,
Dla tych, którzy utknęli na Git <2.5 i którzy mają submoduły, spróbuj, git-new-workdir-recursivektóry jest opakowaniem git-new-workdir.
Walf
13

Natknąłem się na to pytanie, mając nadzieję na rozwiązanie, którego tutaj nie znalazłem. Więc teraz, że ja nie znaleźć to, co potrzebne, postanowiłem opublikować go tutaj dla innych.

Uwaga: Prawdopodobnie nie jest to dobre rozwiązanie, jeśli musisz edytować wiele gałęzi jednocześnie, np. Stany OP. Jest za posiadające wiele oddziałów wyrejestrowany jednocześnie, że nie zamierza edytować. (Wiele katalogów roboczych wspieranych przez jeden folder .git.)

Nauczyłem się kilku rzeczy, odkąd po raz pierwszy zadałem to pytanie:

  1. Co to jest „ nagie repozytorium ”. Jest to zasadniczo zawartość .gitkatalogu, nie będąc zlokalizowanym w działającym drzewie.

  2. Fakt, że możesz określić lokalizację używanego repozytorium (lokalizację katalogu .git) w wierszu polecenia z gitopcją--git-dir=

  3. Fakt, że możesz określić lokalizację swojej kopii roboczej za pomocą --work-tree=

  4. Co to jest „repozytorium lustrzane”.

To ostatnie jest dość ważnym rozróżnieniem. Tak naprawdę nie chcę pracować z repozytorium, muszę tylko mieć jednocześnie kopie różnych gałęzi i / lub tagów. W rzeczywistości muszę zagwarantować, że gałęzie nie będą się różnić od gałęzi mojego pilota. Zatem lustro jest dla mnie idealne.

Więc w moim przypadku użycia dostałem to, czego potrzebowałem, robiąc:

git clone --mirror <remoteurl> <localgitdir> # Where localgitdir doesn't exist yet
mkdir firstcopy
mkdir secondcopy
git --git-dir=<localgitdir> --work-tree=firstcopy checkout -f branch1
git --git-dir=<localgitdir> --work-tree=secondcopy checkout -f branch2

Największym zastrzeżeniem jest to, że nie ma osobnego HEAD dla dwóch kopii. Po powyższym, uruchomienie git --git-dir=<localgitdir> --work-tree=firstcopy statuspokaże wszystkie różnice między gałęzią 2 i gałęzią 1 jako niezatwierdzone zmiany - ponieważ HEAD wskazuje na gałąź 2. (Dlatego używam tej -fopcji checkout, ponieważ tak naprawdę nie planuję żadnych lokalnych zmian. Mogę pobrać dowolny tag lub gałąź dla dowolnego drzewa roboczego, o ile korzystam z tej -fopcji).

W moim przypadku, gdy na tym samym komputerze istnieje wiele kas, bez konieczności ich edycji , działa to doskonale. Nie wiem, czy jest jakiś sposób na posiadanie wielu HEAD dla wielu drzew roboczych bez skryptu, takiego jak ten, który jest opisany w innych odpowiedziach, ale mam nadzieję, że i tak jest to pomocne dla kogoś innego.

Dzika karta
źródło
Właśnie tego szukałem, ale nie mogę sprawić, by zadziałało ... Robię się fatalny: nie repozytorium git: „<localgitdir>” ”. Jakieś pomysły?
Dan R
Nieważne, okazuje się, że użyłem „~” w nazwie mojego katalogu, a gitowi się to nie podobało. Kiedy użyłem pełnej ścieżki, zadziałało dobrze.
Dan R
@ DanR, cieszę się, że pomogło. :) Możesz także użyć $HOME. Jest jeszcze jedno zastrzeżenie dotyczące powyższej metody, którą odkryłem później, która dotyczy plików, które nie istnieją w tej czy innej gałęzi. Jeśli wyewidencjonujesz A do katalogu 1, następnie wyewidencjonujesz B do katalogu 2, a następnie wymusisz pobranie C do katalogu 1, jeśli istnieje plik, który istnieje w A, ale nie w B lub C, plik nie zostanie usunięty z katalogu 1 nawet przez wymuszenie pobrania . git cleanW takim przypadku możesz więc poeksperymentować - lub zrobić to, co zrobiłem i po prostu użyj tej metody do zapełnienia świeżo utworzonego katalogu.
Wildcard,
Dzięki za wskazówkę. W każdym razie zamierzam zapakować to jako część narzędzia CLI w ruby, więc upewnię się, że zawsze zaczyna się od zera.
Dan R
@ DanR, może zainteresować Cię kod, który wtedy pisałem . Większość z nich ogólnie dotyczy dowolnego skryptu pomostowego git, z wyjątkiem kontroli składni CFEngine. (Być może możesz to zastąpić sprawdzeniami składni Ruby.) :)
Wildcard
3

Jedyne rozwiązanie, jakie mogę wymyślić, to sklonowanie dwóch katalogów i dodanie ich jako zdalnych repozytoriów. Możesz następnie wyciągać rzeczy ze zmienionego jednego do drugiego bez faktycznego wypychania czegokolwiek do zdalnego repozytorium.

Zakładam, że chcesz mieć dwa działające katalogi, a nie dwa klony pilota, ponieważ nie chcesz wypychać niektórych gałęzi do pilota. W przeciwnym razie dwa klony twojego pilota będą działały dobrze - wystarczy wykonać kilka popchnięć i pociągnięć, aby wszystkie trzy były zsynchronizowane.

vhallac
źródło
Cześć. Facet powyżej udostępnił fajne rozwiązanie, polecenie git worktree . Działa ładniej niż klonowanie kilka razy tego samego repozytorium. Wypróbuj, spodoba ci się ta nowa funkcja.