Konfigurowanie gałęzi docelowych dla żądań ściągnięcia
Azure DevOps Services
Domyślnie usługa Azure DevOps sugeruje tworzenie nowych żądań ściągnięcia względem gałęzi domyślnej. W repozytorium z wieloma gałęziami używanymi na potrzeby żądań ściągnięcia właściciele repozytoriów mogą skonfigurować listę gałęzi docelowych żądania ściągnięcia, aby te sugestie wybierały odpowiednią gałąź docelową.
Aby włączyć tę funkcję, utwórz plik o nazwie .azuredevops/pull_request_targets.yml
w domyślnej gałęzi repozytorium.
Ten plik YAML powinien zawierać jedną listę o nazwie pull_request_targets
, zawierającą nazwy gałęzi lub prefiksy zgodne z gałęziami kandydata.
Rozważmy na przykład następujące elementy:
pull_request_targets:
- main
- release/*
- feature/*
Ta lista potencjalnych obiektów docelowych określa main
jako gałąź docelową do wybrania jako pierwszą, ale jeśli gałąź rozpoczynająca się od release/
lub feature/
jest lepszym wyborem, ta gałąź zostanie wybrana zamiast tego.
Aby uzyskać więcej wytycznych dotyczących żądań ściągnięcia i zagadnień dotyczących zarządzania, zobacz About pull requests (Informacje o żądaniach ściągnięcia).
Kiedy jest używana ta konfiguracja?
Istnieje wiele punktów wejścia do używania dynamicznej gałęzi docelowej.
Sugestie dotyczące żądania ściągnięcia. Gdy użytkownik wypchnie gałąź do usługi Azure DevOps, jego następna wizyta na stronie Repozytoria może sugerować utworzenie żądania ściągnięcia z tej gałęzi. Ten przycisk "Utwórz nowe żądanie ściągnięcia" wybiera gałąź docelową dynamicznie.
Adres URL żądania ściągnięcia. Gdy użytkownik przechodzi bezpośrednio do strony tworzenia żądania ściągnięcia
sourceRef
przy użyciu parametru, ale pomijatargetRef
parametr, usługa Azure DevOps wybiera gałąź docelową na podstawie tego dynamicznego wyboru.
Istnieje możliwość tworzenia żądań ściągnięcia przy użyciu tego dynamicznego wyboru, ale klienci muszą dodać opcjonalny sygnał, że użytkownik nie określił gałęzi docelowej. Sprawdź wybrane narzędzie klienckie, aby sprawdzić, czy opcja jest włączona.
Co to są dobrzy kandydaci do celów oddziałów?
Zalecamy, aby skonfigurowana lista gałęzi kandydatów zawierała tylko gałęzie chronione przez zasady żądania ściągnięcia. Takie gałęzie są prawdopodobnie zmieniane tylko przez kończenie żądań ściągnięcia, co gwarantuje, że poprzednia pozycja gałęzi znajduje się w historii pierwszego nadrzędnego zatwierdzenia porady. Jeśli jest używana strategia scalania, drugi element nadrzędny reprezentuje zatwierdzenia wprowadzane do gałęzi docelowej przez ukończenie żądania ściągnięcia, a pierwszy element nadrzędny jest poprzednią poradą.
Jak usługa Azure DevOps wybiera gałąź?
Usługa Git nie śledzi metadanych wokół tworzenia gałęzi. Nie ma dokładnego sposobu określania gałęzi, która została użyta podczas tworzenia gałęzi tematu. Zamiast tego usługa Azure DevOps używa heurystyki opartej na historii pierwszej nadrzędnej gałęzi.
Wśród możliwych gałęzi docelowych usługa Azure DevOps wybiera gałąź, której historia pierwszego elementu nadrzędnego przecina się z pierwszą historią nadrzędną gałęzi źródłowej.
Przykład: brak zatwierdzeń scalania
Rozważ następującą strukturę gałęzi, która jest uproszczona bardziej niż zwykle, ponieważ nie ma zatwierdzeń scalania. W tym przykładzie cała historia jest reprezentowana przez historię pierwszego obiektu nadrzędnego.
,-E---F <-- release/2024-September
/
A---B---C---D <--- main
\
`-G---H <--- feature/targets
\
`-I <--- topic
W przypadku tej historii i użytej wcześniej listy przykładowej pull_request_targets
mamy trzy gałęzie docelowe kandydata w kolejności priorytetu:
main
release/2024-September
feature/targets
Gałąź źródłowa , topic
jest następnie porównywana z tymi gałęziami.
main
przecina się z wartościątopic
oB
wartości , pozostawiającG,I
wartość ,topic
a nie w obiekciemain
.release/2024-September
przecina się ztopic
przyA
wyjeździeB,G,I
topic
, a nie w .release/2024-September
feature/targets
przecina się z wartościątopic
oG
wartości , pozostawiającI
wartość ,topic
a nie w obiekciefeature/targets
.
W związku z tym w tym przykładzie feature/targets
gałąź jest wybierana jako gałąź docelowa dla żądania ściągnięcia z gałęzią topic
źródłową.
Przykład: scalanie zatwierdzeń
W bardziej skomplikowanym przykładzie, w którym feature/targets
gałąź została scalona i main
scalona main
z samą sobą, historia zatwierdzń ma więcej przypadków do rozważenia:
,-E---F <-- release/2024-September
/
A---B---C---D---J---K <--- main
\ _/ \
\ / \
`G---H---L--\--M <--- feature/targets
\ \/
\
`I <--- topic
W tym miejscu zatwierdzenie D
w main
reprezentuje czas, w którym feature/targets
zostało scalone z elementem main
. Zatwierdzenie M
reprezentuje czas main
scalenia z feature/targets
elementem . Związek między zatwierdzeniami M
i J
jest rysowany w sposób, aby podkreślić, że J
jest drugim elementem nadrzędnym, podczas gdy L
jest pierwszym elementem M
nadrzędnym.
W takim przypadku, gdy weźmiesz pod uwagę pełną historię zatwierdzeń, main
a feature/targets
obie przecinają historię elementu topic
w .G
Jednak pierwsza historia nadrzędna nadal pokazuje preferencję dla feature/targets
elementu .
Zerwanie więzi
Jeśli dwie gałęzie mają to samo skrzyżowanie historii pierwszego nadrzędnego, usługa Azure Devops wybiera gałąź, która zostanie wyświetlona wcześniej na pull_request_targets
liście. Jeśli wiele gałęzi jest nadal powiązanych na pull_request_targets
podstawie listy z powodu dopasowania prefiksu, najwcześniej w kolejności alfabetycznej wygrywa.
Te rodzaje powiązań są najczęściej obecne podczas tworzenia nowych gałęzi kandydatów, takich jak początek nowej gałęzi funkcji lub rozwidlenie gałęzi wydania.
,-E---F <-- release/2024-October
/
A---B---C---D <--- main
\
\
`G <--- topic
W tym przykładzie release/2024-October
gałąź została utworzona poza gałęzią main
po topic
rozgałęzieniu main
elementu . Chociaż jest to intuicyjne dla czytelnika przez człowieka, kolejność main
kategorii i release/*
na pull_request_targets
liście wskazuje preferowaną kolejność dla usługi Azure DevOps.
Co zrobić, jeśli usługa Azure DevOps wybierze niewłaściwą gałąź docelową?
Strona tworzenia żądania ściągnięcia ma selektor do dostosowywania gałęzi docelowej, jeśli wybór dynamiczny nie jest zgodny z oczekiwaniami. Gałąź docelową można również dostosować po utworzeniu żądania ściągnięcia.
Co ważniejsze, warto zrozumieć, dlaczego heurystyka może wybierać "niewłaściwą" gałąź docelową.
Ta heurystyka opiera się na pewnych założeniach dotyczących sposobu tworzenia gałęzi docelowych i gałęzi źródłowej. Oto kilka potencjalnych powodów, dla których heurystyka nie działa:
Gałęzie docelowe nie są chronione przez zasady żądań ściągnięcia. Jeśli gałęzie docelowe można wypchnąć dowolnie, historia pierwszego elementu nadrzędnego nie jest wiarygodnym wskaźnikiem poprzedniej lokalizacji tej gałęzi.
Gałąź źródłowa została utworzona na podstawie poprzedniej porady gałęzi kandydata. Jeśli gałąź źródłowa wybrała dowolne zatwierdzenie w historii, nie ma gwarancji co do pierwszej historii nadrzędnej, od których zależy.
Gałąź źródłowa była zaawansowana przy użyciu
git commit
poleceń i .git merge
Polecenia, takie jakgit reset --hard
lubgit rebase
mogą zmieniać historię gałęzi w nieprzewidywalny sposób.
Jeśli nie zgadzasz się z gałęzią docelową wybraną przez tę heurystyczną, rozważ zaktualizowanie wybranego wyboru przy użyciu polecenia git rebase --onto <new-target> <old-target> <source>
. Polecenie git rebase
ponownie zapisuje historię pierwszego elementu nadrzędnego, aby wybrać nowy element docelowy.
Jednym z typowych błędów, które użytkownicy popełniają, gdy zdają sobie sprawę, że są one oparte na niewłaściwej gałęzi, jest użycie git merge
odpowiedniej gałęzi do swojej historii.
Scalanie nie zmienia historii pierwszego elementu nadrzędnego, a zatem nie zmienia wyboru gałęzi docelowej.
Jak mogę przetestować tę decyzję lokalnie?
Heurystyczny używany przez usługę Azure DevOps został dodany do podstawowego klienta Git i jest dostępny w usłudze Git w wersji 2.47.0 i nowszych.
Aby przetestować tę logikę we własnym repozytorium, najpierw uruchom polecenie git fetch origin
, aby upewnić się, że masz najnowszą wersję gałęzi docelowych. Następnie uruchom następujące git for-each-ref
polecenie, dostosowane do listy gałęzi kandydatów:
$ git for-each-ref --format="%(is-base:HEAD) %(refname)" \
refs/remotes/origin/main \
"refs/remotes/origin/release/*" \
"refs/remotes/origin/feature/*"
refs/remotes/origin/main
refs/remotes/origin/release/2024-September
(HEAD) refs/remotes/origin/feature/targets
W tym poleceniu HEAD
zatwierdzenie jest używane jako źródło i porównuje historię pierwszego nadrzędnego gałęzi docelowych w taki sam sposób. Podczas gdy każda gałąź kandydata jest wymieniona w danych wyjściowych, ciąg (HEAD)
wskazuje, które z gałęzi powinny być używane jako gałąź docelowa.