Merge lp:~lifeless/bzr/bug-403322 into lp:bzr/2.0

Proposed by Robert Collins
Status: Merged
Approved by: Andrew Bennetts
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~lifeless/bzr/bug-403322
Merge into: lp:bzr/2.0
Diff against target: 42 lines
2 files modified
NEWS (+8/-0)
bzrlib/workingtree_4.py (+11/-3)
To merge this branch: bzr merge lp:~lifeless/bzr/bug-403322
Reviewer Review Type Date Requested Status
Andrew Bennetts Approve
Review via email: mp+12639@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

This avoids an ordering bug in dirstate updates by not using the less tested, O(tree) performing set_state_from_inventory method (which leaves us with one caller of it, and that internal to dirstate).

Revision history for this message
Andrew Bennetts (spiv) wrote :

The NEWS entry is a bit too abstract. It basically says "make the internals slightly nicer", but it's in the Bug Fixes section. I assume from your merge proposal that this actually fixes a bug, possibly a user-observable one, so the NEWS entry ought to say something about that. i.e. start the entry with something like "Fix IndexError on moving added file", then you can go into details.

32 + # reconstruct a clean inventory from the dirstate,
33 + self._inventory = None
34 + # generate a delta,
35 + delta = inv._make_delta(self.inventory)

That looks a bit odd. _make_delta is always called with None? Oh, I see "_inventory" != "inventory". Ugh. That's confusing (I spent too many minutes puzzling over this!), but not the fault of this patch I guess, and your comment (eventually) helped.

In general using _make_delta and apply_inventory_delta sounds good! So tweak that NEWS entry and you're good.

review: Approve
Revision history for this message
John A Meinel (jameinel) wrote :

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

Andrew Bennetts wrote:
> Review: Approve
> The NEWS entry is a bit too abstract. It basically says "make the internals slightly nicer", but it's in the Bug Fixes section. I assume from your merge proposal that this actually fixes a bug, possibly a user-observable one, so the NEWS entry ought to say something about that. i.e. start the entry with something like "Fix IndexError on moving added file", then you can go into details.
>
> 32 + # reconstruct a clean inventory from the dirstate,
> 33 + self._inventory = None
> 34 + # generate a delta,
> 35 + delta = inv._make_delta(self.inventory)
>
> That looks a bit odd. _make_delta is always called with None? Oh, I see "_inventory" != "inventory". Ugh. That's confusing (I spent too many minutes puzzling over this!), but not the fault of this patch I guess, and your comment (eventually) helped.
>
> In general using _make_delta and apply_inventory_delta sounds good! So tweak that NEWS entry and you're good.
>

I think updating the comment to say:

# Setting self._inventory = None forces the dirstate to regenerate the
# working inventory. We do this because 'inv' may be a copy of
# self._inventory, or may be mutated, etc.
self._inventory = None
delta = inv._make_delta(self.inventory)

This doesn't seem like the best-performing way to go, but I will say the
delta code paths are probably more thoroughly tested at this point.

Have you tested to make sure that bug #403322 is really fixed? (bzr mv
of a newly added directory doesn't fail?)

It might be nice to have a test case added for that edge case.

def test_rename_one_after_add(self):
  tree = self.make_branch_and_tree('.')
  self.build_tree(['a/'])
  tree.add(['a'])
  tree.commit('a')
  self.build_tree(['a/a/'])
  tree.rename_one('a/a', 'a/d')
  tree.rename_one('a/d', 'a/b') # bug #403322

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrDX+sACgkQJdeBCYSNAANHiwCgiljZLNPxpLPwMT2S0SGnWJ+e
+DQAoNBO0TtlWCt2ujHzJX8JYbLPXy+3
=m9t2
-----END PGP SIGNATURE-----

Revision history for this message
Robert Collins (lifeless) wrote :

On Wed, 2009-09-30 at 13:42 +0000, John A Meinel wrote:
>
>
> It might be nice to have a test case added for that edge case.

So, if I was going to add one I'd be strongly tempted to add a test at
the broken layer, but the fix is to stop using that layer.

-Rob

Revision history for this message
Robert Collins (lifeless) wrote :

Sadly, this WT level change breaks TestCommitBuilder, though I'm
*totally* at a loss to see how. I'm tracking it down nowish.

If its trivial I'll just land, otherwise we'll be needing more reviews.

-Rob

Revision history for this message
Robert Collins (lifeless) wrote :

On Thu, 2009-10-01 at 00:00 +0000, Robert Collins wrote:
> Sadly, this WT level change breaks TestCommitBuilder, though I'm
> *totally* at a loss to see how. I'm tracking it down nowish.
>
> If its trivial I'll just land, otherwise we'll be needing more reviews.

It was trivial.

-Rob

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2009-09-30 00:02:11 +0000
3+++ NEWS 2009-09-30 22:22:10 +0000
4@@ -22,6 +22,14 @@
5 ``keyboard-interactive`` auth but not ``password`` auth when using
6 Paramiko. (Andrew Bennetts, #433846)
7
8+* Occasional IndexError on renamed files have been fixed. Operations that
9+ set a full inventory in the working tree will now go via the
10+ apply_inventory_delta code path which is simpler and easier to
11+ understand than dirstates set_state_from_inventory method. This may
12+ have a small performance impact on operations built on _write_inventory,
13+ but such operations are already doing full tree scans, so no radical
14+ performance change should be observed. (Robert Collins, #403322)
15+
16 Improvements
17 ************
18
19
20=== modified file 'bzrlib/workingtree_4.py'
21--- bzrlib/workingtree_4.py 2009-08-25 04:43:21 +0000
22+++ bzrlib/workingtree_4.py 2009-09-30 22:22:10 +0000
23@@ -1267,9 +1267,17 @@
24 if self._dirty:
25 raise AssertionError("attempting to write an inventory when the "
26 "dirstate is dirty will lose pending changes")
27- self.current_dirstate().set_state_from_inventory(inv)
28- self._make_dirty(reset_inventory=False)
29- if self._inventory is not None:
30+ had_inventory = self._inventory is not None
31+ # Setting self._inventory = None forces the dirstate to regenerate the
32+ # working inventory. We do this because self.inventory may be inv, or
33+ # may have been modified, and either case would prevent a clean delta
34+ # being created.
35+ self._inventory = None
36+ # generate a delta,
37+ delta = inv._make_delta(self.inventory)
38+ # and apply it.
39+ self.apply_inventory_delta(delta)
40+ if had_inventory:
41 self._inventory = inv
42 self.flush()
43

Subscribers

People subscribed via source and target branches