(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

Reply via email to