Udostępnij za pośrednictwem


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 pomija targetRef 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 , topicjest następnie porównywana z tymi gałęziami.

  • main przecina się z wartością topic o Bwartości , pozostawiając G,I wartość , topic a nie w obiekcie main.
  • release/2024-Septemberprzecina się z topic przy A wyjeździe B,G,I topic, a nie w .release/2024-September
  • feature/targets przecina się z wartością topic o Gwartości , pozostawiając I wartość , topic a nie w obiekcie feature/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/targetselementem . 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/targetselementu .

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 mainelementu . 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 jak git reset --hard lub git 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.

Następne kroki