Patch for updating the working dir files after diff

Fabio Zadrozny fabiofz at gmail.com
Sun Aug 26 19:58:26 CDT 2007


Hi all,

The patch below allows that any changes done while doing an external diff
are propagated back to the working directory... I haven't been able to run
the tests (too much time to make it work in windows), so, if someone applies
it, it would be nice if a unit-test could be added to check it too.

The patch was generated against http://selenic.com/repo/hg

Cheers,

Fabio

# HG changeset patch
# User Fabio Zadrozny <fabiofz at gmail dot com>
# Date 1188174678 10800
# Node ID b4ea50e512e7c170a2309fb195dd5bd310b0eae0
# Parent  bbdcdc7f170ed71911496f64e52554c030fe8a34
Propagating changes back to working dirs when changing files in external
diff tool.

diff -r bbdcdc7f170e -r b4ea50e512e7 hgext/extdiff.py
--- a/hgext/extdiff.py    Mon Aug 20 21:10:45 2007 -0500
+++ b/hgext/extdiff.py    Sun Aug 26 21:31:18 2007 -0300
@@ -84,13 +84,18 @@ def snapshot_wdir(ui, repo, files, tmpro
     '''snapshot files from working directory.
     if not using snapshot, -I/-X does not work and recursive diff
     in tools like kdiff3 and meld displays too many files.'''
-    dirname = os.path.basename(repo.root)
+    repo_root = repo.root
+
+    dirname = os.path.basename(repo_root)
     if dirname == "":
         dirname = "root"
     base = os.path.join(tmproot, dirname)
     os.mkdir(base)
     ui.note(_('making snapshot of %d files from working dir\n') %
             (len(files)))
+
+    fns_and_mtime = []
+
     for fn in files:
         wfn = util.pconvert(fn)
         ui.note('  %s\n' % wfn)
@@ -98,13 +103,27 @@ def snapshot_wdir(ui, repo, files, tmpro
         destdir = os.path.dirname(dest)
         if not os.path.isdir(destdir):
             os.makedirs(destdir)
+
         fp = open(dest, 'wb')
         for chunk in util.filechunkiter(repo.wopener(wfn)):
             fp.write(chunk)
-    return dirname
+        fp.close()
+
+        fns_and_mtime.append((dest, os.path.join(repo_root, fn),
+            os.path.getmtime(dest)))
+
+
+    return dirname, fns_and_mtime


 def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
+    '''Do the actuall diff:
+
+    - copy to a temp structure if diffing 2 internal revisions
+    - copy to a temp structure if diffing working revision with
+      another one and more than 1 file is changed
+    - just invoke the diff for a single file in the working dir
+    '''
     node1, node2 = cmdutil.revpair(repo, opts['rev'])
     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
     modified, added, removed, deleted, unknown = repo.status(
@@ -119,11 +138,17 @@ def dodiff(ui, repo, diffcmd, diffopts,
         dir1 = snapshot_node(ui, repo, modified + removed, node1, tmproot)
         changes = len(modified) + len(removed) + len(added)

+        fns_and_mtime = []
+
         # 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)
+            #we only actually need to get the files to copy back to the
working
+            #dir in this case (because the other cases are: diffing 2
revisions
+            #or single file -- in which case the file is already directly
passed
+            #to the diff tool).
+            dir2, fns_and_mtime = snapshot_wdir(ui, repo, modified + added,
tmproot)
         else:
             # This lets the diff tool open the changed file directly
             dir2 = ''
@@ -146,6 +171,13 @@ def dodiff(ui, repo, diffcmd, diffopts,
                     util.shellquote(dir1), util.shellquote(dir2)))
         ui.debug('running %r in %s\n' % (cmdline, tmproot))
         util.system(cmdline, cwd=tmproot)
+
+        for copy_fn, working_fn, mtime in fns_and_mtime:
+            if os.path.getmtime(copy_fn) != mtime:
+                ui.debug('File changed while diffing. '
+                         'Overwriting: %s (src: %s)\n' % (working_fn,
copy_fn))
+                util.copyfile(copy_fn, working_fn)
+
         return 1
     finally:
         ui.note(_('cleaning up temp directory\n'))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://selenic.com/pipermail/mercurial-devel/attachments/20070826/424d1f61/attachment.htm 


More information about the Mercurial-devel mailing list