Cómo fusionar conflictos de Git en Emacs


84

Mi fusión reciente de Git ha resultado en una gran cantidad de conflictos. Mi enfoque actual es buscar la próxima aparición de '<<<' y luego realizar la fusión mediante la edición de texto estándar.

Pregunta : ¿hay alguna forma en que Emacs pueda admitir la fusión utilizando la información disponible en Git sobre mi versión, su versión y la versión base del archivo?


Editar: Esta pregunta tiene un alcance diferente al de esta pregunta relacionada , ya que no se limita a invocar ediff.


77
Si usara Magit, podría cargar el búfer de estado y luego presionar los earchivos que se muestran como conflictivos. Magit se iniciaría ediffpara hacer la fusión y luego le pedirá que confirme sus cambios, luego podría organizar el archivo combinado.
wvxvw

@Beginner: otras 3 personas pensaron que era un duplicado, y yo fui la última votación. Por qué: el otro hilo citado da las mismas respuestas ( smergey vc-resolve-conflict, además de una ediff), y ha estado disponible por más tiempo. Sin embargo, estoy de acuerdo en que el primer hilo podría usar un título mejor.
Dan

@Dan no estoy de acuerdo: es una pregunta diferente y que la respuesta sea similar no cambia eso.
Principiante

1
@IqbalAnsari: Creo que el otro hilo necesita un título mejor para que la gente pueda encontrarlo más fácilmente. De hecho, creo que el título de hilo de Principiante sería genial para eso. Sin embargo, esperemos un poco para ver si la gente quiere volver a abrir este hilo. Si no, estaría a favor de renombrar el primer hilo con el título de Principiante.
Dan

1
Y por lo que vale, creo que esta es una buena pregunta con buenas respuestas. Es solo que también creo que es un duplicado, pero otros pueden no compartir esa opinión (sobre la duplicación, eso es).
Dan

Respuestas:


86

Es posible que desee probar smerge-modesimplemente abrir el archivo en conflicto y hacerlo M-xsmerge-modeRET. Destacará todas las regiones en conflicto. También agrega combinaciones de teclas para resolver fácilmente los conflictos, consulte su documentación C-hfsmerge-modeRETpara conocerlos.

Prefijo predeterminado

Encuentro el prefijo predeterminado para smerge-mode C-c^engorroso, así que lo he cambiado a C-cv

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

Combinaciones de teclas importantes

Para mí, los enlaces más importantes son:

smerge-nextobligado a smerge-command-prefixnpasar al siguiente conflicto.

smerge-previousobligado a smerge-command-prefixppasar al conflicto anterior.

smerge-keep-currentobligado a smerge-command-prefixRETmantener la versión en la que está el cursor.

smerge-keep-mineobligado a smerge-command-prefixmmantener sus cambios.

smerge-keep-otherobligado a smerge-command-prefixomantener otros cambios.

smerge-ediffobligado a smerge-command-prefixEcomenzar una sesión de ediff para fusionar los conflictos. Esto es lo mismo que vc-resolve-conflicts(gracias @phils y @Malabarba por señalar esto).

Habilitar el modo smerge automáticamente

ACTUALIZACIÓN: Lo siguiente solo es relevante en las versiones de Emacs anteriores 25.1, lo siguiente puede causar problemas en versiones posteriores, consulte https://github.com/magit/magit/issues/3897

Además, puede estar interesado en habilitar automáticamente smerge-modecuando visite un archivo / búfer con marcadores de conflicto, puede usar algo como lo siguiente para lograr esto

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

Tenga en cuenta que estoy usando buffer-list-update-hooky no, find-file-hookya que la mayoría de las veces tengo conflictos en un búfer que ya está abierto en emacs, en cuyo caso no find-file-hooksirve de nada.

También verifique otros métodos mencionados en esta respuesta


1
(1) No lo olvides smerge-ediff. (2) ¿En qué versión de Emacs estás? En la rama maestra actual de emacs, smerge se activa automáticamente. (3) ¿Por qué estás usando en buffer-list-update-hooklugar de find-file-hook?
Malabarba

Para mayor aclaración, tenga en cuenta que smerge-ediffy vc-resolve-conflictsson lo mismo.
Phil

@Malabarba 1) Mencioné que smerge-modelas combinaciones de teclas están documentadas en su documentación. Tal vez pueda citar el manual aquí para completarlo. Gracias por la respuesta. 2) Estoy en v24.5, aunque a veces pruebo la rama maestra, no recuerdo que se haya activado automáticamente (¿es un cambio reciente?). 3) Esto se debe a que la mayoría de las veces tengo conflictos en búferes ya abiertos, en cuyo caso tendría que activar explícitamentesmerge-mode
Iqbal Ansari

@IqbalAnsari ¿hay alguna razón para no haber smerge-modehabilitado todo el tiempo? Quizás no haga mucho hasta que se invoque.
PythonNut

@PythonNut Buena pregunta, desafortunadamente no tengo una respuesta ya que nunca intenté mantenerla habilitada todo el tiempo, sin embargo, vale la pena
probarla

32

Editar: dado que esta respuesta obtuvo más votos positivos de lo que esperaba, la amplié un poco.

Para complementar la respuesta de @IqbalAnsari, también puede usar vc-resolve-conflicts(como lo han mencionado otros, es un alias smerge-ediff). Esto iniciará la ediffinterfaz. A la izquierda estará el primer padre de fusión y el segundo padre de fusión a la derecha. Están etiquetados en la línea de modelo con MINEy OTHERrespectivamente. El búfer combinado se muestra a continuación (ver captura de pantalla).

Una captura de pantalla de la interfaz <code> ediff </code>

Atajos de teclado

  • Navega a través de los conflictos con ny p.
  • Aceptar versiones con ao b.
  • Mira el antepasado con /!
  • Salga de la sesión de ediff con q.

También puede navegar al búfer combinado other-windowy editar manualmente en caso de que resolver un conflicto sea más complicado que aceptar una versión. Cuando haya terminado, puede guardar el búfer y salir de Emacs como de costumbre. Para obtener más ayuda, solo use ?durante la ediffsesión, hay un montón de comandos muy útiles allí. ¡Todavía no sé qué hacen la mitad de ellos!


2
Este es el mejor método de la OMI. Lo tengo obligado C-x v <, aunque en la práctica es más probable que lo invoque con Magit (según el comentario de wvxvw).
Phil

1
Dado que el año 2000 vc-resolve-conflictes un alias para smerge-ediff, que como su nombre indica comienza una sesión de Ediff, no una sesión de Emerge. Por cierto, el encabezado de la biblioteca ediff.elreconoce emerge.ella influencia de s y luego continúa diciendo "La versión actual de Ediff reemplaza a Emerge. Proporciona una interfaz de usuario superior y tiene numerosas características principales que no se encuentran en Emerge. En particular, puede hacer parches, y Operaciones de comparación, fusión y directorio de archivos de 2 y 3 vías ".
tarsius

66
También tenga en cuenta que magit-ediff-resolve( Emo een un archivo con conflictos) utiliza smerge-ediffinternamente. Sin embargo, anula el ediff-quit-hookpara proporcionar una experiencia de finalización de sesión ligeramente mejor. En lugar de decirle que puede guardar "el búfer" (hay varios búferes), le pregunta si desea guardar el búfer (mientras le muestra su nombre).
tarsius

¿Hay alguna manera de mostrar 4 ventanas (la nuestra, la principal, la de ellos, el espacio de trabajo) como vimdiff?
user1133275

9

Si utiliza Spacemacs, le recomiendo activar "smerge-transient-mode", que muestra un menú de hidra con todos los comandos de smerge posibles.

Para hacer eso, simplemente llame a Mx spacemacs/smerge-transient-state/body, que por defecto está asignado a SPC-g-r.

Aquí hay una captura de pantalla:

ingrese la descripción de la imagen aquí

Editar su archivo debería ser intuitivo:

  1. Presione npara ir al siguiente trozo.
  2. Elige una acción de fusión .
  3. Repita hasta que esté hecho.