# HG changeset patch # User Patrick Mezard # Date 1350222672 -7200 # Node ID 502613f6b5836bd2a5d21e3d28f117567b70ce60 # Parent 8b2480175bae45e0f5421692932ebb05da77bc12 editor: ignore added or copied files excluded by a filemap Files brought by a copied add_directory() were processed despite being excluded by the filemap. This was also the case with added files. The conversion was still correct because they were eventually filtered out in the replay.convert_rev() but processing them in itself may be problematic. Filemaps are often use to exclude large binary files and before this change, some of them could be marked as missing and be fetched before being discarded. A test configuration entry named hgsubversion.failoninvalidreplayfile was added to help testing this case. It should become the default behaviour in the future. diff --git a/hgsubversion/editor.py b/hgsubversion/editor.py --- a/hgsubversion/editor.py +++ b/hgsubversion/editor.py @@ -312,10 +312,9 @@ class HgEditor(svnwrap.Editor): @svnwrap.ieditor def open_file(self, path, parent_baton, base_revision, p=None): self._checkparentdir(parent_baton) - fpath, branch = self.meta.split_branch_path(path)[:2] - if not fpath: - self.ui.debug('WARNING: Opening non-existant file %s\n' % path) + if not self.meta.is_path_valid(path): return None + fpath, branch = self.meta.split_branch_path(path)[:2] self.ui.note('M %s\n' % path) @@ -324,9 +323,6 @@ class HgEditor(svnwrap.Editor): base, isexec, islink, copypath = copy.resolve(self._getctx) return self._openfile(path, base, isexec, islink, copypath) - if not self.meta.is_path_valid(path): - return None - baserev = base_revision if baserev is None or baserev == -1: baserev = self.current.rev.revnum - 1 @@ -350,16 +346,20 @@ class HgEditor(svnwrap.Editor): def add_file(self, path, parent_baton=None, copyfrom_path=None, copyfrom_revision=None, file_pool=None): self._checkparentdir(parent_baton) + # Use existing=False because we use the fact a file is being + # added here to populate the branchmap which is used with + # existing=True. + fpath, branch = self.meta.split_branch_path(path, existing=False)[:2] + if not fpath or fpath not in self.meta.filemap: + return None if path in self._svncopies: raise EditingError('trying to replace copied file %s' % path) if path in self._deleted: self._deleted.remove(path) - fpath, branch = self.meta.split_branch_path(path, existing=False)[:2] - if not fpath: - return None if (branch not in self.meta.branches and not self.meta.get_path_tag(self.meta.remotename(branch))): - # we know this branch will exist now, because it has at least one file. Rock. + # we know this branch will exist now, because it has at + # least one file. Rock. self.meta.branches[branch] = None, 0, self.current.rev.revnum if not copyfrom_path: self.ui.note('A %s\n' % path) @@ -478,6 +478,8 @@ class HgEditor(svnwrap.Editor): if not f.startswith(frompath): continue dest = path + '/' + f[len(frompath):] + if not self.meta.is_path_valid(dest): + continue if dest in self._deleted: self._deleted.remove(dest) if copyfromparent: diff --git a/hgsubversion/replay.py b/hgsubversion/replay.py --- a/hgsubversion/replay.py +++ b/hgsubversion/replay.py @@ -99,8 +99,12 @@ def _convert_rev(ui, meta, svn, r, tbdel date = meta.fixdate(rev.date) # build up the branches that have files on them + failoninvalid = ui.configbool('hgsubversion', + 'failoninvalidreplayfile', False) for f in files_to_commit: if not meta.is_path_valid(f): + if failoninvalid: + raise hgutil.Abort('file %s should not be in commit list' % f) continue p, b = meta.split_branch_path(f)[:2] if b not in branch_batches: diff --git a/tests/fixtures/copies.sh b/tests/fixtures/copies.sh new file mode 100755 --- /dev/null +++ b/tests/fixtures/copies.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# +# Generate copies.svndump +# + +rm -rf temp +mkdir temp +cd temp +mkdir -p import/trunk/dir +echo a > import/trunk/dir/a + +svnadmin create testrepo +svnurl=file://`pwd`/testrepo +svn import import $svnurl -m init + +svn co $svnurl project +cd project +svn cp trunk/dir trunk/dir2 +echo b >> trunk/dir2/a +svn ci -m 'copy/edit trunk/dir/a' +cd .. + +svnadmin dump testrepo > ../copies.svndump diff --git a/tests/fixtures/copies.svndump b/tests/fixtures/copies.svndump new file mode 100644 --- /dev/null +++ b/tests/fixtures/copies.svndump @@ -0,0 +1,100 @@ +SVN-fs-dump-format-version: 2 + +UUID: 707bea87-43e4-45d9-8f28-5d06ca9e3f3b + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2012-10-14T12:41:39.387675Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 105 +Content-length: 105 + +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2012-10-14T12:41:39.409053Z +K 7 +svn:log +V 4 +init +PROPS-END + +Node-path: trunk +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk/dir +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk/dir/a +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3 +Text-content-sha1: 3f786850e387550fdab836ed7e6dc881de23001b +Content-length: 12 + +PROPS-END +a + + +Revision-number: 2 +Prop-content-length: 123 +Content-length: 123 + +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2012-10-14T12:41:41.048526Z +K 7 +svn:log +V 21 +copy/edit trunk/dir/a +PROPS-END + +Node-path: trunk/dir2 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: trunk/dir + + +Node-path: trunk/dir2/a +Node-kind: file +Node-action: change +Text-content-length: 4 +Text-content-md5: dd8c6a395b5dd36c56d23275028f526c +Text-content-sha1: 05dec960e24d918b8a73a1c53bcbbaac2ee5c2e0 +Content-length: 4 + +a +b + + diff --git a/tests/test_fetch_mappings.py b/tests/test_fetch_mappings.py --- a/tests/test_fetch_mappings.py +++ b/tests/test_fetch_mappings.py @@ -108,6 +108,8 @@ class MapTests(test_util.TestBase): filemap.close() ui = self.ui(stupid) ui.setconfig('hgsubversion', 'filemap', self.filemap) + ui.setconfig('hgsubversion', 'failoninvalidreplayfile', 'true') + ui.setconfig('hgsubversion', 'failonmissing', 'true') commands.clone(ui, test_util.fileurl(repo_path), self.wc_path, filemap=self.filemap) return self.repo @@ -143,6 +145,10 @@ class MapTests(test_util.TestBase): self.assertEqual(self.repo['default'].manifest().keys(), ['alpha', 'beta']) + def test_file_map_copy(self): + repo = self._loadwithfilemap('copies.svndump', "exclude dir2\n") + self.assertEqual(['dir/a'], list(repo['tip'])) + def test_branchmap(self, stupid=False): repo_path = self.load_svndump('branchmap.svndump') branchmap = open(self.branchmap, 'w')