Jak rozwiązać konflikty scalania w Git?
git
instalacji domyślnej . Udało mi się wejść dziś na stronę startową SE, 2017, z 1,3 mln wyświetleń i tysiącami głosów w obie strony. Fascynujący.
Jak rozwiązać konflikty scalania w Git?
git
instalacji domyślnej . Udało mi się wejść dziś na stronę startową SE, 2017, z 1,3 mln wyświetleń i tysiącami głosów w obie strony. Fascynujący.
Odpowiedzi:
Próbować: git mergetool
Otwiera GUI, które przeprowadzi cię przez każdy konflikt, i będziesz mógł wybrać sposób połączenia. Czasami wymaga to później ręcznej edycji, ale zwykle wystarczy sam. Z pewnością jest to o wiele lepsze niż zrobienie wszystkiego ręcznie.
Zgodnie z komentarzem @JoshGlover:
Komenda
niekoniecznie otwiera GUI, chyba że go zainstalujesz. Uruchomienie
git mergetool
dla mnie spowodowało, że zostałemvimdiff
użyty. Można zainstalować jeden z poniższych narzędzi, aby go używać zamiast:meld
,opendiff
,kdiff3
,tkdiff
,xxdiff
,tortoisemerge
,gvimdiff
,diffuse
,ecmerge
,p4merge
,araxis
,vimdiff
,emerge
.
Poniżej znajduje się przykładowa procedura do vimdiff
rozwiązywania konfliktów scalania. Na podstawie tego linku
Krok 1 : Uruchom następujące polecenia w swoim terminalu
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false
Spowoduje to ustawienie vimdiff jako domyślnego narzędzia do scalania.
Krok 2 : Uruchom następujące polecenie w terminalu
git mergetool
Krok 3 : Zobaczysz ekran vimdiff w następującym formacie
╔═══════╦══════╦════════╗
║ ║ ║ ║
║ LOCAL ║ BASE ║ REMOTE ║
║ ║ ║ ║
╠═══════╩══════╩════════╣
║ ║
║ MERGED ║
║ ║
╚═══════════════════════╝
Te 4 widoki są
LOKALNIE - jest to plik z bieżącego oddziału
BASE - wspólny przodek, jak plik wyglądał przed obiema zmianami
ZDALNIE - plik, który scalasz ze swoim oddziałem
POŁĄCZONE - wynik scalania, to jest zapisywane w repozytorium
Możesz poruszać się między tymi widokami za pomocą ctrl+ w. Możesz bezpośrednio przejść do widoku POŁĄCZONE za pomocą ctrl+, wa następnie j.
Więcej informacji o nawigacji vimdiff tutaj i tutaj
Krok 4 . Możesz edytować widok POŁĄCZONY w następujący sposób
Jeśli chcesz otrzymywać zmiany z ZDALNEGO
:diffg RE
Jeśli chcesz uzyskać zmiany z BASE
:diffg BA
Jeśli chcesz otrzymywać zmiany z LOKALNEJ
:diffg LO
Krok 5 . Zapisz, wyjdź, zobowiązaj się i posprzątaj
:wqa
zapisz i wyjdź z vi
git commit -m "message"
git clean
Usuń dodatkowe pliki (np. * .Orig) utworzone przez narzędzie diff.
git mergetool -y
aby zapisać kilka naciśnięć klawiszy, jeśli scalasz wiele plików jednocześnie.
git mergetool
dla mnie spowodowało, że zostałem vimdiff
użyty. Można zainstalować jeden z poniższych narzędzi, aby go używać zamiast: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
.
git mergetool -t bc3
).
Oto prawdopodobny przypadek użycia od góry:
Wprowadzisz kilka zmian, ale ups, nie jesteś na bieżąco:
git fetch origin
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.
Bądź na bieżąco i spróbuj ponownie, ale masz konflikt:
git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.
Więc decydujesz się spojrzeć na zmiany:
git mergetool
O rany, o rany, zmieniłem niektóre rzeczy, ale żeby użyć moich zmian ... nie ... ich zmian ...
git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"
A potem próbujemy ostatni raz
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Ta-da!
git merge --help
this question
Uważam, że narzędzia do scalania rzadko pomagają mi zrozumieć konflikt lub rozwiązanie. Zazwyczaj odnoszę większe sukcesy, patrząc na znaczniki konfliktu w edytorze tekstów i używając git log jako dodatku.
Oto kilka wskazówek:
Najlepszą rzeczą, jaką znalazłem, jest użycie stylu konfliktu scalania „diff3”:
git config merge.conflictstyle diff3
Powoduje to utworzenie takich znaczników konfliktu:
<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a
feature/topic branch.
>>>>>>>
Środkowa część wyglądała jak wspólny przodek. Jest to przydatne, ponieważ można porównać go z wersjami górną i dolną, aby lepiej zrozumieć, co zostało zmienione w każdej gałęzi, co daje lepszy pomysł na to, jaki był cel każdej zmiany.
Jeśli konflikt składa się tylko z kilku linii, generalnie czyni to konflikt bardzo oczywistym. (Umiejętność rozwiązania konfliktu jest zupełnie inna; musisz zdawać sobie sprawę z tego, nad czym pracują inni ludzie. Jeśli jesteś zdezorientowany, prawdopodobnie najlepiej po prostu zadzwoń do tej osoby do swojego pokoju, aby mogli zobaczyć, czego szukasz) w.)
Jeśli konflikt jest dłuższy, wytnę i wkleję każdą z trzech sekcji w trzy osobne pliki, takie jak „moje”, „wspólne” i „ich”.
Następnie mogę uruchomić następujące polecenia, aby zobaczyć dwa porcje diff, które spowodowały konflikt:
diff common mine
diff common theirs
Nie jest to to samo, co użycie narzędzia scalania, ponieważ narzędzie scalania obejmie również wszystkie nie sprzeczne porcje diff. Uważam, że to rozprasza.
Ktoś już o tym wspominał, ale zrozumienie intencji stojących za każdym kawałkiem różnic jest ogólnie bardzo pomocne w zrozumieniu, skąd wziął się konflikt i jak sobie z nim poradzić.
git log --merge -p <name of file>
To pokazuje wszystkie zatwierdzenia, które dotknęły tego pliku pomiędzy wspólnym przodkiem i dwiema główkami, które łączycie. (Więc nie obejmuje zatwierdzeń, które już istnieją w obu gałęziach przed scaleniem.) Pomaga to zignorować różne fragmenty, które wyraźnie nie są czynnikiem w twoim obecnym konflikcie.
Sprawdź swoje zmiany za pomocą zautomatyzowanych narzędzi.
Jeśli masz automatyczne testy, uruchom je. Jeśli masz kłaczki , uruchom to. Jeśli jest to projekt do zbudowania, skompiluj go przed zatwierdzeniem itp. We wszystkich przypadkach musisz wykonać trochę testów, aby upewnić się, że zmiany nic nie zepsuły. (Cholera, nawet scalenie bez konfliktów może uszkodzić działający kod.)
Planować naprzód; komunikować się ze współpracownikami.
Planowanie z wyprzedzeniem i świadomość, nad czym pracują inni, może pomóc w zapobieganiu konfliktom scalania i / lub pomóc w ich wcześniejszym rozwiązywaniu - a szczegóły są wciąż aktualne.
Na przykład, jeśli wiesz, że ty i inna osoba pracujecie nad innym refaktoryzacją, która wpłynie na ten sam zestaw plików, powinieneś porozmawiać ze sobą wcześniej i lepiej zrozumieć, jakie rodzaje zmian każdy z was jest zrobienie. Możesz zaoszczędzić sporo czasu i wysiłku, jeśli przeprowadzisz zaplanowane zmiany serio, a nie równolegle.
W przypadku poważnych refaktoryzacji, które przecinają dużą część kodu, powinieneś poważnie rozważyć pracę serią: wszyscy przestają pracować nad tym obszarem kodu, podczas gdy jedna osoba wykonuje pełne refaktoryzowanie.
Jeśli nie możesz pracować seryjnie (być może z powodu presji czasu), to przekazanie informacji o spodziewanych konfliktach scalania przynajmniej pomoże ci rozwiązać problemy wcześniej, dopóki szczegóły nie zostaną pominięte. Na przykład, jeśli współpracownik dokonuje destrukcyjnej serii zatwierdzeń w ciągu jednego tygodnia, możesz zdecydować o scaleniu / zmianie bazy w tym oddziale współpracowników raz lub dwa razy dziennie w ciągu tego tygodnia. W ten sposób, jeśli znajdziesz konflikty scalania / rebase, możesz je rozwiązać szybciej niż przez kilka tygodni, aby scalić wszystko razem w jedną dużą bryłę.
Jeśli nie masz pewności co do scalenia, nie zmuszaj go.
Scalanie może wydawać się przytłaczające, szczególnie gdy jest wiele sprzecznych plików, a znaczniki konfliktu pokrywają setki linii. Często przy szacowaniu projektów oprogramowania nie poświęcamy wystarczającej ilości czasu na ogólne rzeczy, takie jak porządne scalenie, więc wydaje się, że spędzanie kilku godzin na rozwiązywaniu każdego konfliktu to prawdziwy problem.
Na dłuższą metę planowanie z wyprzedzeniem i świadomość, nad czym pracują inni, są najlepszymi narzędziami do przewidywania konfliktów scalania i przygotowania się do ich poprawnego rozwiązania w krótszym czasie.
p4merge
, które można zainstalować i używać niezależnie od innych narzędzi Perforce (z których nie korzystałem, ale słyszałem skargi).
git config merge.conflictstyle diff3
- Dziękuję Panu. To jest niesamowite i uwolniło mnie od prób znalezienia (i zapłacenia $$) dobrego GUI do łączenia w 3 kierunkach. IMO jest to lepsze, ponieważ pokazuje wspólnego przodka, a także lokalnego / zdalnego i pokazuje ostatnie wiersze dziennika zatwierdzenia, których (AFAIK) nie robi GUI. Zatwierdzenia zdecydowanie pomagają zidentyfikować kod, który należy do jakiej gałęzi.
Sprawdź, które pliki są w konflikcie (Git powinien ci to powiedzieć).
Otwórz każdy plik i sprawdź różnice; Git rozgranicza ich. Mamy nadzieję, że będzie oczywiste, którą wersję każdego bloku zachować. Być może będziesz musiał omówić to z innymi programistami, którzy popełnili kod.
Po rozwiązaniu konfliktu w pliku git add the_file
.
Po rozwiązaniu wszystkich konfliktów wykonaj git rebase --continue
dowolne polecenie Git po zakończeniu.
git add
pliki w indeksie; nic nie dodaje do repozytorium. git commit
dodaje rzeczy do repozytorium. Takie użycie ma sens w przypadku scalania - scalanie automatycznie powoduje stopniowanie wszystkich zmian, które można scalić automatycznie; Twoim obowiązkiem jest scalenie pozostałych zmian i dodanie ich do indeksu po zakończeniu.
Sprawdź odpowiedzi w pytaniu Przepełnienie stosu Przerwanie scalania w Git , szczególnie odpowiedź Charlesa Baileya, która pokazuje, jak przeglądać różne wersje pliku z problemami, na przykład:
# Common base version of the file.
git show :1:some_file.cpp
# 'Ours' version of the file.
git show :2:some_file.cpp
# 'Theirs' version of the file.
git show :3:some_file.cpp
Konflikty scalania mają miejsce, gdy zmiany są wprowadzane do pliku w tym samym czasie. Oto jak to rozwiązać.
git
CLIOto proste kroki, które należy zrobić, gdy wejdziesz w stan konfliktu:
git status
(w Unmerged paths
sekcji).Rozwiązuj konflikty osobno dla każdego pliku, stosując jedną z następujących metod:
Użyj GUI, aby rozwiązać konflikty: git mergetool
(najprostszy sposób).
Aby zaakceptować zdalnego / inna wersja, przeznaczenie: git checkout --theirs path/file
. Spowoduje to odrzucenie wszelkich lokalnych zmian wprowadzonych dla tego pliku.
Aby zaakceptować wersję lokalną / naszą, użyj: git checkout --ours path/file
Należy jednak zachować ostrożność, ponieważ zdalne zmiany powodowały konflikty z jakiegoś powodu.
Powiązane: Jakie jest dokładne znaczenie „naszego” i „ich” w git?
Edytuj pliki będące w konflikcie ręcznie i poszukaj bloku kodu pomiędzy <<<<<
/ >>>>>
a następnie wybierz wersję z góry lub z dołu =====
. Zobacz: Jak przedstawiane są konflikty .
Konflikty ścieżek i nazw plików można rozwiązać za pomocą git add
/ git rm
.
Na koniec przejrzyj pliki gotowe do zatwierdzenia, używając: git status
.
Jeśli nadal masz żadnych plików mocy Unmerged paths
, a nie ręcznie rozwiązać konflikt, pozwól Git wie, że go rozwiązać przez: git add path/file
.
Jeśli wszystkie konflikty zostały pomyślnie rozwiązane, zatwierdź zmiany przez: git commit -a
i wypchnij zdalnie jak zwykle.
Zobacz także: Rozwiązywanie konfliktu scalania z wiersza poleceń w GitHub
Aby zapoznać się z praktycznym samouczkiem, sprawdź: Scenariusz 5 - Naprawianie konfliktów scalania według Katacody .
Z powodzeniem korzystałem z DiffMerge, który może wizualnie porównywać i scalać pliki w systemach Windows, macOS i Linux / Unix.
Graficznie pokazuje zmiany między 3 plikami i pozwala na automatyczne łączenie (jeśli jest to bezpieczne) i pełną kontrolę nad edytowaniem pliku wynikowego.
Źródło obrazu: DiffMerge (zrzut ekranu systemu Linux)
Wystarczy go pobrać i uruchomić w repo jako:
git mergetool -t diffmerge .
W systemie macOS można zainstalować za pomocą:
brew install caskroom/cask/brew-cask
brew cask install diffmerge
I prawdopodobnie (jeśli nie jest dostarczony) potrzebujesz następującej dodatkowej prostej owijarki umieszczonej w ŚCIEŻCE (np. /usr/bin
):
#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"
Następnie możesz użyć następujących skrótów klawiaturowych:
Alternatywnie możesz użyć opendiff (część Xcode Tools), który pozwala ci połączyć dwa pliki lub katalogi w celu utworzenia trzeciego pliku lub katalogu.
Jeśli często popełniasz małe zatwierdzenia, zacznij od spojrzenia na komentarze zatwierdzenia za pomocą git log --merge
. Następnie git diff
pokaże konflikty.
W przypadku konfliktów obejmujących więcej niż kilka wierszy łatwiej jest zobaczyć, co się dzieje w zewnętrznym narzędziu GUI. Lubię opendiff - Git obsługuje również vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, pojawiają się po wyjęciu z pudełka i możesz zainstalować inne: git config merge.tool "your.tool"
ustawisz wybrane narzędzie, a następniegit mergetool
po nieudanym scaleniu pokaże różnice w kontekście.
Za każdym razem, gdy edytujesz plik w celu rozwiązania konfliktu, git add filename
zaktualizujesz indeks, a Twój plik różnicowy już go nie pokaże. Gdy wszystkie konflikty zostaną rozwiązane, a ich pliki zostały git add
-ed, git commit
zakończy scalanie.
Zobacz, jak prezentowane są konflikty lub, w Git,git merge
dokumentację, aby zrozumieć, jakie są znaczniki konfliktu scalania.
Ponadto sekcja Jak rozwiązać konflikty wyjaśnia, jak rozwiązać konflikty:
Po obejrzeniu konfliktu możesz zrobić dwie rzeczy:
Zdecyduj się nie łączyć. Jedyne, czego potrzebujesz, to zresetować plik indeksu do
HEAD
zatwierdzenia, aby cofnąć 2. i wyczyścić zmiany drzewka roboczego dokonane przez 2. i 3 .;git merge --abort
można do tego użyć.Rozwiąż konflikty. Git zaznaczy konflikty w działającym drzewie. Edytuj pliki w odpowiednim kształcie, a
git add
następnie w indeksie. Użyj,git commit
aby zamknąć ofertę.Możesz rozwiązać konflikt za pomocą wielu narzędzi:
Użyj narzędzia wielofunkcyjnego.
git mergetool
aby uruchomić graficzny program do łączenia, który przeprowadzi cię przez proces scalania.Spójrz na różnice.
git diff
pokaże trójdrożny diff, podkreślając zmiany zarówno z wersji jakHEAD
iMERGE_HEAD
.Spójrz na różnice z każdej gałęzi.
git log --merge -p <path>
pokaże najpierw różnice dlaHEAD
wersji, a następnie dlaMERGE_HEAD
wersji.Spójrz na oryginały.
git show :1:filename
pokazuje wspólnego przodka,git show :2:filename
pokazujeHEAD
wersję igit show :3:filename
pokazujeMERGE_HEAD
wersję.
Możesz także przeczytać o znacznikach konfliktu scalania i sposobach ich rozwiązywania w sekcji książki Pro Git Podstawowe konflikty scalania .
Chcę albo w całości moją wersję, albo chcę przejrzeć poszczególne zmiany i zdecydować o każdej z nich.
W pełni zaakceptuj moją lub jej wersję :
Zaakceptuj moją wersję (lokalną, naszą):
git checkout --ours -- <filename>
git add <filename> # Marks conflict as resolved
git commit -m "merged bla bla" # An "empty" commit
Zaakceptuj ich wersję (zdalną, ich):
git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"
Jeśli chcesz zrobić dla wszystkich plików konfliktu, uruchom:
git merge --strategy-option ours
lub
git merge --strategy-option theirs
Przejrzyj wszystkie zmiany i zaakceptuj je indywidualnie
git mergetool
git add <filename>
git commit -m "merged bla bla"
Domyślnie mergetool
działa w wierszu poleceń . Jak korzystać z narzędzia do łączenia linii poleceń powinno być osobnym pytaniem.
Możesz także zainstalować do tego celu narzędzie wizualne , np. meld
I uruchomić
git mergetool -t meld
Otworzy wersję lokalną (naszą), wersję „podstawową” lub „scaloną” (aktualny wynik scalenia) i wersję zdalną (ich). Po zakończeniu zapisz połączoną wersję, uruchom git mergetool -t meld
ponownie, aż pojawi się komunikat „Żadne pliki nie wymagają scalenia”, a następnie przejdź do kroków 3. i 4.
W przypadku użytkowników Emacsa, którzy chcą rozwiązać konflikty scalania częściowo:
git diff --name-status --diff-filter=U
pokazuje wszystkie pliki wymagające rozwiązania konfliktu.
Otwórz każdy z tych plików jeden po drugim lub wszystkie jednocześnie:
emacs $(git diff --name-only --diff-filter=U)
Odwiedzając bufor wymagający edycji w Emacsie, wpisz
ALT+x vc-resolve-conflicts
Otworzy to trzy bufory (mój, ich i bufor wyjściowy). Nawiguj, naciskając „n” (następny region), „p” (region podglądu). Naciśnij „a” i „b”, aby skopiować odpowiednio mój lub ich region do bufora wyjściowego. I / lub bezpośrednio edytuj bufor wyjściowy.
Po zakończeniu: naciśnij „q”. Emacs zapyta, czy chcesz zapisać ten bufor: tak. Po zakończeniu bufora oznacz go jako rozwiązany, uciekając przed przestępcą:
git add FILENAME
Po zakończeniu ze wszystkimi typami buforów
git commit
aby zakończyć scalanie.
Mówiąc o pull / fetch / merge w powyższych odpowiedziach, chciałbym podzielić się ciekawą i produktywną sztuczką,
git pull --rebase
To powyższe polecenie jest najbardziej użytecznym poleceniem w moim życiu git, które zaoszczędziło wiele czasu.
Przed przekazaniem nowo zatwierdzonej zmiany na zdalny serwer, spróbuj git pull --rebase
raczej git pull
ręczniemerge
zatwierdzonej a ona automatycznie zsynchronizuje najnowsze zmiany na serwerze zdalnym (z funkcją pobierania + scalania) i umieści twoje lokalne zatwierdzenie na górze w dzienniku git. Nie musisz martwić się o ręczne wyciąganie / scalanie.
W przypadku konfliktu wystarczy użyć
git mergetool
git add conflict_file
git rebase --continue
Znajdź szczegóły na: http://gitolite.com/git-pull--rebase
Po prostu, jeśli dobrze wiesz, że zmiany w jednym z repozytoriów nie są ważne i chcesz rozwiązać wszystkie zmiany na korzyść drugiego, użyj:
git checkout . --ours
aby rozwiązać zmiany na korzyść swojego repozytorium , lub
git checkout . --theirs
w celu rozwiązania zmian na korzyść drugiego lub głównego repozytorium .
W przeciwnym razie będziesz musiał użyć narzędzia do scalania GUI, aby przechodzić między plikami jeden po drugim, powiedzmy, że to narzędzie do scalania p4merge
lub napisać nazwę, którą już zainstalowałeś
git mergetool -t p4merge
a po zakończeniu pliku będziesz musiał zapisać i zamknąć, aby otworzyć następny.
Wykonaj następujące kroki, aby naprawić konflikty scalania w Git:
Sprawdź status Git: status git
Pobierz łatkę: git fetch ( sprawdź odpowiednią łatkę z Git commit)
Kasa lokalna (tutaj temp1 w moim przykładzie tutaj): git checkout -b temp1
Wyciągnij najnowszą zawartość z master: git pull --rebase origin master
Uruchom narzędzie do łączenia i sprawdzaj konflikty i napraw je ... oraz sprawdź zmiany w oddziale zdalnym za pomocą bieżącego oddziału: git scaletool
Sprawdź status jeszcze raz: status git
Usuń niechciane pliki utworzone lokalnie przez scaletool, zwykle scaletool tworzy dodatkowy plik z rozszerzeniem * .orig. Usuń ten plik, ponieważ jest to tylko duplikat, napraw zmiany lokalnie i dodaj poprawną wersję swoich plików. git dodaj #your_changed_correct_files
Sprawdź status jeszcze raz: status git
Zatwierdź zmiany w tym samym identyfikatorze zatwierdzenia (pozwala to uniknąć nowego oddzielnego zestawu poprawek): git commit --amend
Push do gałęzi master: git push (do repozytorium Git)
Istnieją 3 kroki:
Znajdź, które pliki powodują konflikty według poleceń
git status
Sprawdź pliki, w których można znaleźć konflikty oznaczone jako
<<<<<<<<head
blablabla
Zmień go tak, jak chcesz, a następnie zatwierdź za pomocą poleceń
git add solved_conflicts_files
git commit -m 'merge msg'
Konflikty scalania można naprawić na wiele sposobów, które opisują inne.
Myślę, że prawdziwym kluczem jest wiedza o tym, jak przebiegają zmiany w lokalnych i zdalnych repozytoriach. Kluczem do tego jest zrozumienie gałęzi śledzenia. Przekonałem się, że uważam gałąź śledzenia za „brakujący element w środku” między mną, moim lokalnym, aktualnym katalogiem plików a pilotem zdefiniowanym jako pochodzenie.
Osobiście przyzwyczaiłem się do 2 rzeczy, które pomagają tego uniknąć.
Zamiast:
git add .
git commit -m"some msg"
Który ma dwie wady -
a) Wszystkie nowe / zmienione pliki zostaną dodane, co może obejmować pewne niepożądane zmiany.
b) Nie możesz najpierw przejrzeć listy plików.
Zamiast tego robię:
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
W ten sposób bardziej rozważnie wybierasz pliki, które chcesz dodać, a także przeglądasz listę i zastanawiasz się więcej podczas korzystania z edytora wiadomości. Uważam, że poprawia to także moje komunikaty zatwierdzania, gdy korzystam z edytora pełnoekranowego zamiast z -m
opcji.
[Aktualizacja - w miarę upływu czasu zmieniłem więcej na:
git status # Make sure I know whats going on
git add .
git commit # Then use the editor
]
Ponadto (i bardziej odpowiednie dla twojej sytuacji) staram się unikać:
git pull
lub
git pull origin master.
ponieważ pull oznacza scalenie, a jeśli masz lokalne zmiany, które nie chcesz scalić, możesz łatwo skończyć ze scalonym kodem i / lub konfliktami scalającymi dla kodu, który nie powinien zostać scalony.
Zamiast tego próbuję to zrobić
git checkout master
git fetch
git rebase --hard origin/master # or whatever branch I want.
Pomocne może być również:
git branch, fork, fetch, merge, rebase and clone, jakie są różnice?
git checkout master
i git fetch
i git rebase --hard origin/master
git add .
, czy to zapisze nasze lokalne modyfikacje, abyśmy mogli kontynuować git checkout master
? czy są to dwa różne scenariusze?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
hard 'użycie: git rebase [-i] [opcje] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] lub: git rebase [-i] [ opcje] [--exec <cmd>] [--onto <newbase>] --root [<branch>] lub: git rebase --continue | --abort | --skip | --edit-todo `
Odpowiedź CoolAJ86 podsumowuje prawie wszystko. W przypadku zmiany obu gałęzi w tym samym fragmencie kodu konieczne będzie ręczne scalenie. Otwórz plik w konflikcie w dowolnym edytorze tekstu i powinieneś zobaczyć następującą strukturę.
(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too
<<<<<<<<<<<
(Code not in conflict here)
Wybierz jedną z alternatyw lub kombinację obu w taki sposób, aby nowy kod był, jednocześnie usuwając znaki równości i nawiasy kątowe.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
Nie zawsze wydaje mi się, że działa i zwykle kończy się wyświetlaniem każdego zatwierdzenia, które różniło się między dwiema gałęziami, dzieje się tak nawet wtedy, gdy używasz --
do oddzielenia ścieżki od polecenia.
Aby obejść ten problem, otwieram dwie linie poleceń w jednym uruchomieniu
git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
a w drugim
git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
Zamiana $MERGED_IN_BRANCH
na gałąź, którą scaliłem i [path]
na plik będący w konflikcie. To polecenie rejestruje wszystkie zatwierdzenia, w postaci łatki, pomiędzy ( ..
) dwoma zatwierdzeniami. Jeśli zostawisz jedną stronę pustą, jak w powyższych poleceniach, git automatycznie użyje HEAD
(gałąź, w której się scalasz w tym przypadku).
To pozwoli ci zobaczyć, jakie zatwierdzenia poszły do pliku w dwóch gałęziach po ich rozejściu. Zwykle znacznie ułatwia rozwiązywanie konfliktów.
patience
Dziwi mnie, że nikt inny nie mówił o rozwiązywaniu konfliktów za patience
pomocą strategii rekurencyjnej scalania. W przypadku dużego konfliktu scalania przy użyciupatience
zapewniło mi dobre wyniki. Chodzi o to, że będzie próbował dopasować bloki zamiast poszczególnych linii.
Jeśli na przykład zmienisz wcięcie programu, domyślna strategia scalania Git czasami pasuje do pojedynczych nawiasów, {
które należą do różnych funkcji. Można tego uniknąć dzięki patience
:
git merge -s recursive -X patience other-branch
Z dokumentacji:
With this option, merge-recursive spends a little extra time to avoid
mismerges that sometimes occur due to unimportant matching lines
(e.g., braces from distinct functions). Use this when the branches to
be merged have diverged wildly.
Jeśli masz konflikt scalania i chcesz zobaczyć, co inni mieli na myśli podczas modyfikowania swojej gałęzi, czasem łatwiej jest porównać ich gałąź bezpośrednio ze wspólnym przodkiem (zamiast naszej gałęzi). Do tego możesz użyć merge-base
:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
Zwykle chcesz zobaczyć tylko zmiany dla konkretnego pliku:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
Od 12 grudnia 2016 r. Możesz łączyć oddziały i rozwiązywać konflikty na github.com
Dlatego jeśli nie chcesz używać wiersza polecenia ani narzędzi innych firm, które są oferowane tutaj ze starszych odpowiedzi , skorzystaj z natywnego narzędzia GitHub.
Ten post na blogu szczegółowo wyjaśnia, ale podstawowe jest to, że po „scaleniu” dwóch gałęzi za pomocą interfejsu użytkownika zobaczysz teraz opcję „rozwiąż konflikty”, która przeniesie Cię do edytora umożliwiającego radzenie sobie z tymi konfliktami scalania.
Jeśli chcesz połączyć z gałęzi (testowej) do wzorcowej, możesz wykonać następujące kroki:
Krok 1 : Przejdź do oddziału
git checkout test
Krok 2 :
git pull --rebase origin master
Krok 3 : Jeśli występują jakieś konflikty, przejdź do tych plików, aby je zmodyfikować.
Krok 4 : Dodaj te zmiany
git add #your_changes_files
Krok 5 :
git rebase --continue
Krok 6 : Jeśli nadal występuje konflikt, wróć do kroku 3 ponownie. Jeśli nie ma konfliktu, wykonaj następujące czynności:
git push origin +test
Krok 7 : I wtedy nie ma konfliktu między testem a mistrzem. Możesz użyć scalania bezpośrednio.
Zawsze wykonuję poniższe kroki, aby uniknąć konfliktów.
Teraz możesz zrobić to samo i utrzymywać tyle lokalnych oddziałów, ile chcesz, i pracować jednocześnie, po prostu robię kasę git do twojego oddziału, gdy zajdzie taka potrzeba.
Konflikty scalania mogą wystąpić w różnych sytuacjach:
Aby rozwiązać konflikty, musisz zainstalować narzędzie do scalania zgodne z Git. Ja osobiście korzystam z KDiff3 i uważam, że jest miły i przydatny. Możesz pobrać jego wersję dla systemu Windows tutaj:
https://sourceforge.net/projects/kdiff3/files/
BTW, jeśli zainstalujesz rozszerzenia Git, w kreatorze instalacji jest opcja zainstalowania Kdiff3.
Następnie zainstaluj git configs, aby użyć Kdiff jako narzędzia do łączenia:
$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false
$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false
(Pamiętaj, aby zastąpić ścieżkę rzeczywistą ścieżką pliku exe Kdiff.)
Następnie za każdym razem, gdy napotkasz konflikt scalania, wystarczy uruchomić polecenie:
$git mergetool
Następnie otwiera Kdiff3 i najpierw próbuje automatycznie rozwiązać konflikty scalania. Większość konfliktów zostałaby rozwiązana spontanicznie, a resztę trzeba naprawić ręcznie.
Oto jak wygląda Kdiff3:
Następnie, gdy skończysz, zapisz plik, a on przejdzie do następnego pliku z konfliktem i robisz to samo, dopóki wszystkie konflikty nie zostaną rozwiązane.
Aby sprawdzić, czy wszystko zostało pomyślnie scalone, po prostu ponownie uruchom komendę scaletool, powinieneś otrzymać ten wynik:
$git mergetool
No files need merging
Te odpowiedzi to dodanie alternatywy dla użytkowników VIM, takich jak ja, którzy wolą robić wszystko w edytorze.
Tpope wymyślił tę świetną wtyczkę dla VIM, zwaną zbiegiem . Po zainstalowaniu możesz uruchomić, :Gstatus
aby sprawdzić pliki, które powodują konflikty i:Gdiff
otworzyć Git na trzy sposoby scalania.
Po połączeniu w 3-kierunkowy sposób zbieg pozwoli ci uzyskać zmiany w dowolnej z łączonych gałęzi w następujący sposób:
:diffget //2
, uzyskaj zmiany z oryginalnej gałęzi ( HEAD )::diffget //3
, uzyskaj zmiany z łączącej się gałęzi: Po zakończeniu scalania pliku wpisz :Gwrite
scalony bufor. Vimcasts opublikowało świetny film szczegółowo wyjaśniający te kroki.
git fetch
git sprawdź swój oddział
git rebase master
W tym kroku spróbujesz naprawić konflikt przy użyciu preferowanego IDE
Możesz użyć tego linku, aby sprawdzić ho, aby rozwiązać konflikt w pliku
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
git dodaj
git rebase - kontynuuj
git commit - popraw
git push origin HEAD: refs / draughts / master (push jak draughts)
Teraz wszystko jest w porządku i znajdziesz swoje zatwierdzenie w gerrit
Mam nadzieję, że pomoże to każdemu w tej sprawie.
Wypróbuj kod Visual Studio Code do edycji, jeśli jeszcze tego nie zrobiłeś. Robi to po próbie scalenia (i pojawia się w konflikcie scalania). Kod VS automatycznie wykrywa konflikty scalania.
To może pomóc bardzo dobrze, pokazując jakie są zmiany wprowadzone do pierwotnego i należy przyjąć incoming
lub
current change
(czyli oryginalny przed scaleniem) „?.
Pomogło mi i może również działać dla ciebie!
PS: Będzie działać tylko wtedy, gdy skonfigurowałeś git za pomocą swojego kodu i Visual Studio Code.
Bezpieczniejszym sposobem rozwiązywania konfliktów jest użycie git-mediate (najczęściej sugerowane rozwiązania to imho podatne na błędy).
Zobacz ten post, aby uzyskać krótkie wprowadzenie na temat korzystania z niego.
Dla tych, którzy używają Visual Studio (2015 w moim przypadku)
Zamknij swój projekt w VS. Zwłaszcza w dużych projektach VS ma tendencję do wariowania podczas łączenia za pomocą interfejsu użytkownika.
Wykonaj scalanie w wierszu polecenia.
git Checkout target_branch
git merge source_branch
Następnie otwórz projekt w VS i przejdź do Team Explorer -> Oddział. Teraz pojawia się komunikat z informacją, że scalanie jest w toku, a konfliktowe pliki znajdują się bezpośrednio pod komunikatem.
Kliknij plik powodujący konflikt, a pojawi się opcja Scal, porównaj, pobierz źródło, wybierz cel. Narzędzie do scalania w VS jest bardzo łatwe w użyciu.
Jeśli używasz intelliJ jako IDE Spróbuj połączyć rodzica do swojego oddziału przez
git checkout <localbranch>
git merge origin/<remotebranch>
Pokaże wszystkie takie konflikty
A_MBPro: test anu $ git merge origin / Auto-scaling src / test / java / com /.../ TestClass.java CONFLICT (content): Scal konflikt w src / test / java / com /.../ TestClass.java
Zauważ teraz, że plik TestClass.java jest pokazany na czerwono w intelliJ Wyświetlany jest również status git
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/test/java/com/.../TestClass.java
Otwórz plik w intelliJ, będzie miał sekcje z
<<<<<<< HEAD
public void testMethod() {
}
=======
public void testMethod() { ...
}
>>>>>>> origin/<remotebranch>
gdzie HEAD to zmiany w lokalnym oddziale i pochodzenie / to zmiany ze zdalnego oddziału. Tutaj zachowaj potrzebne rzeczy i usuń niepotrzebne rzeczy, a następnie wykonaj zwykłe czynności. To jest
git add TestClass.java
git commit -m "commit message"
git push