Come unire i conflitti Git in Emacs


84

La mia recente fusione con Git ha provocato un gran numero di conflitti. Il mio approccio attuale è quello di cercare la prossima occorrenza di '<<<' e quindi eseguire l'unione mediante la modifica del testo standard.

Domanda : c'è un modo in cui Emacs può supportare l'unione usando le informazioni disponibili in Git sulla mia versione, la loro versione e la versione base del file?


Modifica: questa domanda ha un ambito diverso rispetto a questa domanda correlata , poiché non si limita a invocare ediff.


7
Se dovessi usare Magit, potresti caricare il buffer di stato e quindi premere esui file mostrati come in conflitto. Magit si avviava ediffper eseguire l'unione e in seguito ti chiedeva di confermare le modifiche, quindi puoi mettere in scena il file unito.
wvxvw,

@Binner: altre 3 persone hanno pensato che fosse un duplicato e io sono stato l'ultimo voto. Perché: l'altro thread citato fornisce le stesse risposte ( smergee vc-resolve-conflict, oltre a una ediff), ed è in circolazione da più tempo. Concordo sul fatto che il primo thread potrebbe usare un titolo migliore, comunque.
Dan

@Dan Non sono d'accordo: è una domanda diversa e che la risposta è simile non cambia.
Principiante,

1
@IqbalAnsari: penso che l'altro thread abbia bisogno di un titolo migliore in modo che le persone possano trovarlo più facilmente. In effetti, penso che il titolo del thread di Beginner sarebbe perfetto per questo. Tuttavia, aspettiamo solo un po 'per vedere se le persone vogliono riaprire questo thread. Altrimenti, sarei a favore di rinominare il primo thread con il titolo di Principiante.
Dan

1
E per quello che vale, penso che questa sia una buona domanda con buone risposte. È solo che penso che sia anche un duplicato, ma altri potrebbero non condividere quell'opinione (sulla duplicazione, cioè).
Dan

Risposte:


86

Potresti provare smerge-modesemplicemente aprire il file in conflitto e farlo M-xsmerge-modeRET. Evidenzierà tutte le regioni in conflitto. Aggiunge inoltre le combinazioni di tasti per risolvere facilmente i conflitti, consultare la sua documentazione C-hfsmerge-modeRETper conoscerli.

Prefisso predefinito

Trovo il prefisso predefinito per smerge-mode C-c^ingombrante, quindi l'ho cambiato in C-cv

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

Tasti importanti

Per me gli attacchi più importanti sono:

smerge-nextdestinato a smerge-command-prefixnpassare al prossimo conflitto.

smerge-previousdestinato a smerge-command-prefixppassare al conflitto precedente.

smerge-keep-currentdestinato a smerge-command-prefixRETmantenere la versione su cui si trova il cursore.

smerge-keep-minedestinato a smerge-command-prefixmmantenere le modifiche.

smerge-keep-otherdestinato a smerge-command-prefixomantenere altre modifiche.

smerge-ediffdestinato a smerge-command-prefixEiniziare una sessione ediff per unire i conflitti. Questo è lo stesso di vc-resolve-conflicts(grazie a @phils e @Malabarba per averlo segnalato).

Abilitazione automatica della modalità smerge

AGGIORNAMENTO: Quanto segue è rilevante solo nelle versioni precedenti di Emacs 25.1, quanto segue può causare problemi nelle versioni successive, consultare https://github.com/magit/magit/issues/3897

Inoltre potresti essere interessato ad abilitare automaticamente smerge-modequando visiti un file / buffer con marcatori di conflitto che puoi usare qualcosa come il seguente per raggiungere questo obiettivo

(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)

Nota che sto usando buffer-list-update-hooke non find-file-hookperché la maggior parte delle volte ottengo conflitti in un buffer che è già aperto in emacs, nel qual caso non find-file-hookè di aiuto.

Controlla anche gli altri metodi menzionati in questa risposta


1
(1) Non dimenticare smerge-ediff. (2) In quale versione di Emacs sei? Nel ramo master di emacs corrente, smerge si attiva automaticamente. (3) Perché stai usando buffer-list-update-hookinvece di find-file-hook?
Malabarba,

Per ulteriori chiarimenti, si noti che smerge-ediffe vc-resolve-conflictssono la stessa cosa.
phils,

@Malabarba 1) Ho menzionato che smerge-modele associazioni di tasti sono documentate nella sua documentazione. Forse posso citare il manuale qui per completezza. Grazie per il feedback. 2) Sono su v24.5, anche se a volte provo il ramo master, non ricordo che smerge venga girato automaticamente (è una modifica recente?). 3) Questo perché la maggior parte delle volte ho conflitti in buffer già aperti, nel qual caso avrei bisogno di attivare esplicitamentesmerge-mode
Iqbal Ansari

@IqbalAnsari c'è qualche motivo per non averlo smerge-modeabilitato in ogni momento? Forse non fa molto fino a quando non viene invocato.
PythonNut

@PythonNut Buona domanda, sfortunatamente non ho una risposta poiché non ho mai provato a tenerlo sempre abilitato, ma vale la pena provarlo
Iqbal Ansari

32

Modifica: poiché questa risposta ha ottenuto più voti di quanto mi aspettassi, l'ho ampliata un po '.

Per integrare la risposta di @IqbalAnsari, potresti anche usare vc-resolve-conflicts(come detto da altri, è un alias a smerge-ediff). Questo avvierà l' ediffinterfaccia. A sinistra sarà il primo genitore di unione e il secondo genitore di unione a destra. Sono etichettati sulla modelina con MINEe OTHERrispettivamente. Il buffer unito è mostrato di seguito (vedi screenshot).

Uno screenshot dell'interfaccia <code> ediff </code>

keybindings

  • Naviga attraverso i conflitti con ne p.
  • Accetta le versioni con ao b.
  • Guarda l'antenato con /!
  • Esci dalla sessione ediff con q.

È inoltre possibile accedere al buffer unito other-windowe modificarlo manualmente nel caso in cui la risoluzione di un conflitto sia più complicata rispetto all'accettazione di una versione. Al termine, è possibile salvare il buffer ed uscire da Emacs come al solito. Per ulteriore aiuto, basta usare ?durante la ediffsessione, ci sono un sacco di comandi molto utili. Ancora non so cosa ne faccia la metà!


2
Questo è il metodo migliore IMO. L'ho legato C-x v <, anche se in pratica ho maggiori probabilità di invocarlo con Magit (come da commento di wvxvw).
phils,

1
Dal 2000 vc-resolve-conflictè un alias per il smerge-ediffquale, come suggerisce il nome, inizia una sessione Ediff, non una sessione Emerge. A proposito, l'intestazione della libreria di ediff.elriconosce l' emerge.elinfluenza e poi continua dicendo "La versione attuale di Ediff sostituisce Emerge. Fornisce un'interfaccia utente superiore e ha numerose funzionalità principali che non si trovano in Emerge. In particolare, può fare patch e Operazioni di confronto, unione e directory di file a 2 e 3 vie. "
tarsius,

6
Si noti inoltre che magit-ediff-resolve( Emo esu un file con conflitti) utilizza smerge-ediffinternamente. Sovrascrive, tuttavia, ediff-quit-hookper fornire un'esperienza di finitura della sessione leggermente migliore. Invece di dirti che potresti salvare "il buffer" (ci sono diversi buffer), ti chiede se vuoi salvare il buffer (mostrandoti il ​​suo nome).
tarsius,

C'è un modo per mostrare 4 finestre (la nostra, la madre, la loro, l'area di lavoro) come vimdiff?
user1133275

9

Se ti capita di usare Spacemacs, ti consiglio di attivare "smerge-transient-mode", che fa apparire un menu Hydra con tutti i possibili comandi smerge.

Per fare ciò, basta chiamare Mx spacemacs/smerge-transient-state/body, che è assegnato per impostazione predefinita SPC-g-r.

Ecco uno screenshot:

inserisci qui la descrizione dell'immagine

La modifica del file dovrebbe quindi essere intuitiva:

  1. Premere nper passare al pezzo successivo.
  2. Scegli un'azione di unione .
  3. Ripeti fino al termine.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.