Nie chcę wizualnego narzędzia do scalania, a także nie chcę zmuszać do vi konfliktu pliku i ręcznego wybierania między HEAD (moim) a zaimportowaną zmianą (ich). Przez większość czasu chcę albo wszystkie ich zmiany, albo wszystkie moje. Zwykle dzieje się tak, ponieważ moja zmiana sprawiła, że grałem w górę i wraca do mnie poprzez przyciągnięcie, ale może być nieco zmodyfikowana w różnych miejscach.
Czy istnieje narzędzie wiersza polecenia, które pozbywa się znaczników konfliktu i wybiera wszystkie takie czy inne sposoby na podstawie mojego wyboru? Lub zestaw komend git, które mogę aliasu sobie do każdego z nich.
# accept mine
alias am="some_sequence;of;commands"
alias at="some_other_sequence;of;commands"
Robienie tego jest raczej denerwujące. Do „zaakceptuj moje” próbowałem:
randy@sabotage ~/linus $ git merge test-branch
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
Automatic merge failed; fix conflicts and then commit the result.
randy@sabotage ~/linus $ git checkout Makefile
error: path 'Makefile' is unmerged
andy@sabotage ~/linus $ git reset --hard HEAD Makefile
fatal: Cannot do hard reset with paths.
Jak mam się pozbyć tych znaczników zmian?
Potrafię:
git reset HEAD Makefile; rm Makefile; git checkout Makefile
Ale wydaje się to dość okrągłe, musi być lepszy sposób. I w tym momencie nie jestem pewien, czy git nawet myśli, że nastąpiło scalenie, więc nie sądzę, że to koniecznie działa.
Idąc w drugą stronę, robienie „zaakceptuj ich” jest równie nieporządne. Jedyny sposób, w jaki mogę to rozgryźć, to:
git show test-branch:Makefile > Makefile; git add Makefile;
Daje mi to także błędny komunikat zatwierdzenia, który zawiera dwa razy Konflikty: Makefile.
Czy ktoś może wskazać, jak wykonać powyższe dwie czynności w prostszy sposób? Dzięki
Odpowiedzi:
Rozwiązanie jest bardzo proste.
git checkout <filename>
próbuje wyewidencjonować plik z indeksu , a zatem nie powiedzie się podczas scalania.To, co musisz zrobić, to (tzn. Sprawdzić zatwierdzenie ):
Aby pobrać własną wersję , możesz użyć jednego z:
lub
lub
Aby pobrać drugą wersję , możesz użyć jednego z:
lub
lub
Musisz także uruchomić polecenie „dodaj”, aby oznaczyć go jako rozwiązany:
źródło
--ours
i--theirs
oznacza dokładnie odwrotność tego, co intuicyjnie myślałem, wypróbowując to polecenie ...git show
- pomija to normalizację nowej linii.--
jest używany przez Git do oddzielania wersji (nazwy oddziałów itp.) Od nazw ścieżek (nazwy plików, katalogi). Ważne jest, aby Git nie mógł zdecydować, czy nazwa jest nazwą oddziału, czy nazwą pliku. Jest to zgodne z konwencją POSIX (lub GNU) polegającą na używaniu podwójnego myślnika do oddzielania opcji od argumentów (nazw plików).theirs
/ours
może pojawić zamienione jeśli rozwiązywania konfliktów w kontekście operacji rebase. Ponieważ rebase działa poprzez sprawdzenie gałęzi docelowej, a następnie wybieranie cherry commits z „twojej” gałęzi na cel, nadchodząca zmiana („ich”) pochodzi z „twojej” gałęzi, a bieżąca gałąź jest gałęzią docelową („naszą”) ).Spróbuj tego:
Aby zaakceptować ich zmiany:
git merge --strategy-option theirs
Aby zaakceptować swoje:
git merge --strategy-option ours
źródło
Na podstawie odpowiedzi Jakuba możesz dla wygody skonfigurować następujące aliasy git:
Opcjonalnie biorą jedną lub kilka ścieżek plików do rozwiązania i domyślnie rozwiązują wszystko w bieżącym katalogu, jeśli nie są podane.
Dodaj je do
[alias]
sekcji swojego~/.gitconfig
lub uruchomźródło
[alias]
sekcji w swoim~.gitconfig
lub użyjgit config --global accept-ours "..."
. Zredagowałem moją odpowiedź.~/.gitconfig
.!f() { git checkout --ours -- "${@:-.}" git add -u "${@:-.}; }; f
W oparciu o odpowiedź Kynana, oto te same aliasy, zmodyfikowane, aby mogły obsługiwać spacje i początkowe myślniki w nazwach plików:
źródło
Idealną sytuacją dla rozwiązywania konfliktów jest gdy wiesz z wyprzedzeniem, w jaki sposób chcesz je rozwiązać i może przekazać
-Xours
lub-Xtheirs
cyklicznych opcje strategiczne seryjnej. Poza tym widzę trzy scenariusze:Aby rozwiązać te trzy scenariusze, możesz dodać następujące wiersze do
.gitconfig
pliku (lub odpowiednika):The
get(ours|theirs)
Narzędzie po prostu utrzymuje odpowiednią wersję pliku i odrzuca wszystkie zmiany z innej wersji (więc nie występuje łączenie).merge(ours|theirs)
Narzędzie ponownie robi trzy sposób scalania z lokalnego, zasady i zdalne wersje pliku, wybierając do rozwiązywania konfliktów w danym kierunku. Ma to pewne zastrzeżenia, w szczególności: ignoruje opcje diff, które zostały przekazane do polecenia scalania (takie jak obsługa algorytmu i białych znaków); czy scalanie odbywa się czysto z oryginalnych plików (więc wszelkie ręczne zmiany w pliku są odrzucane, co może być dobre lub złe); i ma tę zaletę, że nie można go pomylić ze znacznikami różnic, które powinny znajdować się w pliku.The
keep(ours|theirs)
Narzędzie po prostu edytuje się znaczników diff oraz wydzielone sekcje, wykrywanie ich przez wyrażenie regularne. Ma to tę zaletę, że zachowuje opcje różnic z polecenia scalania i pozwala ręcznie rozwiązać niektóre konflikty, a następnie automatycznie rozwiązać pozostałe. Ma tę wadę, że jeśli w pliku znajdują się inne znaczniki konfliktu, może się pomylić.Wszystkie są używane przez uruchamianie,
git mergetool -t (get|merge|keep)(ours|theirs) [<filename>]
jeśli jeśli<filename>
nie zostanie dostarczone, przetwarza wszystkie pliki będące w konflikcie.Ogólnie rzecz biorąc, zakładając, że wiesz, że nie ma żadnych znaczników różnic, które mylą wyrażenie regularne,
keep*
warianty polecenia są najpotężniejsze. Jeśli pozostawiszmergetool.keepBackup
opcję nieustawioną lub true, po scaleniu możesz różnicować*.orig
plik względem wyniku scalenia, aby sprawdzić, czy ma to sens. Jako przykład uruchamiam następujące pomergetool
prostu, aby sprawdzić zmiany przed zatwierdzeniem:Uwaga : jeśli
merge.conflictstyle
nie jest, to zamiastdiff3
tego należy zastosować/^|||||||/
wzorzec wsed
regule/^=======/
.źródło