~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 04:47:33 UTC
  • Revision ID: mbp@sourcefrog.net-20050606044733-e902b05ac1747cd2
- fix invocation of testbzr when giving explicit bzr location

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 time, tempfile
 
56
    import os, time, tempfile
57
57
 
58
 
    from bzrlib.osutils import local_time_offset, username
59
 
    from bzrlib.branch import gen_file_id
60
 
    from bzrlib.errors import BzrError
61
 
    from bzrlib.revision import Revision, RevisionReference
62
 
    from bzrlib.trace import mutter, note
 
58
    from inventory import Inventory
 
59
    from osutils import isdir, isfile, sha_string, quotefn, \
 
60
         local_time_offset, username, kind_marker, is_inside_any
 
61
    
 
62
    from branch import gen_file_id
 
63
    from errors import BzrError
 
64
    from revision import Revision
 
65
    from trace import mutter, note
63
66
 
64
67
    branch.lock_write()
65
68
 
74
77
 
75
78
        work_tree = branch.working_tree()
76
79
        work_inv = work_tree.inventory
 
80
        inv = Inventory()
77
81
        basis = branch.basis_tree()
78
82
        basis_inv = basis.inventory
 
83
        missing_ids = []
79
84
 
80
85
        if verbose:
81
86
            note('looking for changes...')
82
87
 
83
 
        missing_ids, new_inv = _gather_commit(branch,
84
 
                                              work_tree,
85
 
                                              work_inv,
86
 
                                              basis_inv,
87
 
                                              specific_files,
88
 
                                              verbose)
 
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
 
89
161
 
90
162
        for file_id in missing_ids:
91
163
            # Any files that have been deleted are now removed from the
108
180
        inv_id = rev_id
109
181
 
110
182
        inv_tmp = tempfile.TemporaryFile()
111
 
        new_inv.write_xml(inv_tmp)
 
183
        inv.write_xml(inv_tmp)
112
184
        inv_tmp.seek(0)
113
185
        branch.inventory_store.add(inv_tmp, inv_id)
114
186
        mutter('new inventory_id is {%s}' % inv_id)
115
187
 
116
 
        # We could also just sha hash the inv_tmp file
117
 
        # however, in the case that branch.inventory_store.add()
118
 
        # ever actually does anything special
119
 
        inv_sha1 = branch.get_inventory_sha1(inv_id)
120
 
 
121
188
        branch._write_inventory(work_inv)
122
189
 
123
190
        if timestamp == None:
133
200
        rev = Revision(timestamp=timestamp,
134
201
                       timezone=timezone,
135
202
                       committer=committer,
 
203
                       precursor = branch.last_patch(),
136
204
                       message = message,
137
205
                       inventory_id=inv_id,
138
 
                       inventory_sha1=inv_sha1,
139
206
                       revision_id=rev_id)
140
207
 
141
 
        precursor_id = branch.last_patch()
142
 
        if precursor_id:
143
 
            precursor_sha1 = branch.get_revision_sha1(precursor_id)
144
 
            rev.parents = [RevisionReference(precursor_id, precursor_sha1)]
145
 
 
146
208
        rev_tmp = tempfile.TemporaryFile()
147
209
        rev.write_xml(rev_tmp)
148
210
        rev_tmp.seek(0)
178
240
    return s
179
241
 
180
242
 
181
 
def _gather_commit(branch, work_tree, work_inv, basis_inv, specific_files,
182
 
                   verbose):
183
 
    """Build inventory preparatory to commit.
184
 
 
185
 
    This adds any changed files into the text store, and sets their
186
 
    test-id, sha and size in the returned inventory appropriately.
187
 
 
188
 
    missing_ids
189
 
        Modified to hold a list of files that have been deleted from
190
 
        the working directory; these should be removed from the
191
 
        working inventory.
192
 
    """
193
 
    from bzrlib.inventory import Inventory
194
 
    from osutils import isdir, isfile, sha_string, quotefn, \
195
 
         local_time_offset, username, kind_marker, is_inside_any
196
 
    
197
 
    from branch import gen_file_id
198
 
    from errors import BzrError
199
 
    from revision import Revision
200
 
    from bzrlib.trace import mutter, note
201
 
 
202
 
    inv = Inventory()
203
 
    missing_ids = []
204
 
    
205
 
    for path, entry in work_inv.iter_entries():
206
 
        ## TODO: Check that the file kind has not changed from the previous
207
 
        ## revision of this file (if any).
208
 
 
209
 
        p = branch.abspath(path)
210
 
        file_id = entry.file_id
211
 
        mutter('commit prep file %s, id %r ' % (p, file_id))
212
 
 
213
 
        if specific_files and not is_inside_any(specific_files, path):
214
 
            if basis_inv.has_id(file_id):
215
 
                # carry over with previous state
216
 
                inv.add(basis_inv[file_id].copy())
217
 
            else:
218
 
                # omit this from committed inventory
219
 
                pass
220
 
            continue
221
 
 
222
 
        if not work_tree.has_id(file_id):
223
 
            if verbose:
224
 
                print('deleted %s%s' % (path, kind_marker(entry.kind)))
225
 
            mutter("    file is missing, removing from inventory")
226
 
            missing_ids.append(file_id)
227
 
            continue
228
 
 
229
 
        # this is present in the new inventory; may be new, modified or
230
 
        # unchanged.
231
 
        old_ie = basis_inv.has_id(file_id) and basis_inv[file_id]
232
 
        
233
 
        entry = entry.copy()
234
 
        inv.add(entry)
235
 
 
236
 
        if old_ie:
237
 
            old_kind = old_ie.kind
238
 
            if old_kind != entry.kind:
239
 
                raise BzrError("entry %r changed kind from %r to %r"
240
 
                        % (file_id, old_kind, entry.kind))
241
 
 
242
 
        if entry.kind == 'directory':
243
 
            if not isdir(p):
244
 
                raise BzrError("%s is entered as directory but not a directory"
245
 
                               % quotefn(p))
246
 
        elif entry.kind == 'file':
247
 
            if not isfile(p):
248
 
                raise BzrError("%s is entered as file but is not a file" % quotefn(p))
249
 
 
250
 
            new_sha1 = work_tree.get_file_sha1(file_id)
251
 
 
252
 
            if (old_ie
253
 
                and old_ie.text_sha1 == new_sha1):
254
 
                ## assert content == basis.get_file(file_id).read()
255
 
                entry.text_id = old_ie.text_id
256
 
                entry.text_sha1 = new_sha1
257
 
                entry.text_size = old_ie.text_size
258
 
                mutter('    unchanged from previous text_id {%s}' %
259
 
                       entry.text_id)
260
 
            else:
261
 
                content = file(p, 'rb').read()
262
 
 
263
 
                # calculate the sha again, just in case the file contents
264
 
                # changed since we updated the cache
265
 
                entry.text_sha1 = sha_string(content)
266
 
                entry.text_size = len(content)
267
 
 
268
 
                entry.text_id = gen_file_id(entry.name)
269
 
                branch.text_store.add(content, entry.text_id)
270
 
                mutter('    stored with text_id {%s}' % entry.text_id)
271
 
 
272
 
        if verbose:
273
 
            marked = path + kind_marker(entry.kind)
274
 
            if not old_ie:
275
 
                print 'added', marked
276
 
            elif old_ie == entry:
277
 
                pass                    # unchanged
278
 
            elif (old_ie.name == entry.name
279
 
                  and old_ie.parent_id == entry.parent_id):
280
 
                print 'modified', marked
281
 
            else:
282
 
                print 'renamed', marked
283
 
                        
284
 
    return missing_ids, inv
285
 
 
286