[MERGE] dpush / foreign vcs testing
John Arbash Meinel
john at arbash-meinel.com
Fri Apr 3 15:19:36 BST 2009
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Jelmer Vernooij wrote:
...
>>>>> I'm still looking for review of this patch; it would be nice if it
>>>>> could land in 1.14 so that bzr-git doesn't have to depend on bzr-svn
>>>>> for dpush... :-)
>>>> Updated patch with against bzr.dev.
>>> Here's the final version, with a slight performance improvement and a
>>> fix to handle nested files.
>> Is there any chance somebody could review this patch? It would be nice
>> if it could make it into 1.14. It's been waiting in the queue for two
>> months now.
> here's an updated patch, with latest bzr.dev merged (and conflicts
> resolved).
>
> Cheers,
>
> Jelmer
>
I think there is a reasonable use case for dpush, mostly from tracking a
foreign branch and not wanting to "interrupt" the upstream. I don't
particularly like doing it this way, but having read the discussions in
the past, I can understand why people feel it would be necessary.
#1) The command should be hidden (IMO), you can do that with "hidden =
True" in the class definition. At least for now, I would prefer not
having someone stumble across the command and try to use it.
I *do* see that you at least add a command that it will fail for most
bzr format implementations.
#2) I find it a little bit odd in design that "dpush" is implemented in
terms of "dpull" being present on the target branch. But it isn't a huge
deal.
#3)
+ try:
+ source_wt = WorkingTree.open_containing(directory)[0]
+ source_branch = source_wt.branch
+ except NoWorkingTree:
+ source_branch = Branch.open_containing(directory)[0]
+ source_wt = None
^- We have BzrDir.open_containing_tree_branch_or_repository() for that
sort of thing. Though personally I prefer:
+ try:
+ source_wt = WorkingTree.open_containing(directory)[0]
+ source_branch = source_wt.branch
+ except NoWorkingTree:
+ source_branch = Branch.open(directory)
+ source_wt = None
(When you are in a WT it makes sense to open the containing object, but
without the WT, it makes more sense to require the exact path.)
...
+ def dpull(self, source, stop_revision=None):
+ """Pull deltas from another branch.
+
+ :note: This does not, like pull, retain the revision ids from
+ the source branch and will, rather than adding bzr-specific
+ metadata, push only those semantics of the revision that
can be
+ natively represented by this branch' VCS.
+
+ :param source: Source branch
+ :param stop_revision: Revision to pull, defaults to last revision.
+ """
+ raise NotImplementedError(self.dpull)
^- You define the :param: to supply, but you don't define the return
value. I can see that it is some sort of revid_map by inspecting the
code. A bit of clarification would be nice. (Does it map everything,
just map the ones that were modified, etc.)
...
+ if not no_rebase:
+ _, old_last_revid = source_branch.last_revision_info()
+ new_last_revid = revid_map[old_last_revid]
+ source_branch.pull(target_branch, overwrite=True,
+ stop_revision=new_last_revid)
^- It seems a bit odd that you would use the revid_map to map the old
last revision to the new one, rather than doing something like:
source_branch.pull(target_branch, overwrite=True)
Since you just *pushed* the last revision for the target branch...
...
+def determine_fileid_renames(old_inv, new_inv):
^- This seems like it should be an implementation detail, and thus a
private function.
I would probably say that you should check if the "file_id" exists in
the target before you translate back into paths, simply because checking
the 10,000 files that *didn't* change by mapping through paths seems a
bit expensive. Also, you just computed the path in the local inventory
because it is exactly the path in the old inventory. So calling
'id2path' yet again on the new_inv seems wasteful.
That can come later, just a some recommendations.
...
+def update_workinginv_fileids(wt, old_inv, new_inv):
^- this looks dangerously destructive. You call 'unversion()' on a
containing directory, but there is no guarantee that all files
underneath that directory will have new file ids.
I didn't audit the code paths particularly closely, it may be that you
have defined it to unversion everything from the target, and re-add
everything back. Rather inefficient, but I guess it "works".
...
=== added file 'bzrlib/tests/blackbox/test_dpush.py'
+from bzrlib.tests.test_foreign import DummyForeignVcsDirFormat
+
+import os
+
+class TestDpush(ExternalBase):
minor style issue. stdlib imports come before bzrlib imports, and we
want 2 blank spaces between imports an the class definitions.
+ def setUp(self):
+ BzrDirFormat.register_control_format(DummyForeignVcsDirFormat)
+ super(TestDpush, self).setUp()
+
+ def tearDown(self):
+ try:
+
BzrDirFormat.unregister_control_format(DummyForeignVcsDirFormat)
+ except ValueError:
+ pass
+ super(TestDpush, self).tearDown()
^- I'm pretty sure it is easier to addCleanup() than do tearDown, but I
think either works.
+ def test_dpush_native(self):
+ tree = self.make_branch_and_tree("dp")
+ self.run_bzr("init dc")
+ error = self.run_bzr("dpush -d dc dp", retcode=3)[1]
+ self.assertContainsRe(error, 'not a foreign branch, use regular
push')
^- We generally prefer if you use "make_branch_and_tree" for everything
except the final "dpush" command. That actually goes for a lot of your
"dpush" tests, where we would prefer you to use things like
"branch.bzrdir.sprout()" rather than "run_bzr('branch a b')".
I realize you may have copied the cruft from a "push" test suite, it
would be nice not to propagate it, though.
BB:tweak
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAknWGvgACgkQJdeBCYSNAAO8VACgqkCmNbtWj5siG6Zp9u8Dk4hU
uqMAnRzSVK/5sYUdExmgBRCNhJ6a5BSE
=JiUp
-----END PGP SIGNATURE-----
More information about the bazaar
mailing list