Praca z Git i Perforce: przepływ pracy integracji
Scenariusz jest następujący: Twój zespół pracuje niezależnie na repozytorium Git, jednak część organizacji wciąż korzysta z Perforce do zarządzania fragmentami tej samej bazy kodu. Zespoły korzystające z Perforce nie planują migracji, ale Twój zespół przeszedł już na system Git (z wielu uzasadnionych powodów). Ważna jest zatem możliwość zachowania procesu dwukierunkowego udostępniania kodu między obiema bazami kodu, aby ulepszenia opracowane w dowolnej z wersji mogły być udostępniane, najlepiej bez ponoszenia zbyt dużych kosztów i obarczania zespołu ogromem pracy.
W tym miejscu do akcji wkracza nasz przewodnik. W TomTom taka operacja synchronizacji realizowana jest dla każdego nowego wydania, czyli w tym przypadku raz na sześć tygodni.
-- Ten post powstał we współpracy z Andreą Carlevato, Adolfo Bulfonim i Krzysztofem Karczewskim, którzy byli uprzejmi opowiedzieć o procesie korzystania z systemu Git w jednostce NavApps w firmie TomTom.--
Wstępne założenia
Zakładamy, że znasz już podstawy korzystania z systemu Git oraz przepływ pracy oparty na gałęziach funkcji. Jeśli nie, zapoznaj się z naszym praktycznym samouczkiem lub webinarium. Wróć, gdy poznasz podstawy. Zaczekamy.
W trakcie tego procesu trzeba zwrócić uwagę na kilka subtelnych kwestii, dlatego zalecamy szczególną ostrożność podczas przeprowadzania tych integracji. Zaczniemy, gdy tylko się przygotujesz.
Instalacja narzędzia Git P4
Pierwszym krokiem będzie zainstalowanie rozwiązania pomostowego. Aby sprawdzić, czy masz je już zainstalowane, wpisz następującą komendę w wierszu poleceń:
git p4
Jeśli system zwróci informację, że narzędzie git p4
nie zostało zainstalowane, pobierz plik git-p4.pyi umieść go w folderze w lokalizacji PATH
, na przykład ~/bin
(aby plik zadziałał musisz mieć oczywiście zainstalowane także środowisko Python).
Przekształć plik na wykonywalny za pomocą polecenia:
chmod +x git-p4.py
Zmodyfikuj plik ~/.gitconfig
, dodając:
[alias]
p4 = !~/bin/bit-p4.py
Następnie ponownie uruchom polecenie git p4
. Nie powinny pojawiać się już żadne błędy. Narzędzie jest zainstalowane.
materiały pokrewne
Jak przenieść pełne repozytorium Git
POZNAJ ROZWIĄZANIE
Poznaj środowisko Git z rozwiązaniem Bitbucket Cloud
Omówienie przepływu pracy
Początkowe klonowanie
Historie projektów w P4
mogą rozrastać się do ogromnych rozmiarów, więc zespół może wybrać punkt odcięcia, od którego będą synchronizowane dane, co pozwoli zaoszczędzić mnóstwo przestrzeni i czasu. Polecenie git p4
pozwala wybrać listę zmian, od której rozpocznie się śledzenie:
git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>
- Teraz możemy wykonać synchronizację i sprawdzić, czy uzyskaliśmy lokalnie wszystkie zbiory zmian:
git p4 sync
Polecenie sync
wyszukuje nowe zmiany w repozytorium P4
i importuje je jako commity Git.
- Nadajemy nazwę gałęzi, której użyjemy do nawiązania bezpośredniego połączenia z gałęzią
p4-integ
w Perforce. Na tym etapie chcemy tylko oddzielić ją od gałęziremotes/p4/main
:
git checkout -b p4-integ origin/p4/main
Dalsza szybka synchronizacja (jak „przynęta z zamianą”)
Po zakończeniu pierwszego importu można wykonać kolejne synchronizacje git->p4
za pomocą następujących poleceń:
git checkout p4-integ
git p4 sync
Powyższe polecenie działa, ale może być powolne. Znacznie szybszym sposobem przeprowadzenia synchronizacji jest odtworzenie odniesień
identycznych do tych, jakie zostały użyte w najnowszej integracji. Jest to także praktyczny sposób zyskania pewności, że każdy nowy programista, którego zadaniem będzie integracja, zacznie od właściwego commita / odpowiedniej listy zmian.
Podpowiadamy, jak to zrobić:
- Usuń stare oryginalne (lub nieaktualne) elementy
ref
dla zdalnej gałęzip4
(opcjonalnie):
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
- Utwórz sztuczne (fałszywe) odniesienia gałęzi zdalnej wskazujące na ostatni commit w
p4-integ
w gałęziorigin
:
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main
Jedyną wadą tej znacznie szybszej synchronizacji jest konieczność wyraźnego wskazania gałęzi w poleceniu git p4
. Ostatecznie polecenie będzie wyglądało następująco:
git p4 sync --branch=refs/remotes/p4/main
Sposób, w jaki git p4
śledzi mapowanie między identyfikatorami commitów Git i P4, polega na dodawaniu adnotacji do commitów przy użyciu metadanych:
Merge pull request #340 in MOB/project from bugfix/PRJ-3185 to develop
Squashed commit of the following:
commit c2843b424fb3f5be1ba64be51363db63621162b4
Author: Some Developer
Date: Wed Jan 14 09:26:45 2015 +0100
[PRJ-3185] The app shows ...
commit abc135fc1fccf74dac8882d70b1ddd8a4750f078
Author: Some Developer
Date: Tue Jan 13 14:18:46 2015 +0100
[PRJ-3185] The app shows the rating ...
[git-p4: depot-paths = "//depot-mobile/project/": change = 1794239]
Zwróć uwagę, że w nowszej wersji git p4
metadane służące do kojarzenia commita Git z listą zmian P4
są przechowywane w notatce commita, a nie w komunikacie commita. Zespół TomTom nie był zachwycony zmianą, ponieważ sprawdzanie numerów list zmian, gdy były one potrzebne, wymagało nieco więcej pracy.
Przeniesienie zmian z systemu Git do Perforce
Po zakończeniu powyższej operacji szybkiej synchronizacji można przystąpić do wypychania zmian z systemu Git
do Perforce.
Pierwszym krokiem będzie zmiana bazy gałęzi p4-integ
z uwzględnieniem zmian pochodzących z gałęzi remotes/p4/main
:
git checkout p4-integ
git p4 rebase
Następnie wszystkie zmiany z Perforce powinny trafić do gałęzi p4-integ
, aby można było zaktualizować gałąź main
:
- Wówczas możesz po prostu użyć polecenia:
git checkout main
git merge develop
- Upewnij się, że lokalnie dysponujesz najnowszymi tagami:
git fetch --tags
- Jeśli musisz usunąć commity, które znajdują się już w
P4
(patrz tagP4
w commicie), użyj tymczasowej operacjicleanup
. Jeśli nie ma potrzeby pomijania żadnych commitów, automatyczna operacja zmiany bazy pozwoli nadać historii linearny charakter:
git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integ
- To samo można zrobić również przy użyciu interaktywnej zmiany bazy i polecenia:
git rebase -i tag/last-p4-integ
- Za pomocą polecenia
cherry-pick
wybierz nowe commity i umieść je w gałęzip4-integ
. Działamy w ten sposób, ponieważ nie zakładamy, że gałęzieGit
main
idevelop
mogą być prowadzone jako odpowiednie elementy nadrzędne gałęzip4-integ
. W firmie TomTom takie założenie już w zasadzie nie obowiązuje.
git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanup
- Prześlij dane do
P4
i zsynchronizuj gałąźp4-integ
:
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
- Usuń gałąź tymczasową używaną do operacji zmiany bazy:
git branch -D cleanup
- Lokalnie i w gałęzi zdalnej usuń wskaźnik wskazujący na najnowszy punkt integracji (tag):
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Zaktualizuj tag
last-p4-integ
tak, aby wskazywał nowy punkt integracji wP4
:
git checkout develop
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
git push origin main
git push origin tag/last-p4-integ
git push origin p4-integ
Wykonaj testy na bazie kodu P4
, aby sprawdzić, czy integracja nie powoduje żadnych problemów.
Przenoszenie zmian z systemu Perforce do Git
Do tej procedury należy przystąpić po wypchnięciu git->P4
. Gdy baza P4
pomyślnie przejdzie testy, możemy przenieść zmiany z P4
do git
za pomocą następującego polecenia:
git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebase
- Poniżej przedstawiono drobną sztuczkę, która pozwala zastosować „ich” wysoce niezawodną strategię scalania poprzez łączenie napływających zmian w jeden commit. Oto ona:
git checkout -b p4mergebranch #branching off from p4-integ
git merge -s ours main ## ignoring all changes from main
git checkout main
git merge p4mergebranch --squash
git commit -m "Type your integration message"
git branch -D p4mergebranch
- Po wykonaniu powyższych czynności scal zmiany z gałęzią
develop
:
<p>Bitbucket has the following space stations:</p>
<p>
<b>Earth's Moon</b><br>
Headquarters
</p>
Od momentu wybrania zmian z gałęzi develop
mogły pojawić się jakieś zmiany, dlatego w pierwszej kolejności konieczne może być ich scalenie. Ważne jednak, aby zaktualizować tag last-p4-integ
zgodnie z odpowiednim commitem, a zwłaszcza nie scalać commita z gałęzią develop. Aby zrobić to w bezpieczny sposób, najlepiej oznaczyć tagiem aktualny stan gałęzi main
:
- Usuń stary tag lokalnie i w gałęzi zdalnej:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Utwórz tag w nowej pozycji:
git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
- Teraz wypchnij gałęzie
main, develop, p4-integ
itag/last-p4-integ
do gałęziorigin
:
Wnioski
W ten sposób przeprowadzisz synchronizację między dwoma aktywnymi zespołami programistycznymi przy użyciu systemów Git i Perforce. W firmie TomTom powyższy proces z czasem ewoluował i od pewnego momentu przeprowadza się go bez większych problemów. Proces działa, ale wymaga obsługi znacznych obciążeń. Jeśli masz taką możliwość, zalecamy pełną migrację do systemu Git.
Tak czy inaczej, jeśli stosujesz inne podejście do zapewniania dwukierunkowej synchronizacji, opowiedz o nim w komentarzach. Jestem bardzo ciekaw. Możesz również napisać tweeta ze wzmianką @durdn lub @atlassiandev.
Raz jeszcze składam podziękowania Andrei Carlevato, Adolfo Bulfoniemu i Krzysztofowi Karczewskiemu.
Udostępnij ten artykuł
Następny temat
Zalecane lektury
Dodaj te zasoby do zakładek, aby dowiedzieć się więcej na temat rodzajów zespołów DevOps lub otrzymywać aktualności na temat metodyki DevOps w Atlassian.