18
18
from copy import deepcopy
19
19
from cStringIO import StringIO
24
20
from unittest import TestSuite
25
21
from warnings import warn
28
import bzrlib.bzrdir as bzrdir
24
from bzrlib import bzrdir, errors, lockdir, osutils, revision, \
29
28
from bzrlib.config import TreeConfig
30
29
from bzrlib.decorators import needs_read_lock, needs_write_lock
31
30
import bzrlib.errors as errors
36
35
NotBranchError, UninitializableFormat,
37
36
UnlistableStore, UnlistableBranch,
39
import bzrlib.inventory as inventory
40
from bzrlib.inventory import Inventory
41
38
from bzrlib.lockable_files import LockableFiles, TransportLock
42
from bzrlib.lockdir import LockDir
43
from bzrlib.osutils import (isdir, quotefn,
44
rename, splitpath, sha_file,
45
file_kind, abspath, normpath, pathjoin,
49
from bzrlib.repository import Repository
50
from bzrlib.revision import (
55
from bzrlib.store import copy_all
56
from bzrlib.symbol_versioning import *
57
from bzrlib.textui import show_status
39
from bzrlib.symbol_versioning import (deprecated_function,
43
zero_eight, zero_nine,
58
45
from bzrlib.trace import mutter, note
59
import bzrlib.transactions as transactions
60
from bzrlib.transport import Transport, get_transport
62
import bzrlib.urlutils as urlutils
66
48
BZR_BRANCH_FORMAT_4 = "Bazaar-NG branch, format 0.0.4\n"
156
138
warn('%s is deprecated' % self.setup_caching)
157
139
self.cache_root = cache_root
141
def get_config(self):
142
return bzrlib.config.BranchConfig(self)
159
144
def _get_nick(self):
160
cfg = self.tree_config()
161
return cfg.get_option(u"nickname", default=self.base.split('/')[-2])
145
return self.get_config().get_nickname()
163
147
def _set_nick(self, nick):
164
cfg = self.tree_config()
165
cfg.set_option(nick, "nickname")
166
assert cfg.get_option("nickname") == nick
148
self.get_config().set_user_option('nickname', nick)
168
150
nick = property(_get_nick, _set_nick)
231
213
last_revision = from_history[-1]
233
215
# no history in the source branch
234
last_revision = NULL_REVISION
216
last_revision = revision.NULL_REVISION
235
217
return self.repository.fetch(from_branch.repository,
236
218
revision_id=last_revision,
265
247
if config is None:
266
config = bzrlib.config.BranchConfig(self)
248
config = self.get_config()
268
250
return self.repository.get_commit_builder(self, parents, config,
269
251
timestamp, timezone, committer, revprops, revision_id)
331
313
If self and other have not diverged, return a list of the revisions
332
314
present in other, but missing from self.
334
>>> from bzrlib.workingtree import WorkingTree
335
>>> bzrlib.trace.silent = True
336
>>> d1 = bzrdir.ScratchDir()
337
>>> br1 = d1.open_branch()
338
>>> wt1 = d1.open_workingtree()
339
>>> d2 = bzrdir.ScratchDir()
340
>>> br2 = d2.open_branch()
341
>>> wt2 = d2.open_workingtree()
342
>>> br1.missing_revisions(br2)
344
>>> wt2.commit("lala!", rev_id="REVISION-ID-1")
346
>>> br1.missing_revisions(br2)
348
>>> br2.missing_revisions(br1)
350
>>> wt1.commit("lala!", rev_id="REVISION-ID-1")
352
>>> br1.missing_revisions(br2)
354
>>> wt2.commit("lala!", rev_id="REVISION-ID-2A")
356
>>> br1.missing_revisions(br2)
358
>>> wt1.commit("lala!", rev_id="REVISION-ID-2B")
360
>>> br1.missing_revisions(br2)
361
Traceback (most recent call last):
362
DivergedBranches: These branches have diverged. Try merge.
364
316
self_history = self.revision_history()
365
317
self_len = len(self_history)
376
328
assert isinstance(stop_revision, int)
377
329
if stop_revision > other_len:
378
raise bzrlib.errors.NoSuchRevision(self, stop_revision)
330
raise errors.NoSuchRevision(self, stop_revision)
379
331
return other_history[self_len:stop_revision]
381
333
def update_revisions(self, other, stop_revision=None):
578
530
In particular this checks that revisions given in the revision-history
579
531
do actually match up in the revision graph, and that they're all
580
532
present in the repository.
534
Callers will typically also want to check the repository.
582
536
:return: A BranchCheckResult.
587
541
revision = self.repository.get_revision(revision_id)
588
542
except errors.NoSuchRevision, e:
589
raise BzrCheckError("mainline revision {%s} not in repository"
543
raise errors.BzrCheckError("mainline revision {%s} not in repository"
591
545
# In general the first entry on the revision history has no parents.
592
546
# But it's not illegal for it to have parents listed; this can happen
593
547
# in imports from Arch when the parents weren't reachable.
594
548
if mainline_parent_id is not None:
595
549
if mainline_parent_id not in revision.parent_ids:
596
raise BzrCheckError("previous revision {%s} not listed among "
550
raise errors.BzrCheckError("previous revision {%s} not listed among "
597
551
"parents of {%s}"
598
552
% (mainline_parent_id, revision_id))
599
553
mainline_parent_id = revision_id
767
721
utf8_files = [('revision-history', ''),
768
722
('branch-name', ''),
770
control_files = LockableFiles(branch_transport, 'lock', LockDir)
724
control_files = LockableFiles(branch_transport, 'lock', lockdir.LockDir)
771
725
control_files.create_lock()
772
726
control_files.lock_write()
773
727
control_files.put_utf8('format', self.get_format_string())
792
746
format = BranchFormat.find_format(a_bzrdir)
793
747
assert format.__class__ == self.__class__
794
748
transport = a_bzrdir.get_branch_transport(None)
795
control_files = LockableFiles(transport, 'lock', LockDir)
749
control_files = LockableFiles(transport, 'lock', lockdir.LockDir)
796
750
return BzrBranch5(_format=self,
797
751
_control_files=control_files,
798
752
a_bzrdir=a_bzrdir,
913
867
self._base = self._transport.base
914
868
self._format = _format
915
869
if _control_files is None:
916
raise BzrBadParameterMissing('_control_files')
870
raise ValueError('BzrBranch _control_files is None')
917
871
self.control_files = _control_files
918
872
if deprecated_passed(init):
919
873
warn("BzrBranch.__init__(..., init=XXX): The init parameter is "
935
889
if (not relax_version_check
936
890
and not self._format.is_supported()):
937
raise errors.UnsupportedFormatError(
938
'sorry, branch format %r not supported' % fmt,
939
['use a different bzr version',
940
'or remove the .bzr directory'
941
' and "bzr init" again'])
891
raise errors.UnsupportedFormatError(format=fmt)
942
892
if deprecated_passed(transport):
943
893
warn("BzrBranch.__init__(transport=XXX...): The transport "
944
894
"parameter is deprecated as of bzr 0.8. "
1011
961
FIXME: DELETE THIS METHOD when pre 0.8 support is removed.
1013
963
if format is None:
1014
format = BzrBranchFormat.find_format(self.bzrdir)
964
format = BranchFormat.find_format(self.bzrdir)
1015
965
self._format = format
1016
966
mutter("got branch format %s", self._format)
1100
1050
return list(history)
1102
1052
@needs_write_lock
1053
def generate_revision_history(self, revision_id, last_rev=None,
1055
"""Create a new revision history that will finish with revision_id.
1057
:param revision_id: the new tip to use.
1058
:param last_rev: The previous last_revision. If not None, then this
1059
must be a ancestory of revision_id, or DivergedBranches is raised.
1060
:param other_branch: The other branch that DivergedBranches should
1061
raise with respect to.
1063
# stop_revision must be a descendant of last_revision
1064
stop_graph = self.repository.get_revision_graph(revision_id)
1065
if last_rev is not None and last_rev not in stop_graph:
1066
# our previous tip is not merged into stop_revision
1067
raise errors.DivergedBranches(self, other_branch)
1068
# make a new revision history from the graph
1069
current_rev_id = revision_id
1071
while current_rev_id not in (None, revision.NULL_REVISION):
1072
new_history.append(current_rev_id)
1073
current_rev_id_parents = stop_graph[current_rev_id]
1075
current_rev_id = current_rev_id_parents[0]
1077
current_rev_id = None
1078
new_history.reverse()
1079
self.set_revision_history(new_history)
1103
1082
def update_revisions(self, other, stop_revision=None):
1104
1083
"""See Branch.update_revisions."""
1105
1084
other.lock_read()
1119
1098
if stop_revision in my_ancestry:
1120
1099
# last_revision is a descendant of stop_revision
1122
# stop_revision must be a descendant of last_revision
1123
stop_graph = self.repository.get_revision_graph(stop_revision)
1124
if last_rev is not None and last_rev not in stop_graph:
1125
# our previous tip is not merged into stop_revision
1126
raise errors.DivergedBranches(self, other)
1127
# make a new revision history from the graph
1128
current_rev_id = stop_revision
1130
while current_rev_id not in (None, NULL_REVISION):
1131
new_history.append(current_rev_id)
1132
current_rev_id_parents = stop_graph[current_rev_id]
1134
current_rev_id = current_rev_id_parents[0]
1136
current_rev_id = None
1137
new_history.reverse()
1138
self.set_revision_history(new_history)
1101
self.generate_revision_history(stop_revision, last_rev=last_rev,
1146
1110
@deprecated_method(zero_eight)
1147
1111
def working_tree(self):
1148
1112
"""Create a Working tree object for this branch."""
1149
from bzrlib.workingtree import WorkingTree
1150
1114
from bzrlib.transport.local import LocalTransport
1151
1115
if (self.base.find('://') != -1 or
1152
1116
not isinstance(self._transport, LocalTransport)):
1191
1155
def get_push_location(self):
1192
1156
"""See Branch.get_push_location."""
1193
config = bzrlib.config.BranchConfig(self)
1194
push_loc = config.get_user_option('push_location')
1157
push_loc = self.get_config().get_user_option('push_location')
1195
1158
return push_loc
1197
1160
def set_push_location(self, location):
1198
1161
"""See Branch.set_push_location."""
1199
config = bzrlib.config.LocationConfig(self.base)
1200
config.set_user_option('push_location', location)
1162
self.get_config().set_user_option('push_location', location,
1202
1165
@needs_write_lock
1203
1166
def set_parent(self, url):
1221
1184
url = urlutils.relative_url(self.base, url)
1222
1185
self.control_files.put('parent', url + '\n')
1187
@deprecated_function(zero_nine)
1224
1188
def tree_config(self):
1189
"""DEPRECATED; call get_config instead.
1190
TreeConfig has become part of BranchConfig."""
1225
1191
return TreeConfig(self)
1418
1384
@deprecated_function(zero_eight)
1419
def ScratchBranch(*args, **kwargs):
1420
"""See bzrlib.bzrdir.ScratchDir."""
1421
d = ScratchDir(*args, **kwargs)
1422
return d.open_branch()
1425
@deprecated_function(zero_eight)
1426
1385
def is_control_file(*args, **kwargs):
1427
1386
"""See bzrlib.workingtree.is_control_file."""
1428
1387
return bzrlib.workingtree.is_control_file(*args, **kwargs)