Rev 5017: ``bzr add`` won't blindly add conflict related files. in file:///home/vila/src/bzr/bugs/322767-dont-add-conflict-related-files/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Mon Feb 8 16:36:13 GMT 2010
At file:///home/vila/src/bzr/bugs/322767-dont-add-conflict-related-files/
------------------------------------------------------------
revno: 5017
revision-id: v.ladeuil+lp at free.fr-20100208163613-9sgl3ugvdxapwgw8
parent: v.ladeuil+lp at free.fr-20100208104948-jylpbzqlqyg6we1e
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 322767-dont-add-conflict-related-files
timestamp: Mon 2010-02-08 17:36:13 +0100
message:
``bzr add`` won't blindly add conflict related files.
* bzrlib/tests/per_workingtree/test_smart_add.py:
(TestSmartAddConflictRelatedFiles): Make sure we don't add blindly
but that we can add on demand.
* bzrlib/mutabletree.py:
(MutableTree.smart_add): Check that we don't, implicitly, add a
file generated to help resolve a conflict.
* bzrlib/conflicts.py:
(Conflict.associated_filenames): New helper.
(Conflict.cleanup): Use the helper to reduce duplication.
(PathConflict, ContentsConflict, TextConflict, HandledConflict):
Define associated_filenames instead of cleanup.
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2010-02-07 10:51:26 +0000
+++ b/NEWS 2010-02-08 16:36:13 +0000
@@ -36,6 +36,9 @@
* Avoid infinite recursion when probing for apport.
(Vincent Ladeuil, #516934)
+* ``bzr add`` will not add conflict related files unless explicitly required.
+ (Vincent Ladeuil, #322767)
+
Testing
*******
=== modified file 'bzrlib/conflicts.py'
--- a/bzrlib/conflicts.py 2010-02-05 10:27:33 +0000
+++ b/bzrlib/conflicts.py 2010-02-08 16:36:13 +0000
@@ -412,8 +412,17 @@
raise NotImplementedError(self.__class__.__name__ + '.' + action)
meth(tree)
+ def associated_filenames(self):
+ """The names of the files generated to help resolve the conflict."""
+ raise NotImplementedError(self.associated_filenames)
+
def cleanup(self, tree):
- raise NotImplementedError(self.cleanup)
+ for fname in self.associated_filenames():
+ try:
+ osutils.delete_any(tree.abspath(fname))
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
def action_done(self, tree):
"""Mark the conflict as solved once it has been handled."""
@@ -446,9 +455,9 @@
s.add('conflict_path', self.conflict_path)
return s
- def cleanup(self, tree):
+ def associated_filenames(self):
# No additional files have been generated here
- pass
+ return []
def action_take_this(self, tree):
tree.rename_one(self.conflict_path, self.path)
@@ -467,13 +476,8 @@
format = 'Contents conflict in %(path)s'
- def cleanup(self, tree):
- for suffix in ('.BASE', '.OTHER'):
- try:
- osutils.delete_any(tree.abspath(self.path + suffix))
- except OSError, e:
- if e.errno != errno.ENOENT:
- raise
+ def associated_filenames(self):
+ return [self.path + suffix for suffix in ('.BASE', '.OTHER')]
# FIXME: I smell something weird here and it seems we should be able to be
# more coherent with some other conflict ? bzr *did* a choice there but
@@ -501,13 +505,8 @@
format = 'Text conflict in %(path)s'
- def cleanup(self, tree):
- for suffix in CONFLICT_SUFFIXES:
- try:
- osutils.delete_any(tree.abspath(self.path+suffix))
- except OSError, e:
- if e.errno != errno.ENOENT:
- raise
+ def associated_filenames(self):
+ return [self.path + suffix for suffix in CONFLICT_SUFFIXES]
class HandledConflict(Conflict):
@@ -529,9 +528,9 @@
s.add('action', self.action)
return s
- def cleanup(self, tree):
- """Nothing to cleanup."""
- pass
+ def associated_filenames(self):
+ # Nothing has been generated here
+ return []
class HandledPathConflict(HandledConflict):
=== modified file 'bzrlib/mutabletree.py'
--- a/bzrlib/mutabletree.py 2009-10-06 14:40:37 +0000
+++ b/bzrlib/mutabletree.py 2010-02-08 16:36:13 +0000
@@ -380,6 +380,8 @@
if not file_list:
# no paths supplied: add the entire tree.
+ # FIXME: this assumes we are running in a working tree subdir :-/
+ # -- vila 20100208
file_list = [u'.']
# mutter("smart add of %r")
inv = self.inventory
@@ -387,6 +389,14 @@
ignored = {}
dirs_to_add = []
user_dirs = set()
+ conflicts_related = []
+ # Not all mutable trees can have conflicts
+ if getattr(self, 'conflicts', None) is not None:
+ # Collect all related files without checking whether they exist or
+ # are versioned. It's cheaper to do that once for all conflicts
+ # than trying to find the relevant conflict for each added file.
+ for c in self.conflicts():
+ conflicts_related.extend(c.associated_filenames())
# validate user file paths and convert all paths to tree
# relative : it's cheaper to make a tree relative path an abspath
@@ -453,6 +463,13 @@
if illegalpath_re.search(directory.raw_path):
trace.warning("skipping %r (contains \\n or \\r)" % abspath)
continue
+ if directory.raw_path in conflicts_related:
+ # If the file looks like one generated for a conflict, don't
+ # add it.
+ trace.warning(
+ 'skipping %s (generated to help resolve conflicts)',
+ abspath)
+ continue
if parent_ie is not None:
versioned = directory.base_path in parent_ie.children
=== modified file 'bzrlib/tests/per_workingtree/test_smart_add.py'
--- a/bzrlib/tests/per_workingtree/test_smart_add.py 2010-02-08 10:49:48 +0000
+++ b/bzrlib/tests/per_workingtree/test_smart_add.py 2010-02-08 16:36:13 +0000
@@ -227,6 +227,36 @@
in wt.inventory.iter_entries()])
+class TestSmartAddConflictRelatedFiles(per_workingtree.TestCaseWithWorkingTree):
+
+ def make_tree_with_text_conflict(self):
+ tb = self.make_branch_and_tree('base')
+ self.build_tree_contents([('base/file', 'content in base')])
+ tb.add('file')
+ tb.commit('Adding file')
+
+ t1 = tb.bzrdir.sprout('t1').open_workingtree()
+
+ self.build_tree_contents([('base/file', 'content changed in base')])
+ tb.commit('Changing file in base')
+
+ self.build_tree_contents([('t1/file', 'content in t1')])
+ t1.commit('Changing file in t1')
+ t1.merge_from_branch(tb.branch)
+ return t1
+
+ def test_cant_add_generated_files_implicitly(self):
+ t = self.make_tree_with_text_conflict()
+ added, ignored = t.smart_add([t.basedir])
+ self.assertEqual(([], {}), (added, ignored))
+
+ def test_can_add_generated_files_explicitly(self):
+ fnames = ['file.%s' % s for s in ('BASE', 'THIS', 'OTHER')]
+ t = self.make_tree_with_text_conflict()
+ added, ignored = t.smart_add([t.basedir + '/%s' % f for f in fnames])
+ self.assertEqual((fnames, {}), (added, ignored))
+
+
class TestSmartAddTreeUnicode(per_workingtree.TestCaseWithWorkingTree):
_test_needs_features = [tests.UnicodeFilenameFeature]
More information about the bazaar-commits
mailing list