Zaktualizuj gałęzie Git z poziomu głównego

675

Jestem nowy w Git i teraz jestem w takiej sytuacji:

  • Mam cztery gałęzie (master, b1, b2 i b3).
  • Po tym, jak pracowałem nad b1-b3, zdałem sobie sprawę, że muszę coś zmienić w głównym oddziale, co powinno być we wszystkich innych gałęziach.
  • Zmieniłem to, czego potrzebowałem masteri ... oto mój problem:

Jak zaktualizować wszystkie inne oddziały za pomocą masterkodu oddziału?

Ionuț Staicu
źródło
3
Znalazłem tutaj odpowiedź: w jaki sposób scalasz pliki selektywne z git-merge?
wjandrea
58
Jeszcze jedno proste zadanie utrudnione przez Git. Deweloperzy Git powinni wykorzystywać przepełnienie stosu jako sprzężenie zwrotne w swojej pętli SDLC. 300 000 osób powinno wskazać, że coś jest nie tak z przepływem pracy Git. Muszą zatrudnić eksperta UX, ponieważ najwyraźniej nie są w stanie zrobić tego dobrze.
jww

Odpowiedzi:

620

Masz dwie opcje:

Pierwszy to scalanie, ale tworzy to dodatkowe zatwierdzenie dla scalania.

Kasa dla każdego oddziału:

git checkout b1

Następnie scal:

git merge origin/master

Następnie wciśnij:

git push origin b1

Alternatywnie możesz zrobić rebase:

git fetch
git rebase origin/master
Chris Kooken
źródło
15
Martwię się o to podejście. Kiedy uruchamiam git log --graph, wykres pokazuje, że wzorzec jest faktycznie scalony z gałęzią tematów. Czy na dłuższą metę spowoduje to jakiś problem? Myślałem, że najlepszą praktyką jest zawsze łączenie gałęzi tematów z powrotem do opanowania. Proszę skomentuj.
Patrick
2
Wypatruj tego problemu, jeśli korzystasz z przepływu pracy scalania: randyfay.com/node/89
Hampus Ahlgren
22
Scalasz wzorzec w b1. Dlaczego ty got push origin master... nie ma sensu. Nie zmieniasz gałęzi master. Myślę, że to pomyłka przy przegłosowaniu 119: /
Yves Lange
22
Nie używaj metody scalania, używając git rebase masterpoprawnej odpowiedzi
Weston Ganger,
6
Dla tych z nas, którzy czytają później - obawy @Kursion dotyczące literówki zostały rozwiązane przez redakcję autora. Druga najwyższa, wyżej oceniona odpowiedź mówi w zasadzie to samo co ta odpowiedź, ale ze schematem struktury gałęzi i ostrzeżeniem, dlaczego nie chcesz bazować.
poza theteal
495

Masz w zasadzie dwie opcje:

  1. Łączysz się. To jest właściwie dość proste i idealnie lokalne działanie:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    To pozostawia historię dokładnie tak, jak to się stało: rozwidliłeś się z mastera, dokonałeś zmian we wszystkich gałęziach, a na końcu wprowadziłeś zmiany z mastera do wszystkich trzech gałęzi.

    gitpotrafi poradzić sobie z tą sytuacją naprawdę dobrze, jest przeznaczony do łączenia zachodzącego we wszystkich kierunkach jednocześnie. Możesz ufać, że będzie w stanie poprawnie zebrać wszystkie wątki. Po prostu nie ma znaczenia, czy gałąź się b1połączy master, czy masterpołączy b1, zatwierdzenie scalania wygląda tak samo dla git. Jedyną różnicą jest to, która gałąź ostatecznie wskazuje na to zatwierdzenie scalania.

  2. Ty bazujesz. Osoby z SVN lub podobnym doświadczeniem uważają to za bardziej intuicyjne. Polecenia są analogiczne do przypadku scalenia:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

    Ludziom podoba się to podejście, ponieważ zachowuje ono liniową historię we wszystkich gałęziach. Jednak ta liniowa historia jest kłamstwem i powinieneś być tego świadomy. Rozważ ten wykres zatwierdzania:

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    Efektem scalenia jest prawdziwa historia:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    Jednak rebase daje ci tę historię:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    Chodzi o to, że rewizje E', F'i G'nigdy tak naprawdę nie istniał, i prawdopodobnie nigdy nie były testowane. Mogą nawet się nie kompilować. W rzeczywistości dość łatwe jest tworzenie bezsensownych zatwierdzeń poprzez rebase, szczególnie gdy zmiany mastersą ważne dla rozwoju w b1.

    Konsekwencją tego może być, że nie można odróżnić, który z trzech zatwierdzeń E, Fi Gfaktycznie wprowadził regresji, zmniejszając wartość git bisect.

    Nie mówię, że nie powinieneś używać git rebase. Ma swoje zastosowania. Ale za każdym razem, gdy go używasz, musisz zdawać sobie sprawę z faktu, że kłamiesz na temat historii. I powinieneś przynajmniej skompilować test nowych zatwierdzeń.

cmaster - przywróć monikę
źródło
Byłem scalanie kolejny oddział źródłowy (nie master) oraz dodatkowe kroki, aby dodać do tego miłą odpowiedź była zaktualizować go na moim lokalnym repo przed scalanie (aby mieć najnowszy kod lokalnie) git checkout <source branch> git pull. Następnie kontynuując powyżej: git checkout b1...
Rod
3
Jako długoletni użytkownik SVN wolę opcję scalania od bazy: za pomocą dowolnej kontroli wersji bardzo, bardzo ważne jest prowadzenie dokładnych rejestrów wprowadzonych zmian i przyczyn. Widzę apelację bazy w celu uproszczenia widocznej historii, ale powinieneś wtedy wrócić i dodać do zatwierdzonych komentarzy E ', F', G '- i najlepiej, aby rebase był automatycznie dodawany do tych komentarzy. W przeciwnym razie, jeśli proces kompilacji / testowania / wdrażania-testowania ulegnie awarii na G ', musisz dowiedzieć się, dlaczego zmiany zostały wprowadzone bez pełnej informacji.
WillC
13
Historia jest kłamstwem
piratemurray,
Dzięki używam „git merge any-branch-name” do scalenia jednego kodu oddziału do drugiego oddziału. Lokalnie mogę przetestować kod oddziału 1, gdy jestem na oddziale 2
Priti
1
@blamb Konflikty scalania zdarzają się zarówno z, jak git mergei git rebase. Nie da się tego uniknąć. git rebasema tę zaletę, że pozwala ukryć kilka etapów zmiany zasad (tj. zmianę tej samej gałęzi na kilka różnych zatwierdzeń w sekwencji, aby zmniejszyć liczbę konfliktów na każdym etapie). Niemniej jednak sam fakt, że rebase kłamie na temat historii, znacznie ułatwia spieprzanie w tak wieloetapowym rebase ... Dlatego zawsze wolę scalanie, nawet gdy oznacza to, że muszę zaśmiecać historię kilkoma zatwierdzeniami scalania .
cmaster
238

git rebase masterjest właściwym sposobem na zrobienie tego. Scalenie oznaczałoby zatwierdzenie do scalenia, a ponowne bazowanie nie.

Michael J. Gray
źródło
52
Co powiesz na to, kiedy już wypchnąłeś się do źródła, jeśli zmienisz bazę, przepisujesz historię zmian, co spowoduje konflikt ze zdalną gałęzią. Myślę, że rebase powinien być używany tylko podczas ściągania lub gdy nie zostałeś wypchnięty do zdalnej gałęzi.
Matt Smith
6
Jeśli jesteś jedynym pracującym w oddziale zdalnym, możesz użyć funkcji git push - force origin, aby zaktualizować zdalną gałąź w odmianie bazy lokalnej. stackoverflow.com/questions/8939977/…
stormwild
7
rebase i scal oba działa, rebase jest najlepszy dla prywatnych oddziałów, ponieważ daje czystszy wykres historii. ta odpowiedź jest najlepsza
Junchen Liu
5
Potrzebuję jaśniejszego określenia kompromisu między klarownością (świetną dla pojedynczego użytkownika lub małego zespołu) lub niechlujną prawdą (dla gałęzi kodu z wieloma współtwórcami - wymagana dla łatwości konserwacji (z mojego doświadczenia - YMMV)).
WillC
1
re „co jeśli już naciskałeś?” -> Złotą zasadą git rebase jest nigdy nie używać go w publicznych oddziałach .
Trevor Boyd Smith
53

Jeśli pracowałeś nad gałęzią bez przerwy lub wiele innych wydarzyło się podczas pracy nad czymś, najlepiej przenieść swoją gałąź na master. Utrzymuje to porządek w historii i znacznie ułatwia śledzenie.

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

Uwagi:

  • Nie bazuj na oddziałach, nad którymi współpracowałeś z innymi.
  • Powinieneś bazować na gałęzi, do której chcesz się połączyć, co nie zawsze może być master.

Rozdział na temat zmiany bazy znajduje się na stronie http://git-scm.com/book/ch3-6.html i mnóstwo innych zasobów w Internecie.

Simon Bingham
źródło
Dzięki za proste rozwiązanie
inny Wysoki facet
18

@cmaster udzielił najlepiej opracowanej odpowiedzi. W skrócie:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

Nie należy ponownie zapisywać historii oddziału, a zamiast tego utrzymywać ją w aktualnym stanie do przyszłych odniesień. Łącząc się z master, tworzy jedno dodatkowe zatwierdzenie, ale jest tanie. Zobowiązania nie kosztują.

niebieski księżyc
źródło
13

Aby zaktualizować inne gałęzie, takie jak (kopia zapasowa), za pomocą kopii oddziału głównego. Możesz wykonać dowolną drogę (rebase lub merge) ...

  1. Wykonaj zmianę bazy (nie będzie żadnych dodatkowych zmian dokonanych w oddziale kopii zapasowej).
  2. Scal gałęzie (nastąpi dodatkowe zatwierdzenie automatycznie w gałęzi kopii zapasowej).

    Uwaga: Rebase to nic innego jak ustanowienie nowej bazy (nowa kopia)

git checkout backup
git merge master
git push

(Powtórz dla innych oddziałów, jeśli takie jak backup2 i etc ..,)

git checkout backup
git rebase master
git push

(Powtórz dla innych oddziałów, jeśli takie jak backup2 i etc ..,)

Sundar Gsv
źródło
9

Możesz połączyć lub zastosować indywidualne zatwierdzenia między oddziałami, używając git cherry-pick .

Brian Agnew
źródło
1

Istnieją dwie opcje tego problemu.

1) git rebase

2) Git Merge

Tylko różnią się z powyższymi w przypadku scalenia, będą miały dodatkowe zatwierdzenie w historii

1) Git Checkout Branch (b1, b2, b3)

2) git rebase origin / master (w przypadku konfliktów rozwiąż je lokalnie wykonując git rebase - kontynuuj)

3) git push

Alternatywnie opcja scalania git jest podobna

1) Git Checkout „Your_branch” (b1, b2, b3)

2) Git Merge Master

3) git push

kris
źródło
0

aby zaktualizować swój oddział z poziomu głównego:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
D_Oghli
źródło