Mercurial > hgsubversion
changeset 582:44c56a7727c4
editor: fix issamefile() and copy detection in replay mode
Known failures:
- comprehensive/test_verify on replace_branch_with_branch: replaced files
content is incorrect
- comprehensive/test_stupid_pull on replace_branch_with_branch: very stupid
mode does not handle replacements correctly.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Tue, 02 Mar 2010 17:06:06 +0100 |
parents | 90efea2c19df |
children | a016b253910b |
files | hgsubversion/editor.py hgsubversion/util.py tests/fixtures/replace_branch_with_branch.sh tests/fixtures/replace_branch_with_branch.svndump tests/test_fetch_branches.py |
diffstat | 5 files changed, 309 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/hgsubversion/editor.py +++ b/hgsubversion/editor.py @@ -216,13 +216,13 @@ class HgEditor(delta.Editor): fctx = ctx.filectx(from_file) flags = fctx.flags() self.current.set(path, fctx.data(), 'x' in flags, 'l' in flags) - if from_branch == branch: - parentid = self.meta.get_parent_revision(self.current.rev.revnum, - branch) - if parentid != revlog.nullid: - parentctx = self.repo.changectx(parentid) - if util.issamefile(parentctx, ctx, from_file): - self.current.copies[path] = from_file + if from_branch == branch: + parentid = self.meta.get_parent_revision( + self.current.rev.revnum, branch) + if parentid != revlog.nullid: + parentctx = self.repo.changectx(parentid) + if util.issamefile(parentctx, ctx, from_file): + self.current.copies[path] = from_file @ieditor def add_directory(self, path, parent_baton, copyfrom_path,
--- a/hgsubversion/util.py +++ b/hgsubversion/util.py @@ -145,7 +145,9 @@ def swap_out_encoding(new_encoding="UTF- def issamefile(parentctx, childctx, f): - """Assuming f exists and is the same in childctx and parentctx, return True.""" + """Return True if f exists and is the same in childctx and parentctx""" + if f not in parentctx or f not in childctx: + return False if parentctx == childctx: return True if parentctx.rev() > childctx.rev():
new file mode 100755 --- /dev/null +++ b/tests/fixtures/replace_branch_with_branch.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +RSVN="`pwd`/rsvn.py" +export PATH=/bin:/usr/bin +mkdir temp +cd temp + +svnadmin create repo +svn co file://`pwd`/repo wc + +cd wc +mkdir trunk branches +cd trunk +echo a > a +cd .. +svn add * +svn ci -m 'initial' + +svn up +svn cp trunk branches/branch1 +svn ci -m 'branch1' +svn up +echo b > branches/branch1/b +echo d > branches/branch1/d +svn add branches/branch1/b branches/branch1/d +svn ci -m 'add b to branch1' +svn cp trunk branches/branch2 +svn ci -m 'branch2' +svn up +echo c > branches/branch2/c +svn add branches/branch2/c +svn ci -m 'add c to branch2' +svn up + +# Clobber branch1 with branch2 +cd .. +cat > clobber.rsvn <<EOF +rdelete branches/branch1 +rcopy branches/branch2 branches/branch1 +rcopy branches/branch1/d branches/branch1/a +EOF + +python $RSVN --message=blah --username=evil `pwd`/repo < clobber.rsvn + +svnadmin dump repo > ../replace_branch_with_branch.svndump
new file mode 100644 --- /dev/null +++ b/tests/fixtures/replace_branch_with_branch.svndump @@ -0,0 +1,234 @@ +SVN-fs-dump-format-version: 2 + +UUID: 9ccfc2a0-ffd9-470e-a000-ccb1f0fe21e5 + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2010-02-24T20:15:47.286918Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 108 +Content-length: 108 + +K 7 +svn:log +V 7 +initial +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-02-24T20:15:48.124168Z +PROPS-END + +Node-path: branches +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk/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: 108 +Content-length: 108 + +K 7 +svn:log +V 7 +branch1 +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-02-24T20:15:51.070312Z +PROPS-END + +Node-path: branches/branch1 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: trunk + + +Revision-number: 3 +Prop-content-length: 118 +Content-length: 118 + +K 7 +svn:log +V 16 +add b to branch1 +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-02-24T20:15:53.123732Z +PROPS-END + +Node-path: branches/branch1/b +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: 3b5d5c3712955042212316173ccf37be +Text-content-sha1: 89e6c98d92887913cadf06b2adb97f26cde4849b +Content-length: 12 + +PROPS-END +b + + +Node-path: branches/branch1/d +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: e29311f6f1bf1af907f9ef9f44b8328b +Text-content-sha1: e983f374794de9c64e3d1c1de1d490c0756eeeff +Content-length: 12 + +PROPS-END +d + + +Revision-number: 4 +Prop-content-length: 108 +Content-length: 108 + +K 7 +svn:log +V 7 +branch2 +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-02-24T20:15:55.095809Z +PROPS-END + +Node-path: branches/branch2 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 2 +Node-copyfrom-path: trunk + + +Revision-number: 5 +Prop-content-length: 118 +Content-length: 118 + +K 7 +svn:log +V 16 +add c to branch2 +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-02-24T20:15:57.098439Z +PROPS-END + +Node-path: branches/branch2/c +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: 2cd6ee2c70b0bde53fbe6cac3c8b8bb1 +Text-content-sha1: 2b66fd261ee5c6cfc8de7fa466bab600bcfe4f69 +Content-length: 12 + +PROPS-END +c + + +Revision-number: 6 +Prop-content-length: 102 +Content-length: 102 + +K 7 +svn:log +V 4 +blah +K 10 +svn:author +V 4 +evil +K 8 +svn:date +V 27 +2010-02-24T20:15:59.687871Z +PROPS-END + +Node-path: branches/branch1 +Node-kind: dir +Node-action: delete + +Node-path: branches/branch1 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 5 +Node-copyfrom-path: branches/branch2 + + + + +Node-path: branches/branch1/a +Node-kind: file +Node-action: delete + +Node-path: branches/branch1/a +Node-kind: file +Node-action: add +Node-copyfrom-rev: 5 +Node-copyfrom-path: branches/branch1/d +Text-copy-source-md5: e29311f6f1bf1af907f9ef9f44b8328b +Text-copy-source-sha1: e983f374794de9c64e3d1c1de1d490c0756eeeff + + + +
--- a/tests/test_fetch_branches.py +++ b/tests/test_fetch_branches.py @@ -131,6 +131,26 @@ class TestFetchBranches(test_util.TestBa self.assertEqual(node.hex(repo['tip'].node()), '4108a81a82c7925d5551091165dc54c41b06a8a8') + def test_replace_branch_with_branch(self, stupid=False): + repo = self._load_fixture_and_fetch('replace_branch_with_branch.svndump', + stupid) + self.assertEqual(7, len(repo)) + # tip is former topological branch1 being closed + ctx = repo['tip'] + self.assertEqual('1', ctx.extra().get('close', '0')) + self.assertEqual('branch1', ctx.branch()) + # r5 is where the replacement takes place + ctx = repo[5] + self.assertEqual(set(['a', 'c']), set(ctx)) + self.assertEqual('0', ctx.extra().get('close', '0')) + self.assertEqual('branch1', ctx.branch()) + self.assertEqual('c\n', ctx['c'].data()) + # a replacement does not work yet + #self.assertEqual('d\n', ctx['a'].data()) + + def test_replace_branch_with_branch_stupid(self, stupid=False): + self.test_replace_branch_with_branch(True) + def suite(): all = [unittest.TestLoader().loadTestsFromTestCase(TestFetchBranches), ]