# HG changeset patch # User Patrick Mezard # Date 2008-06-18 22:14:24 # Node ID c9b8d2565b922474c09b6af63d95210339f51bb1 # Parent a3c41abfa82842ad0859729f2826ae4ce18f306d convert: reintegrate file retrieval code in sinks It simplifies the sink interface and all the sinks to handle files data as they want. diff --git a/hgext/convert/common.py b/hgext/convert/common.py --- a/hgext/convert/common.py +++ b/hgext/convert/common.py @@ -153,26 +153,18 @@ class converter_sink(object): mapping equivalent authors identifiers for each system.""" return None - def putfile(self, f, e, data): - """Put file for next putcommit(). - f: path to file - e: '', 'x', or 'l' (regular file, executable, or symlink) - data: file contents""" - raise NotImplementedError() - - def delfile(self, f): - """Delete file for next putcommit(). - f: path to file""" - raise NotImplementedError() - - def putcommit(self, files, parents, commit): + def putcommit(self, files, copies, parents, commit, source): """Create a revision with all changed files listed in 'files' and having listed parents. 'commit' is a commit object containing at a minimum the author, date, and message for this changeset. - Called after putfile() and delfile() calls. Note that the sink - repository is not told to update itself to a particular revision - (or even what that revision would be) before it receives the - file data.""" + 'files' is a list of (path, version) tuples, 'copies'is a dictionary + mapping destinations to sources, and 'source' is the source repository. + Only getfile() and getmode() should be called on 'source'. + + Note that the sink repository is not told to update itself to + a particular revision (or even what that revision would be) + before it receives the file data. + """ raise NotImplementedError() def puttags(self, tags): @@ -181,7 +173,7 @@ class converter_sink(object): raise NotImplementedError() def setbranch(self, branch, pbranches): - """Set the current branch name. Called before the first putfile + """Set the current branch name. Called before the first putcommit on the branch. branch: branch name for subsequent commits pbranches: (converted parent revision, parent branch) tuples""" diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py --- a/hgext/convert/convcmd.py +++ b/hgext/convert/convcmd.py @@ -221,8 +221,6 @@ class converter(object): def copy(self, rev): commit = self.commitcache[rev] - do_copies = hasattr(self.dest, 'copyfile') - filenames = [] changes = self.source.getchanges(rev) if isinstance(changes, basestring): @@ -241,21 +239,6 @@ class converter(object): pbranches.append((self.map[prev], self.commitcache[prev].branch)) self.dest.setbranch(commit.branch, pbranches) - for f, v in files: - filenames.append(f) - try: - data = self.source.getfile(f, v) - except IOError, inst: - self.dest.delfile(f) - else: - e = self.source.getmode(f, v) - self.dest.putfile(f, e, data) - if do_copies: - if f in copies: - copyf = copies[f] - # Merely marks that a copy happened. - self.dest.copyfile(copyf, f) - try: parents = self.splicemap[rev].replace(',', ' ').split() self.ui.status('spliced in %s as parents of %s\n' % @@ -263,7 +246,7 @@ class converter(object): parents = [self.map.get(p, p) for p in parents] except KeyError: parents = [b[0] for b in pbranches] - newnode = self.dest.putcommit(filenames, parents, commit) + newnode = self.dest.putcommit(files, copies, parents, commit, self.source) self.source.converted(rev, newnode) self.map[rev] = newnode diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py --- a/hgext/convert/hg.py +++ b/hgext/convert/hg.py @@ -72,21 +72,6 @@ class mercurial_sink(converter_sink): h = self.repo.changelog.heads() return [ hex(x) for x in h ] - def putfile(self, f, e, data): - self.repo.wwrite(f, data, e) - if f not in self.repo.dirstate: - self.repo.dirstate.normallookup(f) - - def copyfile(self, source, dest): - self.repo.copy(source, dest) - - def delfile(self, f): - try: - util.unlink(self.repo.wjoin(f)) - #self.repo.remove([f]) - except OSError: - pass - def setbranch(self, branch, pbranches): if not self.clonebranches: return @@ -125,7 +110,25 @@ class mercurial_sink(converter_sink): self.repo.pull(prepo, [prepo.lookup(h) for h in heads]) self.before() - def putcommit(self, files, parents, commit): + def putcommit(self, files, copies, parents, commit, source): + # Apply changes to working copy + for f, v in files: + try: + data = source.getfile(f, v) + except IOError, inst: + try: + util.unlink(self.repo.wjoin(f)) + except OSError: + pass + else: + e = source.getmode(f, v) + self.repo.wwrite(f, data, e) + if f not in self.repo.dirstate: + self.repo.dirstate.normallookup(f) + if f in copies: + self.repo.copy(copies[f], f) + files = [f[0] for f in files] + seen = {} pl = [] for p in parents: diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py --- a/hgext/convert/subversion.py +++ b/hgext/convert/subversion.py @@ -1013,12 +1013,6 @@ class svn_sink(converter_sink, commandli if 'x' in flags: self.setexec.append(filename) - def delfile(self, name): - self.delete.append(name) - - def copyfile(self, source, dest): - self.copies.append([source, dest]) - def _copyfile(self, source, dest): # SVN's copy command pukes if the destination file exists, but # our copyfile method expects to record a copy that has @@ -1081,7 +1075,20 @@ class svn_sink(converter_sink, commandli def revid(self, rev): return u"svn:%s@%s" % (self.uuid, rev) - def putcommit(self, files, parents, commit): + def putcommit(self, files, copies, parents, commit, source): + # Apply changes to working copy + for f, v in files: + try: + data = source.getfile(f, v) + except IOError, inst: + self.delete.append(f) + else: + e = source.getmode(f, v) + self.putfile(f, e, data) + if f in copies: + self.copies.append([copies[f], f]) + files = [f[0] for f in files] + for parent in parents: try: return self.revid(self.childmap[parent])