Question

Using Windows, Mercurial, and the extdiff extension (for Mercurial). I was trying to set up extdiff to use WinDiff as an external diff tool, but I think I've narrowed the problem down enough to say that the trouble is before I'm even getting that far.

From what I understand of extdiff, it merely calls your cmd.winmerge program, and passes the necessary directories to it. I'm also working off of some assumptions outlined here (which may or may not be accurate; I'm just learning Mercurial):

http://bitbucket.org/tortoisehg/stable/issue/457/multiple-extdiff-threads-in-one-process-causes-side#comment-36216

which says:

The extdiff (visual diff) extension works like this:

1-Generate temporary directory(ies) for older changesets 
2-run util.system( cwd=tempdir, "yourdiff tool dir1 dir2" ) 
    util.system does: 
        2.1 store cwd; 
        2.2 cd tempdir 
3-run your diff tool, wait for it to exit 
4-cd oldcwd 
5-Then finally extdiff deletes the temp directories. 

The trouble that I'm having is that extdiff doesn't seem to be changing into the temp directory before proceeding, as it appears it is supposed to do in step 2.1 above.

In trying to isolate the problem, I wrote a batch file just to see what the cd was, what was being passed, and how exactly it was being passed. The batch file is as follows:

@echo off
echo %cd%
echo %1
echo %2
D:\Documents\apps\WinMergePortable\App\WinMerge\WinMergeU.exe %1 %2

I then set up extdiff to use this batch file as my extdiff program. This works, but I see that when it echoes %cd%, it's just c:\ , not c:\temp as expected. I've verified that extdiff is creating the temporary files in the proper temporary directories (as it's supposed to per step 1 above; something like c:\temp\extdiff.xxxxxx\someFolder.someChangesetID\file.ext), so I know it's SEEING those directories. It's just not properly changing into them before it's calling WinMerge, so when WinMerge is opened, it doesn't see the temp files (since it's not in the proper working directory).

That's basically where I'm stuck. I don't know where else to go from here. I thought of just putting

cd %tmp%

in my batch file, but that still doesn't grab the extdiff.xxxxx\ subdirectory which extdiff is creating the temp files in.

In summary: :-(


EDIT: Changing the batch file to

@echo off
echo %cd%\extdiff*
echo %1
echo %2
D:\Documents\apps\WinMergePortable\App\WinMerge\WinMergeU.exe %1 %2

seems to make it work (note changed second line), but it still seems a nasty hack to instead of how it's supposed to work. :-\

EDIT: Here is my Mercurial.ini file:

[ui]
username = Tim Skoch <my_real@email.address>
editor = D:\Documents\apps\Notepad++\notepad++.exe -multiInst

[extensions]
hgext.graphlog = 
hgext.extdiff = 

[extdiff]
cmd.winmerge = d:\Documents\apps\mercurial\diff_winmerge.bat
Was it helpful?

Solution

I can confirm that extdiff will change to a temporary directory before starting your diff program. You can use --debug to see this. Here I'm using true as the diff program (it just exist immediately):

$ hg extdiff -p true --debug
making snapshot of 2 files from rev 18480437f81b
  a
  b
making snapshot of 2 files from working directory
  a
  b
running "'true'  'foo.18480437f81b' 'foo'" in /tmp/extdiff.IJ9clg
cleaning up temp directory

The two arguments for the diff program are directories: a snapshot directory for the old versions and one for the new versions. They are inside the /tmp/extdiff.IJ9clg temporary directory.

One confusing point is that the arguments for the diff program are different depending on the number of modified files. With just one modified file, there is no need to create a snapshot of the working copy. So if a is the only modified file, you'll see

$ hg extdiff -p true --debug
making snapshot of 1 files from rev 18480437f81b
  a
running "'true'  '/tmp/extdiff.mUlnP_/foo.18480437f81b/a' '/home/mg/tmp/foo/a'"
in /tmp/extdiff.mUlnP_
cleaning up temp directory

Here the diff program was started with two files as arguments. As described in hg help -e extdiff, you can use some variables to build the command line. The default corresponds to $parent $child.

You say that WinMerge "cannot find the files correctly". There are other questions and answers on SO about WinMerge and they seem to have it working just fine. Maybe you can try their command line options.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top