Merge lp:~mbp/bzr/427773-empty-limbo into lp:bzr/2.4

Proposed by Martin Pool
Status: Merged
Approved by: Martin Pool
Approved revision: no longer in the source branch.
Merged at revision: 6062
Proposed branch: lp:~mbp/bzr/427773-empty-limbo
Merge into: lp:bzr/2.4
Diff against target: 114 lines (+51/-18)
4 files modified
bzrlib/osutils.py (+15/-0)
bzrlib/tests/per_merger.py (+24/-8)
bzrlib/transform.py (+6/-10)
doc/en/release-notes/bzr-2.4.txt (+6/-0)
To merge this branch: bzr merge lp:~mbp/bzr/427773-empty-limbo
Reviewer Review Type Date Requested Status
Jelmer Vernooij Pending
Review via email: mp+83857@code.launchpad.net

This proposal supersedes a proposal from 2011-11-29.

Commit message

tolerate empty limbo and pending-deletion directories (bug 427773)

Description of the change

fix up niggling bug 427773 by tolerating empty limbo dirs.

also, I saw we were actually squashing any exception raised while creating them, so this fixes that.

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 guess FAT is another filesystem on Unix where this occurs?

102 +class _PosixPermissionsFeature(Feature):
103 +
104 + def _probe(self):
105 + def has_perms():
106 + # create temporary file and check if specified perms are maintained.
107 + import tempfile
108 +
109 + write_perms = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
110 + f = tempfile.mkstemp(prefix='bzr_perms_chk_')
Should this be using self.test_dir ? I'm not sure how to get at that variable from within a Feature though. I'm not sure how many people have /tmp mounted over SMB though. :-)

review: Approve
Revision history for this message
Martin Pool (mbp) wrote : Posted in a previous version of this proposal

ah, this is orignially off 2.4 so the diff is a bit weird...

Revision history for this message
Martin Pool (mbp) wrote :

+class _PosixPermissionsFeature(Feature):

That's in 2.4 and I guess not yet merged up to trunk.

I think it is probably harmless enough not to be worth chasing: it's possible that tempfile creates things in a different place to what our TestCase does but not all that likely.

It would be kind of nice to move the tests's own tempdir into a feature that could somehow be depended upon by this. It seems like you want almost a concept of a dynamic scope environment for the tests, or perhaps just a pointer back to the test object is enough.

Anyhow, I will merge the limbo related bits, thanks for the review.

Revision history for this message
Martin Pool (mbp) wrote :

sent to pqm by email

Revision history for this message
Martin Pool (mbp) 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/osutils.py'
2--- bzrlib/osutils.py 2011-11-18 00:32:50 +0000
3+++ bzrlib/osutils.py 2011-12-01 01:06:24 +0000
4@@ -2532,3 +2532,18 @@
5 fn = getattr(os, 'fdatasync', getattr(os, 'fsync', None))
6 if fn is not None:
7 fn(fileno)
8+
9+
10+def ensure_empty_directory_exists(path, exception_class):
11+ """Make sure a local directory exists and is empty.
12+
13+ If it does not exist, it is created. If it exists and is not empty, an
14+ instance of exception_class is raised.
15+ """
16+ try:
17+ os.mkdir(path)
18+ except OSError, e:
19+ if e.errno != errno.EEXIST:
20+ raise
21+ if os.listdir(path) != []:
22+ raise exception_class(path)
23
24=== modified file 'bzrlib/tests/per_merger.py'
25--- bzrlib/tests/per_merger.py 2011-01-12 01:01:53 +0000
26+++ bzrlib/tests/per_merger.py 2011-12-01 01:06:24 +0000
27@@ -175,17 +175,33 @@
28 transform.finalize()
29 return (limbodir, deletiondir)
30
31- def test_merge_with_existing_limbo(self):
32- wt = self.make_branch_and_tree('this')
33- (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
34- os.mkdir(limbodir)
35+ def test_merge_with_existing_limbo_empty(self):
36+ """Empty limbo dir is just cleaned up - see bug 427773"""
37+ wt = self.make_branch_and_tree('this')
38+ (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
39+ os.mkdir(limbodir)
40+ self.do_merge(wt, wt)
41+
42+ def test_merge_with_existing_limbo_non_empty(self):
43+ wt = self.make_branch_and_tree('this')
44+ (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
45+ os.mkdir(limbodir)
46+ os.mkdir(os.path.join(limbodir, 'something'))
47 self.assertRaises(errors.ExistingLimbo, self.do_merge, wt, wt)
48 self.assertRaises(errors.LockError, wt.unlock)
49
50- def test_merge_with_pending_deletion(self):
51- wt = self.make_branch_and_tree('this')
52- (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
53- os.mkdir(deletiondir)
54+ def test_merge_with_pending_deletion_empty(self):
55+ wt = self.make_branch_and_tree('this')
56+ (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
57+ os.mkdir(deletiondir)
58+ self.do_merge(wt, wt)
59+
60+ def test_merge_with_pending_deletion_non_empty(self):
61+ """Also see bug 427773"""
62+ wt = self.make_branch_and_tree('this')
63+ (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
64+ os.mkdir(deletiondir)
65+ os.mkdir(os.path.join(deletiondir, 'something'))
66 self.assertRaises(errors.ExistingPendingDeletion, self.do_merge, wt, wt)
67 self.assertRaises(errors.LockError, wt.unlock)
68
69
70=== modified file 'bzrlib/transform.py'
71--- bzrlib/transform.py 2011-11-14 09:37:40 +0000
72+++ bzrlib/transform.py 2011-12-01 01:06:24 +0000
73@@ -1562,18 +1562,14 @@
74 try:
75 limbodir = urlutils.local_path_from_url(
76 tree._transport.abspath('limbo'))
77- try:
78- os.mkdir(limbodir)
79- except OSError, e:
80- if e.errno == errno.EEXIST:
81- raise ExistingLimbo(limbodir)
82+ osutils.ensure_empty_directory_exists(
83+ limbodir,
84+ errors.ExistingLimbo)
85 deletiondir = urlutils.local_path_from_url(
86 tree._transport.abspath('pending-deletion'))
87- try:
88- os.mkdir(deletiondir)
89- except OSError, e:
90- if e.errno == errno.EEXIST:
91- raise errors.ExistingPendingDeletion(deletiondir)
92+ osutils.ensure_empty_directory_exists(
93+ deletiondir,
94+ errors.ExistingPendingDeletion)
95 except:
96 tree.unlock()
97 raise
98
99=== modified file 'doc/en/release-notes/bzr-2.4.txt'
100--- doc/en/release-notes/bzr-2.4.txt 2011-11-14 09:37:40 +0000
101+++ doc/en/release-notes/bzr-2.4.txt 2011-12-01 01:06:24 +0000
102@@ -35,6 +35,12 @@
103 * Cope with Unix filesystems, such as smbfs, where chmod gives 'permission
104 denied'. (Martin Pool, #606537)
105
106+* When the ``limbo`` or ``pending-deletion`` directories exist, typically
107+ because of an interrupted tree update, but are empty, bzr no longer
108+ errors out, because there is nothing for the user to clean up. Also,
109+ errors in creation of these directories are no longer squelched.
110+ (Martin Pool, #427773)
111+
112 * During merges, when two entries end up using the same path for two
113 different file-ids (the same file being 'bzr added' in two different
114 branches) , 'duplicate' conflicts are created instead of 'content'

Subscribers

People subscribed via source and target branches