[PATCH] extdiff: add labels, read diff arguments from [merge-tools]

Steve Borho steve at borho.org
Sat May 15 12:31:27 CDT 2010


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1262924345 21600
# Node ID 53e70c7714bc9dc14116c0d6514157e95a790c09
# Parent  ba78a1bfbfd9fbe0fa48a05b8d94e6dcf431f635
extdiff: add labels, read diff arguments from [merge-tools]

hgtk has been using these same configs since Feb. Users only have to name the
tools they would like to use, ex:

[extdiff]
kdiff3 =
meld =

diff --git a/contrib/mergetools.hgrc b/contrib/mergetools.hgrc
--- a/contrib/mergetools.hgrc
+++ b/contrib/mergetools.hgrc
@@ -6,6 +6,7 @@
 kdiff3.regappend=\kdiff3.exe
 kdiff3.fixeol=True
 kdiff3.gui=True
+kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
 
 gvimdiff.args=--nofork -d -g -O $local $other $base
 gvimdiff.regkey=Software\Vim\GVim
@@ -19,14 +20,17 @@
 
 meld.gui=True
 meld.args=--label='local' $local --label='base' $base --label='other' $other
+meld.diffargs=-a --label='$plabel1' $parent --label='$clabel' $child
 
 tkdiff.args=$local $other -a $base -o $output
 tkdiff.gui=True
 tkdiff.priority=-8
+tkdiff.diffargs=-L '$plabel1' $parent -L '$clabel' $child
 
 xxdiff.args=--show-merged-pane --exit-with-merge-status --title1 local --title2 base --title3 other --merged-filename $output --merge $local $base $other
 xxdiff.gui=True
 xxdiff.priority=-8
+xxdiff.diffargs=--title1 '$plabel1' $parent --title2 '$clabel' $child
 
 diffmerge.regkey=Software\SourceGear\SourceGear DiffMerge\
 diffmerge.regname=Location
@@ -34,6 +38,7 @@
 diffmerge.args=-nosplash -merge -title1=local -title2=merged -title3=other $local $base $other -result=$output
 diffmerge.checkchanged=True
 diffmerge.gui=True
+diffmerge.diffargs=--nosplash --title1='$plabel1' --title2='$clabel' $parent $child
 
 p4merge.args=$base $local $other $output
 p4merge.regkey=Software\Perforce\Environment
@@ -41,16 +46,19 @@
 p4merge.regappend=\p4merge.exe
 p4merge.gui=True
 p4merge.priority=-8
+p4merge.diffargs=$parent $child
 
 tortoisemerge.args=/base:$base /mine:$local /theirs:$other /merged:$output
 tortoisemerge.regkey=Software\TortoiseSVN
 tortoisemerge.checkchanged=True
 tortoisemerge.gui=True
 tortoisemerge.priority=-8
+tortoisemerge.diffargs=/base:$parent /mine:$child /basename:'$plabel1' /minename:'$clabel'
 
 ecmerge.args=$base $local $other --mode=merge3 --title0=base --title1=local --title2=other --to=$output
 ecmerge.regkey=Software\Elli\xc3\xa9 Computing\Merge
 ecmerge.gui=True
+ecmerge.diffargs=$parent $child --mode=diff2 --title1='$plabel1' --title2='$clabel'
 
 filemerge.executable=/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge
 filemerge.args=-left $other -right $local -ancestor $base -merge $output
@@ -62,12 +70,14 @@
 beyondcompare3.regname=ExePath
 beyondcompare3.gui=True
 beyondcompare3.priority=-2
+beyondcompare3.diffargs=/lro /lefttitle='$plabel1' /righttitle='$clabel' /solo /expandall $parent $child
 
 ; Linux version of Beyond Compare
 bcompare.args=$local $other $base -mergeoutput=$output -ro -lefttitle=parent1 -centertitle=base -righttitle=parent2 -outputtitle=merged -automerge -reviewconflicts -solo
 bcompare.premerge=False
 bcompare.gui=True
 bcompare.priority=-1
+bcompare.diffargs=-lro -lefttitle='$plabel1' -righttitle='$clabel' -solo -expandall $parent $child
 
 winmerge.args=/e /x /wl /ub /dl other /dr local $other $local $output
 winmerge.regkey=Software\Thingamahoochie\WinMerge
@@ -75,6 +85,7 @@
 winmerge.checkchanged=True
 winmerge.gui=True
 winmerge.priority=-10
+winmerge.diffargs=/r /e /x /ub /wl /dl '$plabel1' /dr '$clabel' $parent $child
 
 araxis.regkey=SOFTWARE\Classes\TypeLib\{46799e0a-7bd1-4330-911c-9660bb964ea2}\7.0\HELPDIR
 araxis.regappend=\ConsoleCompare.exe
@@ -84,3 +95,9 @@
 araxis.checkconflict=True
 araxis.binary=True
 araxis.gui=True
+araxis.diffargs=/2 /wait /title1:"$plabel1" /title2:"$clabel" $parent $child
+
+diffuse.priority=-3
+diffuse.args=$local $base $other
+diffuse.gui=True
+diffuse.diffargs=$parent $child
diff --git a/hgext/extdiff.py b/hgext/extdiff.py
--- a/hgext/extdiff.py
+++ b/hgext/extdiff.py
@@ -35,6 +35,22 @@
   # your .vimrc
   vimdiff = gvim -f '+next' '+execute "DirDiff" argv(0) argv(1)'
 
+Tool arguments can include variables that are expanded at runtime:
+
+  $parent1, $plabel1 - filename, descriptive label of first parent
+  $child,   $clabel  - filename, descriptive label of child revision
+  $parent2, $plabel2 - filename, descriptive label of second parent
+  $parent is an alias for $parent1.
+
+The extdiff extension will look in your [diff-tools] and [merge-tools]
+sections for diff tool arguments, when none are specified in [extdiff].
+
+  [extdiff]
+  kdiff3 = 
+
+  [diff-tools]
+  kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
+
 You can use -I/-X and list of file or directory names like normal "hg
 diff" command. The extdiff extension makes snapshots of only needed
 files, so running the external diff program will actually be pretty
@@ -133,18 +149,23 @@
         # Always make a copy of node1a (and node1b, if applicable)
         dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
         dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0]
+        rev1a = '@%d' % repo[node1a].rev()
         if do3way:
             dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
             dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0]
+            rev1b = '@%d' % repo[node1b].rev()
         else:
             dir1b = None
+            rev1b = ''
 
         fns_and_mtime = []
 
         # If node2 in not the wc or there is >1 change, copy it
         dir2root = ''
+        rev2 = ''
         if node2:
             dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0]
+            rev2 = '@%d' % repo[node2].rev()
         elif len(common) > 1:
             #we only actually need to get the files to copy back to
             #the working dir in this case (because the other cases
@@ -156,23 +177,32 @@
             dir2 = ''
             dir2root = repo.root
 
+        label1a = rev1a
+        label1b = rev1b
+        label2 = rev2
+
         # If only one change, diff the files instead of the directories
         # Handle bogus modifies correctly by checking if the files exist
         if len(common) == 1:
             common_file = util.localpath(common.pop())
             dir1a = os.path.join(dir1a, common_file)
+            label1a = common_file + rev1a
             if not os.path.isfile(os.path.join(tmproot, dir1a)):
                 dir1a = os.devnull
             if do3way:
                 dir1b = os.path.join(dir1b, common_file)
+                label1b = common_file + rev1b
                 if not os.path.isfile(os.path.join(tmproot, dir1b)):
                     dir1b = os.devnull
             dir2 = os.path.join(dir2root, dir2, common_file)
+            label2 = common_file + rev2
 
         # Function to quote file/dir names in the argument string.
         # When not operating in 3-way mode, an empty string is
         # returned for parent2
-        replace = dict(parent=dir1a, parent1=dir1a, parent2=dir1b, child=dir2)
+        replace = dict(parent=dir1a, parent1=dir1a, parent2=dir1b,
+                       plabel1=label1a, plabel2=label1b,
+                       clabel=label2, child=dir2)
         def quote(match):
             key = match.group()[1:]
             if not do3way and key == 'parent2':
@@ -180,7 +210,7 @@
             return util.shellquote(replace[key])
 
         # Match parent2 first, so 'parent1?' will match both parent1 and parent
-        regex = '\$(parent2|parent1?|child)'
+        regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel)'
         if not do3way and not re.search(regex, args):
             args += ' $parent1 $child'
         args = re.sub(regex, quote, args)
@@ -252,6 +282,12 @@
                 path = diffopts.pop(0)
             else:
                 path, diffopts = cmd, []
+        # look for diff arguments in [diff-tools] then [merge-tools]
+        if diffopts == []:
+            args = ui.config('diff-tools', cmd+'.diffargs') or \
+                   ui.config('merge-tools', cmd+'.diffargs')
+            if args:
+                diffopts = shlex.split(args)
         def save(cmd, path, diffopts):
             '''use closure to save diff command to use'''
             def mydiff(ui, repo, *pats, **opts):


More information about the Mercurial-devel mailing list