--- a/mercurial/patch.py Tue May 17 23:46:37 2011 +0200
+++ b/mercurial/patch.py Tue May 17 23:46:38 2011 +0200
@@ -18,25 +18,6 @@
class PatchError(Exception):
pass
-# helper functions
-
-def copyfile(src, dst, basedir):
- abssrc, absdst = [scmutil.canonpath(basedir, basedir, x)
- for x in [src, dst]]
- if os.path.lexists(absdst):
- raise util.Abort(_("cannot create %s: destination already exists") %
- dst)
-
- dstdir = os.path.dirname(absdst)
- if dstdir and not os.path.isdir(dstdir):
- try:
- os.makedirs(dstdir)
- except IOError:
- raise util.Abort(
- _("cannot create %s: unable to create destination directory")
- % dst)
-
- util.copyfile(abssrc, absdst)
# public functions
@@ -406,10 +387,17 @@
"""
pass
+ def copy(self, src, dst):
+ """Copy src file into dst file. Create intermediate directories if
+ necessary. Files are specified relatively to the patching base
+ directory.
+ """
+ raise NotImplementedError
+
class fsbackend(abstractbackend):
- def __init__(self, ui, opener):
+ def __init__(self, ui, basedir):
super(fsbackend, self).__init__(ui)
- self.opener = opener
+ self.opener = scmutil.opener(basedir)
def readlines(self, fname):
if os.path.islink(fname):
@@ -456,6 +444,23 @@
fp.writelines(lines)
fp.close()
+ def copy(self, src, dst):
+ basedir = self.opener.base
+ abssrc, absdst = [scmutil.canonpath(basedir, basedir, x)
+ for x in [src, dst]]
+ if os.path.lexists(absdst):
+ raise util.Abort(_("cannot create %s: destination already exists")
+ % dst)
+ dstdir = os.path.dirname(absdst)
+ if dstdir and not os.path.isdir(dstdir):
+ try:
+ os.makedirs(dstdir)
+ except IOError:
+ raise util.Abort(
+ _("cannot create %s: unable to create destination directory")
+ % dst)
+ util.copyfile(abssrc, absdst)
+
# @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
@@ -1147,15 +1152,15 @@
Callers probably want to call '_updatedir' after this to
apply certain categories of changes not done by this function.
"""
- return _applydiff(ui, fp, patchfile, copyfile, changed, strip=strip,
+ return _applydiff(ui, fp, patchfile, changed, strip=strip,
eolmode=eolmode)
-def _applydiff(ui, fp, patcher, copyfn, changed, strip=1, eolmode='strict'):
+def _applydiff(ui, fp, patcher, changed, strip=1, eolmode='strict'):
rejects = 0
err = 0
current_file = None
cwd = os.getcwd()
- backend = fsbackend(ui, scmutil.opener(cwd))
+ backend = fsbackend(ui, os.getcwd())
for state, values in iterhunks(fp):
if state == 'hunk':
@@ -1188,7 +1193,7 @@
# Binary patches really overwrite target files, copying them
# will just make it fails with "target file exists"
if gp.op in ('COPY', 'RENAME') and not gp.binary:
- copyfn(gp.oldpath, gp.path, cwd)
+ backend.copy(gp.oldpath, gp.path)
changed[gp.path] = gp
else:
raise util.Abort(_('unsupported parser state: %s') % state)