404
404
"""Inventory for the working copy.""")
407
def add(self, files, verbose=False, ids=None):
407
def add(self, files, ids=None):
408
408
"""Make files versioned.
410
Note that the command line normally calls smart_add instead.
410
Note that the command line normally calls smart_add instead,
411
which can automatically recurse.
412
413
This puts the files in the Added state, so that they will be
413
414
recorded by the next commit.
423
424
TODO: Perhaps have an option to add the ids even if the files do
426
TODO: Perhaps return the ids of the files? But then again it
427
is easy to retrieve them if they're needed.
429
TODO: Adding a directory should optionally recurse down and
430
add all non-ignored children. Perhaps do that in a
427
TODO: Perhaps yield the ids and paths as they're added.
433
429
# TODO: Re-adding a file that is removed in the working copy
434
430
# should probably put it back with the previous ID.
470
466
file_id = gen_file_id(f)
471
467
inv.add_path(f, kind=kind, file_id=file_id)
474
print 'added', quotefn(f)
476
469
mutter("add file %s file_id:{%s} kind=%r" % (f, file_id, kind))
478
471
self._write_inventory(inv)
884
877
def lookup_revision(self, revision):
885
878
"""Return the revision identifier for a given revision information."""
886
revno, info = self._get_revision_info(revision)
879
revno, info = self.get_revision_info(revision)
904
897
revision can also be a string, in which case it is parsed for something like
905
898
'date:' or 'revid:' etc.
907
revno, rev_id = self._get_revision_info(revision)
909
raise bzrlib.errors.NoSuchRevision(self, revision)
912
def get_rev_id(self, revno, history=None):
913
"""Find the revision id of the specified revno."""
917
history = self.revision_history()
918
elif revno <= 0 or revno > len(history):
919
raise bzrlib.errors.NoSuchRevision(self, revno)
920
return history[revno - 1]
922
def _get_revision_info(self, revision):
923
"""Return (revno, revision id) for revision specifier.
925
revision can be an integer, in which case it is assumed to be revno
926
(though this will translate negative values into positive ones)
927
revision can also be a string, in which case it is parsed for something
928
like 'date:' or 'revid:' etc.
930
A revid is always returned. If it is None, the specifier referred to
931
the null revision. If the revid does not occur in the revision
932
history, revno will be None.
935
900
if revision is None:
942
907
revs = self.revision_history()
943
908
if isinstance(revision, int):
911
# Mabye we should do this first, but we don't need it if revision == 0
945
913
revno = len(revs) + revision + 1
948
rev_id = self.get_rev_id(revno, revs)
949
916
elif isinstance(revision, basestring):
950
917
for prefix, func in Branch.REVISION_NAMESPACES.iteritems():
951
918
if revision.startswith(prefix):
952
result = func(self, revs, revision)
954
revno, rev_id = result
957
rev_id = self.get_rev_id(revno, revs)
919
revno = func(self, revs, revision)
960
raise BzrError('No namespace registered for string: %r' %
963
raise TypeError('Unhandled revision type %s' % revision)
922
raise BzrError('No namespace registered for string: %r' % revision)
967
raise bzrlib.errors.NoSuchRevision(self, revision)
924
if revno is None or revno <= 0 or revno > len(revs):
925
raise BzrError("no such revision %s" % revision)
926
return revno, revs[revno-1]
970
928
def _namespace_revno(self, revs, revision):
971
929
"""Lookup a revision by revision number"""
972
930
assert revision.startswith('revno:')
974
return (int(revision[6:]),)
932
return int(revision[6:])
975
933
except ValueError:
977
935
REVISION_NAMESPACES['revno:'] = _namespace_revno
979
937
def _namespace_revid(self, revs, revision):
980
938
assert revision.startswith('revid:')
981
rev_id = revision[len('revid:'):]
983
return revs.index(rev_id) + 1, rev_id
940
return revs.index(revision[6:]) + 1
984
941
except ValueError:
986
943
REVISION_NAMESPACES['revid:'] = _namespace_revid
988
945
def _namespace_last(self, revs, revision):
991
948
offset = int(revision[5:])
992
949
except ValueError:
996
953
raise BzrError('You must supply a positive value for --revision last:XXX')
997
return (len(revs) - offset + 1,)
954
return len(revs) - offset + 1
998
955
REVISION_NAMESPACES['last:'] = _namespace_last
1000
957
def _namespace_tag(self, revs, revision):
1075
1032
# TODO: Handle timezone.
1076
1033
dt = datetime.datetime.fromtimestamp(r.timestamp)
1077
1034
if first >= dt and (last is None or dt >= last):
1080
1037
for i in range(len(revs)):
1081
1038
r = self.get_revision(revs[i])
1082
1039
# TODO: Handle timezone.
1083
1040
dt = datetime.datetime.fromtimestamp(r.timestamp)
1084
1041
if first <= dt and (last is None or dt <= last):
1086
1043
REVISION_NAMESPACES['date:'] = _namespace_date
1088
1045
def revision_tree(self, revision_id):
1154
1111
inv.rename(file_id, to_dir_id, to_tail)
1156
print "%s => %s" % (from_rel, to_rel)
1158
1113
from_abs = self.abspath(from_rel)
1159
1114
to_abs = self.abspath(to_rel)
1180
1135
Note that to_name is only the last component of the new name;
1181
1136
this doesn't change the directory.
1138
This returns a list of (from_path, to_path) pairs for each
1139
entry that is moved.
1183
1142
self.lock_write()
1185
1144
## TODO: Option to move IDs only
1220
1179
for f in from_paths:
1221
1180
name_tail = splitpath(f)[-1]
1222
1181
dest_path = appendpath(to_name, name_tail)
1223
print "%s => %s" % (f, dest_path)
1182
result.append((f, dest_path))
1224
1183
inv.rename(inv.path2id(f), to_dir_id, name_tail)
1226
1185
os.rename(self.abspath(f), self.abspath(dest_path))