/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/conflicts.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-11-16 18:33:33 UTC
  • mfrom: (2138.1.1 robuster.external.diff)
  • Revision ID: pqm@pqm.ubuntu.com-20061116183333-5f56523d7b44e564
(Dmitry Vasiliev) Robuster external diff output handling.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Aaron Bentley
2
 
 
 
1
# Copyright (C) 2005 Aaron Bentley, Canonical Ltd
 
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(), """
23
26
import errno
24
27
 
25
 
import bzrlib
26
 
from bzrlib.commands import register_command
27
 
from bzrlib.errors import BzrCommandError, NotConflicted, UnsupportedOperation
 
28
from bzrlib import (
 
29
    commands,
 
30
    errors,
 
31
    osutils,
 
32
    rio,
 
33
    )
 
34
""")
28
35
from bzrlib.option import Option
29
 
from bzrlib.osutils import rename, delete_any
30
 
from bzrlib.rio import Stanza
31
36
 
32
37
 
33
38
CONFLICT_SUFFIXES = ('.THIS', '.BASE', '.OTHER')
34
39
 
35
40
 
36
 
class cmd_conflicts(bzrlib.commands.Command):
 
41
class cmd_conflicts(commands.Command):
37
42
    """List files with conflicts.
38
43
 
39
44
    Merge will do its best to combine the changes in two branches, but there
55
60
            print conflict
56
61
 
57
62
 
58
 
class cmd_resolve(bzrlib.commands.Command):
 
63
class cmd_resolve(commands.Command):
59
64
    """Mark a conflict as resolved.
60
65
 
61
66
    Merge will do its best to combine the changes in two branches, but there
76
81
        from bzrlib.workingtree import WorkingTree
77
82
        if all:
78
83
            if file_list:
79
 
                raise BzrCommandError("If --all is specified, no FILE may be provided")
 
84
                raise errors.BzrCommandError("If --all is specified,"
 
85
                                             " no FILE may be provided")
80
86
            tree = WorkingTree.open_containing('.')[0]
81
87
            resolve(tree)
82
88
        else:
83
89
            if file_list is None:
84
 
                raise BzrCommandError("command 'resolve' needs one or more FILE, or --all")
 
90
                raise errors.BzrCommandError("command 'resolve' needs one or"
 
91
                                             " more FILE, or --all")
85
92
            tree = WorkingTree.open_containing(file_list[0])[0]
86
93
            to_resolve = [tree.relpath(p) for p in file_list]
87
94
            resolve(tree, to_resolve)
88
95
 
89
96
 
90
97
def resolve(tree, paths=None, ignore_misses=False):
91
 
    tree.lock_write()
 
98
    tree.lock_tree_write()
92
99
    try:
93
100
        tree_conflicts = tree.conflicts()
94
101
        if paths is None:
99
106
                tree_conflicts.select_conflicts(tree, paths, ignore_misses)
100
107
        try:
101
108
            tree.set_conflicts(new_conflicts)
102
 
        except UnsupportedOperation:
 
109
        except errors.UnsupportedOperation:
103
110
            pass
104
111
        selected_conflicts.remove_files(tree)
105
112
    finally:
113
120
    """
114
121
    conflicted = False
115
122
    try:
116
 
        rename(filename + ".THIS", filename)
 
123
        osutils.rename(filename + ".THIS", filename)
117
124
        conflicted = True
118
125
    except OSError, e:
119
126
        if e.errno != errno.ENOENT:
131
138
        if e.errno != errno.ENOENT:
132
139
            raise
133
140
    if not conflicted:
134
 
        raise NotConflicted(filename)
 
141
        raise errors.NotConflicted(filename)
135
142
 
136
143
 
137
144
class ConflictList(object):
198
205
                continue
199
206
            for suffix in CONFLICT_SUFFIXES:
200
207
                try:
201
 
                    delete_any(tree.abspath(conflict.path+suffix))
 
208
                    osutils.delete_any(tree.abspath(conflict.path+suffix))
202
209
                except OSError, e:
203
210
                    if e.errno != errno.ENOENT:
204
211
                        raise
207
214
        """Select the conflicts associated with paths in a tree.
208
215
        
209
216
        File-ids are also used for this.
 
217
        :return: a pair of ConflictLists: (not_selected, selected)
210
218
        """
211
219
        path_set = set(paths)
212
220
        ids = {}
260
268
        self.file_id = file_id
261
269
 
262
270
    def as_stanza(self):
263
 
        s = Stanza(type=self.typestring, path=self.path)
 
271
        s = rio.Stanza(type=self.typestring, path=self.path)
264
272
        if self.file_id is not None:
265
273
            s.add('file_id', self.file_id)
266
274
        return s
273
281
            return -1
274
282
        return cmp(self._cmp_list(), other._cmp_list())
275
283
 
 
284
    def __hash__(self):
 
285
        return hash((type(self), self.path, self.file_id))
 
286
 
276
287
    def __eq__(self, other):
277
288
        return self.__cmp__(other) == 0
278
289
 
292
303
        global ctype
293
304
        return ctype[type](**kwargs)
294
305
 
 
306
    @staticmethod
 
307
    def sort_key(conflict):
 
308
        if conflict.path is not None:
 
309
            return conflict.path, conflict.typestring
 
310
        elif getattr(conflict, "conflict_path", None) is not None:
 
311
            return conflict.conflict_path, conflict.typestring
 
312
        else:
 
313
            return None, conflict.typestring
 
314
 
295
315
 
296
316
class PathConflict(Conflict):
297
317
    """A conflict was encountered merging file paths"""
419
439
 
420
440
    typestring = 'unversioned parent'
421
441
 
422
 
    format = 'Conflict adding versioned files to %(path)s.  %(action)s.'
 
442
    format = 'Conflict because %(path)s is not versioned, but has versioned'\
 
443
             ' children.  %(action)s.'
423
444
 
424
445
 
425
446
class MissingParent(HandledConflict):
426
447
    """An attempt to add files to a directory that is not present.
427
 
    Typically, the result of a merge where one tree deleted the directory and
428
 
    the other added a file to it.
 
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)
429
451
    """
430
452
 
431
453
    typestring = 'missing parent'
433
455
    format = 'Conflict adding files to %(path)s.  %(action)s.'
434
456
 
435
457
 
 
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
 
436
469
 
437
470
ctype = {}
438
471
 
445
478
 
446
479
 
447
480
register_types(ContentsConflict, TextConflict, PathConflict, DuplicateID,
448
 
               DuplicateEntry, ParentLoop, UnversionedParent, MissingParent,)
 
481
               DuplicateEntry, ParentLoop, UnversionedParent, MissingParent,
 
482
               DeletingParent,)