38
39
timestamp -- if not None, seconds-since-epoch for a
39
40
postdated/predated commit.
43
If true, commit only those files.
42
46
import os, time, tempfile
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
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
54
57
branch._need_writelock()
65
68
# detect missing/deleted files, and remove them from the
66
69
# working inventory.
68
work_inv = branch.read_working_inventory()
71
work_tree = branch.working_tree()
72
work_inv = work_tree.inventory
70
74
basis = branch.basis_tree()
71
75
basis_inv = basis.inventory
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.
82
88
file_id = entry.file_id
83
89
mutter('commit prep file %s, id %r ' % (p, file_id))
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())
96
# omit this from committed inventory
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")
88
show_status('D', entry.kind, quotefn(path))
89
103
missing_ids.append(file_id)
92
# TODO: Handle files that have been deleted
94
# TODO: Maybe a special case for empty files? Seems a
95
# waste to store them many times.
99
108
if basis_inv.has_id(file_id):
105
114
if entry.kind == 'directory':
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"
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))
112
content = file(p, 'rb').read()
114
entry.text_sha1 = sha_string(content)
115
entry.text_size = len(content)
122
new_sha1 = work_tree.get_file_sha1(file_id)
117
124
old_ie = basis_inv.has_id(file_id) and basis_inv[file_id]
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}' %
134
content = file(p, 'rb').read()
136
entry.text_sha1 = sha_string(content)
137
entry.text_size = len(content)
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)
133
elif (old_ie.name == entry.name
134
and old_ie.parent_id == entry.parent_id):
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)
148
note('renamed %s' % path)
139
show_status(state, entry.kind, quotefn(path))
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.
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