OK, myślałem, że to prosty scenariusz git, czego mi brakuje?
Mam master
oddział i feature
oddział. Trochę pracuję master
, trochę dalej feature
, a potem jeszcze trochę dalej master
. Kończę z czymś takim (kolejność leksykograficzna oznacza kolejność zatwierdzeń):
A--B--C------F--G (master)
\
D--E (feature)
Nie mam problemu z aktualizowaniem git push origin master
pilota master
ani z git push origin feature
(gdy jest on feature
) utrzymywaniem zdalnej kopii zapasowej dla mojej feature
pracy. Do tej pory jesteśmy dobrzy.
Ale teraz chcę bazować feature
na F--G
zatwierdzeniach na master, więc ja git checkout feature
i git rebase master
. Nadal dobrze. Teraz mamy:
A--B--C------F--G (master)
\
D'--E' (feature)
Problem: w momencie, gdy chcę wykonać kopię zapasową nowego, opartego na feature
rozgałęzieniu git push origin feature
, push jest odrzucany, ponieważ drzewo zmieniło się z powodu zmiany. Można to rozwiązać tylko za pomocą git push --force origin feature
.
Nienawidzę używania, --force
nie będąc pewnym, że go potrzebuję. Więc potrzebuję tego? Czy ponowne bazowanie niekoniecznie oznacza, że następne push
powinno być --force
pełne?
Ta gałąź funkcji nie jest dzielona z innymi programistami, więc nie mam problemu de facto z siłą nacisku, nie zamierzam stracić żadnych danych, pytanie jest bardziej koncepcyjne.
git pull feature-branch
, to ściągnięcie wygeneruje nowe zatwierdzenie scalania (poprzez połączenie zdalnych i lokalnych wersji gałęzi funkcji). Więc albo otrzymujesz niepotrzebne scalenie po zmianie bazy, albo naciskasz--force
.push --force
nie stanowi problemu), aby zachować historię zatwierdzeń liniowo bez żadnych zatwierdzeń scalania.--force-with-lease
jak sugeruje @hardev, jest świetną opcjąZamiast używać -f lub --force programiści powinni używać
Dlaczego? Ponieważ sprawdza zdalną gałąź pod kątem zmian, co jest absolutnie dobrym pomysłem. Wyobraźmy sobie, że James i Lisa pracują nad tym samym działem funkcji, a Lisa wprowadziła zatwierdzenie. James zmienia teraz swój oddział lokalny i jest odrzucany, gdy próbuje pchać. Oczywiście James uważa, że dzieje się tak z powodu zmiany bazy i użycia - force i przepisałby wszystkie zmiany Lisy. Gdyby James użył opcji - force-with-leasing, otrzymałby ostrzeżenie, że ktoś dopuścił się popełnienia przestępstwa. Nie rozumiem, dlaczego ktokolwiek używałby --force zamiast --force-with-lease podczas wypychania po rebase.
źródło
git push --force-with-lease
uratował mi sporo.--force-with-lease
rozwiązuje problem używania--force
Zamiast tego użyłbym „checkout -b” i łatwiej to zrozumieć.
po usunięciu uniemożliwisz wypchnięcie zamykającej gałęzi, która zawiera inny identyfikator SHA. W tym przypadku usuwam tylko gałąź zdalną.
źródło
push --force
, więc jest to tylko sposób na obejście repozytorium git--force
. W związku z tym nie sądzę, aby był to zawsze dobry pomysł - albo repo na to pozwalapush --force
, albo z dobrego powodu go wyłącza. Odpowiedź Nabi jest bardziej odpowiednia, jeśli--force
jest wyłączona na zdalnym repozytorium, ponieważ nie ma ryzyka utraty zatwierdzeń od innych programistów lub spowodowania innych problemów.Jednym z rozwiązań jest zrobienie tego, co robi skrypt scalania rebasingu msysGit - po rebase połącz się ze starą głową
feature
z-s ours
. Skończysz z wykresem zatwierdzenia:... a twoje pchnięcie
feature
będzie szybkie.Innymi słowy, możesz wykonać:
(Nie testowano, ale myślę, że to prawda ...)
źródło
git rebase
(zamiast ponownego łączeniamaster
z gałęzią funkcji) jest tworzenie historii czystych liniowych zatwierdzeń. Z twoim podejściem historia staje się jeszcze gorsza. A ponieważ rebasing tworzy nowe zatwierdzenia bez odniesienia do ich poprzednich wersji, nie jestem nawet pewien, czy wynik tego scalenia będzie odpowiedni.merge -s ours
to, że sztucznie dodaje odwołanie nadrzędne do poprzedniej wersji. Jasne, historia nie wygląda na czystą, ale wydaje się, że pytający jest szczególnie zaniepokojony tym, że musi wymusić naciskfeature
gałęzi, i to się omija. Jeśli chcesz dokonać zmiany bazy, to mniej więcej jedno lub drugie. :) Ogólnie rzecz biorąc, myślę, że interesujące jest to, że projektours
Wcześniej widziałem strategię, ale pomyślałem, że ma ona zastosowanie tylko do sytuacji konfliktowych, automatycznie rozwiązując je za pomocą zmian w naszym oddziale. Okazało się, że działa inaczej. I działanie w ten sposób jest bardzo przydatne, jeśli potrzebujesz wersji bazowej (np. Do opiekuna repozytoriów, aby zastosować ją czystomaster
), ale chcesz uniknąć wymuszania wypychania (jeśli wiele innych ppl z jakiegoś powodu używa twojej gałęzi funkcji).Może się zdarzyć, że w tej gałęzi jest tylko jeden programista, który teraz (po zmianie bazy) nie jest zgodny z początkiem / funkcją.
Jako taki sugerowałbym użycie następującej sekwencji:
Tak, nowy oddział, to powinno rozwiązać ten problem bez użycia siły, co, jak sądzę, ogólnie jest poważną wadą git.
źródło
Moim sposobem na uniknięcie wymuszenia siły jest utworzenie nowej gałęzi i kontynuowanie pracy nad tą nową gałęzią, a po pewnej stabilności usunąć starą gałąź, która została ponownie bazowana:
źródło
Inni odpowiedzieli na twoje pytanie. Jeśli zmienisz gałąź, będziesz musiał zmusić ją do popchnięcia.
Rebase i wspólne repozytorium na ogół się nie dogadują. To jest przepisywanie historii. Jeśli inni używają tej gałęzi lub rozgałęziają się z tej gałęzi, zmiana bazy będzie dość nieprzyjemna.
Ogólnie rzecz biorąc, rebase działa dobrze w przypadku zarządzania oddziałami lokalnymi. Zdalne zarządzanie oddziałami działa najlepiej w przypadku jawnych połączeń (--no-ff).
Unikamy również scalania wzorca w gałąź funkcji. Zamiast tego bazujemy na master, ale z nową nazwą oddziału (np. Dodając sufiks wersji). Pozwala to uniknąć problemu zmiany bazy w repozytorium współdzielonym.
źródło
Co jest złego
git merge master
wfeature
gałęzi? Pozwoli to zachować pracę, którą wykonałeś, jednocześnie oddzielając ją od gałęzi głównej.Edycja: Przepraszam, nie przeczytałem zgłoszenia problemu. Będziesz potrzebował siły podczas wykonywania
rebase
. Wszystkie polecenia modyfikujące historię będą wymagały--force
argumentu. Jest to bezpieczne, aby zapobiec utracie pracy (stareD
iE
zostałyby utracone).Więc wykonałeś polecenie,
git rebase
które sprawiło, że drzewo wyglądało (chociaż częściowo ukryte jakoD
iE
nie ma już w nazwanej gałęzi):Tak więc, próbując wcisnąć nowy
feature
oddział (z nimD'
iE'
w nim), straciszD
iE
.źródło
Dla mnie działają następujące proste kroki:
Po wykonaniu powyższych czynności możemy również usunąć gałąź myFeature, wykonując następujące polecenie:
źródło
Poniższe działa dla mnie:
git push -f origin branch_name
i nie usuwa żadnego mojego kodu.
Ale jeśli chcesz tego uniknąć, możesz wykonać następujące czynności:
wtedy możesz wybrać wszystkie swoje zobowiązania do nowego oddziału.
git cherry-pick COMMIT ID
a następnie pchnij nowy oddział.źródło
-f
jest pseudonimem--force
, dlatego w miarę możliwości pytanie próbuje tego uniknąć.Ponieważ PO rozumie problem, po prostu szuka ładniejszego rozwiązania ...
Co powiesz na to jako praktykę?
Posiadaj w branży rozwijającej funkcje (w której nigdy nie bazujesz na bazach i nie naciskasz na siłę, więc inni twórcy funkcji nie nienawidzą cię). Tutaj regularnie pobieraj te zmiany z głównego za pomocą scalenia. Messier history , tak, ale życie jest łatwe i nikt nie przeszkadza w jego pracy.
Mają drugą gałąź opracowywania funkcji, w której jeden członek zespołu ds. Funkcji normalnie popycha wszystkie zmiany funkcji, a nawet przekształca je, a nawet wymusza. Więc prawie czysto w oparciu o dość niedawne zatwierdzenie główne. Po zakończeniu funkcji przesuń gałąź na master.
Może już istnieć nazwa wzorca dla tej metody.
źródło