git worktree: jak mieć jednocześnie kilka wersji roboczych?

Wersją roboczą nazywam pliki na którymi pracujemy, to te gotowe do zmiany.

Zmiana gałęzi, zmiana HEAD naszego repozytorium powoduje również zmianę wersji roboczej. Zazwyczaj ta zmiana jest bardzo szybka, ponieważ git jest bardzo szybki, ale… im większe repozytorium i większe zmiany między wersjami, to czas potrzebny na przełączanie rośnie.

Czasochłoność przełączania powiększy także IDE, bo zmiana plików projektowych pociągnie za sobą ekran konieczności przeładowania solucji. W projektach z milionem linii, może być to bolesny proces.

A może proces budowy programu zmienił się na przestrzeni czasu?

Mając równolegle dwie różne wersje naszego repozytorium może być bardzo przydatne.

Myślisz sobie: „Znam rozwiązanie tego problemu! Użyję git clone!”. Jest to jakieś rozwiązanie, ale jest lepsze.

Jak to zrobić?

Przedstawiam wam git worktree. Jeżeli myślisz, że masz wiele lat doświadczenia z gitem a nie znasz tego to podpowiem, że ta komenda jest dostępna od wersji 2.5. W chwili pisania tego posta jest dostępna wersja 2.15.1.

Wyobraź sobie taki scenariusz, piszesz THE FEATURE. Jesteś blisko jego skończenia, ale dzwoni na Skype SZEF i mówi, że jest BUG do zrobienia na ASAP. Zrobienia BUGA zajmie tobie 5 minut, ale przełączenie na master zajmie tobie 15 minut. Trzeba improwizować.

Wykonanie takiej komendy w katalogu głównym naszego repozytorium

git worktree add -b hotfix ../hotfix origin/master

Powoduje kilka czyności naraz

  • -b hotfix – utworzenie nowej gałęzi o nazwie hotfix
  • ../hotfix – w katalogu sąsiednim do naszego repozytorium o nazwie hotfix
  • origin/master – na podstawie gałęzi origin/master

Następnie robisz zmiany w katalogu hotfix, a potem push do origina, wystawiasz pull requesta, idziesz na kawę. Wracasz, kod przeszedł code review, i możesz katalog hotfix usunąć. Tyle.

W repozytorium głównym zostaje zapis o podlinkowanym katalogu, ale ta informacja zostanie usunięta, gdy gitowy Garbage Collector zostanie uruchomiony lub po uruchomieniu komendy git worktree prune.

git nie pozwoli, aby dwie takie same gałęzie były obsługiwane przez dwie oddzielne kopie robocze. Takie użycie prowadziłoby do bardzo ciężki konfliktów synchronizacyjnych.

Dlaczego git clone jest gorszy?

  • Potrzeba sieci, aby sklonować (ściągnięcie dużego repozytorium zajmuje czas, chcemy go oszczędzać)
  • Trzeba bawić się z wieloma parametrami, aby pociągnąć tylko co trzeba

Źródła: