Merge lp:~jelmer/bzr/merge-inner-require-tree-root into lp:bzr

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merged at revision: 5997
Proposed branch: lp:~jelmer/bzr/merge-inner-require-tree-root
Merge into: lp:bzr
Diff against target: 101 lines (+43/-1)
5 files modified
bzrlib/merge.py (+1/-1)
bzrlib/tests/test_merge.py (+18/-0)
bzrlib/tests/test_transform.py (+15/-0)
bzrlib/transform.py (+6/-0)
doc/en/release-notes/bzr-2.4.txt (+3/-0)
To merge this branch: bzr merge lp:~jelmer/bzr/merge-inner-require-tree-root
Reviewer Review Type Date Requested Status
Aaron Bentley (community) Disapprove
Review via email: mp+66133@code.launchpad.net

Commit message

Re-introduce root when merge result is empty tree.

Description of the change

Now that merge uses the transform functionality to fix up roots, it no longer re-adds a tree root if the target tree is empty.

This breaks when the target tree is a working tree, which can not be root-less.

This makes TreeTransform.fixup_new_roots() check that a tree root is present, and re-add the old tree root if there is none. This is consistent with the
old behaviour in merge.

To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

I think the feature flag is YAGNI, but the rest seems fine.
Tweak
John
=:->
On Jun 28, 2011 2:05 PM, "Jelmer Vernooij" <email address hidden> wrote:
> Jelmer Vernooij has proposed merging
lp:~jelmer/bzr/merge-inner-require-tree-root into lp:bzr.
>
> Requested reviews:
> bzr-core (bzr-core)
> Related bugs:
> Bug #801257 in Bazaar: "newer versions break bzr-loom"
> https://bugs.launchpad.net/bzr/+bug/801257
>
> For more details, see:
>
https://code.launchpad.net/~jelmer/bzr/merge-inner-require-tree-root/+merge/66133
>
> Now that merge uses the transform functionality to fix up roots, it no
longer re-adds a tree root if the target tree is empty.
>
> This breaks when the target tree is a working tree, which can not be
root-less.
>
> This makes TreeTransform.fixup_new_roots() check that a tree root is
present, and re-add the old tree root if there is none. This is consistent
with the
> old behaviour in merge.
> --
>
https://code.launchpad.net/~jelmer/bzr/merge-inner-require-tree-root/+merge/66133
> Your team bzr-core is requested to review the proposed merge of
lp:~jelmer/bzr/merge-inner-require-tree-root into lp:bzr.

Revision history for this message
Aaron Bentley (abentley) wrote :

This change is at the wrong level. A TreeTransform whose result lacks a tree root is valid, because it can be used to produce an empty PreviewTree.

Instead, it should be done in TreeTransform.apply. That code already has functionality to ensure the root directory is not deleted, which makes your "if self.final_kind(self.root) is None: self.cancel_deletion(self.root)" redundant.

review: Disapprove
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Hi Aaron,

On 12/07/11 19:39, Aaron Bentley wrote:
> Review: Disapprove
> This change is at the wrong level. A TreeTransform whose result lacks a tree root is valid, because it can be used to produce an empty PreviewTree.
>
> Instead, it should be done in TreeTransform.apply. That code already has functionality to ensure the root directory is not deleted, which makes your "if self.final_kind(self.root) is None: self.cancel_deletion(self.root)" redundant.
This already landed before your review, but I don't really understand
how TreeTransform.apply is better than TreeTransform.fix_tree_roots.

This particular code *is* necessary because without it the loom test
suite breaks (as discussed in Dublin). What alternative do you suggest
exactly?

Cheers,

Jelmer

Revision history for this message
Aaron Bentley (abentley) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

So first off, I fixed this issue in

https://code.launchpad.net/~abentley/bzr/unbreak-transform/+merge/67872
landed as r6025

On 11-08-06 12:29 PM, Jelmer Vernooij wrote:
> Hi Aaron,
>
> On 12/07/11 19:39, Aaron Bentley wrote:
>> Review: Disapprove
>> This change is at the wrong level. A TreeTransform whose result lacks
>> a tree root is valid, because it can be used to produce an empty
>> PreviewTree.
>>
>> Instead, it should be done in TreeTransform.apply. That code already
>> has functionality to ensure the root directory is not deleted, which
>> makes your "if self.final_kind(self.root) is None:
>> self.cancel_deletion(self.root)" redundant.
> This already landed before your review, but I don't really understand
> how TreeTransform.apply is better than TreeTransform.fix_tree_roots.

The loom code is trying to change a working tree into a shape that's
illegal for working trees, but legal for PreviewTrees.
TreeTransform.apply only affects WorkingTrees, but
TreeTransformBase.fix_tree_roots affects PreviewTree generation as well.
 So it only affects the cases that need the change.

> This particular code *is* necessary because without it the loom test
> suite breaks (as discussed in Dublin).

I was saying that the code is in the wrong place. I was saying only
part of it is redundant.

> What alternative do you suggest
> exactly?

(See my merge proposal.)

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5BPXEACgkQ0F+nu1YWqI0p0gCeOO6QidHXqIrXf2M6LgSVr0ev
kxEAn2BrqzZkLVnufwYOpLtYko8VP/Wy
=MbvA
-----END PGP SIGNATURE-----

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/merge.py'
2--- bzrlib/merge.py 2011-06-21 22:02:33 +0000
3+++ bzrlib/merge.py 2011-06-28 13:45:49 +0000
4@@ -1966,7 +1966,7 @@
5 """
6 if this_tree is None:
7 raise errors.BzrError("bzrlib.merge.merge_inner requires a this_tree "
8- "parameter as of bzrlib version 0.8.")
9+ "parameter")
10 merger = Merger(this_branch, other_tree, base_tree, this_tree=this_tree,
11 pb=pb, change_reporter=change_reporter)
12 merger.backup_files = backup_files
13
14=== modified file 'bzrlib/tests/test_merge.py'
15--- bzrlib/tests/test_merge.py 2011-06-09 18:56:55 +0000
16+++ bzrlib/tests/test_merge.py 2011-06-28 13:45:49 +0000
17@@ -490,6 +490,24 @@
18 finally:
19 tree_file.close()
20
21+ def test_merge_require_tree_root(self):
22+ tree = self.make_branch_and_tree(".")
23+ tree.lock_write()
24+ self.addCleanup(tree.unlock)
25+ self.build_tree(['a'])
26+ tree.add('a')
27+ tree.commit("added a")
28+ old_root_id = tree.get_root_id()
29+ first_rev = tree.branch.revision_history()[0]
30+ merger = _mod_merge.Merger.from_revision_ids(None, tree,
31+ _mod_revision.NULL_REVISION,
32+ first_rev)
33+ merger.merge_type = _mod_merge.Merge3Merger
34+ conflict_count = merger.do_merge()
35+ self.assertEqual(0, conflict_count)
36+ self.assertEquals(set([old_root_id]), tree.all_file_ids())
37+ tree.set_parent_ids([])
38+
39 def test_merge_add_into_deleted_root(self):
40 # Yes, people actually do this. And report bugs if it breaks.
41 source = self.make_branch_and_tree('source', format='rich-root-pack')
42
43=== modified file 'bzrlib/tests/test_transform.py'
44--- bzrlib/tests/test_transform.py 2011-06-13 16:25:08 +0000
45+++ bzrlib/tests/test_transform.py 2011-06-28 13:45:49 +0000
46@@ -291,6 +291,21 @@
47 transform.fixup_new_roots()
48 self.assertNotIn(transform.root, transform._new_id)
49
50+ def test_remove_root_fixup(self):
51+ transform, root = self.get_transform()
52+ old_root_id = self.wt.get_root_id()
53+ self.assertNotEqual('new-root-id', old_root_id)
54+ transform.delete_contents(root)
55+ transform.unversion_file(root)
56+ transform.fixup_new_roots()
57+ transform.apply()
58+ self.assertEqual(old_root_id, self.wt.get_root_id())
59+
60+ transform, root = self.get_transform()
61+ new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
62+ new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
63+ self.assertRaises(ValueError, transform.fixup_new_roots)
64+
65 def test_apply_retains_root_directory(self):
66 # Do not attempt to delete the physical root directory, because that
67 # is impossible.
68
69=== modified file 'bzrlib/transform.py'
70--- bzrlib/transform.py 2011-06-21 15:19:18 +0000
71+++ bzrlib/transform.py 2011-06-28 13:45:49 +0000
72@@ -226,10 +226,16 @@
73 This means that the old root trans-id becomes obsolete, so it is
74 recommended only to invoke this after the root trans-id has become
75 irrelevant.
76+
77 """
78 new_roots = [k for k, v in self._new_parent.iteritems() if v is
79 ROOT_PARENT]
80 if len(new_roots) < 1:
81+ if self.final_kind(self.root) is None:
82+ self.cancel_deletion(self.root)
83+ if self.final_file_id(self.root) is None:
84+ self.version_file(self.tree_file_id(self.root),
85+ self.root)
86 return
87 if len(new_roots) != 1:
88 raise ValueError('A tree cannot have two roots!')
89
90=== modified file 'doc/en/release-notes/bzr-2.4.txt'
91--- doc/en/release-notes/bzr-2.4.txt 2011-06-28 12:18:33 +0000
92+++ doc/en/release-notes/bzr-2.4.txt 2011-06-28 13:45:49 +0000
93@@ -42,6 +42,9 @@
94 * ``GraphThunkIdsToKeys.merge_sort`` now properly returns
95 keys rather than ids. (Jelmer Vernooij, #799677)
96
97+* ``TreeTransformBase.fixup_new_roots`` can now check that a tree root
98+ is present. (Jelmer Vernooij, #801257)
99+
100 .. Fixes for situations where bzr would previously crash or give incorrect
101 or undesirable results.
102