Skip to content

Subverting Difference

FileMerge

Subversion allows you to compare the differences between revisions of a given document with the command:

svn diff

Let’s begin with the simplest and most common use of this command. But first a bit of terminology. Each time a change is committed to the repository its revision number increments. Revision keywords can be used instead of revision numbers. BASE is a revision keyword and refers to the pristine copy of an item in a working copy. The pristine copy of a file is a copy of your file as it was the last time your working copy was updated. It resides in the .svn directory within your file’s directory. So if your file is foo and it resides in directory bar, then running:

ls -a

in directory bar will reveal:

.svn
foo

.svn is an administrative directory that subversion makes use of and you should never modify it. Other useful revision keywords are:

  • HEAD—the latest revision in the repository
  • COMMITTED—the last revision in which the file changed before BASE
  • PREV—the revision that precedes the last revision in which the file changed before BASE, that is, COMMITTED - 1.

The command:

svn diff foo

will compare the foo with BASE, that is, its pristine copy. So it will reveal the changes you have made to foo since you last updated your working copy. This is one of the more common uses of svn diff since it provides information necessary to write an informative commit message.

That’s pretty useful. But sometimes you may want to do something more. Fortunately, svn diff comes with a slew of options that allow for a fair amount of flexibility.

First, suppose you want to compare the modifications that you made to your file with an older revision, say, revision 17. The command:

svn diff -r 17 foo

allows you to do just that. It compares foo as it was in revision 17 with foo as it presently is in your working copy.

Second, suppose you want to compare the differences between to older revisions, say revisions 17 and 23. The command:

svn diff -r 17:23 http://url/of/your/repository/foo

will display these differences.

One really useful option is –diff-cmd. This option allows you to pass arguments to an external diff program. Why is this useful? Well svn diff only displays line differences. If you are writing prose in a text editor, paragraphs are long lines. What would be more useful is for word differences to be displayed. The option –diff-cmd allows you to use an external diff program that displays word differences.

I like to use Apple’s FileMerge, a graphical diff program that can be opened from the command line with:

opendiff

Unfortunately, opendiff and svn diff use different arguments. So to get opendiff to work with subversion requires a shell script wrapper. Fortunately, Bruno De Fraine has done the heavy lifting. His script fmdiff is just such a wrapper. fmdiff can be downloaded (or checked out) form this link. If you install fmdiff in /usr/local/bin or ~/bin as is your preference and make it executable, you could then run the command:

svn diff diff-cmd fmdiff foo

to reveal the differences between foo and its pristine copy in FileMerge.

Bear in mind, if you want to use an external diff program, say, GNU wdiff, you may very well need to write a wrapper script to accommodate a difference in arguments.

{ 5 } Comments

  1. Juan | May 2, 2007 at 2:32 pm | Permalink

    I get the following error message: “svn: ‘diff-cmd’ is not under version control”

    What am I doing worng?

  2. Juan | May 2, 2007 at 3:08 pm | Permalink

    Got it. Should be

    svn diff –diff-cmd fmdiff foo

    Now I’m getting a different error: exec of ‘fmdiff’ failed: No such file or directorysvn: ‘fmdiff’ returned 255

  3. Juan | May 2, 2007 at 3:38 pm | Permalink

    Got it again. Should be

    svn diff –diff-cmd fmdiff.sh foo

  4. Mark Eli Kalderon | May 2, 2007 at 3:38 pm | Permalink

    Couple of things. Is fmdiff on your path? To see the paths searched by the shell type $PATH in the terminal. Is fmdiff in one of the directories listed? If not, then either try using the full path to fmdiff, or add the path to your .profile (with the line: export PATH=”/path/to/directory/of/fmdiff”—I am assuming your shell is bash by the way). Another thing to check is to see if you have made fmdiff executable. In the directory where fmdiff is try: sudo chmod 755 fmdiff. If these commands are unfamiliar to you be sure to check their man pages. Hope this helps.

  5. Mark Eli Kalderon | May 2, 2007 at 3:43 pm | Permalink

    Oh, OK, for some reason my copy lacks the .sh. (Maybe a sign that I should update the script.) Glad it worked out for you.

{ 1 } Trackback

  1. Subversion and TextMate at Excursus | May 18, 2007 at 3:52 pm | Permalink

    […] Subverting Difference […]

Post a Comment

You must be logged in to post a comment.
FireStats icon Powered by FireStats