~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/add.py

  • Committer: Aaron Bentley
  • Date: 2006-04-07 22:46:52 UTC
  • mfrom: (1645 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1727.
  • Revision ID: aaron.bentley@utoronto.ca-20060407224652-4925bc3735b926f8
Merged latest bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
from bzrlib.inventory import InventoryEntry
21
21
from bzrlib.trace import mutter, note, warning
22
22
from bzrlib.errors import NotBranchError
23
 
from bzrlib.branch import is_control_file
 
23
from bzrlib.workingtree import is_control_file
24
24
import bzrlib.osutils
25
25
from bzrlib.workingtree import WorkingTree
26
26
 
41
41
    return expanded_file_list
42
42
 
43
43
 
44
 
def add_reporter_null(path, kind, entry):
45
 
    """Absorb add reports and do nothing."""
46
 
    pass
47
 
 
48
 
 
49
 
def add_reporter_print(path, kind, entry):
50
 
    """Print a line to stdout for each file that's added."""
51
 
    print "added", bzrlib.osutils.quotefn(path)
52
 
 
53
 
 
54
44
def _prepare_file_list(file_list):
55
45
    """Prepare a file list for use by smart_add_*."""
56
46
    import sys
62
52
    return file_list
63
53
 
64
54
 
65
 
def smart_add(file_list, recurse=True, reporter=add_reporter_null):
 
55
def add_action_null(inv, path, kind):
 
56
    """Absorb add actions and do nothing."""
 
57
    pass
 
58
 
 
59
def add_action_print(inv, path, kind):
 
60
    """Print a line to stdout for each file that would be added."""
 
61
    print "added", bzrlib.osutils.quotefn(path)
 
62
 
 
63
def add_action_add(inv, path, kind):
 
64
    """Add each file to the given inventory. Produce no output."""
 
65
    entry = inv.add_path(path, kind=kind)
 
66
    mutter("added %r kind %r file_id={%s}" % (path, kind, entry.file_id))
 
67
 
 
68
def add_action_add_and_print(inv, path, kind):
 
69
    """Add each file to the given inventory, and print a line to stdout."""
 
70
    add_action_add(inv, path, kind)
 
71
    add_action_print(inv, path, kind)
 
72
 
 
73
 
 
74
def smart_add(file_list, recurse=True, action=add_action_add):
66
75
    """Add files to version, optionally recursing into directories.
67
76
 
68
77
    This is designed more towards DWIM for humans than API simplicity.
72
81
    """
73
82
    file_list = _prepare_file_list(file_list)
74
83
    tree = WorkingTree.open_containing(file_list[0])[0]
75
 
    return smart_add_tree(tree, file_list, recurse, reporter)
 
84
    return smart_add_tree(tree, file_list, recurse, action)
76
85
 
77
 
        
78
 
def smart_add_tree(tree, file_list, recurse=True, reporter=add_reporter_null):
 
86
def smart_add_tree(tree, file_list, recurse=True, action=add_action_add):
79
87
    """Add files to version, optionally recursing into directories.
80
88
 
81
89
    This is designed more towards DWIM for humans than API simplicity.
85
93
 
86
94
    Returns the number of files added.
87
95
    """
88
 
    import os
 
96
    import os, errno
89
97
    from bzrlib.errors import BadFileKindError, ForbiddenFileError
90
98
    assert isinstance(recurse, bool)
91
99
 
92
100
    file_list = _prepare_file_list(file_list)
93
101
    user_list = file_list[:]
94
102
    inv = tree.read_working_inventory()
95
 
    count = 0
 
103
    added = []
 
104
    ignored = {}
96
105
 
97
106
    for f in file_list:
98
107
        rf = tree.relpath(f)
99
108
        af = tree.abspath(rf)
100
109
 
101
 
        kind = bzrlib.osutils.file_kind(af)
 
110
        try:
 
111
            kind = bzrlib.osutils.file_kind(af)
 
112
        except OSError, e:
 
113
            if hasattr(e, 'errno') and e.errno == errno.ENOENT:
 
114
                raise errors.NoSuchFile(rf)
 
115
            raise
102
116
 
103
117
        if not InventoryEntry.versionable_kind(kind):
104
118
            if f in user_list:
109
123
 
110
124
        mutter("smart add of %r, abs=%r", f, af)
111
125
        
112
 
        if is_control_file(af):
 
126
        if tree.is_control_filename(af):
113
127
            raise ForbiddenFileError('cannot add control file %s' % f)
114
128
            
115
129
        versioned = (inv.path2id(rf) != None)
116
130
 
117
131
        if kind == 'directory':
118
132
            try:
119
 
                sub_branch = WorkingTree(af)
 
133
                sub_branch = WorkingTree.open(af)
120
134
                sub_tree = True
121
135
            except NotBranchError:
122
136
                sub_tree = False
133
147
        elif sub_tree:
134
148
            mutter("%r is a bzr tree", f)
135
149
        else:
136
 
            count += __add_one(tree, inv, rf, kind, reporter)
 
150
            added.extend(__add_one(tree, inv, rf, kind, action))
137
151
 
138
152
        if kind == 'directory' and recurse and not sub_tree:
139
153
            for subf in os.listdir(af):
140
 
                subp = os.path.join(rf, subf)
141
 
                if subf == bzrlib.BZRDIR:
 
154
                subp = bzrlib.osutils.pathjoin(rf, subf)
 
155
                if tree.is_control_filename(subp):
142
156
                    mutter("skip control directory %r", subp)
143
 
                elif tree.is_ignored(subp):
144
 
                    mutter("skip ignored sub-file %r", subp)
145
157
                else:
146
 
                    mutter("queue to add sub-file %r", subp)
147
 
                    file_list.append(tree.abspath(subp))
148
 
 
149
 
 
150
 
    mutter('added %d entries', count)
 
158
                    ignore_glob = tree.is_ignored(subp)
 
159
                    if ignore_glob is not None:
 
160
                        mutter("skip ignored sub-file %r", subp)
 
161
                        if ignore_glob not in ignored:
 
162
                            ignored[ignore_glob] = []
 
163
                        ignored[ignore_glob].append(subp)
 
164
                    else:
 
165
                        mutter("queue to add sub-file %r", subp)
 
166
                        file_list.append(tree.abspath(subp))
 
167
 
 
168
 
 
169
    mutter('added %d entries', len(added))
151
170
    
152
 
    if count > 0:
 
171
    if len(added) > 0:
153
172
        tree._write_inventory(inv)
154
173
 
155
 
    return count
 
174
    return added, ignored
156
175
 
157
 
def __add_one(tree, inv, path, kind, reporter):
 
176
def __add_one(tree, inv, path, kind, action):
158
177
    """Add a file or directory, automatically add unversioned parents."""
159
178
 
160
179
    # Nothing to do if path is already versioned.
161
180
    # This is safe from infinite recursion because the tree root is
162
181
    # always versioned.
163
182
    if inv.path2id(path) != None:
164
 
        return 0
 
183
        return []
165
184
 
166
185
    # add parent
167
 
    count = __add_one(tree, inv, dirname(path), 'directory', reporter)
168
 
 
169
 
    entry = inv.add_path(path, kind=kind)
170
 
    mutter("added %r kind %r file_id={%s}", path, kind, entry.file_id)
171
 
    reporter(path, kind, entry)
172
 
 
173
 
    return count + 1
 
186
    added = __add_one(tree, inv, dirname(path), 'directory', action)
 
187
    action(inv, path, kind)
 
188
 
 
189
    return added + [path]