2012-03-11 11 views
31

(Domanda adattato da How do I combine the two variants of a conflict in emacs' emerge?)Risoluzione dei conflitti con Emacs Ediff: Come posso prendere i cambiamenti di entrambe le versioni

Ho un file con i marcatori di unione di conflitto. Sembra simile a questo:

<<<<<<< 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 /* [email protected] in Resources */, 
>>>>>>> beta_2.8 

Io uso M-x VC-resolve-conflitti per iniziare Ediff. Riesco a scegliere la variante Un o B colpendo un o B sulla mia tastiera, ma come faccio a combinare entrambe le varianti, una dopo l'altra?

+3

Ho desiderato così tanto tempo, grazie per l'impeto. –

risposta

8

È possibile passare al buffer "C" e modificarlo. Premere + Se si è già scelto A o B per ripristinare il diff.

Se quello che vuoi è premere un tasto per rimuovere automaticamente i marcatori di diff, posso solo dire che sembra una pessima idea.

Le fusioni manuali devono essere lasciate all'utente. Per rimuovere indizi su dove ogni regione diff venisse non mi sembra giusto.

È possibile personalizzare i marcatori di essere righe vuote con questo:

M-:

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

Il punto non è solo rimuovere i marcatori diff, è richiedere che entrambi i diff siano inclusi nel risultato finale - e costringere le persone a fare manualmente questo è un PITA. Spesso il diff sta mostrando dove due persone hanno aggiunto delle cose a una lista. Ovviamente l'utente può selezionarlo e romperne il codice, ma può farlo premendo anche A o B ... –

+0

Sarebbe anche utile poter "copiare" o "copiare" come 'meld' .. – mgalgs

+0

D'accordo con Trey. Viene spinto un tasto di scelta perché un utente vuole fare qualcosa ..Secondo la tua logica, l'ediff dovrebbe rimuovere anche i tasti di scelta rapida per xa e xb ... la maggior parte degli altri strumenti decenti ha questa capacità di prendere A poi B o B poi A .... è l'unico motivo per cui ho lasciato edfiff .. sembra succhiare per la fusione a causa di questa breve venuta. – UpAndAdam

3

La stringa doc per VC-resolve-conflitti dice che è un alias per smerge-ediff.

Se ciò funziona come previsto, il buffer dovrebbe essere in modalità meno piccola, e dovrebbe esserci un menu per smirne. Quel menu contiene tutto ciò di cui hai bisogno.

+4

in particolare c'è 'C-c^a' \t smerge-keep-all; vedi _smerge-mode_ help ... –

+0

Non proprio rilevante per la funzionalità 'ediff' (che non usa' smerge-mode' - o almeno non in questi giorni, se mai lo fosse stata), ma sicuramente una risposta utile se tu * stai * usando 'smerge-mode'. – phils

4

Sì, voglio assolutamente farlo! Con il seguente blocco di codice è possibile ottenere entrambi digitando d - che otterrà il codice dal buffer A e dal buffer B (in questo ordine) nel buffer di unione.

L'unica vera difficoltà in questo codice è il fatto che ediff utilizza una macro in un posto e la versione compilata della funzione deve essere rivalutata con la nuova macro. Ad ogni modo, prova il codice. Testato 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

vedere la mia risposta - implementa l'idea di Trey in un modo molto più semplice. – killdash9

22

Questo fa la stessa risposta di Trey Jackson, ed è molto più semplice. Premendo d si copia A e B nel 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

Questo è fantastico. Per completezza sarebbe possibile aggiungere una riga al riguardo nel menu di aiuto rapido? – chengiz

+4

Questo è geniale. Combinato con '~' per scambiare l'ordine dei buffer è possibile ottenere A poi B * o * B poi A, che a volte è utile. –

+1

La combinazione di tasti 'd' è in conflitto con il salto a diff. L'ho legato a 'B' (maiuscolo) invece. – Joe

Problemi correlati