Która wersja pliku git zostanie ostatecznie użyta: LOKALNA, BAZOWA czy ZDALNA?

174

Kiedy w trakcie dochodzi do kolizji git merge, otwieram narzędzie scalające o nazwie Meld . Otwiera trzy pliki LOKALNE, BAZOWE i ZDALNE. Jak przeczytałem LOCAL to moja lokalna gałąź, BASE jest wspólnym przodkiem, a REMOTE to gałąź, która ma zostać scalona.

Teraz na moje pytanie: która wersja pliku zostanie ostatecznie wykorzystana? Czy to ZDALNE? Jeśli tak, czy mogę go edytować tak, jak chcę, niezależnie od tego, co jest na przykład w gałęzi BASE?

tsusanka
źródło

Odpowiedzi:

142

Jest to jeden w środku: BASE.

W rzeczywistości BASEnie jest to wspólny przodek, ale niedokończone scalenie, w którym konflikty są oznaczone >>>>i <<<<.

Możesz zobaczyć nazwy plików w górnej części okna edycji połączenia.

Zobacz zrzut ekranu tutaj

podstawa połączenia

Możesz edytować BASEplik, jak chcesz, za pomocą poleceń łączenia lub bez.
Możesz także pozbyć się meldowania i po prostu edytować plik za pomocą ulubionego edytora tekstu.

  • Kod między znacznikami <<<< HEADi =====to kod z lokalnego pliku przed scaleniem.
  • Kod między ====i >>>> <branch name>jest kodem zdalnego pliku.
Fabien Quatravaux
źródło
3
Niektórzy ludzie lepiej rozumieją sprzeczne fragmenty w pliku, których automatyczne scalanie nie powiodło się, jeśli mają merge.conflictstyleustawioną opcję konfiguracji diff3zamiast domyślnej merge.
kostix
3
Właściwie nie widzę HEAD, śpiewa <<< i ===. W przypadku, gdy podałeś, środkowe okno będzie puste. Ale to tylko uwaga dla innych, dzięki za odpowiedź.
tsusanka
Jeśli nie widać HEAD, <<<<<i =====znaki, to znaczy, że nie ma konfliktu w ogóle. W tym przypadku środkowe okno nie będzie puste, pokaże wynik scalenia, ale nie będzie „czerwonej” części
Fabien Quatravaux.
10
Kiedy robię łączy się z meldunku, nie widać żadnych <<<<<<, ======ani >>>>>>markerów w panelu środkowym (tj podstawowej wersji) albo; a czasami środkowe okienko będzie puste, jak zgłosił aGr. Może ta różnica wynika z różnych ustawień. Kiedy uruchomić narzędzie meldunku, będą istniały następujące pliki, zakładając, że nazwa pliku w repozytorium jest X.java: X.java, X.java.orig, X.java.BACKUP.#, X.java.BASE.#, X.java.LOCAL.#, X.java.REMOTE.#, gdzie #jest jakaś liczba. Nazywanie wyniku scalania wersją BASE jest mylące; MERGED byłoby lepsze.
Teemu Leisti
3
BASE jest w rzeczywistości wspólnym przodkiem, MERGED to nazwa pliku z częściowymi informacjami o scaleniu. Zobacz moje pytanie i odpowiedź. Konfigurowanie i używanie Meld jako git difftool i connectetool, które dokładnie wyjaśnia, jak to działa. HTH.
Mattst
107

Meld ma ukrytą funkcję 3-drożnego scalania aktywowaną przez przekazanie czwartego parametru:

meld $LOCAL $BASE $REMOTE $MERGED

Prawe i lewe okienka są otwierane w trybie tylko do odczytu, więc nie można przypadkowo scalić w niewłaściwy sposób. Środkowy panel pokazuje wynik scalania. W przypadku konfliktów pokazuje wersję podstawową, dzięki czemu można zobaczyć wszystkie ważne elementy: oryginalny tekst w środku i sprzeczne modyfikacje po obu stronach. Wreszcie, po naciśnięciu przycisku „Zapisz”, zapisywany jest plik $ MERGED - dokładnie tak, jak oczekuje git.

Plik ~ / .gitconfig, którego używam, zawiera następujące ustawienia:

[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE $MERGED

otwiera to połączenie z 3 kartami, pierwszą i drugą kartą zawierającą proste różnice, które próbuję scalić, a trzecia karta, otwarta domyślnie, pokazuje widok scalania 3-kierunkowego.

Powodem, dla którego ta funkcja jest ukryta, jest to, że nie jest jeszcze wystarczająco dopracowana. Jest to bardzo przydatne, tak jak jest teraz, ale Kai Willadsen, autor połączenia, wskazał na kilka zmarszczek, które wymagają wygładzenia. Na przykład nie ma GUI do uruchomienia trybu 3-drożnego scalania, składnia wiersza poleceń jest nieco tajemnicza i tak dalej. Jeśli mówisz w Pythonie i masz trochę czasu - wiesz, co robić.

Edycja: W nowszych wersjach Meld synx nieco się zmienił. To było w komentarzach, ale należy do odpowiedzi.

Polecenie meld używa teraz opcji --output, więc ostatnia linia z powyższego fragmentu powinna wyglądać następująco:

cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
Tomek Bury
źródło
7
@Jesse, @lumbric, wygląda na to, że nowsze wersje połączenia używają flagi --outputdla wyniku $ MERGED. Odkryłem to, patrząc na skrypcie uruchomić Meld dostarczonym z mojej wersji git: github.com/git/git/blob/master/mergetools/meld
Johann
1
@lumbric Myślę, że tak, dla Meld 1.7.x + z rozszerzeniem --output option. Zobacz tę linię w skrypcie uruchamiania:"$merge_tool_path" --output "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
Johann,
12
W najnowszym meldunku (wersja> 1.8.4) musimy użyć opcji --auto-merge. cmd = meld --diff $ BASE $ LOCAL --diff $ BASE $ REMOTE --auto-merge $ LOCAL $ BASE $ REMOTE - wyjście $ MERGED
RoboAlex
7
Miałem ten sam problem, co @pingpongboss przy użyciu Meld 1.8.4: Meld otwierał rzeczy w osobnym panelu, zamiast otwierać trzecią kartę. Komenda finally działało dobrze jest: cmd = meld $LOCAL $BASE $REMOTE --auto-merge --output $MERGED. Tak więc, otwiera to 3 zakładki (stary dobry sposób), automatycznie łączy niekolidujące scalenia w środku, gdzie pośrodku jest $ MERGED, i zostanie użyte jako wyjście rozwiązywania konfliktów.
farmir
2
Składnia wyjściem może być --output=<file>albo -o <file>patrzmeld --help
levsa
57

W grę wchodzą 4 pliki:

  1. $LOCALPlik w gałęzi, w której dokonujesz scalenia; po wyświetleniu nietknięte przez proces scalania

  2. $REMOTEPlik w gałęzi, z której dokonujesz scalenia; po wyświetleniu nietknięte przez proces scalania

  3. $BASEWspólny przodek $ LOCAL i $ REMOTE, tj. punkt, w którym dwie gałęzie zaczęły przekierowywać rozpatrywany plik; po wyświetleniu nietknięte przez proces scalania

  4. $MERGEDCzęściowo scalony plik z konfliktami; jest to jedyny plik, którego dotyczył proces scalania i właściwie nigdy nie został wyświetlony w formaciemeld


$MERGEDPlik jest taki, który zawiera <<<<<<, >>>>>>, =====(i, być może, ||||||) (markery że konflikty wytyczają). To jest plik, który edytujesz ręcznie w celu naprawienia konfliktów.

Ręczna edycja konfliktów i wizualna edycja konfliktów odbywa się na różnych plikach i przedstawia różne informacje.

Podczas korzystania z mergetool (zakładając meld), pliki, które widzą w nim to: $LOCAL, $BASE, $REMOTE. Zwróć uwagę, że nie widzisz $MERGEDpliku, chociaż jest on przekazywany jako ukryty parametr melddo zapisania tam wyniku edycji.

Innymi słowy, w programie meldedytujesz plik w środku, $BASEplik i ręcznie wybierasz wszystkie zmiany od lewej lub prawej strony . Jest to czysty plik, którego nie dotyczył proces scalania. Jedyna usterka polega na tym, że podczas zapisywania nie zapisujesz do $BASEpliku, ale w czwartym ukrytym parametrze meld, czyli $MERGEDpliku (którego nawet nie widzisz). $BASEPlik ma nie zawierać żadnych konfliktów lub częściowe sukcesy scala ponieważ nie jest to $MERGEDplik .

W edycji wizualnej, podczas prezentacji $BASEpliku (zamiast $MERGEDpliku) w gitzasadzie odrzuca wszystkie próby scalenia (te próby są widoczne, jeśli chcesz, w pliku $ MERGED) i pozwala na całkowite scalenie od podstaw .

Najważniejsze jest to, że podczas ręcznego i wizualnego łączenia konfliktów nie patrzysz na te same pliki, ale wynik końcowy jest zapisywany w tym samym pliku (to jest $MERGEDplik).

Instrukcja korekta konfliktów odbywa się na $MERGEDponieważ git ma nie lada zaprezentować trzy pliki, więc to zgniecie informacje z trzech plików ( $LOCAL, $BASE, $REMOTE) w tym $MERGEDpliku.

Ale narzędzia wizualne mają środków , aby pokazać trzy pliki: oni pokazać $LOCAL, $BASE, $REMOTEpliki. Jesteś zbierając od zmian $LOCALi $REMOTEplików i przynoszą ci do $BASEpliku, całkowicie re-building a nawet nadpisanie nieudanej próbie połączenia, które jest $MERGEDplik.

user1284631
źródło
Chciałem tylko, żeby istniały narzędzia (np.
Bez
@yoniYalovitsky: yes, or p4merge
user1284631
Kiedyś korzystałem z narzędzia scalającego z pakietu ClearCase
mishmashru
@yoniLavi - cóż, te narzędzia pokazują 4 okienka , ale niekoniecznie wszystkie cztery pliki, jak opisano w tej odpowiedzi. W szczególności, można skonfigurować te 4 okienku narzędzi, aby pokazać $LOCAL, $REMOTE, $BASEa wyjście początkowo równym $BASE, ale która jest inna niż $MERGEDw tym, że nie ma próbę git do łączenia plików i znaczniki konfliktu i tak dalej. W rzeczywistości byłby to sposób użycia tych narzędzi, który jest najbardziej podobny do podejścia 3-panelowego LOCAL / REMOTE / BASE + OUTPUT, które nie jest połączone. Czwarte okienko pozwala tylko oddzielić podstawę od wyjścia.
BeeOnRope
16

Rozwiązanie Cosmina działa, ale plik $ BASE jest aktualizowany - a nie $ MERGED . Spowoduje to zaktualizowanie pliku $ MERGED :

Połączenie: v1.8.4

[merge]
  conflictstyle = diff3
  tool = mymeld
[mergetool "mymeld"]
  cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE --diff $BASE $LOCAL --diff $BASE $REMOTE
Saad Malik
źródło
Mogę to potwierdzić, rozwiązanie Saada działa dla mnie na Ubuntu. Jeśli chodzi o pierwotne pytanie, jest to aktualna poprawna odpowiedź.
cosmin
3
W mojej wersji meld - 3.11, to polecenie działa świetnie:cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
MartinM
dlaczego miałbyś potrzebować --diff $BASE $LOCAL --diff $BASE $REMOTEna końcu? dla mnie na 1.8.4, to działa dobrze (o ile widzę):cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
farmir
1
@farmir: To nie jest konieczne. Otwiera dwie kolejne zakładki w połączeniu, dzięki czemu możesz zobaczyć LOKALNIE i ZDALNIE w porównaniu z PODSTAWĄ indywidualnie.
Sam Kauffman
1
Bez względu na to, jaką kolejność próbuję z tymi argumentami, trójdrożna karta jest zawsze trzecią kartą, podczas gdy pierwsza karta jest zawsze domyślnie zaznaczona. Czy istnieje sposób, aby domyślnie wybrać trójstronną kartę?
Sam Kauffman
13

Dzięki Meld 1.7 rozwiązanie Tomka Bury'ego już nie działa.

Te ustawienia domyślne nie spełniają mnie:

Ustawienia domyślne

Zamiast tego dla Meld> = 1,7 proponuję jedno z dwóch innych rozwiązań.

Pierwsze rozwiązanie :

 meld $LOCAL $BASE $REMOTE --auto-merge

pierwsze rozwiązanie

Drugie rozwiązanie :

 meld $LOCAL $MERGED $REMOTE

drugie rozwiązanie

.gitconfig

Skopiuj i wklej to do swojego .gitconfigpliku, aby uzyskać rozwiązania opisane powyżej:

[merge]
    tool = meld16
[mergetool "meld17"]
    # use this for Meld >=1.7
    # see http://stackoverflow.com/a/22911793/859591
    # second solution:
    cmd = meld $LOCAL $MERGED $REMOTE
    # first solution:
    #cmd = meld $LOCAL $BASE $REMOTE --auto-merge
[mergetool "meld16"]
    cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED

[include]
    # requires git v1.7.10+
    path = .gitconfig.local

Skopiuj i wklej to do .gitconfig.localpliku, aby ustawić meld17 lub meld16 tylko dla tego komputera, jeśli używasz pliku .gitconfig na wielu komputerach:

# This is a host specific config file!
# Note that git 1.7.10+ is needed
# http://stackoverflow.com/a/9733277/859591
[merge]
    tool = meld17
lumbric
źródło
To nie działa na Meld 1.8.4. Jeśli uruchomisz cmd = meld $LOCAL $BASE $REMOTE --auto-merge, środkowym okienkiem będzie $ BASE, a nie $ MERGE, który jest faktycznie używany jako wynik rozwiązywania konfliktów.
farmir
1
@farmir Wybrałeś $ BASE jako drugą zakładkę.
Alex78191
11

Okazało się, że żaden z wyświetlonych plików domyślnych nie został zapisany. Meld pokazywał $LOCAL, $REMOTEa $BASEdomyślnie. Żeby to zadziałało, $MERGEDzamiast tego musiałem zrobić meld show $BASE. Umieszczając to w moim, ~/.gitconfignaprawiłem to dla mnie:

[merge]
        tool = mymeld
[mergetool "mymeld"]
        cmd = meld "$LOCAL" "$MERGED" "$REMOTE"

Używam Arch, z:

$ git --version
git version 1.8.2
$ meld --version
meld 1.7.1
Thomas Leonard
źródło
Przepraszam, czy ta konfiguracja inux jest kompatybilna?
MadMad666
2

Z jakiegoś powodu najnowsze wersje meldowania nie wyświetlają linii znaczników dodanych dla konfliktów (<<<<<<<, =======, >>>>>>>). Jeśli chcesz zobaczyć te linie, powinieneś zainstalować meld v 1.3.3 lub starszą.

wnasich
źródło
Przydała mi się odpowiedź @lumbric stackoverflow.com/a/22911793/641892
wnasich
2

Proszę zapoznać się z odpowiedzią Saada, aby uzyskać prawidłową odpowiedź.

Dzięki meldowaniu 1.8.1 na Ubuntu otrzymałem

błędna liczba argumentów podanych do --diff

i dodanie --output przed $ MERGED naprawiło to za mnie:

[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
cosmin
źródło