~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: Aaron Bentley
  • Date: 2005-09-29 21:07:17 UTC
  • mfrom: (1393.1.6)
  • mto: (1185.25.1)
  • mto: This revision was merged to the branch mainline in revision 1419.
  • Revision ID: abentley@panoramicfeedback.com-20050929210717-cd73981590f17017
Merged the weave changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
import os.path
 
18
import os
19
19
import tempfile
20
20
import shutil
21
21
import errno
22
 
from fetch import greedy_fetch
23
22
 
24
23
import bzrlib.osutils
25
24
import bzrlib.revision
26
25
from bzrlib.merge_core import merge_flex, ApplyMerge3, BackupBeforeChange
27
26
from bzrlib.changeset import generate_changeset, ExceptionConflictHandler
28
 
from bzrlib.changeset import Inventory, Diff3Merge
29
 
from bzrlib.branch import find_branch
30
 
from bzrlib.errors import BzrCommandError, UnrelatedBranches
 
27
from bzrlib.changeset import Inventory, Diff3Merge, ReplaceContents
 
28
from bzrlib.branch import Branch
 
29
from bzrlib.errors import BzrCommandError, UnrelatedBranches, NoCommonAncestor
 
30
from bzrlib.errors import NoCommits
31
31
from bzrlib.delta import compare_trees
32
32
from bzrlib.trace import mutter, warning
33
 
from bzrlib.fetch import greedy_fetch
 
33
from bzrlib.fetch import greedy_fetch, fetch
34
34
from bzrlib.revision import is_ancestor
 
35
from bzrlib.osutils import rename
 
36
from bzrlib.revision import common_ancestor, MultipleRevisionSources
 
37
from bzrlib.errors import NoSuchRevision
 
38
 
35
39
 
36
40
# comments from abentley on irc: merge happens in two stages, each
37
41
# of which generates a changeset object
46
50
    conflict that are not explicitly handled cause an exception and
47
51
    terminate the merge.
48
52
    """
49
 
    def __init__(self, dir, ignore_zero=False):
50
 
        ExceptionConflictHandler.__init__(self, dir)
 
53
    def __init__(self, ignore_zero=False):
 
54
        ExceptionConflictHandler.__init__(self)
51
55
        self.conflicts = 0
52
56
        self.ignore_zero = ignore_zero
53
57
 
83
87
            last_new_name = name
84
88
        new_name = last_new_name+suffix
85
89
        try:
86
 
            os.rename(name, new_name)
 
90
            rename(name, new_name)
87
91
            return new_name
88
92
        except OSError, e:
89
93
            if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY:
107
111
        self.add_suffix(this_path, ".THIS")
108
112
        self.dump(base_lines, this_path+".BASE")
109
113
        self.dump(other_lines, this_path+".OTHER")
110
 
        os.rename(new_file, this_path)
 
114
        rename(new_file, this_path)
111
115
        self.conflict("Diff3 conflict encountered in %s" % this_path)
112
116
 
113
117
    def new_contents_conflict(self, filename, other_contents):
127
131
            % filename)
128
132
        return "skip"
129
133
 
 
134
    def rem_contents_conflict(self, filename, this_contents, base_contents):
 
135
        base_contents(filename+".BASE", self, False)
 
136
        this_contents(filename+".THIS", self, False)
 
137
        return ReplaceContents(this_contents, None)
 
138
 
130
139
    def finalize(self):
131
140
        if not self.ignore_zero:
132
141
            print "%d conflicts encountered.\n" % self.conflicts
133
142
            
134
143
def get_tree(treespec, temp_root, label, local_branch=None):
135
144
    location, revno = treespec
136
 
    branch = find_branch(location)
 
145
    branch = Branch.open_containing(location)
137
146
    if revno is None:
138
147
        revision = None
139
148
    elif revno == -1:
140
 
        revision = branch.last_patch()
 
149
        revision = branch.last_revision()
141
150
    else:
142
 
        revision = branch.lookup_revision(revno)
 
151
        revision = branch.get_rev_id(revno)
143
152
    return branch, get_revid_tree(branch, revision, temp_root, label,
144
153
                                  local_branch)
145
154
 
234
243
    check_clean
235
244
        If true, this_dir must have no uncommitted changes before the
236
245
        merge begins.
237
 
    all available ancestors of other_revision and base_revision are
 
246
 
 
247
    All available ancestors of other_revision and base_revision are
238
248
    automatically pulled into the branch.
239
249
    """
240
 
    from bzrlib.revision import common_ancestor, MultipleRevisionSources
241
 
    from bzrlib.errors import NoSuchRevision
242
250
    tempdir = tempfile.mkdtemp(prefix="bzr-")
243
251
    try:
244
252
        if this_dir is None:
245
253
            this_dir = '.'
246
 
        this_branch = find_branch(this_dir)
247
 
        this_rev_id = this_branch.last_patch()
 
254
        this_branch = Branch.open_containing(this_dir)
 
255
        this_rev_id = this_branch.last_revision()
248
256
        if this_rev_id is None:
249
257
            raise BzrCommandError("This branch has no commits")
250
258
        if check_clean:
255
263
        other_branch, other_tree = get_tree(other_revision, tempdir, "other",
256
264
                                            this_branch)
257
265
        if other_revision[1] == -1:
258
 
            other_rev_id = other_branch.last_patch()
 
266
            other_rev_id = other_branch.last_revision()
 
267
            if other_rev_id is None:
 
268
                raise NoCommits(other_branch)
259
269
            other_basis = other_rev_id
260
270
        elif other_revision[1] is not None:
261
 
            other_rev_id = other_branch.lookup_revision(other_revision[1])
 
271
            other_rev_id = other_branch.get_rev_id(other_revision[1])
262
272
            other_basis = other_rev_id
263
273
        else:
264
274
            other_rev_id = None
265
 
            other_basis = other_branch.last_patch()
 
275
            other_basis = other_branch.last_revision()
 
276
            if other_basis is None:
 
277
                raise NoCommits(other_branch)
266
278
        if base_revision == [None, None]:
267
 
            base_rev_id = common_ancestor(this_rev_id, other_basis, 
268
 
                                          this_branch)
269
 
            if base_rev_id is None:
 
279
            try:
 
280
                base_rev_id = common_ancestor(this_rev_id, other_basis, 
 
281
                                              this_branch)
 
282
            except NoCommonAncestor:
270
283
                raise UnrelatedBranches()
271
284
            base_tree = get_revid_tree(this_branch, base_rev_id, tempdir, 
272
285
                                       "base", None)
274
287
        else:
275
288
            base_branch, base_tree = get_tree(base_revision, tempdir, "base")
276
289
            if base_revision[1] == -1:
277
 
                base_rev_id = base_branch.last_patch()
 
290
                base_rev_id = base_branch.last_revision()
278
291
            elif base_revision[1] is None:
279
292
                base_rev_id = None
280
293
            else:
281
 
                base_rev_id = base_branch.lookup_revision(base_revision[1])
282
 
            if base_rev_id is not None:
283
 
                base_is_ancestor = is_ancestor(this_rev_id, base_rev_id, 
284
 
                                               MultipleRevisionSources(this_branch, 
285
 
                                                                       base_branch))
286
 
            else:
287
 
                base_is_ancestor = False
 
294
                base_rev_id = base_branch.get_rev_id(base_revision[1])
 
295
            fetch(from_branch=base_branch, to_branch=this_branch)
 
296
            base_is_ancestor = is_ancestor(this_rev_id, base_rev_id,
 
297
                                           this_branch)
288
298
        if file_list is None:
289
299
            interesting_ids = None
290
300
        else:
346
356
 
347
357
    inv_changes = merge_flex(this_tree, base_tree, other_tree,
348
358
                             generate_cset_optimized, get_inventory,
349
 
                             MergeConflictHandler(base_tree.root,
350
 
                                                  ignore_zero=ignore_zero),
 
359
                             MergeConflictHandler(ignore_zero=ignore_zero),
351
360
                             merge_factory=merge_factory, 
352
361
                             interesting_ids=interesting_ids)
353
362
 
357
366
            if path == '.':
358
367
                path = ''
359
368
            else:
360
 
                assert path.startswith('./'), "path is %s" % path
 
369
                assert path.startswith('.' + os.sep), "path is %s" % path
361
370
            path = path[2:]
362
371
        adjust_ids.append((path, id))
363
372
    if len(adjust_ids) > 0: