首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ediff作为git mergetool

使用ediff作为git mergetool
EN

Stack Overflow用户
提问于 2009-11-30 08:53:50
回答 12查看 28.3K关注 0票数 54

我希望能够使用带有"git mergetool“的ediff。

我发现了一些改变源代码的补丁,我不想这么做。相反,我想在我的.gitconfig中添加对ediff的支持。

我知道git内置了对emerge的支持,但我更喜欢ediff。

我尝试将以下代码行添加到我的.gitconfig中:

代码语言:javascript
复制
[mergetool "ediff"]
    cmd = emacs --eval "(ediff-merge-files-with-ancestor \"$LOCAL\" \"$REMOTE\" \"$BASE\" nil \"$MERGED\")"

但是当我尝试用"git mergetool --tool=ediff“来运行它时,我得到的结果是:

代码语言:javascript
复制
eval: 1: Syntax error: "(" unexpected

我做错了什么?

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2009-11-30 17:54:34

我使用一个更复杂的命令。就我所记得的,我是从这个线程http://kerneltrap.org/mailarchive/git/2007/6/28/250230得到的(可能和你提到的一样)。

代码语言:javascript
复制
[mergetool.ediff]
    cmd = emacs --eval \"\
(progn\
  (defun ediff-write-merge-buffer ()\
    (let ((file ediff-merge-store-file))\
      (set-buffer ediff-buffer-C)\
      (write-region (point-min) (point-max) file)\
      (message \\\"Merge buffer saved in: %s\\\" file)\
      (set-buffer-modified-p nil)\
      (sit-for 1)))\
  (setq ediff-quit-hook 'kill-emacs\
        ediff-quit-merge-hook 'ediff-write-merge-buffer)\
  (ediff-merge-files-with-ancestor \\\"$LOCAL\\\" \\\"$REMOTE\\\"\
                                   \\\"$BASE\\\" nil \\\"$MERGED\\\"))\"

请注意,为了增加可读性,我将其分成了几行,并使用\对换行符进行了转义,因此git config将其视为一行。

我通常使用emacsclient来编辑提交消息。不幸的是,上面的mergetool配置没有使用emacsclient,当我试图让它与emacsclient一起工作时,我遇到了各种问题,包括emacsclient立即返回的事实。

但是您刚刚提醒了我这个问题,所以我可能很快就会解决这个问题。但是,如果其他人已经找到了解决方案,那当然是很好的;-)

票数 31
EN

Stack Overflow用户

发布于 2011-11-23 22:59:13

我使用下面的脚本作为mergetool,它工作得很好。

代码语言:javascript
复制
#!/bin/bash

# test args
if [ ! ${#} -ge 3 ]; then
    echo 1>&2 "Usage: ${0} LOCAL REMOTE MERGED BASE"
    echo 1>&2 "       (LOCAL, REMOTE, MERGED, BASE can be provided by \`git mergetool'.)"
    exit 1
fi

# tools
_EMACSCLIENT=/usr/local/bin/emacsclient
_BASENAME=/bin/basename
_CP=/bin/cp
_EGREP=/bin/egrep
_MKTEMP=/bin/mktemp

# args
_LOCAL=${1}
_REMOTE=${2}
_MERGED=${3}
if [ -r ${4} ] ; then
    _BASE=${4}
    _EDIFF=ediff-merge-files-with-ancestor
    _EVAL="${_EDIFF} \"${_LOCAL}\" \"${_REMOTE}\" \"${_BASE}\" nil \"${_MERGED}\""
else
    _EDIFF=ediff-merge-files
    _EVAL="${_EDIFF} \"${_LOCAL}\" \"${_REMOTE}\" nil \"${_MERGED}\""
fi

# console vs. X
if [ "${TERM}" = "linux" ]; then
    unset DISPLAY
    _EMACSCLIENTOPTS="-t"
else
    _EMACSCLIENTOPTS="-c"
fi

# run emacsclient
${_EMACSCLIENT} ${_EMACSCLIENTOPTS} -a "" -e "(${_EVAL})" 2>&1

# check modified file
if [ ! $(egrep -c '^(<<<<<<<|=======|>>>>>>>|####### Ancestor)' ${_MERGED}) = 0 ]; then
    _MERGEDSAVE=$(${_MKTEMP} --tmpdir `${_BASENAME} ${_MERGED}`.XXXXXXXXXX)
    ${_CP} ${_MERGED} ${_MERGEDSAVE}
    echo 1>&2 "Oops! Conflict markers detected in $_MERGED."
    echo 1>&2 "Saved your changes to ${_MERGEDSAVE}"
    echo 1>&2 "Exiting with code 1."
    exit 1
fi

exit 0

要将其与‘git mergetool’一起使用,请在您的git配置中添加以下内容:

代码语言:javascript
复制
[merge]
        tool = ediff

[mergetool "ediff"]
        cmd = /path/to/ediff-merge-script $LOCAL $REMOTE $MERGED $BASE
        trustExitCode = true

此外,您应该检查(在脚本中)使用的工具的路径,以及可怜的人的控制台检测是否适用于您。

脚本本身启动一个emacs客户端(或emacs客户端,-a ""),如果没有基本版本(例如,当合并两个独立创建了相同路径/文件的分支时),则返回ediff-merge-files-with-ancestorediff-merge-files

在emacs客户端完成后,将检查合并的文件中是否有冲突标记。如果找到它们,你的工作将被保存到一个临时文件中,脚本将退出并返回代码1,git将恢复合并文件的pre-mergetool内容。

当不存在冲突标记时,脚本退出并返回代码0,git会将合并视为成功。

重要提示:如果使用--no-wait选项启动emacsclient,则将mergetool选项trustExitCode设置为true以及对冲突标记的编辑后检查将不起作用。

票数 13
EN

Stack Overflow用户

发布于 2010-12-23 03:04:37

下面是我的设置,至少使用Emacs 23.3运行得很好。我使用的技巧是在钩子中使用(递归-编辑),这样emacsclient不会退出,直到建议的ediff-quit钩子调用(退出-递归-编辑)。

我使用了advisted -quit来确保退出-递归-编辑是最后完成的事情。

还有一些钩子可以保存当前的框架和窗口状态并在以后恢复它,钩子会让当前的框架充满整个屏幕。你可能希望修改它,但我发现合并全屏是最好的方法。

我还没有解决中止ediff并使emacsclient返回一个非零退出的问题。

在你的gitconfig中输入:

代码语言:javascript
复制
[mergetool "ediff"]
       cmd = emacsclient --eval \"(git-mergetool-emacsclient-ediff \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" \\\"$MERGED\\\")\"
       trustExitCode = true
[mergetool]
    prompt = false
[merge]
    tool = ediff

放入你的.emacs或等价物中:

代码语言:javascript
复制
;;
;; Setup for ediff.
;;
(require 'ediff)

(defvar ediff-after-quit-hooks nil
  "* Hooks to run after ediff or emerge is quit.")

(defadvice ediff-quit (after edit-after-quit-hooks activate)
  (run-hooks 'ediff-after-quit-hooks))

(setq git-mergetool-emacsclient-ediff-active nil)

(defun local-ediff-frame-maximize ()
  (let* ((bounds (display-usable-bounds))
     (x (nth 0 bounds))
     (y (nth 1 bounds))
     (width (/ (nth 2 bounds) (frame-char-width)))
     (height (/ (nth 3 bounds) (frame-char-height))))
    (set-frame-width (selected-frame) width)
    (set-frame-height (selected-frame) height)
    (set-frame-position (selected-frame) x y)))

(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq ediff-split-window-function 'split-window-horizontally)

(defun local-ediff-before-setup-hook ()
  (setq local-ediff-saved-frame-configuration (current-frame-configuration))
  (setq local-ediff-saved-window-configuration (current-window-configuration))
  (local-ediff-frame-maximize)
  (if git-mergetool-emacsclient-ediff-active
      (raise-frame)))

(defun local-ediff-quit-hook ()
  (set-frame-configuration local-ediff-saved-frame-configuration)
  (set-window-configuration local-ediff-saved-window-configuration))

(defun local-ediff-suspend-hook ()
  (set-frame-configuration local-ediff-saved-frame-configuration)
  (set-window-configuration local-ediff-saved-window-configuration))

(add-hook 'ediff-before-setup-hook 'local-ediff-before-setup-hook)
(add-hook 'ediff-quit-hook 'local-ediff-quit-hook 'append)
(add-hook 'ediff-suspend-hook 'local-ediff-suspend-hook 'append)

;; Useful for ediff merge from emacsclient.
(defun git-mergetool-emacsclient-ediff (local remote base merged)
  (setq git-mergetool-emacsclient-ediff-active t)
  (if (file-readable-p base)
      (ediff-merge-files-with-ancestor local remote base nil merged)
    (ediff-merge-files local remote nil merged))
  (recursive-edit))

(defun git-mergetool-emacsclient-ediff-after-quit-hook ()
  (exit-recursive-edit))

(add-hook 'ediff-after-quit-hooks 'git-mergetool-emacsclient-ediff-after-quit-hook 'append)
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1817370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档