Use ediff interactive merge to help conflict resolution.
Idea from smerge code, adapted to git, new key binding on "e"
This commit is contained in:
parent
5cd62fa9ac
commit
1eac6b70c6
2 changed files with 73 additions and 17 deletions
56
magit.el
56
magit.el
|
@ -1104,6 +1104,7 @@ Many Magit faces inherit from this one by default."
|
|||
(define-key map (kbd "B") 'magit-create-branch)
|
||||
(define-key map (kbd "m") 'magit-manual-merge)
|
||||
(define-key map (kbd "M") 'magit-automatic-merge)
|
||||
(define-key map (kbd "e") 'magit-interactive-resolve-item)
|
||||
(define-key map (kbd "N r") 'magit-svn-rebase)
|
||||
(define-key map (kbd "N c") 'magit-svn-dcommit)
|
||||
(define-key map (kbd "R") 'magit-rebase-step)
|
||||
|
@ -1167,6 +1168,7 @@ Many Magit faces inherit from this one by default."
|
|||
["Create branch" magit-create-branch t]
|
||||
["Merge" magit-automatic-merge t]
|
||||
["Merge (no commit)" magit-manual-merge t]
|
||||
["Interactive resolve" magit-interactive-resolve-item t]
|
||||
["Rebase" magit-rebase-step t]
|
||||
("Git SVN"
|
||||
["Rebase" magit-svn-rebase (magit-svn-enabled)]
|
||||
|
@ -2865,4 +2867,58 @@ Prefix arg means justify as well."
|
|||
(erase-buffer)
|
||||
(shell-command (concat magit-git-executable " branch -va") t t)))
|
||||
|
||||
(defvar magit-ediff-file)
|
||||
(defvar magit-ediff-windows)
|
||||
|
||||
(defun magit-interactive-resolve (file)
|
||||
(let ((merge-status (magit-git-string "ls-files -u -- %s" file))
|
||||
(base-buffer (generate-new-buffer (concat file ".base")))
|
||||
(our-buffer (generate-new-buffer (concat file ".ours")))
|
||||
(their-buffer (generate-new-buffer (concat file ".theirs")))
|
||||
(windows (current-window-configuration)))
|
||||
(if (null merge-status)
|
||||
(error "Cannot resolge %s" file))
|
||||
(with-current-buffer base-buffer
|
||||
(if (string-match "^[0-9]+ [0-9a-f]+ 1" merge-status)
|
||||
(insert (magit-git-string "cat-file blob :1:%s" file))))
|
||||
(with-current-buffer our-buffer
|
||||
(if (string-match "^[0-9]+ [0-9a-f]+ 2" merge-status)
|
||||
(insert (magit-git-string "cat-file blob :2:%s" file))))
|
||||
(with-current-buffer their-buffer
|
||||
(if (string-match "^[0-9]+ [0-9a-f]+ 3" merge-status)
|
||||
(insert (magit-git-string "cat-file blob :3:%s" file))))
|
||||
;; We have now created the 3 buffer with ours, theirs and the ancestor files
|
||||
(with-current-buffer (ediff-merge-buffers-with-ancestor our-buffer their-buffer base-buffer)
|
||||
(make-local-variable 'magit-ediff-file)
|
||||
(setq magit-ediff-file file)
|
||||
(make-local-variable 'magit-ediff-windows)
|
||||
(setq magit-ediff-windows windows)
|
||||
(make-local-variable 'ediff-quit-hook)
|
||||
(add-hook 'ediff-quit-hook
|
||||
(lambda ()
|
||||
(let ((buffer-A ediff-buffer-A)
|
||||
(buffer-B ediff-buffer-B)
|
||||
(buffer-C ediff-buffer-C)
|
||||
(buffer-Ancestor ediff-ancestor-buffer)
|
||||
(file magit-ediff-file)
|
||||
(windows magit-ediff-windows))
|
||||
(ediff-cleanup-mess)
|
||||
(find-file file)
|
||||
(erase-buffer)
|
||||
(insert-buffer-substring buffer-C)
|
||||
(kill-buffer buffer-A)
|
||||
(kill-buffer buffer-B)
|
||||
(kill-buffer buffer-C)
|
||||
(when (bufferp buffer-Ancestor) (kill-buffer buffer-Ancestor))
|
||||
(set-window-configuration windows)
|
||||
(message "Conflict resolution finished; you may save the buffer")))))))
|
||||
|
||||
|
||||
(defun magit-interactive-resolve-item ()
|
||||
(interactive)
|
||||
(magit-section-action (item info "resolv")
|
||||
((diff)
|
||||
(magit-interactive-resolve (cadr info)))))
|
||||
|
||||
|
||||
(provide 'magit)
|
||||
|
|
|
@ -452,10 +452,10 @@ one parent). If you want to abort a manual merge, just do a hard
|
|||
reset to HEAD with @kbd{X}.
|
||||
|
||||
Merges can fail if the two branches you merge want to introduce
|
||||
conflicting changes. In that case, the automatic merge stops before
|
||||
the commit, essentially falling back to a manual merge. You need to
|
||||
resolve the conflicts and stage the resolved files, for example with
|
||||
@kbd{S}.
|
||||
conflicting changes. In that case, the automatic merge stops before the
|
||||
commit, essentially falling back to a manual merge. You need to resolve
|
||||
the conflicts for example with @kbd{e} and stage the resolved files, for
|
||||
example with @kbd{S}.
|
||||
|
||||
You can not stage individual hunks one by one as you resolve them, you
|
||||
can only stage whole files once all conflicts in them have been
|
||||
|
|
Loading…
Reference in a new issue