83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
1 |
# Copyright (C) 2005 by Aaron Bentley
|
2 |
||
3 |
# This program is free software; you can redistribute it and/or modify
|
|
4 |
# it under the terms of the GNU General Public License as published by
|
|
5 |
# the Free Software Foundation; either version 2 of the License, or
|
|
6 |
# (at your option) any later version.
|
|
7 |
||
8 |
# This program is distributed in the hope that it will be useful,
|
|
9 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11 |
# GNU General Public License for more details.
|
|
12 |
||
13 |
# You should have received a copy of the GNU General Public License
|
|
14 |
# along with this program; if not, write to the Free Software
|
|
15 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
147.1.2
by Robert Collins
test empty import and tagged branches |
16 |
|
147.4.10
by Robert Collins
missing an errno import |
17 |
import errno |
18 |
||
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
19 |
from bzrlib.errors import BzrError |
20 |
from bzrlib.errors import NotBranchError, BzrCommandError, NoSuchRevision |
|
115
by aaron.bentley at utoronto
Import fixes from magnus@therning.org |
21 |
from bzrlib.branch import Branch |
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
22 |
from bzrlib.clone import copy_branch |
147.2.8
by Aaron Bentley
Quieten commits |
23 |
from bzrlib.commit import Commit, NullCommitReporter |
147.1.36
by Robert Collins
updates for bzr api changes |
24 |
from bzrlib.commands import Command |
25 |
from bzrlib.option import _global_option |
|
147.4.19
by Robert Collins
Update for integration move of read_working_inventory from Branch to WorkingTree. |
26 |
from bzrlib.workingtree import WorkingTree |
105
by Aaron Bentley
Fixed NoPyBaz detection |
27 |
from errors import NoPyBaz |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
28 |
try: |
147.2.3
by Aaron Bentley
Fixed import issues w/ PyBaz |
29 |
import pybaz |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
30 |
import pybaz.errors |
147.1.14
by Robert Collins
implement a namespace mapper |
31 |
from pybaz import NameParser as NameParser |
147.2.3
by Aaron Bentley
Fixed import issues w/ PyBaz |
32 |
from pybaz.backends.baz import null_cmd |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
33 |
except ImportError: |
147.2.3
by Aaron Bentley
Fixed import issues w/ PyBaz |
34 |
raise NoPyBaz |
147.2.2
by Aaron Bentley
Committed debugging changes |
35 |
from fai import iter_new_merges, direct_merges |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
36 |
import tempfile |
37 |
import os |
|
38 |
import os.path |
|
39 |
import shutil |
|
40 |
import bzrlib |
|
41 |
import bzrlib.trace |
|
42 |
import bzrlib.merge |
|
97
by aaron.bentley at utoronto
Added now-required imports |
43 |
import bzrlib.inventory |
44 |
import bzrlib.osutils |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
45 |
import sys |
46 |
import email.Utils |
|
47 |
from progress import * |
|
48 |
||
147.2.8
by Aaron Bentley
Quieten commits |
49 |
class ImportCommitReporter(NullCommitReporter): |
50 |
def __init__(self, pb): |
|
51 |
self.pb = pb |
|
52 |
||
53 |
def escaped(self, escape_count, message): |
|
54 |
self.pb.clear() |
|
55 |
bzrlib.trace.warning("replaced %d control characters in message" % |
|
56 |
escape_count) |
|
57 |
||
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
58 |
def add_id(files, id=None): |
59 |
"""Adds an explicit id to a list of files.
|
|
60 |
||
61 |
:param files: the name of the file to add an id to
|
|
62 |
:type files: list of str
|
|
63 |
:param id: tag one file using the specified id, instead of generating id
|
|
64 |
:type id: str
|
|
65 |
"""
|
|
66 |
args = ["add-id"] |
|
67 |
if id is not None: |
|
68 |
args.extend(["--id", id]) |
|
69 |
args.extend(files) |
|
70 |
return null_cmd(args) |
|
71 |
||
147.1.2
by Robert Collins
test empty import and tagged branches |
72 |
saved_dir = None |
73 |
||
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
74 |
def test_environ(): |
75 |
"""
|
|
76 |
>>> q = test_environ()
|
|
77 |
>>> os.path.exists(q)
|
|
78 |
True
|
|
79 |
>>> os.path.exists(os.path.join(q, "home", ".arch-params"))
|
|
80 |
True
|
|
81 |
>>> teardown_environ(q)
|
|
82 |
>>> os.path.exists(q)
|
|
83 |
False
|
|
84 |
"""
|
|
147.1.2
by Robert Collins
test empty import and tagged branches |
85 |
global saved_dir |
86 |
saved_dir = os.getcwdu() |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
87 |
tdir = tempfile.mkdtemp(prefix="testdir-") |
88 |
os.environ["HOME"] = os.path.join(tdir, "home") |
|
89 |
os.mkdir(os.environ["HOME"]) |
|
90 |
arch_dir = os.path.join(tdir, "archive_dir") |
|
91 |
pybaz.make_archive("test@example.com", arch_dir) |
|
92 |
work_dir = os.path.join(tdir, "work_dir") |
|
93 |
os.mkdir(work_dir) |
|
94 |
os.chdir(work_dir) |
|
95 |
pybaz.init_tree(work_dir, "test@example.com/test--test--0") |
|
96 |
lib_dir = os.path.join(tdir, "lib_dir") |
|
97 |
os.mkdir(lib_dir) |
|
98 |
pybaz.register_revision_library(lib_dir) |
|
99 |
pybaz.set_my_id("Test User<test@example.org>") |
|
100 |
return tdir |
|
101 |
||
102 |
def add_file(path, text, id): |
|
103 |
"""
|
|
104 |
>>> q = test_environ()
|
|
105 |
>>> add_file("path with space", "text", "lalala")
|
|
106 |
>>> tree = pybaz.tree_root(".")
|
|
107 |
>>> inv = list(tree.iter_inventory_ids(source=True, both=True))
|
|
108 |
>>> ("x_lalala", "path with space") in inv
|
|
109 |
True
|
|
110 |
>>> teardown_environ(q)
|
|
111 |
"""
|
|
112 |
file(path, "wb").write(text) |
|
113 |
add_id([path], id) |
|
114 |
||
115 |
||
116 |
def add_dir(path, id): |
|
117 |
"""
|
|
118 |
>>> q = test_environ()
|
|
119 |
>>> add_dir("path with\(sp) space", "lalala")
|
|
120 |
>>> tree = pybaz.tree_root(".")
|
|
121 |
>>> inv = list(tree.iter_inventory_ids(source=True, both=True))
|
|
122 |
>>> ("x_lalala", "path with\(sp) space") in inv
|
|
123 |
True
|
|
124 |
>>> teardown_environ(q)
|
|
125 |
"""
|
|
126 |
os.mkdir(path) |
|
127 |
add_id([path], id) |
|
128 |
||
129 |
def teardown_environ(tdir): |
|
147.1.2
by Robert Collins
test empty import and tagged branches |
130 |
os.chdir(saved_dir) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
131 |
shutil.rmtree(tdir) |
132 |
||
133 |
def timport(tree, summary): |
|
134 |
msg = tree.log_message() |
|
135 |
msg["summary"] = summary |
|
136 |
tree.import_(msg) |
|
137 |
||
138 |
def commit(tree, summary): |
|
139 |
"""
|
|
140 |
>>> q = test_environ()
|
|
141 |
>>> tree = pybaz.tree_root(".")
|
|
142 |
>>> timport(tree, "import")
|
|
143 |
>>> commit(tree, "commit")
|
|
144 |
>>> logs = [str(l.revision) for l in tree.iter_logs()]
|
|
145 |
>>> len(logs)
|
|
146 |
2
|
|
147 |
>>> logs[0]
|
|
148 |
'test@example.com/test--test--0--base-0'
|
|
149 |
>>> logs[1]
|
|
150 |
'test@example.com/test--test--0--patch-1'
|
|
151 |
>>> teardown_environ(q)
|
|
152 |
"""
|
|
153 |
msg = tree.log_message() |
|
154 |
msg["summary"] = summary |
|
155 |
tree.commit(msg) |
|
156 |
||
157 |
def commit_test_revisions(): |
|
158 |
"""
|
|
159 |
>>> q = test_environ()
|
|
160 |
>>> commit_test_revisions()
|
|
161 |
>>> a = pybaz.Archive("test@example.com")
|
|
162 |
>>> revisions = list(a.iter_revisions("test--test--0"))
|
|
163 |
>>> len(revisions)
|
|
164 |
3
|
|
165 |
>>> str(revisions[2])
|
|
166 |
'test@example.com/test--test--0--base-0'
|
|
167 |
>>> str(revisions[1])
|
|
168 |
'test@example.com/test--test--0--patch-1'
|
|
169 |
>>> str(revisions[0])
|
|
170 |
'test@example.com/test--test--0--patch-2'
|
|
171 |
>>> teardown_environ(q)
|
|
172 |
"""
|
|
173 |
tree = pybaz.tree_root(".") |
|
174 |
add_file("mainfile", "void main(void){}", "mainfile by aaron") |
|
175 |
timport(tree, "Created mainfile") |
|
176 |
file("mainfile", "wb").write("or something like that") |
|
177 |
commit(tree, "altered mainfile") |
|
178 |
add_file("ofile", "this is another file", "ofile by aaron") |
|
179 |
commit(tree, "altered mainfile") |
|
180 |
||
181 |
||
182 |
def commit_more_test_revisions(): |
|
183 |
"""
|
|
184 |
>>> q = test_environ()
|
|
185 |
>>> commit_test_revisions()
|
|
186 |
>>> commit_more_test_revisions()
|
|
187 |
>>> a = pybaz.Archive("test@example.com")
|
|
188 |
>>> revisions = list(a.iter_revisions("test--test--0"))
|
|
189 |
>>> len(revisions)
|
|
190 |
4
|
|
191 |
>>> str(revisions[0])
|
|
192 |
'test@example.com/test--test--0--patch-3'
|
|
193 |
>>> teardown_environ(q)
|
|
194 |
"""
|
|
195 |
tree = pybaz.tree_root(".") |
|
196 |
add_file("trainfile", "void train(void){}", "trainfile by aaron") |
|
197 |
commit(tree, "altered trainfile") |
|
198 |
||
199 |
class NoSuchVersion(Exception): |
|
200 |
def __init__(self, version): |
|
201 |
Exception.__init__(self, "The version %s does not exist." % version) |
|
202 |
self.version = version |
|
203 |
||
204 |
def version_ancestry(version): |
|
205 |
"""
|
|
206 |
>>> q = test_environ()
|
|
207 |
>>> commit_test_revisions()
|
|
208 |
>>> version = pybaz.Version("test@example.com/test--test--0")
|
|
209 |
>>> ancestors = version_ancestry(version)
|
|
210 |
>>> str(ancestors[0])
|
|
211 |
'test@example.com/test--test--0--base-0'
|
|
212 |
>>> str(ancestors[1])
|
|
213 |
'test@example.com/test--test--0--patch-1'
|
|
214 |
>>> version = pybaz.Version("test@example.com/test--test--0.5")
|
|
215 |
>>> ancestors = version_ancestry(version)
|
|
216 |
Traceback (most recent call last):
|
|
217 |
NoSuchVersion: The version test@example.com/test--test--0.5 does not exist.
|
|
218 |
>>> teardown_environ(q)
|
|
219 |
"""
|
|
220 |
try: |
|
221 |
revision = version.iter_revisions(reverse=True).next() |
|
147.2.7
by Aaron Bentley
Handle empty versions correctly |
222 |
except StopIteration: |
223 |
return () |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
224 |
except: |
147.1.2
by Robert Collins
test empty import and tagged branches |
225 |
print version |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
226 |
if not version.exists(): |
227 |
raise NoSuchVersion(version) |
|
228 |
else: |
|
229 |
raise
|
|
230 |
ancestors = list(revision.iter_ancestors(metoo=True)) |
|
231 |
ancestors.reverse() |
|
232 |
return ancestors |
|
233 |
||
234 |
def get_last_revision(branch): |
|
221
by abentley
bzrtools 0.1.1 (baz-import patch) |
235 |
last_patch = branch.last_revision() |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
236 |
try: |
237 |
return arch_revision(last_patch) |
|
238 |
except NotArchRevision: |
|
239 |
raise UserError( |
|
240 |
"Directory \"%s\" already exists, and the last revision is not" |
|
147.2.10
by Aaron Bentley
Improved error handling, esp when invoking on wrong branch |
241 |
" an Arch revision (%s)" % (branch.base, last_patch)) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
242 |
|
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
243 |
def do_branch(br_from, to_location, revision_id): |
244 |
"""Derived from branch in builtins."""
|
|
245 |
br_from.lock_read() |
|
246 |
try: |
|
247 |
try: |
|
248 |
os.mkdir(to_location) |
|
249 |
except OSError, e: |
|
250 |
if e.errno == errno.EEXIST: |
|
251 |
raise UserError('Target directory "%s" already' |
|
252 |
' exists.' % to_location) |
|
253 |
if e.errno == errno.ENOENT: |
|
254 |
raise UserError('Parent of "%s" does not exist.' % |
|
255 |
to_location) |
|
256 |
else: |
|
257 |
raise
|
|
258 |
try: |
|
259 |
copy_branch(br_from, to_location, revision_id, None) |
|
260 |
except NoSuchRevision: |
|
261 |
rmtree(to_location) |
|
262 |
msg = "The branch %s has no revision %s." % (from_location, revision_id) |
|
263 |
raise UserError(msg) |
|
264 |
finally: |
|
265 |
br_from.unlock() |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
266 |
|
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
267 |
def get_remaining_revisions(output_dir, version, reuse_history_from=[]): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
268 |
last_patch = None |
269 |
old_revno = None |
|
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
270 |
output_exists = os.path.exists(output_dir) |
271 |
if output_exists: |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
272 |
# We are starting from an existing directory, figure out what
|
273 |
# the current version is
|
|
147.1.29
by Robert Collins
update to latest bzr api |
274 |
branch = Branch.open(output_dir) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
275 |
last_patch = get_last_revision(branch) |
278
by Aaron Bentley
Handled cases where user supplies empty directories or branches |
276 |
if last_patch is None: |
277 |
raise NotPreviousImport(branch.base) |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
278 |
if version is None: |
279 |
version = last_patch.version |
|
280 |
elif version is None: |
|
281 |
raise UserError("No version specified, and directory does not exist.") |
|
282 |
||
283 |
try: |
|
284 |
ancestors = version_ancestry(version) |
|
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
285 |
if not output_exists and reuse_history_from != []: |
286 |
for ancestor in reversed(ancestors): |
|
147.4.11
by Robert Collins
tweak to fix reusing history with more than one candidate ancestor |
287 |
if last_patch is not None: |
288 |
# found something to copy
|
|
289 |
break
|
|
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
290 |
# try to grab a copy of ancestor
|
291 |
# note that is not optimised: we could look for namespace
|
|
292 |
# transitions and only look for the past after the
|
|
293 |
# transition.
|
|
294 |
for history_root in reuse_history_from: |
|
295 |
possible_source = os.path.join(history_root, |
|
296 |
map_namespace(ancestor.version)) |
|
297 |
try: |
|
298 |
source = Branch.open(possible_source) |
|
299 |
rev_id = revision_id(ancestor) |
|
300 |
if rev_id in source.revision_history(): |
|
301 |
do_branch(source, output_dir, rev_id) |
|
302 |
last_patch = ancestor |
|
303 |
break
|
|
304 |
except NotBranchError: |
|
305 |
pass
|
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
306 |
except NoSuchVersion, e: |
147.1.37
by Robert Collins
get all tests passing again, and disable importing the body of continuation log messages |
307 |
raise UserError(str(e)) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
308 |
|
309 |
if last_patch: |
|
310 |
for i in range(len(ancestors)): |
|
311 |
if ancestors[i] == last_patch: |
|
312 |
break
|
|
313 |
else: |
|
314 |
raise UserError("Directory \"%s\" already exists, and the last " |
|
315 |
"revision (%s) is not in the ancestry of %s" % |
|
316 |
(output_dir, last_patch, version)) |
|
317 |
# Strip off all of the ancestors which are already present
|
|
318 |
# And get a directory starting with the latest ancestor
|
|
319 |
latest_ancestor = ancestors[i] |
|
147.1.29
by Robert Collins
update to latest bzr api |
320 |
old_revno = Branch.open(output_dir).revno() |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
321 |
ancestors = ancestors[i+1:] |
322 |
return ancestors, old_revno |
|
323 |
||
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
324 |
|
325 |
###class Importer(object):
|
|
326 |
### """An importer.
|
|
327 |
###
|
|
328 |
### Currently this is used as a parameter object, though more behaviour is
|
|
329 |
### possible later.
|
|
330 |
### """
|
|
331 |
###
|
|
332 |
### def __init__(self, output_dir, version, printer, fancy=True, fast=False,
|
|
333 |
### verbose=False, dry_run=False, max_count=None,
|
|
334 |
### reuse_history_from=[]):
|
|
335 |
### self.output_dir = output_dir
|
|
336 |
### self.version = version
|
|
337 |
### self.
|
|
338 |
||
339 |
||
147.1.17
by Robert Collins
make feedback be callback based - really |
340 |
def import_version(output_dir, version, printer, fancy=True, fast=False, |
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
341 |
verbose=False, dry_run=False, max_count=None, |
342 |
reuse_history_from=[]): |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
343 |
"""
|
344 |
>>> q = test_environ()
|
|
345 |
>>> result_path = os.path.join(q, "result")
|
|
346 |
>>> commit_test_revisions()
|
|
347 |
>>> version = pybaz.Version("test@example.com/test--test--0.1")
|
|
147.1.20
by Robert Collins
handle missing ancestry |
348 |
>>> def printer(message): print message
|
349 |
>>> import_version('/', version, printer, fancy=False, dry_run=True)
|
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
350 |
Traceback (most recent call last):
|
147.1.45
by Aaron Bentley
Fixed test case |
351 |
NotPreviousImport: / is not the location of a previous import.
|
147.1.20
by Robert Collins
handle missing ancestry |
352 |
>>> import_version(result_path, version, printer, fancy=False, dry_run=True)
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
353 |
Traceback (most recent call last):
|
354 |
UserError: The version test@example.com/test--test--0.1 does not exist.
|
|
355 |
>>> version = pybaz.Version("test@example.com/test--test--0")
|
|
147.1.20
by Robert Collins
handle missing ancestry |
356 |
>>> import_version(result_path, version, printer, fancy=False, dry_run=True)
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
357 |
not fancy
|
358 |
....
|
|
359 |
Dry run, not modifying output_dir
|
|
360 |
Cleaning up
|
|
147.1.20
by Robert Collins
handle missing ancestry |
361 |
>>> import_version(result_path, version, printer, fancy=False)
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
362 |
not fancy
|
363 |
....
|
|
364 |
Cleaning up
|
|
365 |
Import complete.
|
|
147.1.20
by Robert Collins
handle missing ancestry |
366 |
>>> import_version(result_path, version, printer, fancy=False)
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
367 |
Tree is up-to-date with test@example.com/test--test--0--patch-2
|
368 |
>>> commit_more_test_revisions()
|
|
147.1.20
by Robert Collins
handle missing ancestry |
369 |
>>> import_version(result_path, version, printer, fancy=False)
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
370 |
not fancy
|
371 |
..
|
|
372 |
Cleaning up
|
|
373 |
Import complete.
|
|
374 |
>>> teardown_environ(q)
|
|
375 |
"""
|
|
376 |
try: |
|
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
377 |
ancestors, old_revno = get_remaining_revisions(output_dir, version, |
378 |
reuse_history_from) |
|
147.1.2
by Robert Collins
test empty import and tagged branches |
379 |
except NotBranchError, e: |
278
by Aaron Bentley
Handled cases where user supplies empty directories or branches |
380 |
raise NotPreviousImport(e.path) |
147.2.7
by Aaron Bentley
Handle empty versions correctly |
381 |
if old_revno is None and len(ancestors) == 0: |
382 |
print 'Version %s has no revisions.' % version |
|
383 |
return
|
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
384 |
if len(ancestors) == 0: |
147.1.29
by Robert Collins
update to latest bzr api |
385 |
last_revision = get_last_revision(Branch.open(output_dir)) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
386 |
print 'Tree is up-to-date with %s' % last_revision |
387 |
return
|
|
388 |
||
389 |
progress_bar = ProgressBar() |
|
390 |
tempdir = tempfile.mkdtemp(prefix="baz2bzr-", |
|
391 |
dir=os.path.dirname(output_dir)) |
|
392 |
try: |
|
393 |
if not fancy: |
|
394 |
print "not fancy" |
|
395 |
try: |
|
396 |
for result in iter_import_version(output_dir, ancestors, tempdir, |
|
147.2.8
by Aaron Bentley
Quieten commits |
397 |
progress_bar, fast=fast, verbose=verbose, dry_run=dry_run, |
147.1.6
by Robert Collins
import symlinks (needs symlink enabled bzr) |
398 |
max_count=max_count): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
399 |
if fancy: |
102
by Aaron Bentley
Got baz2bzr/annotate working now that ProgressBar is a function |
400 |
show_progress(progress_bar, result) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
401 |
else: |
402 |
sys.stdout.write('.') |
|
403 |
finally: |
|
404 |
if fancy: |
|
90
by Aaron Bentley
Adapted bzrlib's progress bar |
405 |
progress_bar.clear() |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
406 |
else: |
407 |
sys.stdout.write('\n') |
|
408 |
||
409 |
if dry_run: |
|
410 |
print 'Dry run, not modifying output_dir' |
|
411 |
return
|
|
412 |
if os.path.exists(output_dir): |
|
413 |
# Move the bzr control directory back, and update the working tree
|
|
147.4.5
by Robert Collins
When an import finds a revision it needs already in the branch, just append it to the revision history |
414 |
revdir = os.path.join(tempdir, "rd") |
415 |
if os.path.exists(revdir): |
|
416 |
# actual imports were done
|
|
417 |
tmp_bzr_dir = os.path.join(tempdir, '.bzr') |
|
418 |
||
419 |
bzr_dir = os.path.join(output_dir, '.bzr') |
|
420 |
new_bzr_dir = os.path.join(tempdir, "rd", '.bzr') |
|
421 |
||
422 |
os.rename(bzr_dir, tmp_bzr_dir) # Move the original bzr out of the way |
|
423 |
os.rename(new_bzr_dir, bzr_dir) |
|
424 |
try: |
|
425 |
bzrlib.merge.merge((output_dir, -1), (output_dir, None), # old_revno), |
|
426 |
check_clean=False, this_dir=output_dir, |
|
427 |
ignore_zero=True) |
|
428 |
except: |
|
429 |
# If something failed, move back the original bzr directory
|
|
430 |
os.rename(bzr_dir, new_bzr_dir) |
|
431 |
os.rename(tmp_bzr_dir, bzr_dir) |
|
432 |
raise
|
|
433 |
else: |
|
434 |
# no imports - perhaps just append_revisions
|
|
435 |
# should not fail:
|
|
147.1.25
by Robert Collins
when will I learn to make check first |
436 |
bzrlib.merge.merge((output_dir, -1), (output_dir, None), # old_revno), |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
437 |
check_clean=False, this_dir=output_dir, |
438 |
ignore_zero=True) |
|
439 |
else: |
|
440 |
revdir = os.path.join(tempdir, "rd") |
|
441 |
os.rename(revdir, output_dir) |
|
442 |
||
443 |
finally: |
|
147.1.17
by Robert Collins
make feedback be callback based - really |
444 |
printer('Cleaning up') |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
445 |
shutil.rmtree(tempdir) |
147.1.17
by Robert Collins
make feedback be callback based - really |
446 |
printer("Import complete.") |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
447 |
|
278
by Aaron Bentley
Handled cases where user supplies empty directories or branches |
448 |
class UserError(BzrCommandError): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
449 |
def __init__(self, message): |
450 |
"""Exception to throw when a user makes an impossible request
|
|
451 |
:param message: The message to emit when printing this exception
|
|
452 |
:type message: string
|
|
453 |
"""
|
|
278
by Aaron Bentley
Handled cases where user supplies empty directories or branches |
454 |
BzrCommandError.__init__(self, message) |
455 |
||
456 |
class NotPreviousImport(UserError): |
|
457 |
def __init__(self, path): |
|
458 |
UserError.__init__(self, "%s is not the location of a previous import." |
|
459 |
% path) |
|
460 |
||
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
461 |
|
462 |
def revision_id(arch_revision): |
|
463 |
"""
|
|
464 |
Generate a Bzr revision id from an Arch revision id. 'x' in the id
|
|
465 |
designates a revision imported with an experimental algorithm. A number
|
|
466 |
would indicate a particular standardized version.
|
|
467 |
||
468 |
:param arch_revision: The Arch revision to generate an ID for.
|
|
469 |
||
470 |
>>> revision_id(pybaz.Revision("you@example.com/cat--br--0--base-0"))
|
|
147.1.2
by Robert Collins
test empty import and tagged branches |
471 |
'Arch-1:you@example.com%cat--br--0--base-0'
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
472 |
"""
|
147.1.2
by Robert Collins
test empty import and tagged branches |
473 |
return "Arch-1:%s" % str(arch_revision).replace('/', '%') |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
474 |
|
475 |
class NotArchRevision(Exception): |
|
476 |
def __init__(self, revision_id): |
|
477 |
msg = "The revision id %s does not look like it came from Arch."\ |
|
478 |
% revision_id |
|
479 |
Exception.__init__(self, msg) |
|
480 |
||
481 |
def arch_revision(revision_id): |
|
482 |
"""
|
|
147.1.2
by Robert Collins
test empty import and tagged branches |
483 |
>>> str(arch_revision("Arch-1:jrandom@example.com%test--test--0"))
|
484 |
Traceback (most recent call last):
|
|
485 |
NotArchRevision: The revision id Arch-1:jrandom@example.com%test--test--0 does not look like it came from Arch.
|
|
486 |
>>> str(arch_revision("Arch-1:jrandom@example.com%test--test--0--base-5"))
|
|
487 |
Traceback (most recent call last):
|
|
488 |
NotArchRevision: The revision id Arch-1:jrandom@example.com%test--test--0--base-5 does not look like it came from Arch.
|
|
489 |
>>> str(arch_revision("Arch-1:jrandom@example.com%test--test--0--patch-5"))
|
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
490 |
'jrandom@example.com/test--test--0--patch-5'
|
491 |
"""
|
|
492 |
if revision_id is None: |
|
493 |
return None |
|
147.1.2
by Robert Collins
test empty import and tagged branches |
494 |
if revision_id[:7] != 'Arch-1:': |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
495 |
raise NotArchRevision(revision_id) |
496 |
else: |
|
497 |
try: |
|
498 |
return pybaz.Revision(revision_id[7:].replace('%', '/')) |
|
499 |
except pybaz.errors.NamespaceError, e: |
|
500 |
raise NotArchRevision(revision_id) |
|
501 |
||
147.2.8
by Aaron Bentley
Quieten commits |
502 |
def iter_import_version(output_dir, ancestors, tempdir, pb, fast=False, |
147.1.6
by Robert Collins
import symlinks (needs symlink enabled bzr) |
503 |
verbose=False, dry_run=False, max_count=None): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
504 |
revdir = None |
505 |
||
506 |
# Uncomment this for testing, it basically just has baz2bzr only update
|
|
507 |
# 5 patches at a time
|
|
508 |
if max_count: |
|
509 |
ancestors = ancestors[:max_count] |
|
510 |
||
511 |
# Not sure if I want this output. basically it tells you ahead of time
|
|
512 |
# what it is going to do, but then later it tells you as it is doing it.
|
|
513 |
# what probably would be best would be to collapse it into ranges, so that
|
|
514 |
# this gives the simple view, and then later it gives the blow by blow.
|
|
515 |
#if verbose:
|
|
516 |
# print 'Adding the following revisions:'
|
|
517 |
# for a in ancestors:
|
|
518 |
# print '\t%s' % a
|
|
519 |
||
520 |
previous_version=None |
|
147.1.20
by Robert Collins
handle missing ancestry |
521 |
missing_ancestor = None |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
522 |
|
523 |
for i in range(len(ancestors)): |
|
524 |
revision = ancestors[i] |
|
147.4.5
by Robert Collins
When an import finds a revision it needs already in the branch, just append it to the revision history |
525 |
rev_id = revision_id(revision) |
147.1.3
by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded |
526 |
direct_merges = [] |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
527 |
if verbose: |
528 |
version = str(revision.version) |
|
529 |
if version != previous_version: |
|
530 |
clear_progress_bar() |
|
531 |
print '\rOn version: %s' % version |
|
532 |
yield Progress(str(revision.patchlevel), i, len(ancestors)) |
|
533 |
previous_version = version |
|
534 |
else: |
|
535 |
yield Progress("revisions", i, len(ancestors)) |
|
147.4.5
by Robert Collins
When an import finds a revision it needs already in the branch, just append it to the revision history |
536 |
if revdir is None and os.path.exists(output_dir): |
537 |
# check for imported revisions and if present just append immediately
|
|
538 |
branch = Branch.open(output_dir) |
|
539 |
if branch.has_revision(rev_id): |
|
540 |
branch.append_revision(rev_id) |
|
541 |
continue
|
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
542 |
if revdir is None: |
543 |
revdir = os.path.join(tempdir, "rd") |
|
147.1.20
by Robert Collins
handle missing ancestry |
544 |
try: |
147.2.14
by abentley
Allouche: More efficient PyBaz use |
545 |
tree, baz_inv, log = get_revision(revdir, revision) |
147.1.20
by Robert Collins
handle missing ancestry |
546 |
except pybaz.errors.ExecProblem, e: |
547 |
if ("%s" % e.args).find('could not connect') == -1: |
|
548 |
raise
|
|
549 |
missing_ancestor = revision |
|
550 |
revdir = None |
|
551 |
print ("unable to access ancestor %s, making into a merge." |
|
552 |
% missing_ancestor) |
|
553 |
continue
|
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
554 |
if os.path.exists(output_dir): |
555 |
bzr_dir = os.path.join(output_dir, '.bzr') |
|
556 |
new_bzr_dir = os.path.join(tempdir, "rd", '.bzr') |
|
557 |
# This would be much faster with a simple os.rename(), but if
|
|
558 |
# we fail, we have corrupted the original .bzr directory. Is
|
|
559 |
# that a big problem, as we can just back out the last
|
|
560 |
# revisions in .bzr/revision_history I don't really know
|
|
147.4.5
by Robert Collins
When an import finds a revision it needs already in the branch, just append it to the revision history |
561 |
# RBC20051024 - yes, it would be a problem as we could not then
|
562 |
# apply the corrupted revision.
|
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
563 |
shutil.copytree(bzr_dir, new_bzr_dir) |
564 |
# Now revdir should have a tree with the latest .bzr, and the
|
|
565 |
# next revision of the baz tree
|
|
147.1.29
by Robert Collins
update to latest bzr api |
566 |
branch = Branch.open(revdir) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
567 |
else: |
158
by Aaron Bentley
Updated to match API changes |
568 |
branch = Branch.initialize(revdir) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
569 |
else: |
570 |
old = os.path.join(revdir, ".bzr") |
|
571 |
new = os.path.join(tempdir, ".bzr") |
|
572 |
os.rename(old, new) |
|
147.2.14
by abentley
Allouche: More efficient PyBaz use |
573 |
baz_inv, log = apply_revision(tree, revision) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
574 |
os.rename(new, old) |
147.1.29
by Robert Collins
update to latest bzr api |
575 |
branch = Branch.open(revdir) |
147.4.2
by Robert Collins
use direct merge log always, whether its a new tree or a patch being applied |
576 |
# cached so we can delete the log
|
577 |
log_date = log.date |
|
578 |
log_summary = log.summary |
|
579 |
log_description = log.description |
|
580 |
is_continuation = log.continuation_of is not None |
|
581 |
log_creator = log.creator |
|
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
582 |
direct_merges = get_direct_merges(revdir, revision, log) |
147.4.2
by Robert Collins
use direct merge log always, whether its a new tree or a patch being applied |
583 |
|
147.1.3
by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded |
584 |
timestamp = email.Utils.mktime_tz(log_date + (0,)) |
147.2.5
by Aaron Bentley
Handled empty summary lines |
585 |
if log_summary is None: |
586 |
log_summary = "" |
|
147.1.37
by Robert Collins
get all tests passing again, and disable importing the body of continuation log messages |
587 |
# log_descriptions of None and "" are ignored.
|
588 |
if not is_continuation and log_description: |
|
147.2.9
by Aaron Bentley
Fixed log conversion |
589 |
log_message = "\n".join((log_summary, log_description)) |
590 |
else: |
|
591 |
log_message = log_summary |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
592 |
branch.lock_write() |
147.4.19
by Robert Collins
Update for integration move of read_working_inventory from Branch to WorkingTree. |
593 |
target_tree = WorkingTree(revdir ,branch=branch) |
594 |
target_tree.lock_write() |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
595 |
try: |
147.1.20
by Robert Collins
handle missing ancestry |
596 |
if missing_ancestor: |
597 |
# if we want it to be in revision-history, do that here.
|
|
147.4.20
by Robert Collins
Branch.commit->WorkingTree.commit |
598 |
target_tree.add_pending_merge(revision_id(missing_ancestor)) |
147.1.20
by Robert Collins
handle missing ancestry |
599 |
missing_ancestor = None |
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
600 |
for merged_rev in direct_merges: |
147.4.20
by Robert Collins
Branch.commit->WorkingTree.commit |
601 |
target_tree.add_pending_merge(revision_id(merged_rev)) |
147.4.19
by Robert Collins
Update for integration move of read_working_inventory from Branch to WorkingTree. |
602 |
target_tree.set_inventory(baz_inv) |
147.2.8
by Aaron Bentley
Quieten commits |
603 |
commitobj = Commit(reporter=ImportCommitReporter(pb)) |
147.2.9
by Aaron Bentley
Fixed log conversion |
604 |
commitobj.commit(branch, log_message.decode('ascii', 'replace'), |
605 |
verbose=False, committer=log_creator, |
|
606 |
timestamp=timestamp, timezone=0, rev_id=rev_id) |
|
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
607 |
finally: |
147.4.19
by Robert Collins
Update for integration move of read_working_inventory from Branch to WorkingTree. |
608 |
target_tree.unlock() |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
609 |
branch.unlock() |
610 |
yield Progress("revisions", len(ancestors), len(ancestors)) |
|
611 |
unlink_unversioned(branch, revdir) |
|
612 |
||
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
613 |
def get_direct_merges(revdir, revision, log): |
614 |
continuation = log.continuation_of |
|
615 |
previous_version = revision.version |
|
616 |
if pybaz.WorkingTree(revdir).tree_version != previous_version: |
|
617 |
pybaz.WorkingTree(revdir).set_tree_version(previous_version) |
|
147.1.3
by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded |
618 |
log_path = "%s/{arch}/%s/%s/%s/%s/patch-log/%s" % (revdir, |
619 |
revision.category.nonarch, revision.branch.nonarch, |
|
620 |
revision.version.nonarch, revision.archive, revision.patchlevel) |
|
147.2.13
by abentley
Allouche: always use a temp dir on the same filesystem |
621 |
temp_path = tempfile.mktemp(dir=os.path.dirname(revdir)) |
147.1.3
by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded |
622 |
os.rename(log_path, temp_path) |
147.1.24
by Robert Collins
trim fai cribbage |
623 |
merges = list(iter_new_merges(revdir, revision.version)) |
147.4.6
by Robert Collins
Fix continuation direct_merges output, and allow reusing history in a version import |
624 |
direct = direct_merges(merges, [continuation]) |
147.1.3
by Robert Collins
test and deliver basic pending-merges into bzr so that merging is recorded |
625 |
os.rename(temp_path, log_path) |
626 |
return direct |
|
627 |
||
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
628 |
def unlink_unversioned(branch, revdir): |
629 |
for unversioned in branch.working_tree().extras(): |
|
630 |
path = os.path.join(revdir, unversioned) |
|
631 |
if os.path.isdir(path): |
|
632 |
shutil.rmtree(path) |
|
633 |
else: |
|
634 |
os.unlink(path) |
|
635 |
||
636 |
def get_log(tree, revision): |
|
147.2.14
by abentley
Allouche: More efficient PyBaz use |
637 |
log = pybaz.Patchlog(revision, tree=tree) |
133
by Aaron Bentley
Weakened check so baz-import works |
638 |
assert str(log.revision) == str(revision), (log.revision, revision) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
639 |
return log |
640 |
||
147.1.6
by Robert Collins
import symlinks (needs symlink enabled bzr) |
641 |
def get_revision(revdir, revision): |
147.2.14
by abentley
Allouche: More efficient PyBaz use |
642 |
tree = revision.get(revdir) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
643 |
log = get_log(tree, revision) |
644 |
try: |
|
147.2.14
by abentley
Allouche: More efficient PyBaz use |
645 |
return tree, bzr_inventory_data(tree), log |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
646 |
except BadFileKind, e: |
647 |
raise UserError("Cannot convert %s because %s is a %s" % (revision,e.path, e.kind) ) |
|
648 |
||
649 |
||
147.2.14
by abentley
Allouche: More efficient PyBaz use |
650 |
def apply_revision(tree, revision): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
651 |
revision.apply(tree) |
652 |
log = get_log(tree, revision) |
|
653 |
try: |
|
147.1.6
by Robert Collins
import symlinks (needs symlink enabled bzr) |
654 |
return bzr_inventory_data(tree), log |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
655 |
except BadFileKind, e: |
656 |
raise UserError("Cannot convert %s because %s is a %s" % (revision,e.path, e.kind) ) |
|
657 |
||
658 |
||
659 |
class BadFileKind(Exception): |
|
660 |
"""The file kind is not permitted in bzr inventories"""
|
|
661 |
def __init__(self, tree_root, path, kind): |
|
662 |
self.tree_root = tree_root |
|
663 |
self.path = path |
|
664 |
self.kind = kind |
|
665 |
Exception.__init__(self, "File %s is of forbidden type %s" % |
|
666 |
(os.path.join(tree_root, path), kind)) |
|
667 |
||
147.1.29
by Robert Collins
update to latest bzr api |
668 |
|
147.1.6
by Robert Collins
import symlinks (needs symlink enabled bzr) |
669 |
def bzr_inventory_data(tree): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
670 |
inv_iter = tree.iter_inventory_ids(source=True, both=True) |
671 |
inv_map = {} |
|
106
by Aaron Bentley
Used limited url-encoding for file ids |
672 |
for arch_id, path in inv_iter: |
147.4.1
by Robert Collins
test escaping of file ids is working |
673 |
bzr_file_id = map_file_id(arch_id) |
106
by Aaron Bentley
Used limited url-encoding for file ids |
674 |
inv_map[path] = bzr_file_id |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
675 |
|
676 |
bzr_inv = [] |
|
677 |
for path, file_id in inv_map.iteritems(): |
|
678 |
full_path = os.path.join(tree, path) |
|
679 |
kind = bzrlib.osutils.file_kind(full_path) |
|
147.1.6
by Robert Collins
import symlinks (needs symlink enabled bzr) |
680 |
if kind not in ("file", "directory", "symlink"): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
681 |
raise BadFileKind(tree, path, kind) |
682 |
parent_dir = os.path.dirname(path) |
|
683 |
if parent_dir != "": |
|
684 |
parent_id = inv_map[parent_dir] |
|
685 |
else: |
|
686 |
parent_id = bzrlib.inventory.ROOT_ID |
|
687 |
bzr_inv.append((path, file_id, parent_id, kind)) |
|
688 |
bzr_inv.sort() |
|
689 |
return bzr_inv |
|
690 |
||
147.1.36
by Robert Collins
updates for bzr api changes |
691 |
_global_option('max-count', type = int) |
147.1.11
by Robert Collins
move baz-import to baz-import-branch |
692 |
class cmd_baz_import_branch(Command): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
693 |
"""Import an Arch or Baz branch into a bzr branch"""
|
147.4.13
by Robert Collins
add a reuse_history option to the baz-import-branch command too. |
694 |
takes_args = ['to_location', 'from_branch?', 'reuse_history*'] |
147.2.10
by Aaron Bentley
Improved error handling, esp when invoking on wrong branch |
695 |
takes_options = ['verbose', 'max-count'] |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
696 |
|
147.1.17
by Robert Collins
make feedback be callback based - really |
697 |
def printer(self, name): |
698 |
print name |
|
699 |
||
147.1.6
by Robert Collins
import symlinks (needs symlink enabled bzr) |
700 |
def run(self, to_location, from_branch=None, fast=False, max_count=None, |
147.4.13
by Robert Collins
add a reuse_history option to the baz-import-branch command too. |
701 |
verbose=False, dry_run=False, reuse_history_list=[]): |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
702 |
to_location = os.path.realpath(str(to_location)) |
703 |
if from_branch is not None: |
|
704 |
try: |
|
100
by Aaron Bentley
Fixed up the baz-import plugin |
705 |
from_branch = pybaz.Version(from_branch) |
83
by Aaron Bentley
Moved most baz2bzr code to baz_import, added Python plugin |
706 |
except pybaz.errors.NamespaceError: |
707 |
print "%s is not a valid Arch branch." % from_branch |
|
708 |
return 1 |
|
147.4.13
by Robert Collins
add a reuse_history option to the baz-import-branch command too. |
709 |
if reuse_history_list is None: |
710 |
reuse_history_list = [] |
|
147.2.10
by Aaron Bentley
Improved error handling, esp when invoking on wrong branch |
711 |
import_version(to_location, from_branch, self.printer, |
147.1.44
by Aaron Bentley
Merged the bzrtools mainline |
712 |
max_count=max_count, |
713 |
reuse_history_from=reuse_history_list) |
|
714 |
||
715 |
||
716 |
class NotInABranch(Exception): |
|
717 |
def __init__(self, path): |
|
718 |
Exception.__init__(self, "%s is not in a branch." % path) |
|
719 |
self.path = path |
|
147.1.11
by Robert Collins
move baz-import to baz-import-branch |
720 |
|
147.1.29
by Robert Collins
update to latest bzr api |
721 |
|
147.1.11
by Robert Collins
move baz-import to baz-import-branch |
722 |
class cmd_baz_import(Command): |
147.4.8
by Robert Collins
Enable reuse of history on archive imports, just append the history locations to the command line |
723 |
"""Import an Arch or Baz archive into bzr branches.
|
724 |
|
|
725 |
reuse_history allows you to specify any previous imports you
|
|
726 |
have done of different archives, which this archive has branches
|
|
727 |
tagged from. This will dramatically reduce the time to convert
|
|
728 |
the archive as it will not have to convert the history already
|
|
729 |
converted in that other branch.
|
|
730 |
"""
|
|
731 |
takes_args = ['to_root_dir', 'from_archive', 'reuse_history*'] |
|
147.1.11
by Robert Collins
move baz-import to baz-import-branch |
732 |
takes_options = ['verbose'] |
733 |
||
147.1.16
by Robert Collins
make feedback be callback based |
734 |
def printer(self, name): |
735 |
print name |
|
736 |
||
147.4.8
by Robert Collins
Enable reuse of history on archive imports, just append the history locations to the command line |
737 |
def run(self, to_root_dir, from_archive, verbose=False, |
738 |
reuse_history_list=[]): |
|
147.4.9
by Robert Collins
But do not require a history location. |
739 |
if reuse_history_list is None: |
740 |
reuse_history_list = [] |
|
147.1.18
by Robert Collins
baz-import twice should work |
741 |
to_root = str(os.path.realpath(to_root_dir)) |
147.1.12
by Robert Collins
create the output directory |
742 |
if not os.path.exists(to_root): |
743 |
os.mkdir(to_root) |
|
147.4.8
by Robert Collins
Enable reuse of history on archive imports, just append the history locations to the command line |
744 |
import_archive(to_root, from_archive, verbose, self.printer, |
745 |
reuse_history_list) |
|
746 |
||
747 |
||
748 |
def import_archive(to_root, from_archive, verbose, printer, |
|
749 |
reuse_history_from=[]): |
|
750 |
real_to = os.path.realpath(to_root) |
|
751 |
history_locations = [real_to] + reuse_history_from |
|
147.1.18
by Robert Collins
baz-import twice should work |
752 |
for version in pybaz.Archive(str(from_archive)).iter_versions(): |
147.1.15
by Robert Collins
archive at a time imports |
753 |
target = os.path.join(to_root, map_namespace(version)) |
147.1.16
by Robert Collins
make feedback be callback based |
754 |
printer("importing %s into %s" % (version, target)) |
147.1.18
by Robert Collins
baz-import twice should work |
755 |
if not os.path.exists(os.path.dirname(target)): |
756 |
os.makedirs(os.path.dirname(target)) |
|
147.4.3
by Robert Collins
dont block archive wide baz-imports when a single version fails dur to either an unbuildable revision or a diverged branch. |
757 |
try: |
147.4.8
by Robert Collins
Enable reuse of history on archive imports, just append the history locations to the command line |
758 |
import_version(target, version, printer, |
759 |
reuse_history_from=reuse_history_from) |
|
147.4.3
by Robert Collins
dont block archive wide baz-imports when a single version fails dur to either an unbuildable revision or a diverged branch. |
760 |
except pybaz.errors.ExecProblem,e: |
761 |
if str(e).find('The requested revision cannot be built.') != -1: |
|
762 |
printer("Skipping version %s as it cannot be built due" |
|
763 |
" to a missing parent archive." % version) |
|
764 |
else: |
|
765 |
raise
|
|
766 |
except UserError, e: |
|
767 |
if str(e).find('already exists, and the last revision ') != -1: |
|
768 |
printer("Skipping version %s as it has had commits made" |
|
769 |
" since it was converted to bzr." % version) |
|
770 |
else: |
|
771 |
raise
|
|
147.1.13
by Robert Collins
create the output directory |
772 |
|
147.1.29
by Robert Collins
update to latest bzr api |
773 |
|
147.1.13
by Robert Collins
create the output directory |
774 |
def map_namespace(a_version): |
147.1.14
by Robert Collins
implement a namespace mapper |
775 |
a_version = pybaz.Version("%s" % a_version) |
776 |
parser = NameParser(a_version) |
|
777 |
version = parser.get_version() |
|
778 |
branch = parser.get_branch() |
|
779 |
category = parser.get_category() |
|
780 |
if branch is None or branch == '': |
|
781 |
branch = "+trunk" |
|
782 |
if version == '0': |
|
783 |
return "%s/%s" % (category, branch) |
|
784 |
return "%s/%s/%s" % (category, version, branch) |
|
147.4.1
by Robert Collins
test escaping of file ids is working |
785 |
|
786 |
def map_file_id(file_id): |
|
787 |
"""Convert a baz file id to a bzr one."""
|
|
788 |
return file_id.replace('%', '%25').replace('/', '%2f') |