Jak połączyć konflikty Git w Emacsie

84

Moje ostatnie scalenie Git spowodowało dużą liczbę konfliktów. Moje obecne podejście polega na wyszukaniu następnego wystąpienia „<<<”, a następnie przeprowadzeniu scalenia za pomocą standardowej edycji tekstu.

Pytanie : czy istnieje sposób, w jaki Emacs może obsługiwać scalanie przy użyciu informacji dostępnych w Git na temat mojej wersji, ich wersji i podstawowej wersji pliku?


Edycja: To pytanie ma inny zakres niż to powiązane pytanie , ponieważ nie ogranicza się do wywoływania ediff.

Początkujący
źródło
7
Jeśli miałbyś użyć Magit, możesz załadować bufor stanu, a następnie naciskać epliki pokazane jako konflikty. Magit uruchomi się, ediffaby wykonać scalenie, a następnie poprosi cię o potwierdzenie zmian, a następnie możesz wprowadzić etap scalania pliku.
wvxvw
@Beginner: 3 inne osoby uważały, że to duplikat, a ja byłem ostatnim głosowaniem. Dlaczego: drugi cytowany wątek daje te same odpowiedzi ( smergei vc-resolve-conflict, jak również jeden z nich ediff) i jest już dostępny. Zgadzam się, że pierwszy wątek mógłby użyć lepszego tytułu.
Dan
@Dan Nie zgadzam się: to jest inne pytanie i że podobne odpowiedzi nie zmieniają tego.
Początkujący
1
@IqbalAnsari: Myślę, że drugi wątek potrzebuje lepszego tytułu, aby ludzie mogli go łatwiej znaleźć. W rzeczywistości uważam, że tytuł wątku Początkującego byłby do tego świetny. Poczekajmy jednak chwilę, aby zobaczyć, czy ludzie chcą ponownie otworzyć ten wątek. Jeśli nie, byłbym za przemianą pierwszego wątku tytułem Początkującego.
Dan
1
I dla tego, co jest warte, myślę, że to dobre pytanie z dobrymi odpowiedziami. Po prostu myślę, że to duplikat - ale inni mogą nie dzielić się tą opinią (to znaczy o duplikacji).
Dan

Odpowiedzi:

86

Możesz spróbować po smerge-modeprostu otworzyć plik będący w konflikcie i zrobić M-xsmerge-modeRET. Podświetli wszystkie konfliktowe regiony. Dodaje także skróty klawiszowe w celu łatwego rozwiązywania konfliktów, zapoznaj się z ich dokumentacją, C-hfsmerge-modeRETaby je poznać.

Domyślny prefiks

Znajduję domyślny przedrostek dla smerge-mode C-c^kłopotliwego, więc zmieniłem go na C-cv

(setq smerge-command-prefix "\C-cv")

Ważne skróty klawiszowe

Dla mnie najważniejsze wiązania to:

smerge-nextmusi smerge-command-prefixnprzejść do następnego konfliktu.

smerge-previousmusi smerge-command-prefixpprzejść do poprzedniego konfliktu.

smerge-keep-currentzobowiązany do smerge-command-prefixRETzachowania wersji, na której znajduje się kursor.

smerge-keep-minezobowiązane do smerge-command-prefixmzachowania twoich zmian.

smerge-keep-otherzobowiązane do smerge-command-prefixozachowania innych zmian.

smerge-ediffzobowiązany do smerge-command-prefixErozpoczęcia sesji ediff w celu scalenia konfliktów. To jest to samo co vc-resolve-conflicts(dzięki @phils i @Malabarba za zwrócenie na to uwagi).

Automatyczne włączanie trybu smerge

AKTUALIZACJA: Poniższe informacje dotyczą tylko wcześniejszych wersji Emacsa 25.1, poniższe mogą powodować problemy w późniejszych wersjach, patrz https://github.com/magit/magit/issues/3897

Dodatkowo możesz być zainteresowany automatycznym włączaniem smerge-modepodczas odwiedzania pliku / bufora ze znacznikami konfliktu, możesz użyć czegoś takiego jak poniżej, aby to osiągnąć

(defun my-enable-smerge-maybe ()
  (when (and buffer-file-name (vc-backend buffer-file-name))
    (save-excursion
      (goto-char (point-min))
      (when (re-search-forward "^<<<<<<< " nil t)
        (smerge-mode +1)))))

(add-hook 'buffer-list-update-hook #'my-enable-smerge-maybe)

Zauważ, że używam buffer-list-update-hooki nie, find-file-hookponieważ przez większość czasu dostaję konflikty w buforze, który jest już otwarty w emacsie, w którym find-file-hookto przypadku nie pomaga.

Sprawdź także inne metody wymienione w tej odpowiedzi

Iqbal Ansari
źródło
1
(1) Nie zapomnij smerge-ediff. (2) Na jakiej wersji Emacsa jesteś? W bieżącej gałęzi Emacsa smerge włącza się automatycznie. (3) Dlaczego używasz buffer-list-update-hookzamiast find-file-hook?
Malabarba,
Aby uzyskać dodatkowe wyjaśnienia, zwróć uwagę na to smerge-ediffi vc-resolve-conflictssą takie same.
phils
@Malabarba 1) Wspomniałem, że smerge-modeskróty klawiszowe są udokumentowane w jego dokumentacji. Być może mogę tutaj zacytować instrukcję. Dzięki za opinie. 2) Korzystam z wersji 24.5, chociaż czasami wypróbowuję gałąź master, nie pamiętam, aby smerge zmieniło się automatycznie (czy to ostatnia zmiana?). 3) Wynika to z tego, że przez większość czasu mam konflikty w już otwartych buforach, w takim przypadku musiałbym wyraźnie włączyćsmerge-mode
Iqbal Ansari,
@IqbalAnsari czy jest jakiś powód, aby nie smerge-modewłączać przez cały czas? Być może nie robi wiele, dopóki nie zostanie wywołany.
PythonNut
@PythonNut Dobre pytanie, niestety nie mam odpowiedzi, ponieważ nigdy nie próbowałem utrzymywać włączonej przez cały czas, warto jednak spróbować
Iqbal Ansari
32

Edycja: ponieważ ta odpowiedź zyskała więcej głosów niż się spodziewałem, nieco ją rozwinąłem.

Aby uzupełnić odpowiedź przez @IqbalAnsari, możesz również użyć vc-resolve-conflicts(jak wspomniano przez innych, jest to alias do smerge-ediff). Spowoduje to uruchomienie ediffinterfejsu. Po lewej stronie będzie pierwszy rodzic scalający, a drugi rodzic scalający po prawej. Są one oznaczone na modelce za pomocą MINEi OTHER. Scalony bufor pokazano poniżej (patrz zrzut ekranu).

Zrzut ekranu interfejsu <code> ediff </code>

Keybindings

  • Nawiguj między konfliktami z ni p.
  • Zaakceptuj wersje za pomocą alub b.
  • Spójrz na przodka z /!
  • Wyjdź z sesji ediff za pomocą q.

Możesz także przejść do połączonego bufora other-windowi edytować ręcznie, na wypadek gdyby rozwiązanie konfliktu było bardziej skomplikowane niż zaakceptowanie wersji. Po zakończeniu możesz zapisać bufor i wyjść z Emacsa jak zwykle. Aby uzyskać więcej pomocy, wystarczy użyć ?podczas ediffsesji, jest tam mnóstwo bardzo przydatnych poleceń. Nadal nie wiem, co robi ich połowa!

suvayu
źródło
2
To najładniejsza metoda IMO. Muszę to zrobić C-x v <, chociaż w praktyce bardziej prawdopodobne jest, że będę ją wywoływał za pomocą Magita (zgodnie z komentarzem wvxvw).
phils,
1
Od 2000 roku vc-resolve-conflictjest pseudonimem smerge-ediff, który, jak sama nazwa wskazuje, rozpoczyna sesję Ediff, a nie sesję Emerge. Nawiasem mówiąc, nagłówek biblioteki ediff.elpotwierdza emerge.elwpływ, a następnie mówi: „Obecna wersja Ediff zastępuje Emerge. Zapewnia doskonały interfejs użytkownika i ma wiele głównych funkcji, których nie ma w Emerge. W szczególności może wykonywać łatanie i Porównywanie, łączenie i katalogowanie plików w dwóch i trzech kierunkach ”.
Tarsius
6
Należy również pamiętać, że magit-ediff-resolve( Emlub ew pliku z konfliktem) korzysta smerge-ediffwewnętrznie. Jednak zastępuje to, ediff-quit-hookaby zapewnić nieco lepsze wrażenia z kończenia sesji. Zamiast mówić, że możesz zapisać „bufor” (istnieje kilka buforów), pyta cię, czy chcesz zapisać bufor (pokazując jednocześnie jego nazwę).
Tarsius
Czy istnieje sposób na pokazanie 4 okien (naszego, rodzica, ich, obszaru roboczego) jak vimdiff?
user1133275,
9

Jeśli zdarzy ci się używać Spacemacs, polecam aktywować „tryb przejściowy smerge”, który wyświetla menu hydra ze wszystkimi możliwymi poleceniami smerge.

Aby to zrobić, wystarczy wywołać Mx spacemacs/smerge-transient-state/body, który jest domyślnie przypisany do SPC-g-r.

Oto zrzut ekranu:

wprowadź opis zdjęcia tutaj

Edycja pliku powinna być intuicyjna:

  1. Naciśnij, naby przejść do następnego przystojniaka.
  2. Wybierz akcję scalania .
  3. Powtarzaj, aż skończysz.
dangom
źródło