Close

Git fetch pull request: odblokowana biegłość

Zdjęcie portretowe Nicoli Paolucciego
Nicola Paolucci

Developer Advocate


W dzisiejszych czasach do zastosowania poprawki do projektu wystarczy utworzenie podziału — co powoduje powstanie pełnej zdalnej kopii projektu, na której możesz pracować — wybranie pliku, który chcesz zmienić, naciśnięcie przycisku Edytuj i zatwierdzenie poprawek.

A co jeśli jesteś odbiorcą pull requestu (w skrócie PR)? Korzystanie z dopracowanego interfejsu internetowego sprawdza się doskonale i często jest w zupełności wystarczające. Wystarczy kliknąć przycisk zatwierdzania, następnie przycisk scalania i gotowe.

Ale nie zawsze tak to wygląda. Często zdarza się, że trzeba pobrać zmiany zawarte w pull requeście (PR) lokalnie, uruchomić kilka testów i zobaczyć, jak wyglądają w środowisku IDE, aby zrozumieć, co zostało zrobione.

Czynności umożliwiające pobranie — dokładniej mówiąc polecenia fetch i checkout — pull requestu współpracownika są teoretycznie proste, ale stają się jeszcze łatwiejsze, jeśli poznasz kilka ważnych szczegółów i porad.

Przedstawię teraz funkcje wiersza polecenia git, które ułatwiają obsługę pull requestów z poziomu wiersza polecenia.

Zanim zaczniemy: uzupełnienie wiersza polecenia powłoki o nazwę i status gałęzi


Zawsze mnie dziwi, że tak wiele osób korzysta z czystego wiersza polecenia, nie widząc gałęzi git, w której się znajdują, ani informacji o zmodyfikowanych/niezatwierdzonych plikach w katalogu roboczym. Jeśli należysz do tych osób, pozwól, że Ci pomogę, przedstawiając parę niesamowitych wskazówek!

Warto zainstalować narzędzie, takie jak fantastyczny Liquid Prompt, które udostępnia znakomite adnotacje dotyczące statusu katalogu roboczego git (i obsługuje także wszelkie inne systemy VCS):

(Na powyższym zrzucie ekranu widać, jak mój wiersz polecenia informuje mnie, że jestem w gałęzi newbranch, że dodałem 5 wierszy do plików, które śledzę w moim katalogu roboczym, i że usunąłem 0).

Logo Git
materiały pokrewne

Instalacja środowiska Git

Logo Bitbucket
POZNAJ ROZWIĄZANIE

Poznaj środowisko Git z rozwiązaniem Bitbucket Cloud

Wszyscy pracują w tym samym repozytorium


Jeśli pracujesz w tym samym repozytorium ze swoim zespołem, proces wyewidencjonowywania pull requestu jest bardzo prosty: wystarczy użyć poleceń fetch i checkout w odniesieniu do gałęzi, z której utworzono pull request:

  • Pobierz wszystkie gałęzie, które zostały opublikowane w udostępnionym repozytorium:
git fetch origin
  • Utwórz gałąź lokalną, która śledzi interesującą Cię gałąź zdalną:
git checkout -b PRJ-1234 origin/PRJ-1234
  • Teraz możesz użyć poleceń diff i merge oraz wykonać testy:
git diff main ./run-tests.sh
  • Po otrzymaniu zadowalającego wyniku wróć do internetowego interfejsu użytkownika i przekaż informacje zwrotne lub od razu zatwierdź zmianę.

Współautorzy pracujący we własnych podziałach


Proces wygląda nieco inaczej, gdy niektórzy współautorzy pracują w oddzielnych podziałach. W takim przypadku można pobrać (polecenie fetch) zdalną gałąź, w której wynik prac lub funkcja zostały zatwierdzone:

  • Najpierw dodaj zdalną gałąź współautora:
git remote add jsmith http://bitbucket.org/jsmith/coolproject.git
  • Zbierz wszystkie najnowsze aktualizacje z repozytorium origin do Twojego głównego repozytorium:
git checkout main git fetch origin git merge main
  • Pobierz wszystkie gałęzie, które zostały opublikowane w podziale współautora:
git fetch jsmith
  • Utwórz gałąź lokalną, która śledzi interesującą Cię gałąź zdalną:
git checkout -b jsmith-PRJ-1234 jsmith/PRJ-1234
  • Teraz możesz użyć poleceń diff i merge oraz wykonać testy:
git diff main ./run-tests.sh

Mniej pracy dzięki referencjom pull requestów


Powyższe rozwiązanie działa, ale może wystąpić kilka potencjalnych problemów:

  • Co jeśli masz wielu współautorów, z których każdy ma własny podział? Dodanie tych wszystkich podziałów i obsługa ich osobno stają się niepraktyczne.
  • Co jeśli nie masz dostępu do niektórych podziałów i nie możesz wyewidencjonowywać gałęzi źródłowej?

Rozwiązaniem obu powyższych problemów jest użycie referencji pull requestów oferowanych przez niektóre serwery git. Procedura, którą teraz pokażę, jest obsługiwana przez niektóre serwery git i różni się nieznacznie w zależności od tego, którego z nich używasz. Poniżej omówię, jak pobrać (polecenie fetch) wszystkie pull requesty do rozwiązania Stash (obecnie Bitbucket Server) i GitHub.

Nie obawiaj się specyfikacji refspec

W pierwszej kolejności musisz zapoznać się ze specyfikacjami refspec. Specyfikacje refspec są przydatne i nie warto się ich obawiać. Są to proste mapowania ze zdalnych gałęzi do lokalnych referencji lub innymi słowy sposób na określenie w git, że „ta zdalna gałąź (lub ten zestaw zdalnych gałęzi) powinna zostać zmapowana na te nazwy lokalnie, w tej przestrzeni nazw”.

Przykładowo polecenie, takie jak:

git fetch +refs/heads/main:refs/remotes/origin/main

spowoduje zmapowanie zdalnej gałęzi main w zdalnym repozytorium origin na lokalna gałąź origin/main, tak aby można było pisać:

git checkout origin/main

i nadal odnosić się do tej zdalnej gałęzi. Znak plus (+) w definicji ma na celu wskazanie, że chcemy, aby referencja w git była aktualizowana, nawet jeśli aktualizacja nie jest fast-forward.

Metoda, której użyjemy do pobrania wszystkich pull requestów, polega na zmapowaniu sposobu, w jaki zdalne repozytorium przechowuje wskaźniki PR HEAD, i zmapowaniu ich na lokalną przestrzeń nazw, aby ułatwić odnoszenie się do nich.

Jeśli więc masz zdefiniowane zdalne repozytorium origin (lub upstream), wykonaj poniższe czynności.

Uwaga: jak słusznie zauważyło kilku programistów Stash (obecnie Bitbucket Server), referencje pokazane poniżej powinny być traktowane jako nieudokumentowane (undocumented) i prywatne (private) i mogą się zmienić w dowolnym momencie.

Pobieranie wszystkich pull requestów: Stash

  • Wykonaj podział repozytorium.
  • Sklonuj swój podział lokalnie:
git clone git@stash.atlassian.com:durdn/tis.git
  • Dodaj pierwotne repozytorium nadrzędne jako upstream.
git remote add upstream git@stash.atlassian.com:tpettersen/tis.git
  • Pobierz najnowsze końcówki z repozytorium „upstream”.
git fetch upstream
  • Dodaj refspec, który zmapuje zdalne końcówki pull requestów na lokalną przestrzeń nazw pr. Możesz to zrobić za pomocą polecenia config:
git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'
  • W .git/config wpisy fetch przybierają następującą postać:
[remote "upstream"]
    url = git@stash.atlassian.com:docker/libswarm.git
    fetch = +refs/heads/*:refs/remotes/upstream/*
    fetch = +refs/pull-requests/*/from:refs/remotes/upstream/pr/*
  • Teraz możesz łatwo wykonać polecenie fetch dla wszystkich gałęzi pull requestów:
$ git fetch upstream

remote: Counting objects: 417, done.
remote: Compressing objects: 100% (274/274), done.
remote: Total 417 (delta 226), reused 277 (delta 128)
Receiving objects: 100% (417/417), 105.28 KiB | 0 bytes/s, done.
Resolving deltas: 100% (226/226), done.

From stash.atlassian.com:docker/libswarm
 * [new ref]         refs/pull-requests/10/from-> upstream/pr/10
 [...]
 * [new ref]         refs/pull-requests/100/from -> upstream/pr/100
 * [new ref]         refs/pull-requests/101/from -> upstream/pr/101
 [...]
 * [new ref]         refs/pull-requests/109/from -> upstream/pr/109
 * [new ref]         refs/pull-requests/110/from -> upstream/pr/110
 [...]
  • Teraz, aby przełączyć się na konkretny pull request, możesz po prostu wpisać:
git checkout pr/102

Pobieranie wszystkich pull requestów: GitHub

Jeśli podziały lub repozytoria nadrzędne znajdują się w GitHub, procedura jest dokładnie taka sama jak powyżej, ale polecenie config zmienia się na:

 git config --add remote.origin.fetch '+refs/pull//head:refs/remotes/origin/pr/'

Natomiast gałąź zdalna w .git/config zmieni się, aby uwzględnić dodatkową konfigurację fetch do mapowania końcówek PR na lokalną przestrzeń nazw pr:

[remote "upstream"] url = git@github.com:docker/libswarm.git fetch = +refs/heads/*:refs/remotes/upstream/* fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*

Pobieranie pojedynczego pull requestu za pomocą referencji

Jeśli nie chcesz konfigurować wpisów fetch w .git/config i po prostu chcesz szybko dostać się do pull requestu, wystarczy jedno polecenie:

  • Wyewidencjonowywanie pojedynczego PR w Stash:
git fetch refs/pull-requests/your-pr-number/from:local-branch-name
  • Wyewidencjonowywanie pojedynczego PR w GitHub:
git fetch refs/pull/your-pr-number/head:local-branch-name

A jeśli często korzystasz z powyższego rozwiązania, możesz usprawnić proces, tworząc alias git:

# For Stash
git config alias.spr '!sh -c "git fetch origin pull-requests/${1}/from:pr/${1}" -'

# For Github
git config alias.gpr '!sh -c "git fetch origin pull/${1}/head:pr/${1}" -'

Po skonfigurowaniu tego aliasu możemy pobrać pull request za pomocą prostego polecenia (dzięki, inuit):

Wnioski


Mam nadzieję, że te informacje okażą się przydatne. Ogólnie rzecz biorąc, śledzenie pracy współpracowników lub współautorów jest proste, gdy utworzy się kilka prostych aliasów lub doda odpowiednie specyfikacje refspec do .git/config. Jeśli macie jakieś pytania, z przyjemnością na nie odpowiem na Twitterze: @durdn lub @AtlDevtools.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Udostępnij ten artykuł

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.

Ludzie współpracujący przy ścianie pełnej narzędzi

Blog Bitbucket

Ilustracja DevOps

Ścieżka szkoleniowa DevOps

Demonstracje funkcji z ekspertami Atlassian

Zobacz, jak Bitbucket Cloud współpracuje z Atlassian Open DevOps

Zapisz się do newslettera DevOps

Thank you for signing up