# HG changeset patch # User Augie Fackler # Date 1246046038 18000 # Node ID ae35c389cdefa32c0e0e3bc806eb6adfb3bfbdac # Parent e533e78f1b2fefcdf168d0caf36728cacc74bcf6 tags: allow editing tags of closed branches without reopening the branch diff --git a/hgsubversion/stupid.py b/hgsubversion/stupid.py --- a/hgsubversion/stupid.py +++ b/hgsubversion/stupid.py @@ -624,14 +624,15 @@ def convert_rev(ui, meta, svn, r, tbdelt ha = meta.repo.commitctx(current_ctx) branch = extra.get('branch', None) - if (not branch in meta.branches - and not meta.is_path_tag(meta.remotename(branch))): - meta.branches[branch] = None, 0, r.revnum if not tag: + if (not branch in meta.branches + and not meta.is_path_tag(meta.remotename(branch))): + print tag, 'madebranch', branch + meta.branches[branch] = None, 0, r.revnum meta.revmap[r.revnum, b] = ha - util.describe_commit(ui, ha, b) - if tag: + else: meta.movetag(tag, ha, parentctx.extra().get('branch', None), r, date) + util.describe_commit(ui, ha, b) # These are branches with an 'R' status in svn log. This means they were # replaced by some other branch, so we need to verify they get marked as closed. diff --git a/hgsubversion/svncommands.py b/hgsubversion/svncommands.py --- a/hgsubversion/svncommands.py +++ b/hgsubversion/svncommands.py @@ -87,6 +87,9 @@ def rebuildmeta(ui, repo, hg_repo_path, branchinfo = {} noderevnums = {} tags = maps.TagMap(repo) + + skipped = set() + for rev in repo: ctx = repo[rev] @@ -122,7 +125,9 @@ def rebuildmeta(ui, repo, hg_repo_path, uuidfile.close() # don't reflect closed branches - if ctx.extra().get('close') and not ctx.files(): + if (ctx.extra().get('close') and not ctx.files() or + ctx.parents()[0].node() in skipped): + skipped.add(ctx.node()) continue # find commitpath, write to revmap diff --git a/hgsubversion/svnmeta.py b/hgsubversion/svnmeta.py --- a/hgsubversion/svnmeta.py +++ b/hgsubversion/svnmeta.py @@ -432,6 +432,17 @@ class SVNMeta(object): isexec=False, copied=False) pextra = parentctx.extra() + revnum, branch = self.parse_converted_revision(pextra['convert_revision']) + newparent = None + for child in parentctx.children(): + cextra = child.extra() + if (self.parse_converted_revision(cextra['convert_revision'])[1] == branch + and cextra.get('close', False)): + newparent = child + if newparent: + parentctx = newparent + pextra = parentctx.extra() + revnum, branch = self.parse_converted_revision(pextra['convert_revision']) ctx = context.memctx(self.repo, (parentctx.node(), node.nullid), rev.message or '...', @@ -441,9 +452,9 @@ class SVNMeta(object): date, pextra) new_hash = self.repo.commitctx(ctx) - revnum, branch = self.parse_converted_revision(pextra['convert_revision']) - assert self.revmap[revnum, branch] == parentctx.node() - self.revmap[revnum, branch] = new_hash + if not newparent: + assert self.revmap[revnum, branch] == parentctx.node() + self.revmap[revnum, branch] = new_hash self.tags[tag] = hash util.describe_commit(self.ui, new_hash, branch) diff --git a/tests/fixtures/commit-to-tag.sh b/tests/fixtures/commit-to-tag.sh --- a/tests/fixtures/commit-to-tag.sh +++ b/tests/fixtures/commit-to-tag.sh @@ -52,6 +52,13 @@ svn ci -m 'Edit an edited tag.' svn cp $REPOPATH/tags/also-edit $REPOPATH/tags/did-edits -m 'Tag an edited tag' +svn cp $REPOPATH/branches/magic $REPOPATH/branches/closeme -m 'Make extra branch for another bogus case' +svn cp $REPOPATH/branches/closeme $REPOPATH/tags/edit-later -m 'Make tag to edit after branch closes' +svn rm $REPOPATH/branches/closeme -m 'Close the branch' +svn up +echo boofar > tags/edit-later/delta +svn ci -m 'Edit this tag after its parent closed' + cd ../.. svnadmin dump temp/repo > commit-to-tag.svndump echo diff --git a/tests/fixtures/commit-to-tag.svndump b/tests/fixtures/commit-to-tag.svndump --- a/tests/fixtures/commit-to-tag.svndump +++ b/tests/fixtures/commit-to-tag.svndump @@ -437,3 +437,103 @@ Node-kind: dir Node-action: add Node-copyfrom-rev: 13 Node-copyfrom-path: tags/also-edit + + +Revision-number: 15 +Prop-content-length: 143 +Content-length: 143 + +K 7 +svn:log +V 40 +Make extra branch for another bogus case +K 10 +svn:author +V 5 +durin +K 8 +svn:date +V 27 +2009-06-26T19:26:28.086924Z +PROPS-END + +Node-path: branches/closeme +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 14 +Node-copyfrom-path: branches/magic + + +Revision-number: 16 +Prop-content-length: 139 +Content-length: 139 + +K 7 +svn:log +V 36 +Make tag to edit after branch closes +K 10 +svn:author +V 5 +durin +K 8 +svn:date +V 27 +2009-06-26T19:26:28.119751Z +PROPS-END + +Node-path: tags/edit-later +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 15 +Node-copyfrom-path: branches/closeme + + +Revision-number: 17 +Prop-content-length: 119 +Content-length: 119 + +K 7 +svn:log +V 16 +Close the branch +K 10 +svn:author +V 5 +durin +K 8 +svn:date +V 27 +2009-06-26T19:26:28.149674Z +PROPS-END + +Node-path: branches/closeme +Node-action: delete + + +Revision-number: 18 +Prop-content-length: 140 +Content-length: 140 + +K 7 +svn:log +V 37 +Edit this tag after its parent closed +K 10 +svn:author +V 5 +durin +K 8 +svn:date +V 27 +2009-06-26T19:26:29.059216Z +PROPS-END + +Node-path: tags/edit-later/delta +Node-kind: file +Node-action: change +Text-content-length: 7 +Text-content-md5: 5bbd00dab68c937673171d0b2e205c96 +Content-length: 7 + +boofar diff --git a/tests/test_rebuildmeta.py b/tests/test_rebuildmeta.py --- a/tests/test_rebuildmeta.py +++ b/tests/test_rebuildmeta.py @@ -33,6 +33,8 @@ def _do_case(self, name, stupid): dtf = os.path.join(dest.path, 'svn', tf) self.assertTrue(os.path.isfile(dtf), '%r is missing!' % tf) old, new = open(stf).read(), open(dtf).read() + # uncomment next line for easy-ish debugging. + #os.system('diff -u %s %s' % (stf, dtf)) self.assertEqual(old, new) self.assertEqual(src.branchtags(), dest.branchtags()) srcbi = pickle.load(open(os.path.join(src.path, 'svn', 'branch_info'))) diff --git a/tests/test_tags.py b/tests/test_tags.py --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -92,15 +92,21 @@ class TestTags(test_util.TestBase): def test_edited_tag(self, stupid=False): repo = self._load_fixture_and_fetch('commit-to-tag.svndump', stupid=stupid) - self.assertEqual(len(repo.heads()), 3) + self.assertEqual(len(repo.heads()), 4) heads = repo.heads() openheads = [h for h in heads if not repo[h].extra().get('close', False)] closedheads = set(heads) - set(openheads) - self.assertEqual(len(openheads), 1) - self.assertEqual(len(closedheads), 2) + self.assertEqual(len(openheads), 0) + self.assertEqual(len(closedheads), 4) closedheads = sorted(list(closedheads), cmp=lambda x,y: cmp(repo[x].rev(), repo[y].rev())) - willedit, alsoedit = closedheads + # closeme has no open heads + for h in openheads: + self.assertNotEqual('closeme', repo[openheads[0]].branch()) + + self.assertEqual(1, len(self.repo.branchheads('magic'))) + + willedit, alsoedit, editlater, closeme = closedheads self.assertEqual( repo[willedit].extra(), {'close': '1', @@ -127,6 +133,13 @@ class TestTags(test_util.TestBase): 'lambda', ]) + self.assertEqual(editlater, repo['edit-later'].node()) + self.assertEqual( + repo[closeme].extra(), + {'close': '1', + 'branch': 'closeme', + 'convert_revision': 'svn:af82cc90-c2d2-43cd-b1aa-c8a78449440a/branches/closeme@17'}) + def test_tags_in_unusual_location(self): repo = self._load_fixture_and_fetch('tag_name_same_as_branch.svndump') self.assertEqual(len(repo.heads()), 1)