2015-02-20 14 views
6

Po zakończeniu pracy na temat branży, I połączyły gałąź temat do pana jak następuje:Git: przebazowania skonfliktowany scalającej

  o---*---o---o topic 
     /   \ 
o---o---o---*---o---o---+ master 

zobowiązuje oznaczone „*” zmodyfikowane ten sam kod, stąd łączenie prowadzenie aby scalić konflikty, które zostały rozwiązane w zatwierdzeniu scalenia (oznaczone "+").

Chociaż połączone i rozwiązane konflikty, mój kolega popchnął nowych zobowiązuje się do opanowania (oznaczona jako „N”), w wyniku następującej historii:

  o---*---o---o topic 
     /   \ 
o---o---o---*---o---o---+ master 
        \ 
        n---n origin/master 

Teraz, spychając moje lokalnej oddział główny oczywiście prowadzi do błąd, jak to nie fast-forward-Push, więc mam dwie możliwości:

  1. wyrzucić moją pracę, master reset do pochodzenia/master i przerobić seryjnej. Chciałbym tego uniknąć, ponieważ będę musiał rozwiązać konflikty od nowa.

  2. Zmień wzorzec na początek/wzorzec i wciśnij. Oto mój problem: wykonanie tego rebase (nawet przy użyciu przełącznika -p) nie działa płynnie, zatwierdzenie scalania pokazuje te same konflikty ponownie, mimo że nowe zatwierdzenia ("n") nie zmieniły niczego dotkniętego przez gałąź tematu . Więc będę musiał ponownie rozwiązać konflikty podczas rebase i będzie miało taki sam wynik jak w przypadku opcji 1.

Co chciałbym osiągnąć jest przebazowania scalanie popełnić „+”, bez konieczności rozwiązywania ponownie konflikty:

  o---*---o---o-------- topic 
     /     \ 
o---o---o---*---o---o---n---n---+ master & origin/master 

Edit:

przełącznik rerere jest włączona, ale nie wydaje się, aby pomóc w jakikolwiek sposób; czy muszę ustawić coś więcej niż ustawienie config.rerere na true, aby naprawić mój problem?

Edit 2:

scalanie scalenie-commit („+”) do pochodzenia/master będzie także pracować (jak zaproponowano w komentarzach i odpowiedzi), ale doprowadzi do pewnego rodzaju brzydkiej historii, która ja” Chciałbym tego uniknąć, ponieważ tylko jeden commit został zatwierdzony.

+0

Możesz także cofnąć pochodzenie/wzorzec przed połączeniem z nim nowego wzorca. – ScayTrase

+0

@ScayTrase Byłoby to możliwe, ale prowadziłoby to do jakiejś brzydkiej historii; Wolałbym czyste rozwiązanie z jednym zatwierdzeniem scalania tylko – rhabarbersaft

+0

Niestety, nie ma realnego wyjścia z tego: bez względu na to, którą z dwóch opcji wybierzesz, najprawdopodobniej będziesz musiał rozwiązać konflikty od nowa. Jeśli spodziewasz się, że znajdziesz się w tej samej sytuacji w przyszłości, prawdopodobnie powinieneś rozważyć aktywowanie ['rerere'] (http://stackoverflow.com/questions/25670519/git-rebase-preserve-merges-fails/ 25671230 # 25671230). – Jubobs

Odpowiedz

0

Co jeśli rebase temat na szczycie mistrza, a następnie przywrócić do poprzedniego mistrza popełnić i wyjąć z pilota, tak że trzeba było to:

  o---*---o---o 
     /   \ 
o---o---o---*---o---o---+ topic 
        \ 
        n---n master & origin/master 

a następnie scalić temat do opanowania, w wyniku tego (nowe zatwierdzenie merge oznaczone "#"):

  o---*---o----o 
     /   \ 
o---o---o---*---o---o----+ topic 
        \  \ 
        n--n--# master 

Czy to powoduje konflikty? Czy to zadziałałoby dla Ciebie?

+0

Chciałbym zapobiec tej "brzydkiej" historii i mieć tylko jeden scalony commit – rhabarbersaft

1

Pierwszy sposób byłby najlepszy. Cofnij scalanie i ponów je, aby zmiany w koleżance zostały wprowadzone do zatwierdzenia scalenia. Ale nie musisz wyrzucać zmian.

Ponieważ wiesz, że zmiany wprowadzone przez twojego kolegę nie wpłynęły na pliki, w których rozwiązałeś konflikty. Możesz utworzyć nowy oddział (nazwijmy go conflict-fix) z Twojego obecnego stanu wzorca. Zresetuj gałąź i ponów scalenie.

Zamiast używać git mergetool lub dowolnego edytora, którego używasz. Możesz przenieść plik do wzorca z innego oddziału, używając git checkout conflict-fix -- <file names>. git add pliki i zatwierdzenie do zakończenia scalania. Następnie możesz usunąć gałąź conflict-fix.

Jest to dość łatwe do zrobienia i spowoduje złożenie pojedynczego scalenia, którego szukasz, co pozwoli ci wprowadzić zmiany. Jeśli nowe zatwierdzenia wpłynęły na pliki, w których rozwiązałeś konflikty, to i tak musisz je ponownie.

EDIT

nie jestem całkowicie zaznajomiony z git rerere ale które powinny pracowali. Jednak na podstawie Twojego komentarza nie powinieneś wymagać ponownego podziału. Nadal byś nie wykonał scalenia, git fetch aktualizacji i ponownie wykonał scalenie. Musiałbyś po prostu zadzwonić do komendy git rerere, aby rozwiązać konflikty w plikach. Z drzewa wygląda tak:

  o---*---o---A topic 
     /   \ 
o---o---o---*---o---o---+ master 
       \ 
        n---n origin/master 

będzie można wykonać następujące czynności:

git reset --hard A 
git checkout master 
git pull 
git merge topic 
git rerere 
//Fix other conflicts 
git push 

I należy skończyć z:

  o---*---o---o-------- topic 
     /     \ 
o---o---o---*---o---o---n---n---+ master & origin/master 

Nie powinno być potrzeby zmieniają bazę czegokolwiek.

http://git-scm.com/docs/git-rerere

+0

Po prostu próbowałem to działa dobrze. Ale: jeśli origin/master zawiera zmiany w tym samym pliku prowadzące do konfliktów (zmodyfikowane w "*"), ale na innych liniach (nie prowadząc do dodatkowych konfliktów scalających), zmiany te zostaną cofnięte, jeśli po prostu sprawdzę "konflikt-fix" '-wersje konfliktowych plików. Dlatego wciąż szukam rozwiązania z Gitem automatycznie ponownie stosującym rozwiązanie konfliktu, które zrobiłem w pierwszym scaleniu (i myślałem, że 'rerere' to zrobi) – rhabarbersaft

+0

Niestety' rerere' nie działa w tym przypadku, po prostu wypróbowałem to znowu jest pewne. Mówi nawet "Nagraną rozdzielczość dla ..." przy łączeniu się po raz pierwszy, ale nie robi nic w ogóle, po ponownym scaleniu zgodnie z propozycją. – rhabarbersaft

0

rerere jest sposobem na uniknięcie tego jest taki kłopotów, ale jeśli nie masz to włączone zanim zrobił pierwszy seryjnej nie pomóc. Możesz dowiedzieć się, czy jest włączona, ponieważ będzie wyświetlać komunikaty o "nagrywaniu wstępnego obrazu".

Wpadłem na to sam niedawno, ponieważ miałem nową maszynę programistyczną i zapomniałem włączyć ponownie przed brzydkim scaleniem. W tym scenariuszu nie ma wielkiego rozwiązania tylko dla gitów, ale oto najłatwiejsze odzyskanie tej sytuacji, którą mogłem wymyślić.

  1. Upewnij się, że katalog roboczy jest dokładnie taki wynik seryjnej (git resetowania HEAD --hard) i skopiować drzewa źródłowego z seryjnej popełnić jakieś bezpieczne
  2. zresetować lokalnym oddziałem powrotem przed wszelkimi połączonych zatwierdzeń (git resetowania --hard mistrz ~ lub git resetowania HEAD ~ n, gdzie n jest to, jak daleko trzeba iść)
  3. git ciągnąć
  4. git merge temat
  5. kopia pliki źródłowe z powrotem do drzewa roboczego nadpisaniem.
  6. git mergetool (obsłużyć dowolny usunięty vs zmodyfikowanych konfliktów)
  7. popełnić i wcisnąć

Ponieważ byliśmy w pracy z Gerrit Ja również pewien, że zmiana-Id był taki sam jak mój poprzedni scalającej tak Mogłem sprawdzić, czy nic nie poszło nie tak.

Powiązane problemy