Mercurial > hg
changeset 16511:ecd2fbe68b25 stable
convert/svn: make svn sink work with svn 1.7
"svn add file" now fails if "file" is already tracked. To filter them we have
to mirror the svn manifest in the sink.
Tested with svn 1.6.12 and 1.7.4.
author | Patrick Mezard <patrick@mezard.eu> |
---|---|
date | Tue, 24 Apr 2012 12:50:41 +0200 |
parents | c7c9473fcc46 |
children | c58bdecdb800 |
files | hgext/convert/subversion.py |
diffstat | 1 files changed, 34 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/convert/subversion.py Wed Apr 25 23:28:54 2012 +0200 +++ b/hgext/convert/subversion.py Tue Apr 24 12:50:41 2012 +0200 @@ -2,17 +2,14 @@ # # Copyright(C) 2007 Daniel Holth et al -import os -import re -import sys +import os, re, sys, tempfile, urllib, urllib2, xml.dom.minidom import cPickle as pickle -import tempfile -import urllib -import urllib2 from mercurial import strutil, scmutil, util, encoding from mercurial.i18n import _ +propertycache = util.propertycache + # Subversion stuff. Works best with very recent Python SVN bindings # e.g. SVN 1.5 or backports. Thanks to the bzr folks for enhancing # these bindings. @@ -1057,6 +1054,29 @@ def wjoin(self, *names): return os.path.join(self.wc, *names) + @propertycache + def manifest(self): + # As of svn 1.7, the "add" command fails when receiving + # already tracked entries, so we have to track and filter them + # ourselves. + m = set() + output = self.run0('ls', recursive=True, xml=True) + doc = xml.dom.minidom.parseString(output) + for e in doc.getElementsByTagName('entry'): + for n in e.childNodes: + if n.nodeType != n.ELEMENT_NODE or n.tagName != 'name': + continue + name = ''.join(c.data for c in n.childNodes + if c.nodeType == c.TEXT_NODE) + # Entries are compared with names coming from + # mercurial, so bytes with undefined encoding. Our + # best bet is to assume they are in local + # encoding. They will be passed to command line calls + # later anyway, so they better be. + m.add(encoding.tolocal(name.encode('utf-8'))) + break + return m + def putfile(self, filename, flags, data): if 'l' in flags: self.wopener.symlink(data, filename) @@ -1099,6 +1119,7 @@ try: self.run0('copy', source, dest) finally: + self.manifest.add(dest) if exists: try: os.unlink(wdest) @@ -1117,13 +1138,16 @@ def add_dirs(self, files): add_dirs = [d for d in sorted(self.dirs_of(files)) - if not os.path.exists(self.wjoin(d, '.svn', 'entries'))] + if d not in self.manifest] if add_dirs: + self.manifest.update(add_dirs) self.xargs(add_dirs, 'add', non_recursive=True, quiet=True) return add_dirs def add_files(self, files): + files = [f for f in files if f not in self.manifest] if files: + self.manifest.update(files) self.xargs(files, 'add', quiet=True) return files @@ -1133,6 +1157,7 @@ wd = self.wjoin(d) if os.listdir(wd) == '.svn': self.run0('delete', d) + self.manifest.remove(d) deleted.append(d) return deleted @@ -1170,6 +1195,8 @@ self.copies = [] if self.delete: self.xargs(self.delete, 'delete') + for f in self.delete: + self.manifest.remove(f) self.delete = [] entries.update(self.add_files(files.difference(entries))) entries.update(self.tidy_dirs(entries))