~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/conflicts.py

  • Committer: Aaron Bentley
  • Date: 2007-02-06 14:52:16 UTC
  • mfrom: (2266 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2268.
  • Revision ID: abentley@panoramicfeedback.com-20070206145216-fcpi8o3ufvuzwbp9
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2007 Canonical Ltd
 
1
# Copyright (C) 2005 Aaron Bentley, Canonical Ltd
2
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
26
26
import errno
27
27
 
28
28
from bzrlib import (
29
 
    builtins,
30
29
    commands,
31
30
    errors,
32
31
    osutils,
33
32
    rio,
34
 
    trace,
35
33
    )
36
34
""")
37
35
from bzrlib.option import Option
56
54
 
57
55
    See also bzr resolve.
58
56
    """
59
 
    takes_options = [
60
 
            Option('text',
61
 
                   help='List paths of files with text conflicts.'),
62
 
        ]
 
57
    takes_options = [Option('text', help='list text conflicts by pathname')]
63
58
 
64
59
    def run(self, text=False):
65
60
        from bzrlib.workingtree import WorkingTree
81
76
    it will mark a conflict.  A conflict means that you need to fix something,
82
77
    before you should commit.
83
78
 
84
 
    Once you have fixed a problem, use "bzr resolve" to automatically mark
85
 
    text conflicts as fixed, resolve FILE to mark a specific conflict as
86
 
    resolved, or "bzr resolve --all" to mark all conflicts as resolved.
 
79
    Once you have fixed a problem, use "bzr resolve FILE.." to mark
 
80
    individual files as fixed, or "bzr resolve --all" to mark all conflicts as
 
81
    resolved.
87
82
 
88
83
    See also bzr conflicts.
89
84
    """
90
85
    aliases = ['resolved']
91
86
    takes_args = ['file*']
92
 
    takes_options = [
93
 
            Option('all', help='Resolve all conflicts in this tree.'),
94
 
            ]
 
87
    takes_options = [Option('all', help='Resolve all conflicts in this tree')]
95
88
    def run(self, file_list=None, all=False):
96
89
        from bzrlib.workingtree import WorkingTree
97
90
        if all:
101
94
            tree = WorkingTree.open_containing('.')[0]
102
95
            resolve(tree)
103
96
        else:
104
 
            tree, file_list = builtins.tree_files(file_list)
105
97
            if file_list is None:
106
 
                un_resolved, resolved = tree.auto_resolve()
107
 
                if len(un_resolved) > 0:
108
 
                    trace.note('%d conflict(s) auto-resolved.', len(resolved))
109
 
                    trace.note('Remaining conflicts:')
110
 
                    for conflict in un_resolved:
111
 
                        trace.note(conflict)
112
 
                    return 1
113
 
                else:
114
 
                    trace.note('All conflicts resolved.')
115
 
                    return 0
116
 
            else:
117
 
                resolve(tree, file_list)
118
 
 
119
 
 
120
 
def resolve(tree, paths=None, ignore_misses=False, recursive=False):
121
 
    """Resolve some or all of the conflicts in a working tree.
122
 
 
123
 
    :param paths: If None, resolve all conflicts.  Otherwise, select only
124
 
        specified conflicts.
125
 
    :param recursive: If True, then elements of paths which are directories
126
 
        have all their children resolved, etc.  When invoked as part of
127
 
        recursive commands like revert, this should be True.  For commands
128
 
        or applications wishing finer-grained control, like the resolve
129
 
        command, this should be False.
130
 
    :ignore_misses: If False, warnings will be printed if the supplied paths
131
 
        do not have conflicts.
132
 
    """
 
98
                raise errors.BzrCommandError("command 'resolve' needs one or"
 
99
                                             " more FILE, or --all")
 
100
            tree = WorkingTree.open_containing(file_list[0])[0]
 
101
            to_resolve = [tree.relpath(p) for p in file_list]
 
102
            resolve(tree, to_resolve)
 
103
 
 
104
 
 
105
def resolve(tree, paths=None, ignore_misses=False):
133
106
    tree.lock_tree_write()
134
107
    try:
135
108
        tree_conflicts = tree.conflicts()
138
111
            selected_conflicts = tree_conflicts
139
112
        else:
140
113
            new_conflicts, selected_conflicts = \
141
 
                tree_conflicts.select_conflicts(tree, paths, ignore_misses,
142
 
                    recursive)
 
114
                tree_conflicts.select_conflicts(tree, paths, ignore_misses)
143
115
        try:
144
116
            tree.set_conflicts(new_conflicts)
145
117
        except errors.UnsupportedOperation:
246
218
                    if e.errno != errno.ENOENT:
247
219
                        raise
248
220
 
249
 
    def select_conflicts(self, tree, paths, ignore_misses=False,
250
 
                         recurse=False):
 
221
    def select_conflicts(self, tree, paths, ignore_misses=False):
251
222
        """Select the conflicts associated with paths in a tree.
252
223
        
253
224
        File-ids are also used for this.
272
243
                if cpath in path_set:
273
244
                    selected = True
274
245
                    selected_paths.add(cpath)
275
 
                if recurse:
276
 
                    if osutils.is_inside_any(path_set, cpath):
277
 
                        selected = True
278
 
                        selected_paths.add(cpath)
279
 
 
280
246
            for key in ('file_id', 'conflict_file_id'):
281
247
                cfile_id = getattr(conflict, key, None)
282
248
                if cfile_id is None:
307
273
 
308
274
    def __init__(self, path, file_id=None):
309
275
        self.path = path
310
 
        # warn turned off, because the factory blindly transfers the Stanza
311
 
        # values to __init__ and Stanza is purely a Unicode api.
312
 
        self.file_id = osutils.safe_file_id(file_id, warn=False)
 
276
        self.file_id = file_id
313
277
 
314
278
    def as_stanza(self):
315
279
        s = rio.Stanza(type=self.typestring, path=self.path)
316
280
        if self.file_id is not None:
317
 
            # Stanza requires Unicode apis
318
 
            s.add('file_id', self.file_id.decode('utf8'))
 
281
            s.add('file_id', self.file_id)
319
282
        return s
320
283
 
321
284
    def _cmp_list(self):
429
392
                 conflict_file_id=None):
430
393
        HandledConflict.__init__(self, action, path, file_id)
431
394
        self.conflict_path = conflict_path 
432
 
        # warn turned off, because the factory blindly transfers the Stanza
433
 
        # values to __init__.
434
 
        self.conflict_file_id = osutils.safe_file_id(conflict_file_id,
435
 
                                                     warn=False)
 
395
        self.conflict_file_id = conflict_file_id
436
396
        
437
397
    def _cmp_list(self):
438
398
        return HandledConflict._cmp_list(self) + [self.conflict_path, 
442
402
        s = HandledConflict.as_stanza(self)
443
403
        s.add('conflict_path', self.conflict_path)
444
404
        if self.conflict_file_id is not None:
445
 
            s.add('conflict_file_id', self.conflict_file_id.decode('utf8'))
 
405
            s.add('conflict_file_id', self.conflict_file_id)
446
406
            
447
407
        return s
448
408
 
515
475
             "%(action)s."
516
476
 
517
477
 
518
 
class NonDirectoryParent(HandledConflict):
519
 
    """An attempt to add files to a directory that is not a director or
520
 
    an attempt to change the kind of a directory with files.
521
 
    """
522
 
 
523
 
    typestring = 'non-directory parent'
524
 
 
525
 
    format = "Conflict: %(path)s is not a directory, but has files in it."\
526
 
             "  %(action)s."
527
 
 
528
478
ctype = {}
529
479
 
530
480
 
537
487
 
538
488
register_types(ContentsConflict, TextConflict, PathConflict, DuplicateID,
539
489
               DuplicateEntry, ParentLoop, UnversionedParent, MissingParent,
540
 
               DeletingParent, NonDirectoryParent)
 
490
               DeletingParent,)