extdiff: do single file diffs from the wc with no copy
authorBrad Schick <schickb@gmail.com>
Mon, 06 Aug 2007 14:50:57 -0700
changeset 5137 2be225ea5722
parent 5136 841568ccc09d
child 5138 9cda2315c7a9
extdiff: do single file diffs from the wc with no copy Extdiff was always making a temporary directory and copying files even when not required. This change makes extdiff avoid the copy when diffing a single file that lives in the wc. This lets external diff tools edit the working copy file directly. It also lets other extensions resuse the functions in extdiff and get in-place diffs.
hgext/extdiff.py
tests/test-extdiff
tests/test-extdiff.out
--- a/hgext/extdiff.py	Mon Aug 06 14:42:11 2007 -0700
+++ b/hgext/extdiff.py	Mon Aug 06 14:50:57 2007 -0700
@@ -113,12 +113,34 @@
         return 0
 
     tmproot = tempfile.mkdtemp(prefix='extdiff.')
+    dir2root = ''
     try:
+        # Always make a copy of node1
         dir1 = snapshot_node(ui, repo, modified + removed, node1, tmproot)
+        changes = len(modified) + len(removed) + len(added)
+
+        # If node2 in not the wc or there is >1 change, copy it
         if node2:
             dir2 = snapshot_node(ui, repo, modified + added, node2, tmproot)
+        elif changes > 1:
+            dir2 = snapshot_wdir(ui, repo, modified + added, tmproot)
         else:
-            dir2 = snapshot_wdir(ui, repo, modified + added, tmproot)
+            # This lets the diff tool open the changed file directly
+            dir2 = ''
+            dir2root = repo.root
+
+        # If only one change, diff the files instead of the directories
+        if changes == 1 :
+            if len(modified):
+                dir1 = os.path.join(dir1, util.localpath(modified[0]))
+                dir2 = os.path.join(dir2root, dir2, util.localpath(modified[0]))  
+            elif len(removed) :
+                dir1 = os.path.join(dir1, util.localpath(removed[0]))
+                dir2 = os.devnull
+            else:
+                dir1 = os.devnull
+                dir2 = os.path.join(dir2root, dir2, util.localpath(added[0]))  
+    
         cmdline = ('%s %s %s %s' %
                    (util.shellquote(diffcmd), ' '.join(diffopts),
                     util.shellquote(dir1), util.shellquote(dir2)))
--- a/tests/test-extdiff	Mon Aug 06 14:42:11 2007 -0700
+++ b/tests/test-extdiff	Mon Aug 06 14:50:57 2007 -0700
@@ -6,7 +6,9 @@
 hg init a
 cd a
 echo a > a
+echo b > b
 hg add
+# should diff cloned directories
 hg extdiff -o -r $opt
 
 echo "[extdiff]" >> $HGRCPATH
@@ -22,13 +24,17 @@
 echo b >> a
 hg ci -d '1 0' -mtest2
 
+# should diff cloned files directly 
 hg falabala -r 0:1
 
 # test diff during merge
 hg update 0
-echo b >> b
-hg add b
+echo c >> c
+hg add c
 hg ci -m "new branch" -d '1 0'
 hg update -C 1
 hg merge tip
-hg falabala || echo "diff-like tools yield a non-zero exit code"
+# should diff cloned file against wc file 
+hg falabala > out || echo "diff-like tools yield a non-zero exit code"
+# cleanup the output since the wc is a tmp directory
+sed  's:\(.* \).*\(\/test-extdiff\):\1[tmp]\2:' out
--- a/tests/test-extdiff.out	Mon Aug 06 14:42:11 2007 -0700
+++ b/tests/test-extdiff.out	Mon Aug 06 14:50:57 2007 -0700
@@ -1,5 +1,7 @@
 adding a
+adding b
 Only in a: a
+Only in a: b
 diffing a.000000000000 a
 hg falabala [OPTION]... [FILE]...
 
@@ -22,10 +24,10 @@
  -X --exclude  exclude names matching the given patterns
 
 use "hg -v help falabala" to show global options
-diffing a.e27a2475d60a a.5e49ec8d3f05
+diffing a.8a5febb7f867/a a.34eed99112ab/a
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
-diffing a.5e49ec8d3f05 a
 diff-like tools yield a non-zero exit code
+diffing a.34eed99112ab/c [tmp]/test-extdiff/a/c