~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commit.py

  • Committer: Martin Pool
  • Date: 2005-06-06 12:54:48 UTC
  • Revision ID: mbp@sourcefrog.net-20050606125448-1673d0903864401a
- refactor commit code

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
        If null (default), a time/random revision id is generated.
54
54
    """
55
55
 
56
 
    import os, time, tempfile
 
56
    import time, tempfile
57
57
 
58
 
    from inventory import Inventory
59
 
    from osutils import isdir, isfile, sha_string, quotefn, \
60
 
         local_time_offset, username, kind_marker, is_inside_any
 
58
    from osutils import local_time_offset, username
61
59
    
62
60
    from branch import gen_file_id
63
61
    from errors import BzrError
77
75
 
78
76
        work_tree = branch.working_tree()
79
77
        work_inv = work_tree.inventory
80
 
        inv = Inventory()
81
78
        basis = branch.basis_tree()
82
79
        basis_inv = basis.inventory
83
 
        missing_ids = []
84
80
 
85
81
        if verbose:
86
82
            note('looking for changes...')
87
83
 
88
 
        for path, entry in work_inv.iter_entries():
89
 
            ## TODO: Check that the file kind has not changed from the previous
90
 
            ## revision of this file (if any).
91
 
 
92
 
            entry = entry.copy()
93
 
 
94
 
            p = branch.abspath(path)
95
 
            file_id = entry.file_id
96
 
            mutter('commit prep file %s, id %r ' % (p, file_id))
97
 
 
98
 
            if specific_files and not is_inside_any(specific_files, path):
99
 
                if basis_inv.has_id(file_id):
100
 
                    # carry over with previous state
101
 
                    inv.add(basis_inv[file_id].copy())
102
 
                else:
103
 
                    # omit this from committed inventory
104
 
                    pass
105
 
                continue
106
 
 
107
 
            if not work_tree.has_id(file_id):
108
 
                if verbose:
109
 
                    print('deleted %s%s' % (path, kind_marker(entry.kind)))
110
 
                mutter("    file is missing, removing from inventory")
111
 
                missing_ids.append(file_id)
112
 
                continue
113
 
 
114
 
            inv.add(entry)
115
 
 
116
 
            if basis_inv.has_id(file_id):
117
 
                old_kind = basis_inv[file_id].kind
118
 
                if old_kind != entry.kind:
119
 
                    raise BzrError("entry %r changed kind from %r to %r"
120
 
                            % (file_id, old_kind, entry.kind))
121
 
 
122
 
            if entry.kind == 'directory':
123
 
                if not isdir(p):
124
 
                    raise BzrError("%s is entered as directory but not a directory"
125
 
                                   % quotefn(p))
126
 
            elif entry.kind == 'file':
127
 
                if not isfile(p):
128
 
                    raise BzrError("%s is entered as file but is not a file" % quotefn(p))
129
 
 
130
 
                new_sha1 = work_tree.get_file_sha1(file_id)
131
 
 
132
 
                old_ie = basis_inv.has_id(file_id) and basis_inv[file_id]
133
 
                if (old_ie
134
 
                    and old_ie.text_sha1 == new_sha1):
135
 
                    ## assert content == basis.get_file(file_id).read()
136
 
                    entry.text_id = old_ie.text_id
137
 
                    entry.text_sha1 = new_sha1
138
 
                    entry.text_size = old_ie.text_size
139
 
                    mutter('    unchanged from previous text_id {%s}' %
140
 
                           entry.text_id)
141
 
                else:
142
 
                    content = file(p, 'rb').read()
143
 
 
144
 
                    # calculate the sha again, just in case the file contents
145
 
                    # changed since we updated the cache
146
 
                    entry.text_sha1 = sha_string(content)
147
 
                    entry.text_size = len(content)
148
 
 
149
 
                    entry.text_id = gen_file_id(entry.name)
150
 
                    branch.text_store.add(content, entry.text_id)
151
 
                    mutter('    stored with text_id {%s}' % entry.text_id)
152
 
                    if verbose:
153
 
                        if not old_ie:
154
 
                            print('added %s' % path)
155
 
                        elif (old_ie.name == entry.name
156
 
                              and old_ie.parent_id == entry.parent_id):
157
 
                            print('modified %s' % path)
158
 
                        else:
159
 
                            print('renamed %s' % path)
160
 
 
 
84
        missing_ids, new_inv = _gather_commit(branch,
 
85
                                              work_tree,
 
86
                                              work_inv,
 
87
                                              basis_inv,
 
88
                                              specific_files,
 
89
                                              verbose)
161
90
 
162
91
        for file_id in missing_ids:
163
92
            # Any files that have been deleted are now removed from the
180
109
        inv_id = rev_id
181
110
 
182
111
        inv_tmp = tempfile.TemporaryFile()
183
 
        inv.write_xml(inv_tmp)
 
112
        new_inv.write_xml(inv_tmp)
184
113
        inv_tmp.seek(0)
185
114
        branch.inventory_store.add(inv_tmp, inv_id)
186
115
        mutter('new inventory_id is {%s}' % inv_id)
240
169
    return s
241
170
 
242
171
 
 
172
def _gather_commit(branch, work_tree, work_inv, basis_inv, specific_files,
 
173
                   verbose):
 
174
    """Build inventory preparatory to commit.
 
175
 
 
176
    This adds any changed files into the text store, and sets their
 
177
    test-id, sha and size in the returned inventory appropriately.
 
178
 
 
179
    missing_ids
 
180
        Modified to hold a list of files that have been deleted from
 
181
        the working directory; these should be removed from the
 
182
        working inventory.
 
183
    """
 
184
    from bzrlib.inventory import Inventory
 
185
    from osutils import isdir, isfile, sha_string, quotefn, \
 
186
         local_time_offset, username, kind_marker, is_inside_any
 
187
    
 
188
    from branch import gen_file_id
 
189
    from errors import BzrError
 
190
    from revision import Revision
 
191
    from bzrlib.trace import mutter, note
 
192
 
 
193
    inv = Inventory()
 
194
    missing_ids = []
 
195
    
 
196
    for path, entry in work_inv.iter_entries():
 
197
        ## TODO: Check that the file kind has not changed from the previous
 
198
        ## revision of this file (if any).
 
199
 
 
200
        ## TODO: Don't need to copy this unless we're going to change it
 
201
        entry = entry.copy()
 
202
 
 
203
        p = branch.abspath(path)
 
204
        file_id = entry.file_id
 
205
        mutter('commit prep file %s, id %r ' % (p, file_id))
 
206
 
 
207
        if specific_files and not is_inside_any(specific_files, path):
 
208
            if basis_inv.has_id(file_id):
 
209
                # carry over with previous state
 
210
                inv.add(basis_inv[file_id].copy())
 
211
            else:
 
212
                # omit this from committed inventory
 
213
                pass
 
214
            continue
 
215
 
 
216
        if not work_tree.has_id(file_id):
 
217
            if verbose:
 
218
                print('deleted %s%s' % (path, kind_marker(entry.kind)))
 
219
            mutter("    file is missing, removing from inventory")
 
220
            missing_ids.append(file_id)
 
221
            continue
 
222
 
 
223
        inv.add(entry)
 
224
 
 
225
        if basis_inv.has_id(file_id):
 
226
            old_kind = basis_inv[file_id].kind
 
227
            if old_kind != entry.kind:
 
228
                raise BzrError("entry %r changed kind from %r to %r"
 
229
                        % (file_id, old_kind, entry.kind))
 
230
 
 
231
        if entry.kind == 'directory':
 
232
            if not isdir(p):
 
233
                raise BzrError("%s is entered as directory but not a directory"
 
234
                               % quotefn(p))
 
235
        elif entry.kind == 'file':
 
236
            if not isfile(p):
 
237
                raise BzrError("%s is entered as file but is not a file" % quotefn(p))
 
238
 
 
239
            new_sha1 = work_tree.get_file_sha1(file_id)
 
240
 
 
241
            old_ie = basis_inv.has_id(file_id) and basis_inv[file_id]
 
242
            if (old_ie
 
243
                and old_ie.text_sha1 == new_sha1):
 
244
                ## assert content == basis.get_file(file_id).read()
 
245
                entry.text_id = old_ie.text_id
 
246
                entry.text_sha1 = new_sha1
 
247
                entry.text_size = old_ie.text_size
 
248
                mutter('    unchanged from previous text_id {%s}' %
 
249
                       entry.text_id)
 
250
            else:
 
251
                content = file(p, 'rb').read()
 
252
 
 
253
                # calculate the sha again, just in case the file contents
 
254
                # changed since we updated the cache
 
255
                entry.text_sha1 = sha_string(content)
 
256
                entry.text_size = len(content)
 
257
 
 
258
                entry.text_id = gen_file_id(entry.name)
 
259
                branch.text_store.add(content, entry.text_id)
 
260
                mutter('    stored with text_id {%s}' % entry.text_id)
 
261
                if verbose:
 
262
                    ## TODO: Also show these for directories!
 
263
                    if not old_ie:
 
264
                        print('added %s' % path)
 
265
                    elif (old_ie.name == entry.name
 
266
                          and old_ie.parent_id == entry.parent_id):
 
267
                        print('modified %s' % path)
 
268
                    else:
 
269
                        print('renamed %s' % path)
 
270
                        
 
271
    return missing_ids, inv