Zakładki i18n

Tuesday 1 January 2013

Emacs as merging tool - ediff

More or less frequently  we need to check if text files are the same. I don't even supposed that I will need such a feature so often. It is great to have such a tool for this task, even better is to have this feature build in our favourite tool. So lets do this with Emacs:-)

I assume that you have basic knowledge about Emacs. Of course this is not mandatory but helps greatly. If you are not using it already I suggest you to give it a try. It is worth an effort and costs nothing.

All examples in this post is prepared for GNU/Linux environment but you can use it anywhere you like. Just remember to write correct file paths in config files if they are any. How it looks ediff is a major mode for Emacs. When we have emacs started already the simplest way to use it is by pressing M-x ediff and choose two files to compare.

After this we see screen looking like one bellow:


On upper window we have first file chosen in the command invocation, the second one is in the middle and on the lower window we have ediff control panel.

If you working with two versions of the same files and want to merge selected changes to another I suggest to decide with file you always put first in ediff command and with while is the second. My choice is to always put files with changes on top but it is personal decision. How it works To start navigate you must select ediff control panel window. Available options shows after pressing ?. To use this options ediff menu bar window must be activated.

Screenshot shows how it can look like when we go to first difference between files those lines is marked with colors.


Try this for a minute to feel friendly with this interface.

If we have problem choosing with difference we want to paste to first or the second file we always could edit this by ourselves. After this we should go to ediff control panel window.

More info about ediff you can find at it's ediff user's manual. Make it more friendly It would be cool to use it with simple command that compares to files. This one do the trick:
emacs --eval "(ediff-files \"file1\" \"file2\")"

Ok but this is rather cumbersome to use. We need to wrap it with some script, so lets do some scripting:
#!/bin/bash

if [[  "${#@}" != "2" ]]; then
    echo "This script requires 2 files parameters."
    exit
fi

if [[ ! -f "$1" ]]; then
    echo "$1 is not regular file"
    exit  

 elif [[ ! -f "$2" ]]; then
    echo "$2 is not regular file"
    exit
fi

exec emacs --eval "(ediff-files \"$1\" \"$2\")"
In addition to run ediff we check if two given files are truly regular text files and if the both files were given in parameter list.

If we use emacs server we can change last line with:
exec emacsclient --alternate-editor="" -c --eval "(ediff-files \"$1\" \"$2\")"
Make it even more friendly Our newly written program have an irritating habit to not close emacs after we press to quit. This one in .emacs saves all changed buffers and gently closes emacs:
(add-hook 'ediff-quit-hook 'save-buffers-kill-emacs 1)

This one is helpful especially if we use emacs just for merging and prefer that it will close automatically after the job is done. This strategy is ok if you always starts merge mode as emacs instance (starting by emacs command) but if you would use it in client mode (have a look emacs server manual) then probably you wouldn't be happy if emacs suddenly quits. One more tip Sometimes we need to merge one files to another but we want to be sure that we will not corrupt the first file. To gain this behaviour we modify our script putting this inside:
emacs --eval "(ediff-files \"$1\" \"$2\" 'ediff-set-read-only-in-buf-A)"

In result our top window (first file in parameter list) is automatically set to read-only mode. We can change this behaviour from ediff control panel window by pressing Xa. Here I use only 'ediff-set-read-only-in-buf-A as optional parameter passed to ediff-files but it is also good place to pass a list of them. This simple way we can easily custom ediff invocation. Conclusion ediff is great tool with big potential. I give only a snapshot of its possibilities. Tasks like create file patches, version control support are ones of these worth mention.

If you want to learn more about it just read some resources over the Internet about it. I think user's manual ediff user's manual is good place to start adventure with this tool.

If you use emacs you must try ediff.

Share your comments about this post. I'm very interested what do you think about this tool and my post. Maybe something could be done better or maybe I forgot to mention about something important. Fear not to leave a feedback :-) References: