Łączenie części gałęzi git z masterem

Mam prostą gałąź z wieloma zmianami:

Master ---A---B---C
                   \
              Foo   E---F---G---H

Teraz muszę połączyć się z Mistrzem tylko częścią moich zmian. Jestem nowy w git (obecnie używam go z SourceCode w systemie Windows) i myślałem o zrobieniu tego w ten sposób:

Master ---A---B---C---?---J---?---?---
                   \     /
              Foo   E---G'
                         \
                    Bar   F'---H'---

Potrzebuję tylko niektórych części z branży. Pracowałem nad 4 interfejsami API różnych producentów do wdrożenia. Teraz tylko 1 musi wejść do produkcji, a reszta jest wstrzymana. Powiedzmy, że zmodyfikowano łącznie 19 plików, ale potrzebuję tylko 7 z nich. Teraz muszę oddzielić tych 7, zsynchronizować z masterem i wypchnąć jako inną gałąź, aby CTO mógł później połączyć je z Masterem.

Czy to jest dobry sposób? A jak mam to zrobić poprawnie?


person Peon    schedule 23.05.2016    source źródło
comment
Na zdjęciu wszystkie zmiany przeszły na master. Może chciałeś tylko E F na Foo, a GH przeniósł się do Bar?   -  person choroba    schedule 23.05.2016
comment
Dokładnie, nadal walczę z tego typu diagramami.   -  person Peon    schedule 23.05.2016
comment
Prawdopodobnie możesz użyć do tego git --cherry-pick   -  person Vishwanath    schedule 23.05.2016
comment
Przeglądając możliwości, myślę, że nie jest to takie proste, jak wspomniałem. Zmiany, które muszę zatwierdzić, obejmują wiele zatwierdzeń w gałęzi, więc do podziału potrzebowałbym części E, części G i części H. Zasadniczo potrzebuję sposobu na wypchnięcie tylko niektórych plików z mojej gałęzi do nowej gałęzi, która zostanie wypchnięta do mastera później tego dnia.   -  person Peon    schedule 23.05.2016
comment
git checkout Foo;git reset E --hard;git cherry-pick G;git checkout -b Bar Foo;git cherry-pick F;git cherry pick H Foo to ABCEG', Bar to ABCEG'F'H'.   -  person ElpieKay    schedule 23.05.2016


Odpowiedzi (1)


Jeśli szczegółowo omówimy Twój problem, musisz:

  1. Podziel 4 (E, F, G, H) z Foo na 2 gałęzie, Foo będzie miał tylko: E, G, ale Bar będzie miał wszystkie 4, E -> G -> F -> H.
  2. Usuń niektóre zatwierdzenia: np. w Foo usuń zatwierdzenia F i H.
  3. Nie jestem pewien, czy chcesz „zmienić kolejność” zatwierdzeń na pasku gałęzi, tj. mieć E, G, F, H -> Zakładam, że to nie rozwiązuje żadnego celu, więc pominę to w mojej odpowiedzi.

Można to zrobić na wiele sposobów, ale ograniczę się do najprostszego schematu, jaki przychodzi mi na myśl, ponieważ nie masz doświadczenia z gitem. spójrzmy więc na podział gałęzi:

Z twojego obecnego Foo (head = H) wykonaj git checkout -b Bar To utworzy pasek gałęzi z zatwierdzeniami E, F, G, H

Istnieją dwa sposoby resetowania gałęzi Foo:
#1 Odrzuć Foo i utwórz ją ponownie git branch -D Foo (aby usunąć z lokalnego) git push origin :Foo (aby usunąć ze zdalnego, jeśli już to zrobiłeś) pchnął to)

Następnie musisz utworzyć nowe Foo z zatwierdzenia „C” swojego mistrza:

git checkout -b Foo <CommitIdShaForC>

Następnie możesz wybierać zatwierdzenia E i G albo z git gui, wykonując gitk Bar, a następnie klikając prawym przyciskiem myszy zatwierdzenie i wybierając opcję wiśniowego wyboru, albo z konsoli:

git cherry-pick <Commit Id for E> <Commit Id for G>

W przypadku problemów z łączeniem spójrz na tę odpowiedź

#2 Cofnij zatwierdzenia z Foo Jeśli nie masz nic przeciwko posiadaniu historii F i H w swoim foo, możesz po prostu przywrócić je w git, zasadniczo git tworzy odwrotną łatkę twoich zatwierdzeń F i H oraz stosuje je jako nowe zatwierdzenia:

  • Jesteś na oddziale Foo i ma on E -> F -> G -> H
  • git revert F
  • Twoja gałąź powinna teraz pokazywać E -> F -> G -> H -> F', gdzie F' cofa to, co dodał zatwierdzenie F
  • git revert H doprowadziłoby do: E -> F -> G -> H -> F' -> H' którego końcowy wynik w kodzie źródłowym byłby taki sam jak w przypadku zatwierdzenia tylko E i G.

Alternatywnie możesz użyć flagi --no-commit na git revert, aby przywrócić zarówno F, jak i H w 1 zatwierdzeniu:

git revert --no-commit F
git revert --no-commit H
git commit -a -m "reverting commits F and H"

Prowadziłoby to do:

E -> F -> G -> H -> I gdzie I jest zatwierdzeniem, które cofa F i H

#Aktualizacja 1 Po napisaniu długiej odpowiedzi widzę, że OP chce mieć „część zatwierdzeń” w kilku gałęziach. W tym przypadku gorąco polecam interaktywną bazę danych, aby można było dzielić zatwierdzenia. Proszę zapoznać się z oficjalną dokumentacją na temat git rebase, w szczególności z sekcją dotyczącą „ Dzielenie zatwierdzeń”. Myślę też, że to pytanie będzie dla Ciebie szczególnie pomocne

person dubes    schedule 23.05.2016
comment
Tak jak pisałem w komentarzu potrzebuję tylko niektórych części z branży. Pracowałem nad 4 interfejsami API różnych producentów do wdrożenia. Teraz tylko 1 musi wejść do produkcji, a reszta jest wstrzymana. Powiedzmy, że zmodyfikowano łącznie 19 plików, ale potrzebuję tylko 7 z nich. Teraz muszę oddzielić tych 7, zsynchronizować z masterem i wypchnąć jako inną gałąź, aby CTO mógł później połączyć je z Masterem. - person Peon; 23.05.2016
comment
@DainisAbols zaktualizował moją odpowiedź, podając wskazówki dotyczące dzielenia zatwierdzeń. Również Twój komentarz dodaje znacznej przejrzystości Twojemu pytaniu. Czy możesz go edytować, aby inni mogli uznać go za przydatny. - person dubes; 23.05.2016
comment
@DainisAbols: spójrz na załączony przeze mnie wątek z pytaniami, myślę, że w końcu to właśnie chcesz zrobić. - person dubes; 23.05.2016
comment
Skończyło się na tym, że utworzyłem gałąź z zatwierdzenia E i porównałem ją z H. Wziąłem tylko niezbędne zmiany i zrobiłem z nimi rebase. W ten sposób otrzymałem odpowiednie dane w osobnej gałęzi, która została pomyślnie połączona z masterem. Po prostu daj znać. - person Peon; 24.05.2016
comment
To było trudne... sytuacja, o której wspomniałeś, była rzeczywiście trudna. Mam nadzieję, że nie będziesz musiał spotykać się z więcej takimi jak oni... ale jeśli do tego dojdzie, odpowiedz na ten komentarz, a my przeniesiemy go na czat i spróbujemy wymyślić interaktywny rebase git - person dubes; 24.05.2016