[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Issue #2044 - Fully customizable external diff invocations

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Thu, 21 Mar 2013 15:05:28 +0000 (GMT)

(I've taken the liberty of changing the subject line.)

Gabriela Gibson wrote:

> IIRC Subversion needs to communicate the following file names to the
> user's diff program:
>
> mine, yours, base and output

You're thinking of 'merge', otherwise known as 'diff3', here?

The '--diff-cmd' command-line option (and corresponding 'diff-cmd' config-file option) is used for displaying a diff of a pair of files.  The output is assumed just to be displayed on the standard output (console) or in a GUI window; it is not captured by Subversion.

Of course it will be sensible to apply the same kind of design to the merge tool configuration.  The '--diff3-cmd' command-line option, and the 'diff3-cmd' and 'merge-tool-cmd' config-file options, are all used for what we call 3-way merging, where two files and a base file (usually their youngest common ancestor) are compared and a merged output file is produced.

I'm not terribly clear about the difference between 'diff3-cmd' and 'merge-tool-cmd'.  Given that I've been working on merging for about two years now, it's about time I found out.  Subversion assumes the output will be written to a file for the
'merge-tool-cmd' option, but assumes it will be written to standard
output with the 'diff3-cmd' option.  I'm not sure why they are different
 and this is one of the inconsistencies we should probably clear up now.

Anyway, I recommend you start with 'diff-cmd', and after you've got that working then expand the solution to cover the 'diff3-cmd' and 'merge-tool-cmd' as well.

> It then takes the user input (--diff-cmd) from either the command line
> or a script, and produces a command to run the external diff in order
> to harvest that output.
>
> All we need to do is to render the command line *exactly* as typed
> within the delimiters of (say) %% at the end and start, with the
> exception that %mine %yours, %base and %output will be string
> substituted
[...]
> What do you think?

I will refrain from commenting on your specific syntax suggestion, and just point out that we would do well to adopt one of the many well known standard syntaxes (sadly there is not a single standard standard).  Enough developers here have experience of this sort of thing to be able to make a good specific suggestion, but to avoid getting side-tracked by a potentially long-winded discussion of the details at this point, let's assume that we will eventually decide on a suitable syntax, conceptually roughly like you are thinking of, but different in the details.

In order to get something working so that you can experiment with how well the whole pluggable diff tool idea works in practice, you could very well start by implementing your own suggestion; just don't spend too much time on this part, start very simple, and be prepared to replace it later.

Meanwhile, perhaps some of the more interesting higher level issues are:

  - Start making a list of popular diff tools
(both command-line and GUI), and the form of command-line we would want to provide for each of them (in terms of the main arguments -- file names and labels -- not caring about the other options they can take).

  - What template parameters do we
need to be able to substitute?  The file paths; the labels; the extra options specified with "-x"; any other things?

  - It could be helpful to use a Wiki page for the above two lists, so that anyone can refer to them at any time while you build them incrementally.  And for writing down other aspects of the evolving design.

  - Are there some diff tools that don't accept 'label' arguments but just display the given file names?  If so, do we need to make Subversion generate temporary file names that are more descriptive than a random unique name such as '.svn/tmp/svn-TiBS24'?  In what cases does Subversion pass random unique names and in what cases does it pass understandable paths such as 'trunk/foo/myfile.c'?  It may depend on what sort of diff we request: WC-WC diff (such as the default base:working diff, 'svn diff myfile.c'), or repos-WC diff (such as svn diff -r10 myfile.c), or repos-repos diff (such as 'svn diff -r10:20 myfile.c').

  - Does Subversion provide good labels?  I have been using 'diff3-cmd' configured to run kdiff3, and the labels Subversion passes to it are like '.mine', '.r1459015' and '.r1459080' -- they don't include the file name at all, which makes it very hard to see what file I'm being asked to merge.  (Maybe the diff3-cmd option was never designed to run a GUI diff tool?  But I do it.)  And for 'merge-tool-cmd' it doesn't appear to pass any labels at the moment.  What a lot of inconsistency to sort out.  But if the labels passed to the diff-cmd are always good, you don't worry about this yet.

  - When we support the diff3/merge tool configuration, how are we going to capture the output?  One merge tools might write to a file whose name we have to provide, another might write to a file whose name *it* provides (do any of the popular tools do that?), while another might write to standard output.  We need to support at least the first and last ways, to avoid forcing users to write a wrapper script for the other cases.

I hope these ideas are useful.  Hopefully the answers to many of those questions will turn out to be simple: "all we really need is X and Y".

If it's not too overwhelming to peek into the future, then isse #2447 "Support for external diff commands for non-text types" is something I'm looking towards.  Not expecting you to do this as well, but once we've got support for customizable diff commands, then I want us to let the user specify two or more different diff commands, and specify some rules to determine which diff command will be used for a given file, probably based on matching MIME types and filename patterns and such like.

- Julian
Received on 2013-03-21 16:06:03 CET

This is an archived mail posted to the Subversion Dev mailing list.