Powiedzmy, że mamy następującą sytuację w Git:
Utworzone repozytorium:
mkdir GitTest2 cd GitTest2 git init
Niektóre zmiany w wzorcu mają miejsce i zostają popełnione:
echo "On Master" > file git commit -a -m "Initial commit"
Feature1 rozgałęził master i część pracy została wykonana:
git branch feature1 git checkout feature1 echo "Feature1" > featureFile git commit -a -m "Commit for feature1"
W międzyczasie wykryto błąd w kodzie głównym i utworzono gałąź poprawki:
git checkout master git branch hotfix1 git checkout hotfix1
Błąd został naprawiony w gałęzi poprawek i scalony z powrotem w master (być może po żądaniu ściągnięcia / sprawdzeniu kodu):
echo "Bugfix" > bugfixFile git commit -a -m "Bugfix Commit" git checkout master git merge --no-ff hotfix1
Prace nad funkcją 1 trwają:
git checkout feature1
Powiedz, że potrzebuję poprawki w mojej gałęzi funkcji, być może dlatego, że błąd również tam występuje. Jak mogę to osiągnąć bez powielania zatwierdzeń w mojej gałęzi funkcji?
Chcę zapobiec otrzymaniu dwóch nowych zatwierdzeń w mojej gałęzi funkcji, które nie mają związku z implementacją funkcji. Wydaje mi się to szczególnie ważne, jeśli używam żądań ściągnięcia: wszystkie te zatwierdzenia zostaną również uwzględnione w żądaniu ściągnięcia i będą musiały zostać przejrzane, chociaż zostało to już zrobione (ponieważ poprawka jest już w systemie głównym).
Nie mogę zrobić git merge master --ff-only
: „fatalny: nie można szybko przewinąć do przodu, przerywanie.”, Ale nie jestem pewien, czy to mi pomogło.
źródło
feature1
jest całkowicie lokalny, spójrz nagit rebase
.git rebase
wydaje mi się czarną magią ....git branch feature1
igit checkout feature1
mogą być łączone wgit checkout -b feature1
4. i mogą być całkowicie zredukowane dogit checkout -b hotfix1 master
Odpowiedzi:
Jak scalimy gałąź główną w gałąź funkcji? Łatwy:
Nie ma sensu wymuszać szybkiego łączenia w przód, ponieważ nie można tego zrobić. Zaangażowałeś się zarówno w gałąź funkcji, jak i gałąź główną. Szybkie przewijanie do przodu jest teraz niemożliwe.
Spójrz na GitFlow . Jest to rozgałęziony model git, który można śledzić, a ty nieświadomie już to zrobiłeś. Jest to także rozszerzenie Gita, które dodaje polecenia do nowych kroków przepływu pracy, które wykonują czynności automatycznie, które w innym przypadku byłyby konieczne ręcznie.
Więc co zrobiłeś dobrze w swoim przepływie pracy? Masz dwie gałęzie do pracy, twoja gałąź feature1 jest w zasadzie gałęzią „develop” w modelu GitFlow.
Utworzyłeś gałąź master z poprawki i scaliłeś ją z powrotem. A teraz utknąłeś.
Model GitFlow prosi o połączenie poprawki również z gałęzią programistyczną, która w twoim przypadku jest „feature1”.
Tak więc prawdziwą odpowiedzią byłoby:
Dodaje to wszystkie zmiany wprowadzone w tej poprawce do gałęzi funkcji, ale tylko te zmiany. Mogą one powodować konflikty z innymi zmianami programistycznymi w gałęzi, ale nie będą powodować konfliktu z gałęzią główną, jeśli w końcu scalisz gałąź funkcji z powrotem do jednostki głównej.
Zachowaj ostrożność przy zmianie bazy. Bazuj tylko wtedy, gdy dokonane zmiany pozostały lokalne w twoim repozytorium, np. Nie wypchnąłeś żadnych oddziałów do innego repozytorium. Rebasing to świetne narzędzie do uporządkowania lokalnych zobowiązań w użyteczną kolejność przed wypchnięciem ich na świat, ale późniejsze ich wycofanie zepsuje rzeczy początkującym początkującym użytkownikom.
źródło
git merge master
połączenie połączy się z lokalną kopią wzorca, więc nawet jeśli zrobiłeś cośgit pull
w gałęzi funkcji po tym, jak ktoś inny połączył inną gałąź w wzorzec, musiszgit checkout master
wtedygit pull
, a potemgit checkout feature1
znowu , a potemgit merge master
.git fetch
igit merge origin/master
git pull origin master
automatycznie połączyorgin/master
się z bieżącym oddziałemPowinieneś być w stanie dokonać zmiany bazy na master:
Zarządzaj wszystkimi pojawiającymi się konfliktami. Kiedy dojdziesz do zatwierdzeń z poprawkami błędów (już w master), Git powie, że nie było żadnych zmian i że być może zostały już zastosowane. Następnie kontynuujesz rebase (pomijając zatwierdzenia już w master) za pomocą
Jeśli wykonasz polecenie
git log
w gałęzi funkcji, zobaczysz, że zatwierdzenie poprawki błędu pojawia się tylko raz, w części głównej.Aby uzyskać bardziej szczegółową dyskusję, zapoznaj się z dokumentacją książki Git na
git rebase
( https://git-scm.com/docs/git-rebase ), która obejmuje ten dokładny przypadek użycia.================ Edytuj dla dodatkowego kontekstu ====================
Ta odpowiedź została udzielona specjalnie na pytanie zadane przez @theomega, biorąc pod uwagę jego szczególną sytuację. Zwróć uwagę na tę część:
Odbudowanie jego prywatnego oddziału na kapitanie jest dokładnie tym, co przyniesie ten wynik. W przeciwieństwie do tego, połączenie mistrza z jego gałęzią zrobiłoby dokładnie to, czego konkretnie nie chce się wydarzyć : dodanie zmiany, która nie jest związana z implementacją funkcji, nad którą pracuje za pośrednictwem swojego oddziału.
Aby zwrócić się do użytkowników, którzy czytają tytuł pytania, pomiń faktyczną treść i kontekst pytania, a następnie przeczytaj tylko górną odpowiedź na ślepo, zakładając, że zawsze będzie ona dotyczyć ich (innego) przypadku użycia, pozwól mi rozwinąć:
git merge master
jak w odpowiedzi @ Svena).Na koniec, jeśli jesteś niezadowolony z faktu, że ta odpowiedź nie najlepiej pasuje do Twojej sytuacji, mimo że dotyczyła @theomega, dodanie poniższego komentarza nie będzie szczególnie pomocne: nie kontroluję, która odpowiedź jest wybrana, robi to tylko @ theomega.
źródło
-f
przy wypychaniu w celu zastąpienia gałęzi wersją opartą na zmianie. Bądź ostrożny!-f
? Czy mój pełny przepływ pracy jest wadliwy, ponieważ potrzebuję-f
?feature1
z Github.master
w oddziale prywatnym (wspomina o „swoim” oddziale lokalnym). W takim przypadkurebase
jest w porządku i jest to ten sam przypadek użycia, o którym wspominałeś o „czyszczeniu”.Na podstawie tego artykułu powinieneś:
utwórz nowy oddział oparty na nowej wersji master
git branch -b newmaster
połącz swoją starą gałąź funkcji w nową
git checkout newmaster
rozwiązać konflikt w nowej gałęzi funkcji
Pierwsze dwa polecenia można połączyć z
git checkout -b newmaster
.W ten sposób Twoja historia pozostaje przejrzysta, ponieważ nie potrzebujesz scalania z powrotem. I nie musisz być tak bardzo ostrożny, ponieważ nie musisz robić bazy Git.
źródło
git merge
1. Scal
origin/master
gałąź zfeature
gałęzią2. Scal
feature
gałąź zorigin/master
gałęziąźródło
Odpowiedź Zimi ogólnie opisuje ten proces. Oto szczegóły:
Utwórz i przełącz się na nowy oddział. Upewnij się, że nowa gałąź jest oparta,
master
aby zawierała najnowsze poprawki.Po przejściu do nowej gałęzi scal zmiany z istniejącej gałęzi funkcji. Spowoduje to dodanie zatwierdzeń bez powielania zatwierdzeń poprawek.
W nowej gałęzi rozwiąż wszelkie konflikty między funkcją a gałęzią główną.
Gotowy! Teraz skorzystaj z nowego oddziału, aby nadal rozwijać swoją funkcję.
źródło
Oto skrypt, którego możesz użyć do scalenia głównej gałęzi z bieżącą gałęzią.
Skrypt wykonuje następujące czynności:
Zapisz ten kod jako plik wsadowy (.bat) i umieść skrypt w dowolnym miejscu w repozytorium. Następnie kliknij go, aby go uruchomić i jesteś gotowy.
źródło
Możesz być w stanie wykonać „wybranie”, aby pobrać dokładnie te zatwierdzenia, które potrzebujesz w gałęzi funkcji.
Zrób,
git checkout hotfix1
aby dostać się do gałęzi poprawki 1. Następnie wykonaj a,git log
aby uzyskać skrót SHA-1 (duża sekwencja losowych liter i cyfr, które jednoznacznie identyfikują zatwierdzenie) danego zatwierdzenia. Skopiuj ten (lub pierwsze 10 lub więcej znaków).Następnie,
git checkout feature1
aby wrócić do gałęzi funkcji.Następnie,
git cherry-pick <the SHA-1 hash that you just copied>
Spowoduje to przeciągnięcie tego zatwierdzenia i tylko tego zatwierdzenia do gałęzi funkcji. Ta zmiana będzie miała miejsce w gałęzi - po prostu „wybrałeś ją”. Następnie wznów pracę, edytuj, zatwierdzaj, wypychaj itd. Do zadowolenia swojego serca.
Kiedy w końcu wykonasz kolejne scalenie z jednej gałęzi do swojej gałęzi funkcji (lub odwrotnie), Git rozpozna, że już scaliłeś się w tym konkretnym zatwierdzeniu, wie, że nie musi to robić ponownie, i po prostu „przeskocz”.
źródło
git merge
działało w tym „powtórzeniu zatwierdzeń” - tak, jakbyś sugerował („i po prostu pomiń”). Mieszanie zbioru wiśni i łączenie może najwyraźniej prowadzić do problemów; patrz: news.ycombinator.com/item?id=3947950Jestem w dziale funkcji i dokonałem refaktoryzacji. Chcę teraz scalić główne zmiany z moją gałęzią funkcji. Jestem daleko w tyle. Uwaga: Nie chcę pobierać zmian głównych do mojego lokalnego, ponieważ moja gałąź funkcji ma moduły przeniesione z jednego miejsca do drugiego. Stwierdziłem, że wykonywanie poniżej bez ściągania nie działa. jest napisane „Już aktualne”.
Działa to poniżej, zauważ użycie git merge origin / master:
źródło