96
91
super(UseExistingRepository, self).__init__(
97
stack_on, stack_on_pwd, require_stacking)
92
stack_on, stack_on_pwd, require_stacking)
98
93
self._repository = repository
100
95
def acquire_repository(self, make_working_trees=None, shared=False,
101
possible_transports=None):
96
possible_transports=None):
102
97
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
104
99
Returns an existing repository to use.
164
159
# Create/update the result branch
166
161
result = ControlDir.open_from_transport(target_transport)
167
except bzr_errors.NotBranchError:
162
except brz_errors.NotBranchError:
168
163
result = cloning_format.initialize_on_transport(target_transport)
169
164
source_branch = self.open_branch()
170
165
source_repository = self.find_repository()
172
167
result_repo = result.find_repository()
173
except bzr_errors.NoRepositoryPresent:
168
except brz_errors.NoRepositoryPresent:
174
169
result_repo = result.create_repository()
175
target_is_empty = True
177
target_is_empty = None # Unknown
179
raise _mod_branch.UnstackableBranchFormat(self._format, self.user_url)
171
raise _mod_branch.UnstackableBranchFormat(
172
self._format, self.user_url)
180
173
interrepo = InterRepository.get(source_repository, result_repo)
182
175
if revision_id is not None:
186
179
determine_wants = interrepo.determine_wants_all
187
180
interrepo.fetch_objects(determine_wants=determine_wants,
188
mapping=source_branch.mapping)
189
result_branch = source_branch.sprout(result,
190
revision_id=revision_id, repository=result_repo)
191
if (create_tree_if_local
192
and isinstance(target_transport, LocalTransport)
193
and (result_repo is None or result_repo.make_working_trees())):
194
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
181
mapping=source_branch.mapping)
182
result_branch = source_branch.sprout(
183
result, revision_id=revision_id, repository=result_repo)
184
if (create_tree_if_local and
185
isinstance(target_transport, LocalTransport) and
186
(result_repo is None or result_repo.make_working_trees())):
187
result.create_workingtree(
188
accelerator_tree=accelerator_tree,
195
189
hardlink=hardlink, from_branch=result_branch)
198
192
def clone_on_transport(self, transport, revision_id=None,
199
force_new_repo=False, preserve_stacking=False, stacked_on=None,
200
create_prefix=False, use_existing_dir=True, no_tree=False):
193
force_new_repo=False, preserve_stacking=False,
194
stacked_on=None, create_prefix=False,
195
use_existing_dir=True, no_tree=False):
201
196
"""See ControlDir.clone_on_transport."""
202
197
from ..repository import InterRepository
203
198
from .mapping import default_mapping
204
199
if stacked_on is not None:
205
raise _mod_branch.UnstackableBranchFormat(self._format, self.user_url)
200
raise _mod_branch.UnstackableBranchFormat(
201
self._format, self.user_url)
207
203
format = BareLocalGitControlDirFormat()
209
205
format = LocalGitControlDirFormat()
210
206
(target_repo, target_controldir, stacking,
211
repo_policy) = format.initialize_on_transport_ex(
212
transport, use_existing_dir=use_existing_dir,
213
create_prefix=create_prefix,
214
force_new_repo=force_new_repo)
207
repo_policy) = format.initialize_on_transport_ex(
208
transport, use_existing_dir=use_existing_dir,
209
create_prefix=create_prefix,
210
force_new_repo=force_new_repo)
215
211
target_repo = target_controldir.find_repository()
216
212
target_git_repo = target_repo._git
217
213
source_repo = self.find_repository()
218
source_git_repo = source_repo._git
219
214
interrepo = InterRepository.get(source_repo, target_repo)
220
215
if revision_id is not None:
221
determine_wants = interrepo.get_determine_wants_revids([revision_id], include_tags=True)
216
determine_wants = interrepo.get_determine_wants_revids(
217
[revision_id], include_tags=True)
223
219
determine_wants = interrepo.determine_wants_all
224
220
(pack_hint, _, refs) = interrepo.fetch_objects(determine_wants,
225
mapping=default_mapping)
221
mapping=default_mapping)
226
222
for name, val in viewitems(refs):
227
223
target_git_repo.refs[name] = val
228
224
result_dir = self.__class__(transport, target_git_repo, format)
296
293
push_result.master_branch = None
297
294
push_result.source_branch = source
298
295
push_result.stacked_on = None
299
repo = self.find_repository()
300
refname = self._get_selected_ref(name)
301
296
from .branch import GitBranch
302
297
if isinstance(source, GitBranch) and lossy:
303
raise bzr_errors.LossyPushToSameVCS(source.controldir, self)
298
raise brz_errors.LossyPushToSameVCS(source.controldir, self)
304
299
target = self.open_branch(name, nascent_ok=True)
305
300
push_result.branch_push_result = source.push(
306
target, overwrite=overwrite, stop_revision=revision_id,
301
target, overwrite=overwrite, stop_revision=revision_id,
308
303
push_result.new_revid = push_result.branch_push_result.new_revid
309
304
push_result.old_revid = push_result.branch_push_result.old_revid
310
push_result.target_branch = self.open_branch(name)
305
push_result.target_branch = target
311
306
if source.get_push_location() is None or remember:
312
307
source.set_push_location(push_result.target_branch.base)
313
308
return push_result
343
338
from .transportgit import TransportRepo
344
340
def _open(transport):
345
341
return TransportRepo(transport, self.bare,
346
refs_text=getattr(self, "_refs_text", None))
342
refs_text=getattr(self, "_refs_text", None))
347
344
def redirected(transport, e, redirection_notice):
348
345
trace.note(redirection_notice)
349
346
return transport._redirected_to(e.source, e.target)
350
347
gitrepo = do_catching_redirections(_open, transport, redirected)
351
348
if not gitrepo._controltransport.has('HEAD'):
352
raise bzr_errors.NotBranchError(path=transport.base)
349
raise brz_errors.NotBranchError(path=transport.base)
353
350
return LocalGitDir(transport, gitrepo, self)
355
352
def get_format_description(self):
358
355
def initialize_on_transport(self, transport):
359
356
from .transportgit import TransportRepo
360
repo = TransportRepo.init(transport, bare=self.bare)
361
return self.open(transport)
357
git_repo = TransportRepo.init(transport, bare=self.bare)
358
return LocalGitDir(transport, git_repo, self)
363
360
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
364
create_prefix=False, force_new_repo=False, stacked_on=None,
365
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
366
shared_repo=False, vfs_only=False):
361
create_prefix=False, force_new_repo=False,
363
stack_on_pwd=None, repo_format_name=None,
364
make_working_trees=None,
365
shared_repo=False, vfs_only=False):
367
366
def make_directory(transport):
368
367
transport.mkdir('.')
370
370
def redirected(transport, e, redirection_notice):
371
371
trace.note(redirection_notice)
372
372
return transport._redirected_to(e.source, e.target)
374
transport = do_catching_redirections(make_directory, transport,
376
except bzr_errors.FileExists:
374
transport = do_catching_redirections(
375
make_directory, transport, redirected)
376
except brz_errors.FileExists:
377
377
if not use_existing_dir:
379
except bzr_errors.NoSuchFile:
379
except brz_errors.NoSuchFile:
380
380
if not create_prefix:
382
382
transport.create_prefix()
444
444
self._mode_check_done = None
446
446
def is_control_filename(self, filename):
447
return (filename == '.git' or
448
filename.startswith('.git/') or
449
filename.startswith('.git\\'))
447
return (filename == '.git'
448
or filename.startswith('.git/')
449
or filename.startswith('.git\\'))
451
451
def _get_symref(self, ref):
452
from dulwich.repo import SYMREF
453
452
ref_chain, unused_sha = self._git.refs.follow(ref)
454
453
if len(ref_chain) == 1:
458
457
def set_branch_reference(self, target_branch, name=None):
459
458
ref = self._get_selected_ref(name)
460
if self.control_transport.base == target_branch.controldir.control_transport.base:
459
target_transport = target_branch.controldir.control_transport
460
if self.control_transport.base == target_transport.base:
461
461
if ref == target_branch.ref:
462
462
raise BranchReferenceLoop(target_branch)
463
463
self._git.refs.set_symbolic_ref(ref, target_branch.ref)
466
target_path = target_branch.controldir.control_transport.local_abspath('.')
467
except bzr_errors.NotLocalUrl:
468
raise bzr_errors.IncompatibleFormat(target_branch._format, self._format)
467
target_branch.controldir.control_transport.local_abspath(
469
except brz_errors.NotLocalUrl:
470
raise brz_errors.IncompatibleFormat(
471
target_branch._format, self._format)
469
472
# TODO(jelmer): Do some consistency checking across branches..
470
self.control_transport.put_bytes('commondir', target_path.encode('utf-8'))
473
self.control_transport.put_bytes(
474
'commondir', target_path.encode('utf-8'))
471
475
# TODO(jelmer): Urgh, avoid mucking about with internals.
472
self._git._commontransport = target_branch.repository._git._commontransport.clone()
473
self._git.object_store = TransportObjectStore(self._git._commontransport.clone(OBJECTDIR))
476
self._git._commontransport = (
477
target_branch.repository._git._commontransport.clone())
478
self._git.object_store = TransportObjectStore(
479
self._git._commontransport.clone(OBJECTDIR))
474
480
self._git.refs.transport = self._git._commontransport
475
target_ref_chain, unused_sha = target_branch.controldir._git.refs.follow(target_branch.ref)
481
target_ref_chain, unused_sha = (
482
target_branch.controldir._git.refs.follow(target_branch.ref))
476
483
for target_ref in target_ref_chain:
477
484
if target_ref == b'HEAD':
481
488
# Can't create a reference to something that is not a in a repository.
482
raise bzr_errors.IncompatibleFormat(self.set_branch_reference, self)
489
raise brz_errors.IncompatibleFormat(
490
self.set_branch_reference, self)
483
491
self._git.refs.set_symbolic_ref(ref, target_ref)
485
493
def get_branch_reference(self, name=None):
519
528
return self.transport
520
529
if isinstance(branch_format, LocalGitControlDirFormat):
521
530
return self.transport
522
raise bzr_errors.IncompatibleFormat(branch_format, self._format)
531
raise brz_errors.IncompatibleFormat(branch_format, self._format)
524
533
def get_repository_transport(self, format):
525
534
if format is None:
526
535
return self.transport
527
536
if isinstance(format, LocalGitControlDirFormat):
528
537
return self.transport
529
raise bzr_errors.IncompatibleFormat(format, self._format)
538
raise brz_errors.IncompatibleFormat(format, self._format)
531
540
def get_workingtree_transport(self, format):
532
541
if format is None:
533
542
return self.transport
534
543
if isinstance(format, LocalGitControlDirFormat):
535
544
return self.transport
536
raise bzr_errors.IncompatibleFormat(format, self._format)
545
raise brz_errors.IncompatibleFormat(format, self._format)
538
547
def open_branch(self, name=None, unsupported=False, ignore_fallbacks=None,
539
ref=None, possible_transports=None, nascent_ok=False):
548
ref=None, possible_transports=None, nascent_ok=False):
540
549
"""'create' a branch for this dir."""
541
550
repo = self.find_repository()
542
551
from .branch import LocalGitBranch
543
552
ref = self._get_selected_ref(name, ref)
544
553
if not nascent_ok and ref not in self._git.refs:
545
raise bzr_errors.NotBranchError(self.root_transport.base,
554
raise brz_errors.NotBranchError(
555
self.root_transport.base, controldir=self)
547
556
ref_chain, unused_sha = self._git.refs.follow(ref)
548
557
if ref_chain[-1] == b'HEAD':
549
558
controldir = self
555
564
refname = self._get_selected_ref(name)
556
565
if refname == b'HEAD':
557
566
# HEAD can't be removed
558
raise bzr_errors.UnsupportedOperation(
567
raise brz_errors.UnsupportedOperation(
559
568
self.destroy_branch, self)
561
570
del self._git.refs[refname]
563
raise bzr_errors.NotBranchError(self.root_transport.base,
572
raise brz_errors.NotBranchError(
573
self.root_transport.base, controldir=self)
566
575
def destroy_repository(self):
567
raise bzr_errors.UnsupportedOperation(self.destroy_repository, self)
576
raise brz_errors.UnsupportedOperation(self.destroy_repository, self)
569
578
def destroy_workingtree(self):
570
raise bzr_errors.UnsupportedOperation(self.destroy_workingtree, self)
579
raise brz_errors.UnsupportedOperation(self.destroy_workingtree, self)
572
581
def destroy_workingtree_metadata(self):
573
raise bzr_errors.UnsupportedOperation(self.destroy_workingtree_metadata, self)
582
raise brz_errors.UnsupportedOperation(
583
self.destroy_workingtree_metadata, self)
575
585
def needs_format_conversion(self, format=None):
576
586
return not isinstance(self._format, format.__class__)
587
597
def open_workingtree(self, recommend_upgrade=True, unsupported=False):
588
598
if not self._git.bare:
589
from dulwich.errors import NoIndexPresent
590
599
repo = self.find_repository()
591
600
from .workingtree import GitWorkingTree
592
601
branch = self.open_branch(ref=b'HEAD', nascent_ok=True)
593
602
return GitWorkingTree(self, repo, branch)
594
603
loc = urlutils.unescape_for_display(self.root_transport.base, 'ascii')
595
raise bzr_errors.NoWorkingTree(loc)
604
raise brz_errors.NoWorkingTree(loc)
597
606
def create_repository(self, shared=False):
598
607
from .repository import GitRepositoryFormat
600
raise bzr_errors.IncompatibleFormat(GitRepositoryFormat(), self._format)
609
raise brz_errors.IncompatibleFormat(
610
GitRepositoryFormat(), self._format)
601
611
return self.find_repository()
603
613
def create_branch(self, name=None, repository=None,
604
614
append_revisions_only=None, ref=None):
605
615
refname = self._get_selected_ref(name, ref)
606
616
if refname != b'HEAD' and refname in self._git.refs:
607
raise bzr_errors.AlreadyBranchError(self.user_url)
617
raise brz_errors.AlreadyBranchError(self.user_url)
608
618
repo = self.open_repository()
609
619
if refname in self._git.refs:
610
ref_chain, unused_sha = self._git.refs.follow(self._get_selected_ref(None))
620
ref_chain, unused_sha = self._git.refs.follow(
621
self._get_selected_ref(None))
611
622
if ref_chain[0] == b'HEAD':
612
623
refname = ref_chain[1]
613
624
from .branch import LocalGitBranch
627
638
parent.copy_tree(basename, basename + ".backup")
629
640
def create_workingtree(self, revision_id=None, from_branch=None,
630
accelerator_tree=None, hardlink=False):
641
accelerator_tree=None, hardlink=False):
631
642
if self._git.bare:
632
raise bzr_errors.UnsupportedOperation(self.create_workingtree, self)
643
raise brz_errors.UnsupportedOperation(
644
self.create_workingtree, self)
633
645
if from_branch is None:
634
646
from_branch = self.open_branch(nascent_ok=True)
635
647
if revision_id is None: