Rev 5989: Do not generate path conflicts if a corresponding content conflict exists in file:///home/vila/src/bzr/bugs/688101-duplicate-ids/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Tue Jun 21 15:19:18 UTC 2011
At file:///home/vila/src/bzr/bugs/688101-duplicate-ids/
------------------------------------------------------------
revno: 5989
revision-id: v.ladeuil+lp at free.fr-20110621151918-qsr5g8sr66asb58a
parent: pqm at pqm.ubuntu.com-20110620104625-ih5t1e8w288pc4l2
fixes bug(s): https://launchpad.net/bugs/688101
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 688101-duplicate-ids
timestamp: Tue 2011-06-21 17:19:18 +0200
message:
Do not generate path conflicts if a corresponding content conflict exists
-------------- next part --------------
=== modified file 'bzrlib/conflicts.py'
--- a/bzrlib/conflicts.py 2011-06-15 13:21:46 +0000
+++ b/bzrlib/conflicts.py 2011-06-21 15:19:18 +0000
@@ -507,12 +507,11 @@
if path_to_create is not None:
tid = tt.trans_id_tree_path(path_to_create)
transform.create_from_tree(
- tt, tt.trans_id_tree_path(path_to_create),
- self._revision_tree(tt._tree, revid), file_id)
+ tt, tid, self._revision_tree(tt._tree, revid), file_id)
tt.version_file(file_id, tid)
-
+ else:
+ tid = tt.trans_id_file_id(file_id)
# Adjust the path for the retained file id
- tid = tt.trans_id_file_id(file_id)
parent_tid = tt.get_tree_parent(tid)
tt.adjust_path(osutils.basename(path), parent_tid, tid)
tt.apply()
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py 2011-06-13 14:10:13 +0000
+++ b/bzrlib/merge.py 2011-06-21 15:19:18 +0000
@@ -1616,8 +1616,8 @@
def cook_conflicts(self, fs_conflicts):
"""Convert all conflicts into a form that doesn't depend on trans_id"""
- self.cooked_conflicts.extend(transform.cook_conflicts(
- fs_conflicts, self.tt))
+ content_conflict_file_ids = set()
+ cooked_conflicts = transform.cook_conflicts(fs_conflicts, self.tt)
fp = transform.FinalPaths(self.tt)
for conflict in self._raw_conflicts:
conflict_type = conflict[0]
@@ -1653,6 +1653,7 @@
break
c = _mod_conflicts.Conflict.factory(conflict_type,
path=path, file_id=file_id)
+ content_conflict_file_ids.add(file_id)
elif conflict_type == 'text conflict':
trans_id = conflict[1]
path = fp.get_path(trans_id)
@@ -1661,6 +1662,15 @@
path=path, file_id=file_id)
else:
raise AssertionError('bad conflict type: %r' % (conflict,))
+ cooked_conflicts.append(c)
+ # We want to get rid of path conflicts when a corresponding contents
+ # conflict exists. This can occur when one branch deletes a file while
+ # the other renames *and* modifies it. In this case, the content
+ # conflict is enough.
+ for c in cooked_conflicts:
+ if (c.typestring == 'path conflict'
+ and c.file_id in content_conflict_file_ids):
+ continue
self.cooked_conflicts.append(c)
self.cooked_conflicts.sort(key=_mod_conflicts.Conflict.sort_key)
=== modified file 'bzrlib/tests/test_conflicts.py'
--- a/bzrlib/tests/test_conflicts.py 2011-05-21 16:29:38 +0000
+++ b/bzrlib/tests/test_conflicts.py 2011-06-21 15:19:18 +0000
@@ -446,6 +446,14 @@
dict(actions='modify_file', check='file_has_more_content')),
('file_deleted',
dict(actions='delete_file', check='file_doesnt_exist')),),
+ # File renamed-modified/deleted
+ (dict(_base_actions='create_file',
+ _path='new-file', _file_id='file-id'),
+ ('file_renamed_and_modified',
+ dict(actions='modify_and_rename_file',
+ check='file_renamed_and_more_content')),
+ ('file_deleted',
+ dict(actions='delete_file', check='file_doesnt_exist')),),
# File modified/deleted in dir
(dict(_base_actions='create_file_in_dir',
_path='dir/file', _file_id='file-id'),
@@ -463,9 +471,16 @@
def do_modify_file(self):
return [('modify', ('file-id', 'trunk content\nmore content\n'))]
+ def do_modify_and_rename_file(self):
+ return [('modify', ('file-id', 'trunk content\nmore content\n')),
+ ('rename', ('file', 'new-file'))]
+
def check_file_has_more_content(self):
self.assertFileEqual('trunk content\nmore content\n', 'branch/file')
+ def check_file_renamed_and_more_content(self):
+ self.assertFileEqual('trunk content\nmore content\n', 'branch/new-file')
+
def do_delete_file(self):
return [('unversion', 'file-id')]
=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py 2011-06-13 16:25:08 +0000
+++ b/bzrlib/transform.py 2011-06-21 15:19:18 +0000
@@ -32,6 +32,7 @@
bencode,
bzrdir,
commit,
+ conflicts,
delta,
errors,
inventory,
@@ -3156,13 +3157,11 @@
def cook_conflicts(raw_conflicts, tt):
"""Generate a list of cooked conflicts, sorted by file path"""
- from bzrlib.conflicts import Conflict
conflict_iter = iter_cook_conflicts(raw_conflicts, tt)
- return sorted(conflict_iter, key=Conflict.sort_key)
+ return sorted(conflict_iter, key=conflicts.Conflict.sort_key)
def iter_cook_conflicts(raw_conflicts, tt):
- from bzrlib.conflicts import Conflict
fp = FinalPaths(tt)
for conflict in raw_conflicts:
c_type = conflict[0]
@@ -3170,16 +3169,17 @@
modified_path = fp.get_path(conflict[2])
modified_id = tt.final_file_id(conflict[2])
if len(conflict) == 3:
- yield Conflict.factory(c_type, action=action, path=modified_path,
- file_id=modified_id)
+ yield conflicts.Conflict.factory(
+ c_type, action=action, path=modified_path, file_id=modified_id)
else:
conflicting_path = fp.get_path(conflict[3])
conflicting_id = tt.final_file_id(conflict[3])
- yield Conflict.factory(c_type, action=action, path=modified_path,
- file_id=modified_id,
- conflict_path=conflicting_path,
- conflict_file_id=conflicting_id)
+ yield conflicts.Conflict.factory(
+ c_type, action=action, path=modified_path,
+ file_id=modified_id,
+ conflict_path=conflicting_path,
+ conflict_file_id=conflicting_id)
class _FileMover(object):
=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt 2011-06-20 09:31:17 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt 2011-06-21 15:19:18 +0000
@@ -29,6 +29,10 @@
Bug Fixes
*********
+* Generate a single conflict (instead of two) when merging a branch
+ modifying and renaming a file in a branch that deleted it (or vice-versa).
+ (Vincent Ladeuil, #688101)
+
* Properly load utf8-encoded config files. (Vincent Ladeuil, #799212)
.. Fixes for situations where bzr would previously crash or give incorrect
More information about the bazaar-commits
mailing list