15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
import sys, os, os.path, random, time, sha, sets, types, re, shutil, tempfile
19
import traceback, socket, fnmatch, difflib, time
20
from binascii import hexlify
23
from inventory import Inventory
24
from trace import mutter, note
25
from tree import Tree, EmptyTree, RevisionTree
26
from inventory import InventoryEntry, Inventory
27
from osutils import isdir, quotefn, isfile, uuid, sha_file, username, \
28
format_date, compact_date, pumpfile, user_email, rand_bytes, splitpath, \
29
joinpath, sha_file, sha_string, file_kind, local_time_offset, appendpath
30
from store import ImmutableStore
31
from revision import Revision
32
from errors import BzrError
33
from textui import show_status
21
from bzrlib.trace import mutter, note
22
from bzrlib.osutils import isdir, quotefn, compact_date, rand_bytes, splitpath, \
23
sha_file, appendpath, file_kind
24
from bzrlib.errors import BzrError
35
26
BZR_BRANCH_FORMAT = "Bazaar-NG branch, format 0.0.4\n"
36
27
## TODO: Maybe include checks for common corruption of newlines, etc?
266
258
def controlfilename(self, file_or_path):
267
259
"""Return location relative to branch."""
268
if isinstance(file_or_path, types.StringTypes):
260
if isinstance(file_or_path, basestring):
269
261
file_or_path = [file_or_path]
270
262
return os.path.join(self.base, bzrlib.BZRDIR, *file_or_path)
336
329
def read_working_inventory(self):
337
330
"""Read the working inventory."""
331
from bzrlib.inventory import Inventory
332
from time import time
339
334
# ElementTree does its own conversion from UTF-8, so open in
343
338
inv = Inventory.read_xml(self.controlfile('inventory', 'rb'))
344
339
mutter("loaded inventory of %d items in %f"
345
% (len(inv), time.time() - before))
340
% (len(inv), time() - before))
400
395
add all non-ignored children. Perhaps do that in a
401
396
higher-level method.
398
from bzrlib.textui import show_status
403
399
# TODO: Re-adding a file that is removed in the working copy
404
400
# should probably put it back with the previous ID.
405
if isinstance(files, types.StringTypes):
406
assert(ids is None or isinstance(ids, types.StringTypes))
401
if isinstance(files, basestring):
402
assert(ids is None or isinstance(ids, basestring))
408
404
if ids is not None:
478
474
is the opposite of add. Removing it is consistent with most
479
475
other tools. Maybe an option.
477
from bzrlib.textui import show_status
481
478
## TODO: Normalize names
482
479
## TODO: Remove nested loops; better scalability
483
if isinstance(files, types.StringTypes):
480
if isinstance(files, basestring):
486
483
self.lock_write()
512
509
# FIXME: this doesn't need to be a branch method
513
510
def set_inventory(self, new_inventory_list):
511
from bzrlib.inventory import Inventory, InventoryEntry
514
512
inv = Inventory()
515
513
for path, file_id, parent, kind in new_inventory_list:
516
514
name = os.path.basename(path)
557
555
def get_revision(self, revision_id):
558
556
"""Return the Revision object for a named revision"""
557
from bzrlib.revision import Revision
559
558
if not revision_id or not isinstance(revision_id, basestring):
560
559
raise ValueError('invalid revision-id: %r' % revision_id)
561
560
r = Revision.read_xml(self.revision_store[revision_id])
830
835
`revision_id` may be None for the null revision, in which case
831
836
an `EmptyTree` is returned."""
837
from bzrlib.tree import EmptyTree, RevisionTree
832
838
# TODO: refactor this to use an existing revision object
833
839
# so we don't need to read it in twice.
834
840
if revision_id == None:
1036
1043
If any files are listed, they are created in the working copy.
1045
from tempfile import mkdtemp
1039
1047
if base is None:
1040
base = tempfile.mkdtemp()
1042
1050
Branch.__init__(self, base, init=init)
1056
1064
>>> os.path.isfile(os.path.join(clone.base, "file1"))
1059
base = tempfile.mkdtemp()
1067
from shutil import copytree
1068
from tempfile import mkdtemp
1061
shutil.copytree(self.base, base, symlinks=True)
1071
copytree(self.base, base, symlinks=True)
1062
1072
return ScratchBranch(base=base)
1064
1074
def __del__(self):
1067
1077
def destroy(self):
1068
1078
"""Destroy the test branch, removing the scratch directory."""
1079
from shutil import rmtree
1071
1082
mutter("delete ScratchBranch %s" % self.base)
1072
shutil.rmtree(self.base)
1073
1084
except OSError, e:
1074
1085
# Work around for shutil.rmtree failing on Windows when
1075
1086
# readonly files are encountered
1125
1138
name = re.sub(r'[^\w.]', '', name)
1127
1140
s = hexlify(rand_bytes(8))
1128
return '-'.join((name, compact_date(time.time()), s))
1141
return '-'.join((name, compact_date(time()), s))