# HG changeset patch # User Patrick Mezard # Date 1305755297 -7200 # Node ID 17cea10c343ec7ee0d88e2ffb6b6ee39dd3e13e9 # Parent f8932d54008851a230eb80bfb5e348ec775d709c patch: add a workingbackend dirstate layer on top of fsbackend _updatedir() is no longer used by internalpatch() The change in test-mq-missingfiles.t comes from workingbackend not considering the missing 'b' file as changed, thus not calling addremove() on it. diff -r f8932d540088 -r 17cea10c343e hgext/record.py --- a/hgext/record.py Wed May 18 23:48:13 2011 +0200 +++ b/hgext/record.py Wed May 18 23:48:17 2011 +0200 @@ -477,8 +477,7 @@ try: ui.debug('applying patch\n') ui.debug(fp.getvalue()) - patch.internalpatch(ui, repo, fp, 1, repo.root, - eolmode=None) + patch.internalpatch(ui, repo, fp, 1, eolmode=None) except patch.PatchError, err: raise util.Abort(str(err)) del fp diff -r f8932d540088 -r 17cea10c343e mercurial/patch.py --- a/mercurial/patch.py Wed May 18 23:48:13 2011 +0200 +++ b/mercurial/patch.py Wed May 18 23:48:17 2011 +0200 @@ -478,6 +478,49 @@ def setmode(self, fname, islink, isexec): util.setflags(self._join(fname), islink, isexec) +class workingbackend(fsbackend): + def __init__(self, ui, repo, similarity): + super(workingbackend, self).__init__(ui, repo.root) + self.repo = repo + self.similarity = similarity + self.removed = set() + self.changed = set() + self.copied = [] + + def writelines(self, fname, lines, mode): + super(workingbackend, self).writelines(fname, lines, mode) + self.changed.add(fname) + + def unlink(self, fname): + super(workingbackend, self).unlink(fname) + self.removed.add(fname) + self.changed.add(fname) + + def copy(self, src, dst): + super(workingbackend, self).copy(src, dst) + self.copied.append((src, dst)) + self.changed.add(dst) + + def setmode(self, fname, islink, isexec): + super(workingbackend, self).setmode(fname, islink, isexec) + self.changed.add(fname) + + def close(self): + wctx = self.repo[None] + addremoved = set(self.changed) + for src, dst in self.copied: + scmutil.dirstatecopy(self.ui, self.repo, wctx, src, dst) + addremoved.discard(src) + if (not self.similarity) and self.removed: + wctx.remove(sorted(self.removed)) + if addremoved: + cwd = self.repo.getcwd() + if cwd: + addremoved = [util.pathto(self.repo.root, cwd, f) + for f in addremoved] + scmutil.addremove(self.repo, addremoved, similarity=self.similarity) + return sorted(self.changed) + # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') @@ -1169,9 +1212,6 @@ If 'eolmode' is 'strict', the patch content and patched file are read in binary mode. Otherwise, line endings are ignored when patching then normalized according to 'eolmode'. - - Callers probably want to call '_updatedir' after this to - apply certain categories of changes not done by this function. """ return _applydiff(ui, fp, patchfile, backend, changed, strip=strip, eolmode=eolmode) @@ -1311,7 +1351,7 @@ util.explainexit(code)[0]) return fuzz -def internalpatch(ui, repo, patchobj, strip, cwd, files=None, eolmode='strict', +def internalpatch(ui, repo, patchobj, strip, files=None, eolmode='strict', similarity=0): """use builtin patch to apply to the working directory. returns whether patch was applied with fuzz factor.""" @@ -1324,7 +1364,7 @@ raise util.Abort(_('unsupported line endings type: %s') % eolmode) eolmode = eolmode.lower() - backend = fsbackend(ui, cwd) + backend = workingbackend(ui, repo, similarity) try: fp = open(patchobj, 'rb') except TypeError: @@ -1334,8 +1374,7 @@ finally: if fp != patchobj: fp.close() - touched = _updatedir(ui, repo, files, similarity) - files.update(dict.fromkeys(touched)) + files.update(dict.fromkeys(backend.close())) if ret < 0: raise PatchError(_('patch failed to apply')) return ret > 0 @@ -1364,7 +1403,7 @@ finally: touched = _updatedir(ui, repo, files, similarity) files.update(dict.fromkeys(touched)) - return internalpatch(ui, repo, patchname, strip, cwd, files, eolmode, + return internalpatch(ui, repo, patchname, strip, files, eolmode, similarity) except PatchError, err: raise util.Abort(str(err)) diff -r f8932d540088 -r 17cea10c343e tests/test-mq-missingfiles.t --- a/tests/test-mq-missingfiles.t Wed May 18 23:48:13 2011 +0200 +++ b/tests/test-mq-missingfiles.t Wed May 18 23:48:17 2011 +0200 @@ -101,7 +101,6 @@ applying changeb unable to find 'b' for patching 1 out of 1 hunks FAILED -- saving rejects to file b.rej - b: No such file or directory patch failed, unable to continue (try -v) patch failed, rejects left in working dir errors during apply, please fix and refresh changeb