Mercurial > hg
changeset 14370:17cea10c343e
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.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Wed, 18 May 2011 23:48:17 +0200 |
parents | f8932d540088 |
children | ec2aae8b375d f90d5641c78b |
files | hgext/record.py mercurial/patch.py tests/test-mq-missingfiles.t |
diffstat | 3 files changed, 48 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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 <patchobj> 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))
--- 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