# HG changeset patch # User Brad Schick # Date 1186437057 25200 # Node ID 2be225ea57229d8754873207a5f7d71b92c07c4b # Parent 841568ccc09df173e01e61553550d930898106e5 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. diff --git a/hgext/extdiff.py b/hgext/extdiff.py --- a/hgext/extdiff.py +++ b/hgext/extdiff.py @@ -113,12 +113,34 @@ def dodiff(ui, repo, diffcmd, diffopts, 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))) diff --git a/tests/test-extdiff b/tests/test-extdiff --- a/tests/test-extdiff +++ b/tests/test-extdiff @@ -6,7 +6,9 @@ echo "extdiff=" >> $HGRCPATH 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 @@ hg ci -d '0 0' -mtest1 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 diff --git a/tests/test-extdiff.out b/tests/test-extdiff.out --- a/tests/test-extdiff.out +++ b/tests/test-extdiff.out @@ -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 @@ options: -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