~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/add.py

- refactor handling of short option names

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