~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/conflicts.py

Optimize common case where unique_lcs returns a set of lines all in a row

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Aaron Bentley, Canonical Ltd
2
 
#
 
1
# Copyright (C) 2005 by Aaron Bentley
 
2
 
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
#
 
7
 
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
#
 
12
 
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
20
# point down
21
21
 
22
22
import os
23
 
 
24
 
from bzrlib.lazy_import import lazy_import
25
 
lazy_import(globals(), """
26
23
import errno
27
24
 
28
 
from bzrlib import (
29
 
    commands,
30
 
    errors,
31
 
    osutils,
32
 
    rio,
33
 
    )
34
 
""")
 
25
import bzrlib
 
26
from bzrlib.commands import register_command
 
27
from bzrlib.errors import BzrCommandError, NotConflicted, UnsupportedOperation
35
28
from bzrlib.option import Option
 
29
from bzrlib.osutils import rename, delete_any
 
30
from bzrlib.rio import Stanza
36
31
 
37
32
 
38
33
CONFLICT_SUFFIXES = ('.THIS', '.BASE', '.OTHER')
39
34
 
40
35
 
41
 
class cmd_conflicts(commands.Command):
 
36
class cmd_conflicts(bzrlib.commands.Command):
42
37
    """List files with conflicts.
43
38
 
44
39
    Merge will do its best to combine the changes in two branches, but there
60
55
            print conflict
61
56
 
62
57
 
63
 
class cmd_resolve(commands.Command):
 
58
class cmd_resolve(bzrlib.commands.Command):
64
59
    """Mark a conflict as resolved.
65
60
 
66
61
    Merge will do its best to combine the changes in two branches, but there
81
76
        from bzrlib.workingtree import WorkingTree
82
77
        if all:
83
78
            if file_list:
84
 
                raise errors.BzrCommandError("If --all is specified,"
85
 
                                             " no FILE may be provided")
 
79
                raise BzrCommandError("If --all is specified, no FILE may be provided")
86
80
            tree = WorkingTree.open_containing('.')[0]
87
81
            resolve(tree)
88
82
        else:
89
83
            if file_list is None:
90
 
                raise errors.BzrCommandError("command 'resolve' needs one or"
91
 
                                             " more FILE, or --all")
 
84
                raise BzrCommandError("command 'resolve' needs one or more FILE, or --all")
92
85
            tree = WorkingTree.open_containing(file_list[0])[0]
93
86
            to_resolve = [tree.relpath(p) for p in file_list]
94
87
            resolve(tree, to_resolve)
95
88
 
96
89
 
97
90
def resolve(tree, paths=None, ignore_misses=False):
98
 
    tree.lock_tree_write()
 
91
    tree.lock_write()
99
92
    try:
100
93
        tree_conflicts = tree.conflicts()
101
94
        if paths is None:
106
99
                tree_conflicts.select_conflicts(tree, paths, ignore_misses)
107
100
        try:
108
101
            tree.set_conflicts(new_conflicts)
109
 
        except errors.UnsupportedOperation:
 
102
        except UnsupportedOperation:
110
103
            pass
111
104
        selected_conflicts.remove_files(tree)
112
105
    finally:
120
113
    """
121
114
    conflicted = False
122
115
    try:
123
 
        osutils.rename(filename + ".THIS", filename)
 
116
        rename(filename + ".THIS", filename)
124
117
        conflicted = True
125
118
    except OSError, e:
126
119
        if e.errno != errno.ENOENT:
138
131
        if e.errno != errno.ENOENT:
139
132
            raise
140
133
    if not conflicted:
141
 
        raise errors.NotConflicted(filename)
 
134
        raise NotConflicted(filename)
142
135
 
143
136
 
144
137
class ConflictList(object):
205
198
                continue
206
199
            for suffix in CONFLICT_SUFFIXES:
207
200
                try:
208
 
                    osutils.delete_any(tree.abspath(conflict.path+suffix))
 
201
                    delete_any(tree.abspath(conflict.path+suffix))
209
202
                except OSError, e:
210
203
                    if e.errno != errno.ENOENT:
211
204
                        raise
214
207
        """Select the conflicts associated with paths in a tree.
215
208
        
216
209
        File-ids are also used for this.
217
 
        :return: a pair of ConflictLists: (not_selected, selected)
218
210
        """
219
211
        path_set = set(paths)
220
212
        ids = {}
268
260
        self.file_id = file_id
269
261
 
270
262
    def as_stanza(self):
271
 
        s = rio.Stanza(type=self.typestring, path=self.path)
 
263
        s = Stanza(type=self.typestring, path=self.path)
272
264
        if self.file_id is not None:
273
265
            s.add('file_id', self.file_id)
274
266
        return s
281
273
            return -1
282
274
        return cmp(self._cmp_list(), other._cmp_list())
283
275
 
284
 
    def __hash__(self):
285
 
        return hash((type(self), self.path, self.file_id))
286
 
 
287
276
    def __eq__(self, other):
288
277
        return self.__cmp__(other) == 0
289
278
 
439
428
 
440
429
    typestring = 'unversioned parent'
441
430
 
442
 
    format = 'Conflict because %(path)s is not versioned, but has versioned'\
443
 
             ' children.  %(action)s.'
 
431
    format = 'Conflict adding versioned files to %(path)s.  %(action)s.'
444
432
 
445
433
 
446
434
class MissingParent(HandledConflict):
447
435
    """An attempt to add files to a directory that is not present.
448
 
    Typically, the result of a merge where THIS deleted the directory and
449
 
    the OTHER added a file to it.
450
 
    See also: DeletingParent (same situation, reversed THIS and OTHER)
 
436
    Typically, the result of a merge where one tree deleted the directory and
 
437
    the other added a file to it.
451
438
    """
452
439
 
453
440
    typestring = 'missing parent'
455
442
    format = 'Conflict adding files to %(path)s.  %(action)s.'
456
443
 
457
444
 
458
 
class DeletingParent(HandledConflict):
459
 
    """An attempt to add files to a directory that is not present.
460
 
    Typically, the result of a merge where one OTHER deleted the directory and
461
 
    the THIS added a file to it.
462
 
    """
463
 
 
464
 
    typestring = 'deleting parent'
465
 
 
466
 
    format = "Conflict: can't delete %(path)s because it is not empty.  "\
467
 
             "%(action)s."
468
 
 
469
445
 
470
446
ctype = {}
471
447
 
478
454
 
479
455
 
480
456
register_types(ContentsConflict, TextConflict, PathConflict, DuplicateID,
481
 
               DuplicateEntry, ParentLoop, UnversionedParent, MissingParent,
482
 
               DeletingParent,)
 
457
               DuplicateEntry, ParentLoop, UnversionedParent, MissingParent,)