14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
from bzrlib.errors import NotBranchError, BzrCommandError
19
from bzrlib.errors import BzrError
20
from bzrlib.errors import NotBranchError, BzrCommandError, NoSuchRevision
18
21
from bzrlib.branch import Branch
22
from bzrlib.clone import copy_branch
19
23
from bzrlib.commit import Commit, NullCommitReporter
20
24
from bzrlib.commands import Command
21
25
from bzrlib.option import _global_option
236
239
"Directory \"%s\" already exists, and the last revision is not"
237
240
" an Arch revision (%s)" % (branch.base, last_patch))
242
def do_branch(br_from, to_location, revision_id):
243
"""Derived from branch in builtins."""
247
os.mkdir(to_location)
249
if e.errno == errno.EEXIST:
250
raise UserError('Target directory "%s" already'
251
' exists.' % to_location)
252
if e.errno == errno.ENOENT:
253
raise UserError('Parent of "%s" does not exist.' %
258
copy_branch(br_from, to_location, revision_id, None)
259
except NoSuchRevision:
261
msg = "The branch %s has no revision %s." % (from_location, revision_id)
240
def get_remaining_revisions(output_dir, version):
266
def get_remaining_revisions(output_dir, version, reuse_history_from=[]):
241
267
last_patch = None
243
if os.path.exists(output_dir):
269
output_exists = os.path.exists(output_dir)
244
271
# We are starting from an existing directory, figure out what
245
272
# the current version is
246
273
branch = Branch.open(output_dir)
254
281
ancestors = version_ancestry(version)
282
if not output_exists and reuse_history_from != []:
283
for ancestor in reversed(ancestors):
284
if last_patch is not None:
285
# found something to copy
287
# try to grab a copy of ancestor
288
# note that is not optimised: we could look for namespace
289
# transitions and only look for the past after the
291
for history_root in reuse_history_from:
292
possible_source = os.path.join(history_root,
293
map_namespace(ancestor.version))
295
source = Branch.open(possible_source)
296
rev_id = revision_id(ancestor)
297
if rev_id in source.revision_history():
298
do_branch(source, output_dir, rev_id)
299
last_patch = ancestor
301
except NotBranchError:
255
303
except NoSuchVersion, e:
256
304
raise UserError(str(e))
270
318
ancestors = ancestors[i+1:]
271
319
return ancestors, old_revno
322
###class Importer(object):
325
### Currently this is used as a parameter object, though more behaviour is
329
### def __init__(self, output_dir, version, printer, fancy=True, fast=False,
330
### verbose=False, dry_run=False, max_count=None,
331
### reuse_history_from=[]):
332
### self.output_dir = output_dir
333
### self.version = version
273
337
def import_version(output_dir, version, printer, fancy=True, fast=False,
274
verbose=False, dry_run=False, max_count=None):
338
verbose=False, dry_run=False, max_count=None,
339
reuse_history_from=[]):
276
341
>>> q = test_environ()
277
342
>>> result_path = os.path.join(q, "result")
306
371
>>> teardown_environ(q)
309
ancestors, old_revno = get_remaining_revisions(output_dir, version)
374
ancestors, old_revno = get_remaining_revisions(output_dir, version,
310
376
except NotBranchError, e:
311
377
raise UserError("%s exists, but is not a bzr branch." % output_dir)
312
378
if old_revno is None and len(ancestors) == 0:
504
570
log_description = log.description
505
571
is_continuation = log.continuation_of is not None
506
572
log_creator = log.creator
507
direct_merges = get_direct_merges(revdir, revision)
573
direct_merges = get_direct_merges(revdir, revision, log)
509
575
timestamp = email.Utils.mktime_tz(log_date + (0,))
510
576
if log_summary is None:
520
586
# if we want it to be in revision-history, do that here.
521
587
branch.add_pending_merge(revision_id(missing_ancestor))
522
588
missing_ancestor = None
523
for merge in direct_merges:
524
branch.add_pending_merge(revision_id(merge.revision))
589
for merged_rev in direct_merges:
590
branch.add_pending_merge(revision_id(merged_rev))
525
591
branch.set_inventory(baz_inv)
526
592
commitobj = Commit(reporter=ImportCommitReporter(pb))
527
593
commitobj.commit(branch, log_message.decode('ascii', 'replace'),
532
598
yield Progress("revisions", len(ancestors), len(ancestors))
533
599
unlink_unversioned(branch, revdir)
535
def get_direct_merges(revdir, revision):
536
if pybaz.WorkingTree(revdir).tree_version != revision.version:
537
pybaz.WorkingTree(revdir).set_tree_version(revision.version)
601
def get_direct_merges(revdir, revision, log):
602
continuation = log.continuation_of
603
previous_version = revision.version
604
if pybaz.WorkingTree(revdir).tree_version != previous_version:
605
pybaz.WorkingTree(revdir).set_tree_version(previous_version)
538
606
log_path = "%s/{arch}/%s/%s/%s/%s/patch-log/%s" % (revdir,
539
607
revision.category.nonarch, revision.branch.nonarch,
540
608
revision.version.nonarch, revision.archive, revision.patchlevel)
541
609
temp_path = tempfile.mktemp(dir=os.path.dirname(revdir))
542
610
os.rename(log_path, temp_path)
543
611
merges = list(iter_new_merges(revdir, revision.version))
544
direct = direct_merges (merges)
612
direct = direct_merges(merges, [continuation])
545
613
os.rename(temp_path, log_path)
611
679
_global_option('max-count', type = int)
612
680
class cmd_baz_import_branch(Command):
613
681
"""Import an Arch or Baz branch into a bzr branch"""
614
takes_args = ['to_location', 'from_branch?']
682
takes_args = ['to_location', 'from_branch?', 'reuse_history*']
615
683
takes_options = ['verbose', 'max-count']
617
685
def printer(self, name):
620
688
def run(self, to_location, from_branch=None, fast=False, max_count=None,
621
verbose=False, dry_run=False):
689
verbose=False, dry_run=False, reuse_history_list=[]):
622
690
to_location = os.path.realpath(str(to_location))
623
691
if from_branch is not None:
626
694
except pybaz.errors.NamespaceError:
627
695
print "%s is not a valid Arch branch." % from_branch
697
if reuse_history_list is None:
698
reuse_history_list = []
629
699
import_version(to_location, from_branch, self.printer,
700
max_count=max_count, reuse_history_from=reuse_history_list)
633
703
class cmd_baz_import(Command):
634
"""Import an Arch or Baz archive into bzr branches."""
635
takes_args = ['to_root_dir', 'from_archive']
704
"""Import an Arch or Baz archive into bzr branches.
706
reuse_history allows you to specify any previous imports you
707
have done of different archives, which this archive has branches
708
tagged from. This will dramatically reduce the time to convert
709
the archive as it will not have to convert the history already
710
converted in that other branch.
712
takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
636
713
takes_options = ['verbose']
638
715
def printer(self, name):
641
def run(self, to_root_dir, from_archive, verbose=False):
718
def run(self, to_root_dir, from_archive, verbose=False,
719
reuse_history_list=[]):
720
if reuse_history_list is None:
721
reuse_history_list = []
642
722
to_root = str(os.path.realpath(to_root_dir))
643
723
if not os.path.exists(to_root):
644
724
os.mkdir(to_root)
645
import_archive(to_root, from_archive, verbose, self.printer)
648
def import_archive(to_root, from_archive, verbose, printer):
725
import_archive(to_root, from_archive, verbose, self.printer,
729
def import_archive(to_root, from_archive, verbose, printer,
730
reuse_history_from=[]):
731
real_to = os.path.realpath(to_root)
732
history_locations = [real_to] + reuse_history_from
649
733
for version in pybaz.Archive(str(from_archive)).iter_versions():
650
734
target = os.path.join(to_root, map_namespace(version))
651
735
printer("importing %s into %s" % (version, target))
652
736
if not os.path.exists(os.path.dirname(target)):
653
737
os.makedirs(os.path.dirname(target))
655
import_version(target, version, printer)
739
import_version(target, version, printer,
740
reuse_history_from=reuse_history_from)
656
741
except pybaz.errors.ExecProblem,e:
657
742
if str(e).find('The requested revision cannot be built.') != -1:
658
743
printer("Skipping version %s as it cannot be built due"