~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commit.py

  • Committer: Martin Pool
  • Date: 2005-05-12 03:10:29 UTC
  • Revision ID: mbp@sourcefrog.net-20050512031029-8afea23b27a3c7b6
- Selective commit!
- commit is now more verbose by default

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
def commit(branch, message, timestamp=None, timezone=None,
20
20
           committer=None,
21
 
           verbose=False):
 
21
           verbose=True,
 
22
           specific_files=None):
22
23
    """Commit working copy as a new revision.
23
24
 
24
25
    The basic approach is to add all the file texts into the
37
38
 
38
39
    timestamp -- if not None, seconds-since-epoch for a
39
40
         postdated/predated commit.
 
41
 
 
42
    specific_files
 
43
        If true, commit only those files.
40
44
    """
41
45
 
42
46
    import os, time, tempfile
43
47
 
44
48
    from inventory import Inventory
45
49
    from osutils import isdir, isfile, sha_string, quotefn, \
46
 
         local_time_offset, username
 
50
         local_time_offset, username, kind_marker, is_inside_any
47
51
    
48
52
    from branch import gen_file_id
49
53
    from errors import BzrError
50
54
    from revision import Revision
51
 
    from textui import show_status
52
55
    from trace import mutter, note
53
56
 
54
57
    branch._need_writelock()
65
68
    # detect missing/deleted files, and remove them from the
66
69
    # working inventory.
67
70
 
68
 
    work_inv = branch.read_working_inventory()
 
71
    work_tree = branch.working_tree()
 
72
    work_inv = work_tree.inventory
69
73
    inv = Inventory()
70
74
    basis = branch.basis_tree()
71
75
    basis_inv = basis.inventory
72
76
    missing_ids = []
 
77
 
 
78
    print 'looking for changes...'
73
79
    for path, entry in work_inv.iter_entries():
74
80
        ## TODO: Cope with files that have gone missing.
75
81
 
82
88
        file_id = entry.file_id
83
89
        mutter('commit prep file %s, id %r ' % (p, file_id))
84
90
 
85
 
        if not os.path.exists(p):
 
91
        if specific_files and not is_inside_any(specific_files, path):
 
92
            if basis_inv.has_id(file_id):
 
93
                # carry over with previous state
 
94
                inv.add(basis_inv[file_id].copy())
 
95
            else:
 
96
                # omit this from committed inventory
 
97
                pass
 
98
            continue
 
99
 
 
100
        if not work_tree.has_id(file_id):
 
101
            note('deleted %s%s' % (path, kind_marker(entry.kind)))
86
102
            mutter("    file is missing, removing from inventory")
87
 
            if verbose:
88
 
                show_status('D', entry.kind, quotefn(path))
89
103
            missing_ids.append(file_id)
90
104
            continue
91
105
 
92
 
        # TODO: Handle files that have been deleted
93
 
 
94
 
        # TODO: Maybe a special case for empty files?  Seems a
95
 
        # waste to store them many times.
96
 
 
97
106
        inv.add(entry)
98
107
 
99
108
        if basis_inv.has_id(file_id):
104
113
 
105
114
        if entry.kind == 'directory':
106
115
            if not isdir(p):
107
 
                raise BzrError("%s is entered as directory but not a directory" % quotefn(p))
 
116
                raise BzrError("%s is entered as directory but not a directory"
 
117
                               % quotefn(p))
108
118
        elif entry.kind == 'file':
109
119
            if not isfile(p):
110
120
                raise BzrError("%s is entered as file but is not a file" % quotefn(p))
111
121
 
112
 
            content = file(p, 'rb').read()
113
 
 
114
 
            entry.text_sha1 = sha_string(content)
115
 
            entry.text_size = len(content)
 
122
            new_sha1 = work_tree.get_file_sha1(file_id)
116
123
 
117
124
            old_ie = basis_inv.has_id(file_id) and basis_inv[file_id]
118
125
            if (old_ie
119
 
                and (old_ie.text_size == entry.text_size)
120
 
                and (old_ie.text_sha1 == entry.text_sha1)):
 
126
                and old_ie.text_sha1 == new_sha1):
121
127
                ## assert content == basis.get_file(file_id).read()
122
 
                entry.text_id = basis_inv[file_id].text_id
 
128
                entry.text_id = old_ie.text_id
 
129
                entry.text_sha1 = new_sha1
 
130
                entry.text_size = old_ie.text_size
123
131
                mutter('    unchanged from previous text_id {%s}' %
124
132
                       entry.text_id)
125
 
 
126
133
            else:
 
134
                content = file(p, 'rb').read()
 
135
 
 
136
                entry.text_sha1 = sha_string(content)
 
137
                entry.text_size = len(content)
 
138
 
127
139
                entry.text_id = gen_file_id(entry.name)
128
140
                branch.text_store.add(content, entry.text_id)
129
141
                mutter('    stored with text_id {%s}' % entry.text_id)
130
 
                if verbose:
131
 
                    if not old_ie:
132
 
                        state = 'A'
133
 
                    elif (old_ie.name == entry.name
134
 
                          and old_ie.parent_id == entry.parent_id):
135
 
                        state = 'M'
136
 
                    else:
137
 
                        state = 'R'
 
142
                if not old_ie:
 
143
                    note('added %s' % path)
 
144
                elif (old_ie.name == entry.name
 
145
                      and old_ie.parent_id == entry.parent_id):
 
146
                    note('modified %s' % path)
 
147
                else:
 
148
                    note('renamed %s' % path)
138
149
 
139
 
                    show_status(state, entry.kind, quotefn(path))
140
150
 
141
151
    for file_id in missing_ids:
 
152
        # Any files that have been deleted are now removed from the
 
153
        # working inventory.  Files that were not selected for commit
 
154
        # are left as they were in the working inventory and ommitted
 
155
        # from the revision inventory.
 
156
        
142
157
        # have to do this later so we don't mess up the iterator.
143
158
        # since parents may be removed before their children we
144
159
        # have to test.
196
211
 
197
212
    branch.append_revision(rev_id)
198
213
 
199
 
    if verbose:
200
 
        note("commited r%d" % branch.revno())
 
214
    note("commited r%d" % branch.revno())
201
215
 
202
216
 
203
217