2012-03-11 18 views
31

(Pregunta adaptado de How do I combine the two variants of a conflict in emacs' emerge?)Resolución de conflictos con Emacs Ediff: ¿Cómo puedo tomar los cambios de ambas versiones

Tengo un archivo con marcas de conflicto de combinación. Es similar a esto:

<<<<<<< HEAD 
      522ADC9C14B2FD9D00F56BAD /* close_test_button.png in Resources */, 
      522ADC9D14B2FD9D00F56BAD /* [email protected] in Resources */, 
      522ADCA014B2FDB100F56BAD /* test_failed.png in Resources */, 
      522ADCA114B2FDB100F56BAD /* [email protected] in Resources */, 
======= 
      EC1633C014B2F3E3004B52E7 /* arrow.png in Resources */, 
      EC1633C114B2F3E3004B52E7 /* [email protected] in Resources */, 
      EC1633C214B2F3E3004B52E7 /* groups.png in Resources */, 
      EC1633C314B2F3E3004B52E7 /* groups[email protected] in Resources */, 
>>>>>>> beta_2.8 

utilizo M-x-vc-a resolver conflictos para comenzar Ediff. Puedo seleccionar la variante A o B por golpear un o b en mi teclado, pero ¿cómo puedo combinar las dos variantes, una después de la otra?

+3

Lo he deseado por mucho tiempo, gracias por el impulso. –

Respuesta

8

Puede cambiar al búfer "C" y editarlo. Presione + Si ya ha elegido A o B para restaurar la diferencia.

Si lo que buscas es presionar una tecla para eliminar automáticamente los marcadores de diferencia, solo puedo decir que parece una idea terrible.

Las fusiones manuales deben dejarse en manos del usuario. Eliminar pistas sobre de dónde viene cada región diff no me parece bien.

Puede personalizar los marcadores de ser líneas en blanco con este:

M-:

(setq ediff-combination-pattern '("" A "" B "" Ancestor)) 
+9

El punto no es solo quitar los marcadores de diferencia, es solicitar que ambos diffs se incluyan en el resultado final, y forzar a las personas a hacer esto manualmente es un PITA. A menudo, la diferencia solo muestra dónde dos personas han agregado elementos a una lista. Obviamente, el usuario puede seleccionar esto y romper su código, pero pueden hacerlo presionando A o B también ... –

+0

También sería útil poder "copiar" o "copiar" como 'meld' .. – mgalgs

+0

De acuerdo con Trey. Un shortkey se presiona porque un usuario quiere hacer algo.Por su razón de ser, ediff debería eliminar las teclas de acceso directo para xa y xb también ... la mayoría de las otras herramientas decentes tienen esta capacidad de tomar A, luego B o B, luego A ... es la única razón por la que alguna vez salgo de Edfiff ... parece apestar por fusionarse debido a esta corta llegada. – UpAndAdam

3

La cadena de documentación para vc-resolver-conflictos dice que es un alias para smerge-ediff.

Si eso funciona como esperaba, entonces su memoria intermedia debe estar en el modo secundario de smerge, y debe haber un menú para smerge. Ese menú contiene todo lo que necesitas.

+4

específicamente hay 'C-c^a' \t smerge-keep-all; ver _smerge-mode_ help ... –

+0

No es realmente relevante para la funcionalidad 'ediff' (que no usa' smerge-mode', o al menos no en estos días, si es que alguna vez lo hizo), pero ciertamente una respuesta útil si usted * está * usando 'modo smerge'. – phils

4

Sí, ¡totalmente quiero hacer esto! Con el siguiente fragmento de código, puede obtener ambos escribiendo d, que le proporcionará el código tanto del buffer A como del buffer B (en ese orden) en el búfer de combinación.

La única dificultad real en este código es el hecho de que ediff usa una macro en un solo lugar, y la versión compilada de la función necesita ser reevaluada con la nueva macro. De todos modos, prueba el código. Probado con Emacs 23.2.

(require 'ediff-init)   ;ensure the macro is defined, so we can override it 

(defmacro ediff-char-to-buftype (arg) 
    `(cond ((memq ,arg '(?a ?A)) 'A) 
    ((memq ,arg '(?b ?B)) 'B) 
    ((memq ,arg '(?c ?C)) 'C) 
    ((memq ,arg '(?d ?D)) 'D) 
    )) 

(require 'ediff) 

;; Literally copied from ediff-util 
;; need to re-evaluate because it uses the macro defined above 
;; and the compiled version needs to be re-compiled with the new definition 
;; why a macro???? 
(defun ediff-diff-to-diff (arg &optional keys) 
    "Copy buffer-X'th difference region to buffer Y \(X,Y are A, B, or C\). 
If numerical prefix argument, copy the difference specified in the arg. 
Otherwise, copy the difference given by `ediff-current-difference'. 
This command assumes it is bound to a 2-character key sequence, `ab', `ba', 
`ac', etc., which is used to determine the types of buffers to be used for 
copying difference regions. The first character in the sequence specifies 
the source buffer and the second specifies the target. 

If the second optional argument, a 2-character string, is given, use it to 
determine the source and the target buffers instead of the command keys." 
    (interactive "P") 
    (ediff-barf-if-not-control-buffer) 
    (or keys (setq keys (this-command-keys))) 
    (if (eq arg '-) (setq arg -1)) ; translate neg arg to -1 
    (if (numberp arg) (ediff-jump-to-difference arg)) 

    (let* ((key1 (aref keys 0)) 
    (key2 (aref keys 1)) 
    (char1 (ediff-event-key key1)) 
    (char2 (ediff-event-key key2)) 
    ediff-verbose-p) 
(ediff-copy-diff ediff-current-difference 
     (ediff-char-to-buftype char1) 
     (ediff-char-to-buftype char2)) 
;; recenter with rehighlighting, but no messages 
(ediff-recenter))) 

(defun ediff-copy-D-to-C (arg) 
    "Copy ARGth difference region from both buffers A and B to C. 
ARG is a prefix argument. If nil, copy the current difference region." 
    (interactive "P") 
    (ediff-diff-to-diff arg "dc")) 

(defun ediff-copy-diff (n from-buf-type to-buf-type 
       &optional batch-invocation reg-to-copy) 
    (let* ((to-buf (ediff-get-buffer to-buf-type)) 
    ;;(from-buf (if (not reg-to-copy) (ediff-get-buffer from-buf-type))) 
    (ctrl-buf ediff-control-buffer) 
    (saved-p t) 
    (three-way ediff-3way-job) 
    messg 
    ediff-verbose-p 
    reg-to-delete reg-to-delete-beg reg-to-delete-end) 

(setq reg-to-delete-beg 
     (ediff-get-diff-posn to-buf-type 'beg n ctrl-buf)) 
(setq reg-to-delete-end 
     (ediff-get-diff-posn to-buf-type 'end n ctrl-buf)) 

(if (eq from-buf-type 'D) 
    ;; want to copy *both* A and B 
    (if reg-to-copy 
    (setq from-buf-type nil) 
     (setq reg-to-copy (concat (ediff-get-region-contents n 'A ctrl-buf) 
       (ediff-get-region-contents n 'B ctrl-buf)))) 
    ;; regular code 
    (if reg-to-copy 
     (setq from-buf-type nil) 
    (setq reg-to-copy (ediff-get-region-contents n from-buf-type ctrl-buf)))) 

(setq reg-to-delete (ediff-get-region-contents 
      n to-buf-type ctrl-buf 
      reg-to-delete-beg reg-to-delete-end)) 

(if (string= reg-to-delete reg-to-copy) 
    (setq saved-p nil) ; don't copy identical buffers 
    ;; seems ok to copy 
    (if (or batch-invocation (ediff-test-save-region n to-buf-type)) 
     (condition-case conds 
     (progn 
     (ediff-with-current-buffer to-buf 
      ;; to prevent flags from interfering if buffer is writable 
      (let ((inhibit-read-only (null buffer-read-only))) 

     (goto-char reg-to-delete-end) 
     (insert reg-to-copy) 

     (if (> reg-to-delete-end reg-to-delete-beg) 
      (kill-region reg-to-delete-beg reg-to-delete-end)) 
     )) 
     (or batch-invocation 
     (setq 
     messg 
     (ediff-save-diff-region n to-buf-type reg-to-delete)))) 
    (error (message "ediff-copy-diff: %s %s" 
      (car conds) 
      (mapconcat 'prin1-to-string (cdr conds) " ")) 
      (beep 1) 
      (sit-for 2) ; let the user see the error msg 
      (setq saved-p nil) 
      ))) 
) 

;; adjust state of difference in case 3-way and diff was copied ok 
(if (and saved-p three-way) 
    (ediff-set-state-of-diff-in-all-buffers n ctrl-buf)) 

(if batch-invocation 
    (ediff-clear-fine-differences n) 
    ;; If diff3 job, we should recompute fine diffs so we clear them 
    ;; before reinserting flags (and thus before ediff-recenter). 
    (if (and saved-p three-way) 
     (ediff-clear-fine-differences n)) 

    (ediff-refresh-mode-lines) 

    ;; For diff2 jobs, don't recompute fine diffs, since we know there 
    ;; aren't any. So we clear diffs after ediff-recenter. 
    (if (and saved-p (not three-way)) 
     (ediff-clear-fine-differences n)) 
    ;; Make sure that the message about saving and how to restore is seen 
    ;; by the user 
    (message "%s" messg)) 
)) 

;; add keybinding in a hook b/c the keymap isn't defined until the hook is run 
(add-hook 'ediff-keymap-setup-hook 'add-d-to-ediff-mode-map) 

(defun add-d-to-ediff-mode-map() 
    (define-key ediff-mode-map "d" 'ediff-copy-D-to-C)) 
+0

ver mi respuesta: implementa la idea de Trey de una manera mucho más simple. – killdash9

22

Esto hace lo mismo que la respuesta útil de Trey Jackson, y es mucho más simple. Presionando d se copiarán tanto A como B en el buffer C.

(defun ediff-copy-both-to-C() 
    (interactive) 
    (ediff-copy-diff ediff-current-difference nil 'C nil 
        (concat 
        (ediff-get-region-contents ediff-current-difference 'A ediff-control-buffer) 
        (ediff-get-region-contents ediff-current-difference 'B ediff-control-buffer)))) 
(defun add-d-to-ediff-mode-map() (define-key ediff-mode-map "d" 'ediff-copy-both-to-C)) 
(add-hook 'ediff-keymap-setup-hook 'add-d-to-ediff-mode-map) 
+1

Esto es genial. Para completar, ¿sería posible agregar una línea al menú de ayuda rápida también? – chengiz

+4

Esto es brillante. Combinado con '~' para intercambiar el orden de los buffers, puede obtener A, luego B * o * B, luego A, lo que a veces también es útil. –

+1

La vinculación 'd' entró en conflicto con jump to diff. Lo até a 'B' (mayúscula) en su lugar. – Joe

Cuestiones relacionadas