Merge lp:~abentley/bzr/is_executable into lp:bzr

Proposed by Aaron Bentley
Status: Superseded
Proposed branch: lp:~abentley/bzr/is_executable
Merge into: lp:bzr
Diff against target: 207 lines (+98/-7) (has conflicts)
8 files modified
bzr (+4/-0)
bzrlib/__init__.py (+4/-0)
bzrlib/revisiontree.py (+1/-1)
bzrlib/tests/per_tree/__init__.py (+1/-0)
bzrlib/tests/per_tree/test_is_executable.py (+37/-0)
bzrlib/tests/test_transform.py (+3/-3)
bzrlib/workingtree_4.py (+1/-1)
doc/en/release-notes/bzr-2.3.txt (+47/-2)
Text conflict in bzr
Text conflict in bzrlib/__init__.py
Text conflict in doc/en/release-notes/bzr-2.3.txt
To merge this branch: bzr merge lp:~abentley/bzr/is_executable
Reviewer Review Type Date Requested Status
bzr-core Pending
Review via email: mp+42203@code.launchpad.net

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

This proposal has been superseded by a proposal from 2010-11-30.

Description of the change

Hi all,

This branch fixes RevisionTree.is_executable to treat directories and symlinks
the same way as other Tree implementations-- to return False rather than None.
The revised behaviour is also consistent with RevisionTree._comparison_data.

This problem filters up and affects Launchpad's incremental diffs for merge
proposals (which are disabled until this issue can be resolved), causing them
to erroneously report property changes on directories and symlinks
that have not changed.

Three tests have been affected, but FWICT, they were testing actual behaviour,
not desirable behaviour. Specifically, the ROOT_ENTRY should only be included
in iter_changes-style output when it has changed, when it has a new child, or
when include_unchanged is specified.

To post a comment you must log in.
Revision history for this message
Andrew Bennetts (spiv) wrote : Posted in a previous version of this proposal

The fix itself seems good.

(I already said this on IRC, but for the benefit of people looking at this page) The change to behaviour seems in principle reasonable, but I'd be nervous about landing it in the stable branch. I'm not sure how likely this is, but it's at least plausible that a plugin might be depending on the root entry being emitted in that case. So my preference is to land this just on lp:bzr.

One extremely minor nit is that the preferred way to do locking and addCleanup is now as a one-liner:

    self.addCleanup(tree.lock_read().unlock)

So if you wish, you could make that tweak, but it's not a big deal at all.

I'm going to vote "Abstain" because the key decision about whether to land this on 2.2 is up to the RM rather than a reviewer, I think.

review: Abstain
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 11/29/2010 5:50 PM, Aaron Bentley wrote:
> Aaron Bentley has proposed merging lp:~abentley/bzr/is_executable into lp:bzr/2.2.
>
> Requested reviews:
> bzr-core (bzr-core)
>
>
> Hi all,
>
> This branch fixes RevisionTree.is_executable to treat directories and symlinks
> the same way as other Tree implementations-- to return False rather than None.
> The revised behaviour is also consistent with RevisionTree._comparison_data.
>
> This problem filters up and affects Launchpad's incremental diffs for merge
> proposals (which are disabled until this issue can be resolved), causing them
> to erroneously report property changes on directories and symlinks
> that have not changed.
>
> Three tests have been affected, but FWICT, they were testing actual behaviour,
> not desirable behaviour. Specifically, the ROOT_ENTRY should only be included
> in iter_changes-style output when it has changed, when it has a new child, or
> when include_unchanged is specified.

I'm a little concerned about doing this in a stable series. I think the
patch is definitely worthy for trunk.

I'm guessing you did it this way because you want it in the launchpad
codebase?

 review: needs_information

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

iEYEARECAAYFAkz1EVsACgkQJdeBCYSNAAN72ACgx2ecqEd8iGOT/Nb/rGTb0KtJ
4jMAn2bc2xDxFQ08Efy6ppdJSgksKdXM
=RuBa
-----END PGP SIGNATURE-----

review: Needs Information
Revision history for this message
Aaron Bentley (abentley) wrote : Posted in a previous version of this proposal

I proposed for 2.2 because I want it for Launchpad, and because it seemed like a small change. I didn't imagine that clients would actually care about the executability of symlinks or directories, but I can think of at least one client (difftacular, used by Launchpad) that cares that the output of RevisionTree.iter_changes(PreviewTree) is sane.

So on balance, it still seems like a reasonable change to make in a stable series. That said, I can propose a more conservative patch for 2.2 that will merely correct the output of RevisionTree.iter_changes(PreviewTree). Or I guess I could fix in in difftactular, though I'd rather not.

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

Keeping 2.2 stable is very important. It's also desirable to keep Launchpad on the stable branch and to have them actually running that branch, not something diverged from it. This also seems at least plausibly like a bug that could be justified to fix in 2.2, assuming the fix is safe.

With regard to assessing safety, it would help to say in the cover letter and NEWS what the behaviour was before. If it crashes, then it seems unlikely that anyone was counting on that behaviour. But I see from the diff it's obviously None.

Consistency with other Trees is a pretty good reason to change it.

=== modified file 'bzrlib/tests/test_transform.py'
--- bzrlib/tests/test_transform.py 2010-10-06 21:29:58 +0000
+++ bzrlib/tests/test_transform.py 2010-11-29 23:49:57 +0000
@@ -2344,7 +2344,7 @@
                   ('TREE_ROOT', 'TREE_ROOT'), ('a', 'a'), ('file', 'file'),
                   (False, False))
 ROOT_ENTRY = ('TREE_ROOT', ('', ''), False, (True, True), (None, None),
- ('', ''), ('directory', 'directory'), (False, None))
+ ('', ''), ('directory', 'directory'), (False, False))

 class TestTransformPreview(tests.TestCaseWithTransport):
@@ -2437,13 +2437,13 @@
         revision_tree, preview_tree = self.get_tree_and_preview_tree()
         changes = preview_tree.iter_changes(revision_tree,
                                             specific_files=[''])
- self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))
+ self.assertEqual([A_ENTRY], list(changes))

     def test_want_unversioned(self):
         revision_tree, preview_tree = self.get_tree_and_preview_tree()
         changes = preview_tree.iter_changes(revision_tree,
                                             want_unversioned=True)
- self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))
+ self.assertEqual([A_ENTRY], list(changes))

     def test_ignore_extra_trees_no_specific_files(self):
         # extra_trees is harmless without specific_files, so we'll silently

So that's a consequence of the value now being the same in all trees, therefore it's not detected as changing?

It seems like if we do break any API clients, it might be through side effects of things like this, rather than because they directly care about the is_executable value.

We could try testing the 2.2-related branches or releases with this patch.

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

Aaron told me on irc that he checked this against some core plugins, and found no new failures, so I think we should merge this to 2.2.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bzr'
--- bzr 2010-10-08 10:50:51 +0000
+++ bzr 2010-11-30 03:56:32 +0000
@@ -23,7 +23,11 @@
23import warnings23import warnings
2424
25# update this on each release25# update this on each release
26<<<<<<< TREE
26_script_version = (2, 3, 0)27_script_version = (2, 3, 0)
28=======
29_script_version = (2, 2, 3)
30>>>>>>> MERGE-SOURCE
2731
28try:32try:
29 version_info = sys.version_info33 version_info = sys.version_info
3034
=== modified file 'bzrlib/__init__.py'
--- bzrlib/__init__.py 2010-11-26 15:57:20 +0000
+++ bzrlib/__init__.py 2010-11-30 03:56:32 +0000
@@ -52,7 +52,11 @@
52# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a52# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
53# releaselevel of 'dev' for unreleased under-development code.53# releaselevel of 'dev' for unreleased under-development code.
5454
55<<<<<<< TREE
55version_info = (2, 3, 0, 'dev', 4)56version_info = (2, 3, 0, 'dev', 4)
57=======
58version_info = (2, 2, 3, 'dev', 0)
59>>>>>>> MERGE-SOURCE
5660
57# API compatibility version61# API compatibility version
58api_minimum_version = (2, 3, 0)62api_minimum_version = (2, 3, 0)
5963
=== modified file 'bzrlib/revisiontree.py'
--- bzrlib/revisiontree.py 2010-05-06 23:41:35 +0000
+++ bzrlib/revisiontree.py 2010-11-30 03:56:32 +0000
@@ -110,7 +110,7 @@
110 def is_executable(self, file_id, path=None):110 def is_executable(self, file_id, path=None):
111 ie = self._inventory[file_id]111 ie = self._inventory[file_id]
112 if ie.kind != "file":112 if ie.kind != "file":
113 return None113 return False
114 return ie.executable114 return ie.executable
115115
116 def has_filename(self, filename):116 def has_filename(self, filename):
117117
=== modified file 'bzrlib/tests/per_tree/__init__.py'
--- bzrlib/tests/per_tree/__init__.py 2010-08-21 16:06:24 +0000
+++ bzrlib/tests/per_tree/__init__.py 2010-11-30 03:56:32 +0000
@@ -381,6 +381,7 @@
381 'get_symlink_target',381 'get_symlink_target',
382 'inv',382 'inv',
383 'iter_search_rules',383 'iter_search_rules',
384 'is_executable',
384 'list_files',385 'list_files',
385 'locking',386 'locking',
386 'path_content_summary',387 'path_content_summary',
387388
=== added file 'bzrlib/tests/per_tree/test_is_executable.py'
--- bzrlib/tests/per_tree/test_is_executable.py 1970-01-01 00:00:00 +0000
+++ bzrlib/tests/per_tree/test_is_executable.py 2010-11-30 03:56:32 +0000
@@ -0,0 +1,37 @@
1# Copyright (C) 2010 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17from bzrlib.tests import (
18 per_tree,
19 SymlinkFeature,
20 )
21
22
23class TestIsExecutable(per_tree.TestCaseWithTree):
24
25 def test_is_executable_dir(self):
26 tree = self.get_tree_with_subdirs_and_all_supported_content_types(
27 False)
28 tree.lock_read()
29 self.addCleanup(tree.unlock)
30 self.assertEqual(False, tree.is_executable('1top-dir'))
31
32 def test_is_executable_symlink(self):
33 self.requireFeature(SymlinkFeature)
34 tree = self.get_tree_with_subdirs_and_all_content_types()
35 tree.lock_read()
36 self.addCleanup(tree.unlock)
37 self.assertEqual(False, tree.is_executable('symlink'))
038
=== modified file 'bzrlib/tests/test_transform.py'
--- bzrlib/tests/test_transform.py 2010-11-19 08:34:39 +0000
+++ bzrlib/tests/test_transform.py 2010-11-30 03:56:32 +0000
@@ -2381,7 +2381,7 @@
2381 ('TREE_ROOT', 'TREE_ROOT'), ('a', 'a'), ('file', 'file'),2381 ('TREE_ROOT', 'TREE_ROOT'), ('a', 'a'), ('file', 'file'),
2382 (False, False))2382 (False, False))
2383ROOT_ENTRY = ('TREE_ROOT', ('', ''), False, (True, True), (None, None),2383ROOT_ENTRY = ('TREE_ROOT', ('', ''), False, (True, True), (None, None),
2384 ('', ''), ('directory', 'directory'), (False, None))2384 ('', ''), ('directory', 'directory'), (False, False))
23852385
23862386
2387class TestTransformPreview(tests.TestCaseWithTransport):2387class TestTransformPreview(tests.TestCaseWithTransport):
@@ -2474,13 +2474,13 @@
2474 revision_tree, preview_tree = self.get_tree_and_preview_tree()2474 revision_tree, preview_tree = self.get_tree_and_preview_tree()
2475 changes = preview_tree.iter_changes(revision_tree,2475 changes = preview_tree.iter_changes(revision_tree,
2476 specific_files=[''])2476 specific_files=[''])
2477 self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))2477 self.assertEqual([A_ENTRY], list(changes))
24782478
2479 def test_want_unversioned(self):2479 def test_want_unversioned(self):
2480 revision_tree, preview_tree = self.get_tree_and_preview_tree()2480 revision_tree, preview_tree = self.get_tree_and_preview_tree()
2481 changes = preview_tree.iter_changes(revision_tree,2481 changes = preview_tree.iter_changes(revision_tree,
2482 want_unversioned=True)2482 want_unversioned=True)
2483 self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))2483 self.assertEqual([A_ENTRY], list(changes))
24842484
2485 def test_ignore_extra_trees_no_specific_files(self):2485 def test_ignore_extra_trees_no_specific_files(self):
2486 # extra_trees is harmless without specific_files, so we'll silently2486 # extra_trees is harmless without specific_files, so we'll silently
24872487
=== modified file 'bzrlib/workingtree_4.py'
--- bzrlib/workingtree_4.py 2010-08-03 13:31:06 +0000
+++ bzrlib/workingtree_4.py 2010-11-30 03:56:32 +0000
@@ -1867,7 +1867,7 @@
1867 def is_executable(self, file_id, path=None):1867 def is_executable(self, file_id, path=None):
1868 ie = self.inventory[file_id]1868 ie = self.inventory[file_id]
1869 if ie.kind != "file":1869 if ie.kind != "file":
1870 return None1870 return False
1871 return ie.executable1871 return ie.executable
18721872
1873 def is_locked(self):1873 def is_locked(self):
18741874
=== modified file 'doc/en/release-notes/bzr-2.3.txt'
--- doc/en/release-notes/bzr-2.3.txt 2010-11-29 01:23:53 +0000
+++ doc/en/release-notes/bzr-2.3.txt 2010-11-30 03:56:32 +0000
@@ -5,9 +5,47 @@
5.. toctree::5.. toctree::
6 :maxdepth: 16 :maxdepth: 1
77
8<<<<<<< TREE
8bzr 2.3b49bzr 2.3b4
9#########10=======
1011bzr 2.2.3
12#########
13
14:2.2.3: NOT RELEASED YET
15
16Compatibility Breaks
17********************
18
19New Features
20************
21
22Bug Fixes
23*********
24
25* RevisionTree.is_executable handles directories and symlinks like other types
26 and functions. (Aaron Bentley, #681885)
27
28Improvements
29************
30
31Documentation
32*************
33
34API Changes
35***********
36
37Internals
38*********
39
40Testing
41*******
42
43
44bzr 2.2.2
45>>>>>>> MERGE-SOURCE
46#########
47
48<<<<<<< TREE
11:2.3.b4: NOT RELEASED YET49:2.3.b4: NOT RELEASED YET
1250
13External Compatibility Breaks51External Compatibility Breaks
@@ -42,6 +80,13 @@
42* Read configuration files in $XDG_CONFIG_HOME/bazaar on Unix if there is80* Read configuration files in $XDG_CONFIG_HOME/bazaar on Unix if there is
43 already a directory there. (Neil Martinsen-Burrell, #195397)81 already a directory there. (Neil Martinsen-Burrell, #195397)
4482
83=======
84:2.2.2: 2010-11-25
85
86This is a bugfix release. None of these bugfixes are critical, but upgrading
87is recommended for all users on earlier 2.2 releases.
88
89>>>>>>> MERGE-SOURCE
45Bug Fixes90Bug Fixes
46*********91*********
4792