changeset 757:6e18d9ab6557

pull: stop handling .hgsvnexternals explicitely in memctx
author Patrick Mezard <pmezard@gmail.com>
date Fri, 19 Nov 2010 17:07:13 +0100
parents 379c7837222f
children 76ebfc41f490
files hgsubversion/replay.py hgsubversion/stupid.py hgsubversion/svnexternals.py
diffstat 3 files changed, 42 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/hgsubversion/replay.py
+++ b/hgsubversion/replay.py
@@ -40,21 +40,23 @@ def updateexternals(ui, meta, current):
             pctx = meta.repo[parent]
             if '.hgsvnexternals' in pctx:
                 external.read(pctx['.hgsvnexternals'].data())
-            branches[bp] = external
+            branches[bp] = (external, pctx)
         else:
-            external = branches[bp]
+            external = branches[bp][0]
 
         external[p] = entry
 
     # register externals file changes
-    for bp, external in branches.iteritems():
+    for bp, (external, pctx) in branches.iteritems():
         if bp and bp[-1] != '/':
             bp += '/'
-        path = (bp and bp + '.hgsvnexternals') or '.hgsvnexternals'
-        if external:
-            current.set(path, external.write(), False, False)
-        else:
-            current.delete(path)
+        updates = svnexternals.getchanges(ui, meta.repo, pctx, external)
+        for fn, data in updates.iteritems():
+            path = (bp and bp + fn) or fn
+            if data is not None:
+                current.set(path, data, False, False)
+            else:
+                current.delete(path)
 
 def convert_rev(ui, meta, svn, r, tbdelta):
 
@@ -144,12 +146,6 @@ def convert_rev(ui, meta, svn, r, tbdelt
             extra.update({'branch': parentctx.extra().get('branch', None),
                           'close': 1})
 
-        if '.hgsvnexternals' not in parentctx and '.hgsvnexternals' in files:
-            # Do not register empty externals files
-            if (files['.hgsvnexternals'] in current.files
-                and not current.files[files['.hgsvnexternals']]):
-                del files['.hgsvnexternals']
-
         def filectxfn(repo, memctx, path):
             current_file = files[path]
             if current_file in current.deleted:
--- a/hgsubversion/stupid.py
+++ b/hgsubversion/stupid.py
@@ -389,10 +389,6 @@ def fetch_externals(svn, branchpath, r, 
             externals[dir] = values.get('svn:externals', '')
         except IOError:
             externals[dir] = ''
-
-    if not externals and '.hgsvnexternals' not in parentctx:
-        # Do not create empty externals files
-        return None
     return externals
 
 
@@ -604,17 +600,20 @@ def convert_rev(ui, meta, svn, r, tbdelt
             files_touched, filectxfn2 = fetch_branchrev(
                 svn, meta, b, branches[b], r, parentctx)
 
+        externals = {}
         if meta.layout != 'single':
             externals = fetch_externals(svn, branches[b], r, parentctx)
-            if externals is not None:
-                files_touched.append('.hgsvnexternals')
+            externals = svnexternals.getchanges(ui, meta.repo, parentctx,
+                                                externals)
+            files_touched.extend(externals)
 
         def filectxfn(repo, memctx, path):
-            if path == '.hgsvnexternals':
-                if not externals:
+            if path in externals:
+                if externals[path] is None:
                     raise IOError(errno.ENOENT, 'no externals')
-                return context.memfilectx(path=path, data=externals.write(),
-                                          islink=False, isexec=False, copied=None)
+                return context.memfilectx(path=path, data=externals[path],
+                                          islink=False, isexec=False,
+                                          copied=None)
             for bad in bad_branch_paths[b]:
                 if path.startswith(bad):
                     raise IOError(errno.ENOENT, 'Path %s is bad' % path)
--- a/hgsubversion/svnexternals.py
+++ b/hgsubversion/svnexternals.py
@@ -287,3 +287,26 @@ def updateexternals(ui, args, repo, **op
             raise hgutil.Abort(_('unknown update actions: %r') % action)
 
     file(repo.join('svn/externals'), 'wb').write(newext)
+
+def getchanges(ui, repo, parentctx, exts):
+    """Take a parent changectx and the new externals definitions as an
+    externalsfile and return a dictionary mapping the special file
+    hgsubversion needs for externals bookkeeping, to their new content
+    as raw bytes or None if the file has to be removed.
+    """
+    files = {
+        '.hgsvnexternals': None,
+        }
+    if exts:
+        files['.hgsvnexternals'] = exts.write()
+
+    # Should the really be updated?
+    updates = {}
+    for fn, data in files.iteritems():
+        if data is not None:
+            if fn not in parentctx or parentctx[fn].data() != data:
+                updates[fn] = data
+        else:
+            if fn in parentctx:
+                updates[fn] = None
+    return updates