[PATCH 5 of 9 RFC] normfn: normalize paths in patches in global style

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Fri May 25 10:00:54 CDT 2012


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1337957587 -32400
# Node ID 23e14c6bf89de2af9fd09c6683137b00ff353c8d
# Parent  c5352f1484a660a1c17cc7267173fad33e4a29bd
normfn: normalize paths in patches in global style

mercurial implementation embeds paths in on-memory-objects
(e.g. manifest, context, and so on) into pathes as it is.

they are normalized in "local style", so should be normalized in
"global style" to create portable patches: this also affects output of
"hg export".

diff -r c5352f1484a6 -r 23e14c6bf89d mercurial/patch.py
--- a/mercurial/patch.py	Fri May 25 23:53:07 2012 +0900
+++ b/mercurial/patch.py	Fri May 25 23:53:07 2012 +0900
@@ -465,19 +465,23 @@
         self.removed = set()
         self.changed = set()
         self.copied = []
+        self.fntolocal = getattr(repo, 'fntolocal', lambda x: x)
 
     def _checkknown(self, fname):
         if self.repo.dirstate[fname] == '?' and self.exists(fname):
             raise PatchError(_('cannot patch %s: file is not tracked') % fname)
 
     def setfile(self, fname, data, mode, copysource):
+        fname = self.fntolocal(fname)
         self._checkknown(fname)
         super(workingbackend, self).setfile(fname, data, mode, copysource)
         if copysource is not None:
+            copysource = self.fntolocal(copysource)
             self.copied.append((copysource, fname))
         self.changed.add(fname)
 
     def unlink(self, fname):
+        fname = self.fntolocal(fname)
         self._checkknown(fname)
         super(workingbackend, self).unlink(fname)
         self.removed.add(fname)
@@ -551,12 +555,14 @@
         self.changed = set()
         self.removed = set()
         self.copied = {}
+        self.fntolocal = getattr(repo, 'fntolocal', lambda x: x)
 
     def _checkknown(self, fname):
         if fname not in self.ctx:
             raise PatchError(_('cannot patch %s: file is not tracked') % fname)
 
     def getfile(self, fname):
+        fname = self.fntolocal(fname)
         try:
             fctx = self.ctx[fname]
         except error.LookupError:
@@ -564,21 +570,26 @@
         flags = fctx.flags()
         return fctx.data(), ('l' in flags, 'x' in flags)
 
-    def setfile(self, fname, data, mode, copysource):
-        if copysource:
+    def setfile(self, xfname, data, mode, xcopysource):
+        fname = self.fntolocal(xfname)
+        if xcopysource:
+            copysource = self.fntolocal(xcopysource)
             self._checkknown(copysource)
         if data is None:
             data = self.ctx[fname].data()
-        self.store.setfile(fname, data, mode, copysource)
+        # use filenames in external representation for store accessing
+        self.store.setfile(xfname, data, mode, xcopysource)
         self.changed.add(fname)
         if copysource:
             self.copied[fname] = copysource
 
     def unlink(self, fname):
+        fname = self.fntolocal(fname)
         self._checkknown(fname)
         self.removed.add(fname)
 
     def exists(self, fname):
+        fname = self.fntolocal(fname)
         return fname in self.ctx
 
     def close(self):
@@ -1444,10 +1455,12 @@
 
 def makememctx(repo, parents, text, user, date, branch, files, store,
                editor=None):
+    fntolocal = getattr(repo, 'fntolocal', lambda x: x)
+    fnfromlocal = getattr(repo, 'fnfromlocal', lambda x: x)
     def getfilectx(repo, memctx, path):
-        data, (islink, isexec), copied = store.getfile(path)
+        data, (islink, isexec), copied = store.getfile(fnfromlocal(path))
         return context.memfilectx(path, data, islink=islink, isexec=isexec,
-                                  copied=copied)
+                                  copied=fntolocal(copied))
     extra = {}
     if branch:
         extra['branch'] = encoding.fromlocal(branch)
@@ -1501,7 +1514,8 @@
                     changed.add(gp.oldpath)
             elif state not in ('hunk', 'git'):
                 raise util.Abort(_('unsupported parser state: %s') % state)
-        return changed
+        fntolocal = getattr(repo, 'fntolocal', lambda x: x)
+        return [fntolocal(f) for f in changed]
     finally:
         fp.close()
 
@@ -1704,6 +1718,8 @@
     if opts.git:
         revs = None
 
+    fnfromlocal = getattr(repo, 'fnfromlocal', lambda x: x)
+
     for f in sorted(modified + added + removed):
         to = None
         tn = None
@@ -1776,7 +1792,10 @@
                 elif binary or nflag != oflag:
                     losedatafn(f)
             if opts.git:
-                header.insert(0, mdiff.diffline(revs, join(a), join(b), opts))
+                header.insert(0, mdiff.diffline(revs,
+                                                join(fnfromlocal(a)),
+                                                join(fnfromlocal(b)),
+                                                opts))
 
         if dodiff:
             if dodiff == 'binary':
@@ -1785,7 +1804,9 @@
                 text = mdiff.unidiff(to, date1,
                                     # ctx2 date may be dynamic
                                     tn, util.datestr(ctx2.date()),
-                                    join(a), join(b), revs, opts=opts)
+                                     join(fnfromlocal(a)),
+                                     join(fnfromlocal(b)),
+                                     revs, opts=opts)
             if header and (text or len(header) > 1):
                 yield ''.join(header)
             if text:


More information about the Mercurial-devel mailing list