changeset 452:ae35c389cdef

tags: allow editing tags of closed branches without reopening the branch
author Augie Fackler <durin42@gmail.com>
date Fri, 26 Jun 2009 14:53:58 -0500
parents e533e78f1b2f
children bb612e625be6 54e57da61c1a
files hgsubversion/stupid.py hgsubversion/svncommands.py hgsubversion/svnmeta.py tests/fixtures/commit-to-tag.sh tests/fixtures/commit-to-tag.svndump tests/test_rebuildmeta.py tests/test_tags.py
diffstat 7 files changed, 152 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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
--- 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)
 
--- 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
--- 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
--- 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')))
--- 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)