我希望能够使用ediff与"git mergetool".
我找到了一些改变源代码的补丁,我不想这样做.相反,我想在我的.gitconfig中添加ediff支持.
我知道git已经内置了对emerge的支持,但我更喜欢ediff.
我试图将这些行添加到我的.gitconfig:
[mergetool "ediff"]
cmd = emacs --eval "(ediff-merge-files-with-ancestor \"$LOCAL\" \"$REMOTE\" \"$BASE\" nil \"$MERGED\")"
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用"git mergetool --tool = ediff"运行时,我得到了这个:
eval: 1: Syntax error: "(" unexpected
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
tar*_*ius 30
我用了一个更复杂的命令.据我记得,我从这个帖子http://kerneltrap.org/mailarchive/git/2007/6/28/250230得到它(可能和你指的一样).
[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\\\"))\"
Run Code Online (Sandbox Code Playgroud)
请注意,我已将其拆分为多行,以提高可读性并转义新行,\因此git config将其视为单行.
我通常使用emacsclient来编辑例如提交消息.遗憾的是,上面的mergetool配置不使用emacsclient,当我试图让它与emacsclient一起工作时,我遇到了各种问题,包括emacsclient立即返回的事实.
但是你刚才提醒我这个问题,所以我可能会尽快解决这个问题.但是,如果其他人已经找到了一个当然很棒的解决方案;-)
u-p*_*nkt 13
我使用以下脚本作为mergetool工作得很好.
#!/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
Run Code Online (Sandbox Code Playgroud)
要将它与`git mergetool'一起使用,请在git config中添加以下内容:
[merge]
tool = ediff
[mergetool "ediff"]
cmd = /path/to/ediff-merge-script $LOCAL $REMOTE $MERGED $BASE
trustExitCode = true
Run Code Online (Sandbox Code Playgroud)
此外,您应该检查(在脚本中)使用的工具的路径以及穷人的控制台检测是否适合您.
脚本本身启动一个emacs客户端(或emacs后面跟一个emacs客户端-a ""),并且ediff-merge-files-with-ancestor或者ediff-merge-files如果没有基本版本(例如合并两个独立创建相同路径/文件的分支时).
emacs客户端完成后,检查合并文件是否有冲突标记.如果找到这些文件,您的工作将被保存到临时文件中,脚本将以代码1退出,git将恢复合并文件的预合并工具内容.
当没有冲突标记存在时,脚本以代码0退出,git将合并视为成功.
重要提示:设置合并工具选项trustExitCode来true以及为冲突标记编辑后检查,如果你开始将无法正常工作emacsclient与--no-wait选项.
小智 8
这是我的设置,它运行得相当好,至少使用Emacs 23.3.我使用的技巧是在钩子中使用(递归编辑),这样emacsclient就不会退出,直到建议的ediff-quit钩子调用(exit-recursive-edit).
我使用了一个建议的ediff-quit来确保退出 - 递归 - 编辑是最后完成的事情.
还有钩子来保存当前帧和窗口状态并在之后恢复它,钩子使当前帧填满屏幕.您可能希望修改它,但我发现合并全屏是最好的方法.
我没有解决中止ediff并使emacsclient返回非零退出的问题.
放入你的gitconfig:
[mergetool "ediff"]
cmd = emacsclient --eval \"(git-mergetool-emacsclient-ediff \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" \\\"$MERGED\\\")\"
trustExitCode = true
[mergetool]
prompt = false
[merge]
tool = ediff
Run Code Online (Sandbox Code Playgroud)
放入你的.emacs或同等的:
;;
;; 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)
Run Code Online (Sandbox Code Playgroud)
除了我在上面的评论中发现的git vs bzr问题之外,我能够确认你需要逃避这些问题.
cmd = emacs --eval "\\(ediff-merge-files-with-ancestor \"$LOCAL\" \"$REMOTE\" \"$BASE\" nil \"$MERGED\"\\)"
Run Code Online (Sandbox Code Playgroud)
请注意双反斜杠字符.我有点明白,他们需要(而不是单一的)来完成sh/bash引用和emacs启动引用机制.我会留给那些更好地掌握Emacs和shell引用来解释血腥细节的人.
-pmr
| 归档时间: |
|
| 查看次数: |
26325 次 |
| 最近记录: |