~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/conflicts.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-02-01 23:48:08 UTC
  • mfrom: (2225.1.6 revert)
  • Revision ID: pqm@pqm.ubuntu.com-20070201234808-3b1302d73474bd8c
Display changes made by revert

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Aaron Bentley
 
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
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
41
46
    it will mark a conflict.  A conflict means that you need to fix something,
42
47
    before you should commit.
43
48
 
 
49
    Conflicts normally are listed as short, human-readable messages.  If --text
 
50
    is supplied, the pathnames of files with text conflicts are listed,
 
51
    instead.  (This is useful for editing all files with text conflicts.)
 
52
 
44
53
    Use bzr resolve when you have fixed a problem.
45
54
 
46
 
    (conflicts are determined by the presence of .BASE .TREE, and .OTHER 
47
 
    files.)
48
 
 
49
55
    See also bzr resolve.
50
56
    """
51
 
    def run(self):
 
57
    takes_options = [Option('text', help='list text conflicts by pathname')]
 
58
 
 
59
    def run(self, text=False):
52
60
        from bzrlib.workingtree import WorkingTree
53
61
        wt = WorkingTree.open_containing(u'.')[0]
54
62
        for conflict in wt.conflicts():
55
 
            print conflict
56
 
 
57
 
 
58
 
class cmd_resolve(bzrlib.commands.Command):
 
63
            if text:
 
64
                if conflict.typestring != 'text conflict':
 
65
                    continue
 
66
                self.outf.write(conflict.path + '\n')
 
67
            else:
 
68
                self.outf.write(str(conflict) + '\n')
 
69
 
 
70
 
 
71
class cmd_resolve(commands.Command):
59
72
    """Mark a conflict as resolved.
60
73
 
61
74
    Merge will do its best to combine the changes in two branches, but there
76
89
        from bzrlib.workingtree import WorkingTree
77
90
        if all:
78
91
            if file_list:
79
 
                raise BzrCommandError("If --all is specified, no FILE may be provided")
 
92
                raise errors.BzrCommandError("If --all is specified,"
 
93
                                             " no FILE may be provided")
80
94
            tree = WorkingTree.open_containing('.')[0]
81
95
            resolve(tree)
82
96
        else:
83
97
            if file_list is None:
84
 
                raise BzrCommandError("command 'resolve' needs one or more FILE, or --all")
 
98
                raise errors.BzrCommandError("command 'resolve' needs one or"
 
99
                                             " more FILE, or --all")
85
100
            tree = WorkingTree.open_containing(file_list[0])[0]
86
101
            to_resolve = [tree.relpath(p) for p in file_list]
87
102
            resolve(tree, to_resolve)
88
103
 
89
104
 
90
105
def resolve(tree, paths=None, ignore_misses=False):
91
 
    tree.lock_write()
 
106
    tree.lock_tree_write()
92
107
    try:
93
108
        tree_conflicts = tree.conflicts()
94
109
        if paths is None:
99
114
                tree_conflicts.select_conflicts(tree, paths, ignore_misses)
100
115
        try:
101
116
            tree.set_conflicts(new_conflicts)
102
 
        except UnsupportedOperation:
 
117
        except errors.UnsupportedOperation:
103
118
            pass
104
119
        selected_conflicts.remove_files(tree)
105
120
    finally:
113
128
    """
114
129
    conflicted = False
115
130
    try:
116
 
        rename(filename + ".THIS", filename)
 
131
        osutils.rename(filename + ".THIS", filename)
117
132
        conflicted = True
118
133
    except OSError, e:
119
134
        if e.errno != errno.ENOENT:
131
146
        if e.errno != errno.ENOENT:
132
147
            raise
133
148
    if not conflicted:
134
 
        raise NotConflicted(filename)
 
149
        raise errors.NotConflicted(filename)
135
150
 
136
151
 
137
152
class ConflictList(object):
198
213
                continue
199
214
            for suffix in CONFLICT_SUFFIXES:
200
215
                try:
201
 
                    delete_any(tree.abspath(conflict.path+suffix))
 
216
                    osutils.delete_any(tree.abspath(conflict.path+suffix))
202
217
                except OSError, e:
203
218
                    if e.errno != errno.ENOENT:
204
219
                        raise
261
276
        self.file_id = file_id
262
277
 
263
278
    def as_stanza(self):
264
 
        s = Stanza(type=self.typestring, path=self.path)
 
279
        s = rio.Stanza(type=self.typestring, path=self.path)
265
280
        if self.file_id is not None:
266
281
            s.add('file_id', self.file_id)
267
282
        return s
432
447
 
433
448
    typestring = 'unversioned parent'
434
449
 
435
 
    format = 'Conflict adding versioned files to %(path)s.  %(action)s.'
 
450
    format = 'Conflict because %(path)s is not versioned, but has versioned'\
 
451
             ' children.  %(action)s.'
436
452
 
437
453
 
438
454
class MissingParent(HandledConflict):
439
455
    """An attempt to add files to a directory that is not present.
440
 
    Typically, the result of a merge where one tree deleted the directory and
441
 
    the other added a file to it.
 
456
    Typically, the result of a merge where THIS deleted the directory and
 
457
    the OTHER added a file to it.
 
458
    See also: DeletingParent (same situation, reversed THIS and OTHER)
442
459
    """
443
460
 
444
461
    typestring = 'missing parent'
446
463
    format = 'Conflict adding files to %(path)s.  %(action)s.'
447
464
 
448
465
 
 
466
class DeletingParent(HandledConflict):
 
467
    """An attempt to add files to a directory that is not present.
 
468
    Typically, the result of a merge where one OTHER deleted the directory and
 
469
    the THIS added a file to it.
 
470
    """
 
471
 
 
472
    typestring = 'deleting parent'
 
473
 
 
474
    format = "Conflict: can't delete %(path)s because it is not empty.  "\
 
475
             "%(action)s."
 
476
 
449
477
 
450
478
ctype = {}
451
479
 
458
486
 
459
487
 
460
488
register_types(ContentsConflict, TextConflict, PathConflict, DuplicateID,
461
 
               DuplicateEntry, ParentLoop, UnversionedParent, MissingParent,)
 
489
               DuplicateEntry, ParentLoop, UnversionedParent, MissingParent,
 
490
               DeletingParent,)