Jak utworzyć gałąź z określonego zatwierdzenia w innej gałęzi

107

Zrobiłem kilka zatwierdzeń w gałęzi master, a następnie połączyłem je w gałęzi deweloperskiej.

Chcę utworzyć gałąź z określonego zatwierdzenia w gałęzi deweloperskiej, która została najpierw zatwierdzona w gałęzi master.

Użyłem poleceń:

git checkout dev
git branch  <branch name> <commit id>

Jednak tworzy to gałąź z gałęzi głównej, a nie gałęzi deweloperskiej, której się spodziewałem. Identyfikator zatwierdzenia jest taki sam w gałęzi master i gałęzi dev. Jak więc mogę odróżnić ten sam identyfikator zatwierdzenia w różnych gałęziach?

PS: Zrobiłem przykład na github tutaj https://github.com/RolandXu/test_for_branch

Użyłem poleceń:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

Oczekuję, że gałąź testowa zawiera aa.txt bb.txt cc.txt. Jednak gałąź testowa zawiera tylko aa.txt i cc.txt. Najprawdopodobniej utworzył gałąź z gałęzi głównej.

RolandXu
źródło

Odpowiedzi:

154

Jeśli używasz tej formy branchpolecenia (z punktem początkowym), nie ma znaczenia, gdzie jesteś HEAD.

Co robisz:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • Najpierw ustaw się HEADna oddział dev,

  • Po drugie, zaczynasz nową gałąź po zatwierdzeniu 07aeec98. W tym zatwierdzeniu nie ma pliku bb.txt (zgodnie z repozytorium na github).

Jeśli chcesz rozpocząć nowy oddział w miejscu, które właśnie wyrejestrowałeś, możesz uruchomić oddział bez punktu początkowego:

git branch test

lub jak odpowiedzieli inni, oddziału i kasy w jednej operacji:

git checkout -b test

Myślę, że możesz być zdezorientowany tym faktem, który 07aeec98jest częścią branży dev. Prawdą jest, że to zatwierdzenie jest przodkiem dev, jego zmiany są potrzebne, aby osiągnąć najnowsze zatwierdzenie w dev. Są to jednak inne zobowiązania, które są potrzebne, aby dotrzeć do najnowszego dev, i niekoniecznie są one w historii 07aeec98.

8480e8ae(gdzie dodałeś bb.txt) nie ma na przykład w historii 07aeec98. Jeśli odłączysz się od 07aeec98, nie otrzymasz zmian wprowadzonych przez 8480e8ae.

Innymi słowy: jeśli połączysz gałąź A i gałąź B w gałąź C, a następnie utworzysz nową gałąź na zatwierdzeniu A, nie otrzymasz zmian wprowadzonych w B.

To samo tutaj, miałeś dwie równoległe gałęzie master i dev, które połączyłeś w dev. Odgałęzienie od zatwierdzenia master (starszego niż scalenie) nie zapewni ci zmian w dev.


Jeśli chcesz na stałe zintegrować nowe zmiany z mastera z gałęziami funkcji, powinieneś scalić masterje i kontynuować. Spowoduje to jednak utworzenie zatwierdzeń scalających w gałęziach funkcji.

Jeśli nie opublikowały swoje oddziały funkcję, można również rebase ich sprawie zaktualizowanego mistrza: git rebase master featureA. Przygotuj się na rozwiązanie ewentualnych konfliktów.

Jeśli potrzebujesz przepływu pracy, w którym możesz pracować nad gałęziami funkcji bez zatwierdzeń scalających i nadal integrować się z nowszymi zmianami w module głównym, polecam:

  • oprzeć każdą nową gałąź funkcji na zatwierdzeniu master
  • stwórz devgałąź na commicie master
  • kiedy chcesz zobaczyć, jak twoja gałąź funkcji integruje się z nowymi zmianami w wzorcu, połącz zarówno główną, jak i gałąź funkcji do dev.

Nie angażuj się devbezpośrednio, używaj go tylko do łączenia innych gałęzi.

Na przykład, jeśli pracujesz nad funkcją A i B:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

Połącz gałęzie w devgałąź, aby sprawdzić, czy dobrze współpracują z nowym wzorcem:

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

Możesz kontynuować pracę nad gałęziami funkcji i devregularnie włączać nowe zmiany z gałęzi głównych i funkcji .

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

Kiedy nadejdzie czas na integrację nowych funkcji, połącz gałęzie funkcji (nie dev!) W master.

Gauthier
źródło
dzięki. Odpowiadasz na moje pytanie. Nie rozumiem trybu git branch. Czy masz jakieś sugestie dotyczące mojego problemu. Mam główną gałąź, która ma wiele terminowych zobowiązań od innych (synchronizacja z koniecznością). Mam gałąź deweloperów, w której pracuję osobiście. Chcę gałęzi, która zawiera wszystkie zatwierdzenia z gałęzi głównej i gałęzi deweloperskiej, wtedy mogę łatwo stworzyć gałąź opartą na tej gałęzi, a następnie rozpocząć określoną pracę.
RolandXu,
Nie mogłem odpowiedzieć w komentarzu, więc aktualizuję odpowiedź o sugerowane przepływy pracy.
Gauthier,
Hej - dzięki za genialną i dokładną odpowiedź! Po prostu ciekawy: w końcu dlaczego miałoby się to robić merge the feature branches (not dev!) into master?
cassi.lup
W branży nie ma prawdziwego nowego rozwoju dev. Powinieneś zachować specyficzne funkcje swoich gałęzi. devzawiera tylko zatwierdzenia scalania. Bardziej sensowne jest scalanie wszystkich nowych funkcji bezpośrednio master, niż łączenie razem funkcji, a następnie łączenie wyniku w master.
Gauthier
@Gauthier Nie odpowiedziałeś na pytanie, dlaczego. Dla mnie brzmi to tak, jakby scalanie a devtylko z funkcjami A Bi scalanie z Cnim w masterjest identyczne jak indywidualne scalanie A Bi Cw master. Jeśli nie, to podważa moje zrozumienie, jak działa git i byłbym bardzo ciekawy, dlaczego!
Steven Lu
55

Masz argumenty w złej kolejności:

git branch <branch-name> <commit>

i do tego nie ma znaczenia, która gałąź jest wyewidencjonowana; zrobi to, co powiesz. (Jeśli pominiesz argument zatwierdzenia, domyślnie tworzy się gałąź w tym samym miejscu co bieżąca).

Jeśli chcesz sprawdzić nowy oddział w trakcie jego tworzenia:

git checkout -b <branch> <commit>

z tym samym zachowaniem, jeśli pominiesz argument zatwierdzenia.

Cascabel
źródło
22

Możesz to zrobić lokalnie, jak wszyscy wspominali, używając

git checkout -b <branch-name> <sha1-of-commit>

Alternatywnie możesz to zrobić w samym githubie, wykonaj następujące kroki:

1- W repozytorium kliknij plik Commits.

2- na zatwierdzeniu, z którego chcesz się rozgałęzić, kliknij, <>aby przeglądać repozytorium w tym punkcie historii.

zatwierdza historię

3- Kliknij tree: xxxxxxw lewym górnym rogu. Po prostu wpisz nową nazwę oddziału i kliknij, Create branch xxxjak pokazano poniżej.

utwórz nową gałąź

Teraz możesz pobrać zmiany z tej gałęzi lokalnie i kontynuować z tego miejsca.

Muhammad Soliman
źródło
To jest to, czego potrzebowałem ... Jak to zrobić na stronie internetowej
eharo2
Nigdy tego nie wiedziałem. To jest to. GUI jest po prostu świetne i chciałem być z dala od CLI.
Rohit Gupta
Powinno to być oznaczone jako Odpowiedź ¡
Sandeep Anand
11

Próbować

git checkout <commit hash>
git checkout -b new_branch

Zatwierdzenie powinno istnieć tylko raz w twoim drzewie, a nie w dwóch oddzielnych gałęziach.

Pozwala to sprawdzić to konkretne zatwierdzenie i nazwać je, jak chcesz.

ZMorek
źródło
Cześć, próbuję git log dev i git log master, stwierdziłem, że identyfikator skrótu zatwierdzenia jest taki sam dla zatwierdzenia, które
łączę
może gitk
przydałoby się
Nowo dodałem przykład w githubie. A Gauthier już odpowiedział na moje pytanie, że źle rozumiem tryb gałęzi git. Dzięki :)
RolandXu,
Myślę, że to jest prawdziwa odpowiedź. Dzięki
virusss8
9

Musisz zrobić:

git branch <branch_name> <commit>

(zamieniłeś nazwę gałęzi i zatwierdzenie)

Możesz też:

git checkout -b <branch_name> <commit>

Jeśli zamiast niej użyjesz nazwy oddziału, otrzymasz gałąź z czubka gałęzi.

manojlds
źródło
Nie o HEADto chodzi. Zamiast tego możesz powiedzieć „końcówka gałęzi” lub „zatwierdzenie, na które wskazuje gałąź”.
Cascabel
@Jefromi - Aby być purystami, możemy powiedzieć tylko gałąź, ponieważ sama gałąź jest wskaźnikiem do, cóż, czubka gałęzi.
manojlds