Udostępnij przez


Konfigurowanie gałęzi docelowych dla żądań ściągnięcia

Azure DevOps Services

Domyślnie usługa Azure DevOps sugeruje tworzenie nowych żądań pobrania 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ę, zatytułowaną pull_request_targets, zawierającą nazwy gałęzi lub prefiksy pasujące do gałęzi 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).

Wymagania wstępne

Kategoria Wymagania
Dostęp do projektu Członek projektu .
uprawnienia — Wyświetlanie kodu w projektach prywatnych: co najmniej dostęp na poziomie Podstawowym.
— Klonowanie lub współtworzenie kodu w prywatnych projektach: członkostwo w grupie zabezpieczeń Współautorzy lub odpowiednie uprawnienia w projekcie.
— Ustaw uprawnienia gałęzi lub repozytorium: Zarządzanie uprawnieniami dla gałęzi lub repozytorium.
- Zmień gałąź domyślną: Edytuj zasady uprawnienia dla repozytorium.
— Zaimportuj repozytorium: członek grupy zabezpieczeń Administratorzy projektów lub uprawnienia na poziomie projektu Git Utwórz repozytorium ustawione na Dozwolone. Aby uzyskać więcej informacji, zobacz Ustawianie uprawnień repozytorium Git.
Usługi Repozytoria włączone.
Narzędzia Opcjonalny. Użyj poleceń az repos: Azure DevOps CLI.

Uwaga

W projektach publicznych użytkownicy z dostępem Stakeholder mają pełny dostęp do usługi Azure Repos, w tym wyświetlanie, klonowanie i współtworzenie kodu.

Kategoria Wymagania
Dostęp do projektu Członek projektu .
uprawnienia — Wyświetl kod: przynajmniej podstawowy dostęp.
— Klonowanie lub współtworzenie kodu: członek grupy zabezpieczeń Współtwórców lub posiadający odpowiednie uprawnienia w projekcie.
Usługi Repozytoria włączone.

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 przesyła gałąź do usługi Azure DevOps, przy jego kolejnej wizycie na stronie Repozytoria może pojawić się sugestia utworzenia pull requesta z tej gałęzi. Przycisk "Utwórz nowe żądanie ściągnięcia" dynamicznie wybiera gałąź docelową.

  • 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 pull requestów przy użyciu tej dynamicznej opcji wyboru, ale narzędzia klienckie muszą dodać dodatkowy sygnał opcjonalny, że użytkownik nie określił gałęzi docelowej. Sprawdź wybrane narzędzie klienckie, aby sprawdzić, czy opcja jest włączona.

Jakie są dobrzy kandydaci do celów rozgałęzień?

Zalecamy, aby skonfigurowana lista gałęzi zawierała tylko gałęzie chronione przez polityki dotyczące żądań ściągnięcia. Takie gałęzie są prawdopodobnie zmieniane tylko przez kończenie pull requestów, co gwarantuje, że poprzednia lokalizacja gałęzi znajduje się w historii pierwszego nadrzędnego commitu. 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łąź?

Git nie śledzi metadanych dotyczących tworzenia gałęzi. Nie ma dokładnego sposobu ustalenia, która gałąź została użyta podczas tworzenia gałęzi tematycznej. 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 rodzica przecina się z historią pierwszego rodzica gałęzi źródłowej najczęściej.

Przykład: brak zatwierdzeń scalania

Rozważ następującą strukturę gałęzi, która jest uproszczona bardziej niż zwykle, ponieważ nie ma żadnych commitów scalających. W tym przykładzie cała historia jest reprezentowana przez historię pierwszego przodka.

  ,-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-September przecina się z topic przy A, pozostawiając B,G,I w 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 gałąź feature/targets jest wybierana jako gałąź docelowa dla żądania ściągnięcia z źródłowej gałęzi topic.

Przykład: scalanie zatwierdzeń

W bardziej skomplikowanym przykładzie, w którym gałąź feature/targets została scalona z main, a następnie main zostało scalone z samym sobą, historia zatwierdzeń 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 oznacza moment, kiedy main zostało scalone z elementem feature/targets. Związek między zatwierdzeniami M i J jest przedstawiony w taki sposób, aby podkreślić, że J jest drugim rodzicem M, podczas gdy L jest pierwszym rodzicem.

W takim przypadku, gdy weźmiesz pod uwagę pełną historię zatwierdzeń, zarówno main, jak i feature/targets przecinają historię 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 opcji jest nadal powiązanych na podstawie listy pull_request_targets z powodu dopasowania prefiksu, wygrywa opcja najwcześniejsza w kolejności alfabetycznej.

Tego rodzaju powiązania są najczęściej obecne podczas tworzenia nowych gałęzi kandydujących, takich jak rozpoczęcie nowej gałęzi funkcyjnej lub rozwidlenie gałęzi wydaniowej.

          ,-E---F <-- release/2024-October
         /
A---B---C---D <--- main
     \
      \
       `G <--- topic

W tym przykładzie gałąź release/2024-October została utworzona z gałęzi main po utworzeniu topic z main. Chociaż jest to intuicyjne dla ludzkiego czytelnika, kolejność kategorii main i release/* na liście pull_request_targets wskazuje preferowaną kolejność dla usługi Azure DevOps.

Co zrobić, jeśli usługa Azure DevOps wybierze niewłaściwą gałąź docelową?

Strona tworzenia pull requesta ma selekcję dostosowującą gałąź docelową, jeśli dynamiczny wybór nie jest zgodny z oczekiwaniami. Gałąź docelową można również dostosować po utworzeniu pull requesta.

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 przesyłać dowolnie, historia pierwszego rodzica nie jest wiarygodnym wskaźnikiem wcześniejszej pozycji tej gałęzi.

  • Gałąź źródłowa została utworzona z poprzedniego punktu końcowego gałęzi kandydującej. 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 została zaktualizowana za pomocą poleceń git commit 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 przepisuje historię pierwszego rodzica, aby skłonić heurystykę do wyboru nowego celu.

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 rodzica, a zatem nie zmienia docelowej gałęzi.

Jak mogę przetestować tę decyzję lokalnie?

Heurystyka używana przez Azure DevOps została dodana do podstawowego klienta Git i jest dostępna w Git w wersjach 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 służy jako źródło i porównuje historię pierwszego przodka gałęzi docelowych w ten sam sposób. Podczas gdy każda gałąź kandydacka jest wymieniona w danych wyjściowych, ciąg (HEAD) wskazuje, która z gałęzi powinna być używana jako gałąź docelowa.

Następne kroki