~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge_core.py

MergeĀ fromĀ martin

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
import changeset
4
4
from changeset import Inventory, apply_changeset, invert_dict
5
 
from bzrlib.osutils import backup_file, rename
 
5
from bzrlib.osutils import backup_file, rename, pathjoin
6
6
from bzrlib.merge3 import Merge3
7
7
import bzrlib
8
8
from bzrlib.atomicfile import AtomicFile
9
9
from changeset import get_contents
10
10
 
 
11
 
11
12
class ApplyMerge3:
 
13
    """Contents-change wrapper around merge3.Merge3"""
 
14
 
12
15
    history_based = False
13
 
    """Contents-change wrapper around merge3.Merge3"""
 
16
 
14
17
    def __init__(self, file_id, base, other, show_base=False, reprocess=False):
15
18
        self.file_id = file_id
16
19
        self.base = base
33
36
    def __ne__(self, other):
34
37
        return not (self == other)
35
38
 
36
 
    def apply(self, filename, conflict_handler, reverse=False):
 
39
    def apply(self, filename, conflict_handler):
37
40
        new_file = filename+".new" 
38
 
        if not reverse:
39
 
            base = self.base
40
 
            other = self.other
41
 
        else:
42
 
            base = self.other
43
 
            other = self.base
 
41
        base = self.base
 
42
        other = self.other
44
43
        def get_lines(tree):
45
44
            if self.file_id not in tree:
46
45
                raise Exception("%s not in tree" % self.file_id)
75
74
            conflict_handler.merge_conflict(new_file, filename, base_lines,
76
75
                                            other_lines)
77
76
 
 
77
 
78
78
class WeaveMerge:
79
79
    """Contents-change wrapper around weave merge"""
 
80
 
80
81
    history_based = True
 
82
 
81
83
    def __init__(self, weave, this_revision_id, other_revision_id):
82
84
        self.weave = weave
83
85
        self.this_revision_id = this_revision_id
99
101
    def __ne__(self, other):
100
102
        return not (self == other)
101
103
 
102
 
    def apply(self, filename, conflict_handler, reverse=False):
 
104
    def apply(self, filename, conflict_handler):
103
105
        this_i = self.weave.lookup(self.this_revision_id)
104
106
        other_i = self.weave.lookup(self.other_revision_id)
105
107
        plan = self.weave.plan_merge(this_i, other_i)
116
118
        else:
117
119
            out_file.commit()
118
120
 
 
121
 
119
122
class BackupBeforeChange:
120
123
    """Contents-change wrapper to back up file first"""
 
124
 
121
125
    def __init__(self, contents_change):
122
126
        self.contents_change = contents_change
123
127
 
135
139
    def __ne__(self, other):
136
140
        return not (self == other)
137
141
 
138
 
    def apply(self, filename, conflict_handler, reverse=False):
 
142
    def apply(self, filename, conflict_handler):
139
143
        backup_file(filename)
140
 
        self.contents_change.apply(filename, conflict_handler, reverse)
 
144
        self.contents_change.apply(filename, conflict_handler)
141
145
 
142
146
 
143
147
def invert_invent(inventory):
158
162
    new_cset = make_merge_changeset(cset, this, base, other, 
159
163
                                    conflict_handler, merge_factory)
160
164
    result = apply_changeset(new_cset, invert_invent(this.inventory),
161
 
                             this.basedir, conflict_handler, False)
 
165
                             this.basedir, conflict_handler)
162
166
    return result
163
167
    
164
168
 
181
185
 
182
186
    return new_cset
183
187
 
 
188
 
184
189
class ThreeWayConflict(Exception):
185
190
    def __init__(self, this, base, other):
186
191
        self.this = this
189
194
        msg = "Conflict merging %s %s and %s" % (this, base, other)
190
195
        Exception.__init__(self, msg)
191
196
 
 
197
 
192
198
def threeway_select(this, base, other):
193
199
    """Returns a value selected by the three-way algorithm.
194
200
    Raises ThreewayConflict if the algorithm yields a conflict"""
239
245
            parent_dir = {this_parent: this_dir, other_parent: other_dir, 
240
246
                          base_parent: base_dir}
241
247
            directory = parent_dir[parent]
242
 
            return os.path.join(directory, name)
 
248
            return pathjoin(directory, name)
243
249
        else:
244
250
            assert parent is None
245
251
            return None
329
335
        self.other_tree = other_tree
330
336
        self.file_id = file_id
331
337
 
332
 
    def apply(self, filename, conflict_handler, reverse=False):
333
 
        if not reverse:
334
 
            base = self.base_tree
335
 
            other = self.other_tree
336
 
        else:
337
 
            base = self.other_tree
338
 
            other = self.base_tree
 
338
    def apply(self, filename, conflict_handler):
 
339
        base = self.base_tree
 
340
        other = self.other_tree
339
341
        base_exec_flag = base.is_executable(self.file_id)
340
342
        other_exec_flag = other.is_executable(self.file_id)
341
343
        this_mode = os.stat(filename).st_mode
357
359
                to_mode = current_mode & ~0111
358
360
            os.chmod(filename, to_mode)
359
361
 
 
362