Merge lp:~jelmer/bzr/314314-obsolete-packs into lp:bzr

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Martin Packman
Approved revision: no longer in the source branch.
Merged at revision: 6362
Proposed branch: lp:~jelmer/bzr/314314-obsolete-packs
Merge into: lp:bzr
Diff against target: 91 lines (+43/-3)
3 files modified
bzrlib/repofmt/pack_repo.py (+17/-3)
bzrlib/tests/test_repository.py (+23/-0)
doc/en/release-notes/bzr-2.5.txt (+3/-0)
To merge this branch: bzr merge lp:~jelmer/bzr/314314-obsolete-packs
Reviewer Review Type Date Requested Status
Martin Packman (community) Approve
Bazaar Developers Pending
John A Meinel Pending
Jelmer Vernooij Pending
Review via email: mp+85247@code.launchpad.net

This proposal supersedes a proposal from 2011-10-19.

Commit message

Deal with the obsolete_packs directory being removed from under us.

Description of the change

Create obsolete_packs directory when repacking if it does not exist, and ignore it when it doesn't exist when trying to clean it up.

Original proposal by Jonathan Riddell, updated to address review comments.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal

I'm not sure if this is the right place for the test, but I don't have an idea for a better one. Ideally we would want to test this for all formats for which it is relevant (rather than in a blackbox test, which only exercises the default format). That's pretty hard though - we can't use bt.per_repository, as it's an implementation detail.

Revision history for this message
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal

Either way, this seems reasonable enough for now. We'll have to move this test when the default format changes, but that's bearable.

review: Approve
Revision history for this message
John A Meinel (jameinel) wrote : Posted in a previous version of this proposal

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

On 10/19/2011 3:42 PM, Jonathan Riddell wrote:
> Jonathan Riddell has proposed merging
> lp:~jr/bzr/314314-obsolete-packs into lp:bzr.
>
> Requested reviews: bzr-core (bzr-core) Related bugs: Bug #314314 in
> Bazaar: "bzr does not automatically create 'obsolete_packs' when it
> is missing." https://bugs.launchpad.net/bzr/+bug/314314
>
> For more details, see:
> https://code.launchpad.net/~jr/bzr/314314-obsolete-packs/+merge/79816
>
> * Create obsolete_packs directory when repacking if it does not
> exist. (Jonathan Riddell, #314314)
>

I really doubt this is correct:
@@ -1221,6 +1222,10 @@
         """
         for pack in packs:
             try:
+ os.mkdir("../obsolete_packs/")
+ except OSError:
+ pass
+ try:
                 pack.pack_transport.move(pack.file_name(),
                     '../obsolete_packs/' + pack.file_name())

Given that the following code is using "pack.pack_transport" that
indicates that this is handling Remote objects. I really don't want to
see "obsolete_packs" suddenly show up in my working directory after
doing 'bzr push'.

 review: needsfixing

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

iEYEARECAAYFAk6e2qoACgkQJdeBCYSNAAPBdgCcDEEfUEJBp+0Kilbk0vq9Afkq
0wAAn2nnPqtBvgWvGGAbiXKj6qAH3PK5
=qwd8
-----END PGP SIGNATURE-----

review: Needs Fixing
Revision history for this message
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal

Thanks John, you're right. Not sure how I missed that.

Revision history for this message
Martin Packman (gz) wrote : Posted in a previous version of this proposal

One other concern:

         for pack in packs:
             try:
+ os.mkdir("../obsolete_packs/")
+ except OSError:
+ pass
+ try:
                 pack.pack_transport.move(pack.file_name(),
                     '../obsolete_packs/' + pack.file_name())
             except (errors.PathError, errors.TransportError), e:

Ignoring the transport issue for now, this does for every pack, try to create the directory and ignoring any errors in the process, then move the file. Presumably this doubles the number of (V)FS operations per pack, which still shouldn't be a big number but seems suboptimal given nearly all the time the directory will already exist.

A better approach would be to detect if the move failed because the move-into directory was missing, create it then, and retry the move. However, it may be that we can't reliably do that over all the different transports we support (translating errors into what they actually mean is very hackish), so always trying to create the directory may still be the best way. Doing that once before this loop, rather than for each pack, should be sufficient though.

review: Needs Fixing
Revision history for this message
Martin Packman (gz) wrote : Posted in a previous version of this proposal

Moving this to work in progress for now, but will see if I can pick it up and address the review comments.

Revision history for this message
Martin Packman (gz) wrote :

The code looks good. I just wonder if this also needs a per_transport or similar test as well. The current tests seem to only cover the local case, and fallout is most likely over ftp and such like.

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

Am 12/12/11 12:28, schrieb Martin Packman:
> Review: Approve
>
> The code looks good. I just wonder if this also needs a per_transport or similar test as well. The current tests seem to only cover the local case, and fallout is most likely over ftp and such like.
Yeah, that would indeed be nice to make sure that has appropriate
testing, regardless of this. I'll leave that for another time though,
this change should improve the current situation in either case.

Cheers,

Jelmer

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

sent to pqm by email

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

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

On 12/12/2011 12:28 PM, Martin Packman wrote:
> Review: Approve
>
> The code looks good. I just wonder if this also needs a
> per_transport or similar test as well. The current tests seem to
> only cover the local case, and fallout is most likely over ftp and
> such like.

I think a patch like this could be reasonably backported to older
versions of bzr. At least to 2.4, maybe not all the way back to
Lucid's 2.1.

John
=:->

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

iEYEARECAAYFAk7l8X4ACgkQJdeBCYSNAAPrGQCdH/7xx/iY1Vbl4893BYPyic7f
S8MAn0bz2ELKEV7e6nDqX5e0uP55AdBk
=2IvX
-----END PGP SIGNATURE-----

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

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/repofmt/pack_repo.py'
2--- bzrlib/repofmt/pack_repo.py 2011-12-07 14:03:01 +0000
3+++ bzrlib/repofmt/pack_repo.py 2011-12-12 13:49:25 +0000
4@@ -1221,8 +1221,18 @@
5 """
6 for pack in packs:
7 try:
8- pack.pack_transport.move(pack.file_name(),
9- '../obsolete_packs/' + pack.file_name())
10+ try:
11+ pack.pack_transport.move(pack.file_name(),
12+ '../obsolete_packs/' + pack.file_name())
13+ except errors.NoSuchFile:
14+ # perhaps obsolete_packs was removed? Let's create it and
15+ # try again
16+ try:
17+ pack.pack_transport.mkdir('../obsolete_packs/')
18+ except errors.FileExists:
19+ pass
20+ pack.pack_transport.move(pack.file_name(),
21+ '../obsolete_packs/' + pack.file_name())
22 except (errors.PathError, errors.TransportError), e:
23 # TODO: Should these be warnings or mutters?
24 mutter("couldn't rename obsolete pack, skipping it:\n%s"
25@@ -1494,7 +1504,11 @@
26 obsolete_pack_transport = self.transport.clone('obsolete_packs')
27 if preserve is None:
28 preserve = set()
29- for filename in obsolete_pack_transport.list_dir('.'):
30+ try:
31+ obsolete_pack_files = obsolete_pack_transport.list_dir('.')
32+ except errors.NoSuchFile:
33+ return found
34+ for filename in obsolete_pack_files:
35 name, ext = osutils.splitext(filename)
36 if ext == '.pack':
37 found.append(name)
38
39=== modified file 'bzrlib/tests/test_repository.py'
40--- bzrlib/tests/test_repository.py 2011-12-11 03:42:09 +0000
41+++ bzrlib/tests/test_repository.py 2011-12-12 13:49:25 +0000
42@@ -1082,6 +1082,23 @@
43 sorted(set([osutils.splitext(n)[0] for n in
44 packs._index_transport.list_dir('.')])))
45
46+ def test__obsolete_packs_missing_directory(self):
47+ tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)
48+ r.control_transport.rmdir('obsolete_packs')
49+ names = packs.names()
50+ pack = packs.get_pack_by_name(names[0])
51+ # Schedule this one for removal
52+ packs._remove_pack_from_memory(pack)
53+ # Now trigger the obsoletion, and ensure that all the remaining files
54+ # are still renamed
55+ packs._obsolete_packs([pack])
56+ self.assertEqual([n + '.pack' for n in names[1:]],
57+ sorted(packs._pack_transport.list_dir('.')))
58+ # names[0] should not be present in the index anymore
59+ self.assertEqual(names[1:],
60+ sorted(set([osutils.splitext(n)[0] for n in
61+ packs._index_transport.list_dir('.')])))
62+
63 def test_pack_distribution_zero(self):
64 packs = self.get_packs()
65 self.assertEqual([0], packs.pack_distribution(0))
66@@ -1357,6 +1374,12 @@
67 obsolete_names = set([osutils.splitext(n)[0] for n in obsolete_packs])
68 self.assertEqual([pack.name], sorted(obsolete_names))
69
70+ def test_pack_no_obsolete_packs_directory(self):
71+ """Bug #314314, don't fail if obsolete_packs directory does
72+ not exist."""
73+ tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)
74+ r.control_transport.rmdir('obsolete_packs')
75+ packs._clear_obsolete_packs()
76
77
78 class TestPack(TestCaseWithTransport):
79
80=== modified file 'doc/en/release-notes/bzr-2.5.txt'
81--- doc/en/release-notes/bzr-2.5.txt 2011-12-12 13:05:24 +0000
82+++ doc/en/release-notes/bzr-2.5.txt 2011-12-12 13:49:25 +0000
83@@ -41,6 +41,9 @@
84 * Allow configuration option default value to be a python callable at
85 registration. (Vincent Ladeuil, #832064)
86
87+* Create obsolete_packs directory when repacking if it does not
88+ exist. (Jonathan Riddell, Jelmer Vernooij, #314314)
89+
90 * Properly ignore '\n' in an option reference since this cannot be part of a
91 config option identifier. (Vincent Ladeuil, #902125)
92