117
117
osutils.copy_tree(cache_dir, root,
118
118
handlers={'file':os.link})
120
def _clone_tree(self, source, dest, link_bzr=False, link_working=True):
120
def _clone_tree(self, source, dest, link_bzr=False, link_working=True,
121
122
"""Copy the contents from a given location to another location.
122
123
Optionally hardlink certain pieces of the tree.
125
126
:param dest: The destination
126
127
:param link_bzr: Should the .bzr/ files be hardlinked?
127
128
:param link_working: Should the working tree be hardlinked?
129
:param hot_cache: Update the hash-cache when you are done
129
131
# We use shutil.copyfile so that we don't copy permissions
130
132
# because most of our source trees are marked readonly to
151
153
shutil.copyfile(source, dest)
152
154
handlers = {'file':file_handler}
153
155
osutils.copy_tree(source, dest, handlers=handlers)
156
tree = workingtree.WorkingTree.open(dest)
160
# tree._hashcache.scan() just checks and removes
161
# entries that are out of date
162
# we need to actually store new ones
163
for path, ie in tree.inventory.iter_entries_by_dir():
164
tree.get_file_sha1(ie.file_id, path)
167
# If we didn't iterate the tree, the hash cache is technically
168
# invalid, and it would be better to remove it, but there is
169
# no public api for that.
155
172
def _protect_files(self, root):
156
173
"""Chmod all files underneath 'root' to prevent writing
171
188
tree = self.make_kernel_like_tree(root=cache_dir,
172
189
hardlink_working=True)
173
190
# Add everything to it
174
add.smart_add_tree(tree, [cache_dir], recurse=True, save=True)
193
add.smart_add_tree(tree, [cache_dir], recurse=True, save=True)
194
self._protect_files(cache_dir+'/.bzr')
176
self._protect_files(cache_dir+'/.bzr')
179
200
def make_kernel_like_added_tree(self, root='.',
180
hardlink_working=True):
201
hardlink_working=True,
181
203
"""Make a kernel like tree, with all files added
183
205
:param root: Where to create the files
184
206
:param hardlink_working: Instead of copying all of the working tree
185
207
files, just hardlink them to the cached files. Tests can unlink
186
208
files that they will change.
209
:param hot_cache: Run through the newly created tree and make sure
210
the stat-cache is correct. The old way of creating a freshly
211
added tree always had a hot cache.
188
213
# There isn't much underneath .bzr, so we don't support hardlinking
189
214
# it. Testing showed there wasn't much gain, and there is potentially
190
215
# a problem if someone modifies something underneath us.
191
216
cache_dir = self._cache_kernel_like_added_tree()
193
self._clone_tree(cache_dir, root,
194
link_working=hardlink_working)
195
return workingtree.WorkingTree.open(root)
218
return self._clone_tree(cache_dir, root,
219
link_working=hardlink_working,
197
222
def _cache_kernel_like_committed_tree(self):
198
223
cache_dir, is_cached = self.get_cache_dir('kernel_like_committed_tree')
202
227
# Get a basic tree with working files
203
228
tree = self.make_kernel_like_added_tree(root=cache_dir,
204
hardlink_working=True)
229
hardlink_working=True,
205
231
tree.commit('first post', rev_id='r1')
207
233
self._protect_files(cache_dir+'/.bzr')
210
236
def make_kernel_like_committed_tree(self, root='.',
211
237
hardlink_working=True,
213
240
"""Make a kernel like tree, with all files added and committed
215
242
:param root: Where to create the files
222
249
cache_dir = self._cache_kernel_like_committed_tree()
224
251
# Now we have a cached tree, just copy it
225
self._clone_tree(cache_dir, root,
226
link_bzr=hardlink_bzr,
227
link_working=hardlink_working)
228
return workingtree.WorkingTree.open(root)
252
return self._clone_tree(cache_dir, root,
253
link_bzr=hardlink_bzr,
254
link_working=hardlink_working,
230
257
def _cache_many_commit_tree(self):
231
258
cache_dir, is_cached = self.get_cache_dir('many_commit_tree')
258
285
because there are no working tree files.
260
287
cache_dir = self._cache_many_commit_tree()
261
self._clone_tree(cache_dir, directory_name,
263
return workingtree.WorkingTree.open(directory_name)
288
return self._clone_tree(cache_dir, directory_name,
265
292
def _cache_heavily_merged_tree(self):
266
293
cache_dir, is_cached = self.get_cache_dir('heavily_merged_tree')
302
329
cache_dir = self._cache_heavily_merged_tree()
303
330
tree_dir = cache_dir + '/tree1'
304
self._clone_tree(tree_dir, directory_name,
306
return workingtree.WorkingTree.open(directory_name)
331
return self._clone_tree(tree_dir, directory_name,
309
336
def test_suite():