I missed a test case before sending the patch..
I had tidied up the code but caused a problem if --subroot is not used.
This was caused by an 'issue' in os.path.join() which leaves
a trailing slash on a path when the next component is blank. Wrapping
join() in normpath()
solves the problem. I ran a combination of tests and all seems better.
using path.join() is neater than lots of if y: x=x+'/' + y , except
where y=None which
causes trouble, so strings are initialised to "".
Kim
================
--- cvs2svn.py Mon Sep 29 21:24:58 2003
+++ cvs2svn_new.py Mon Sep 29 22:55:43 2003
@@ -97,6 +97,7 @@
"""Record that REVISION is the branch number for BRANCH_NAME.
REVISION is an RCS branch number with an odd number of components,
for example '1.7.2' (never '1.7.0.2')."""
+
if self.branch_names.has_key(revision):
sys.stderr.write("Error while parsing '%s':\n"
" branch %s already has name '%s',\n"
@@ -110,6 +111,7 @@
"""Return the name of the branch on which REVISION lies.
REVISION is a non-branch evision number with an even number of,
components, for example '1.7.2.1' (never '1.7.2' nor '1.7.0.2')."""
+
return self.branch_names.get(revision[:revision.rindex(".")])
def add_branch_point(self, revision, branch_name):
@@ -116,6 +118,7 @@
"""Record that BRANCH_NAME sprouts from REVISION.
REVISION is a non-branch revision number with an even number of
components, for example '1.7' (never '1.7.2' nor '1.7.0.2')."""
+
if not self.branchlist.has_key(revision):
self.branchlist[revision] = []
self.branchlist[revision].append(branch_name)
@@ -289,6 +292,8 @@
#
# and the surrounding thread, for why what people really want is a
# way of specifying an in-repository prefix path, not interpolation.
+ #
+ # Now supports various prefix and infixes - Kim Lester, Sept 03
if branch_name and tag_name:
sys.stderr.write('make_path() miscalled: both branch and tag
given.\n')
@@ -295,22 +300,23 @@
sys.exit(1)
if branch_name:
- if path:
- return ctx.branches_base + '/' + branch_name + '/' + path
- else:
- return ctx.branches_base + '/' + branch_name
+ base = ctx.branches_base
+ name = branch_name
elif tag_name:
- if path:
- return ctx.tags_base + '/' + tag_name + '/' + path
- else:
- return ctx.tags_base + '/' + tag_name
+ base = ctx.tags_base
+ name = tag_name
else:
- if path:
- return ctx.trunk_base + '/' + path
- else:
- return ctx.trunk_base
+ base = ctx.trunk_base
+ name = ""
+ p = os.path.normpath(os.path.join(ctx.root, base, ctx.subroot, name,
path))
+
+ if ctx.debug:
+ print "MP: name:%s, path:%s, return:%s" %(name, path, p)
+ return p
+
+
def relative_name(cvsroot, fname):
l = len(cvsroot)
if fname[:l] == cvsroot:
@@ -420,6 +426,7 @@
The actual revision from which the path was copied, which
may be one less than the requested revision when the path
was deleted in the requested revision, or None."""
+
def __init__(self, op, closed_tags, closed_branches,
deleted_entries=None, copyfrom_rev=None):
self.op = op
@@ -475,6 +482,12 @@
self.revs_db[str(self.youngest)] = gen_key()
self.nodes_db[self.revs_db[str(self.youngest)]] = marshal.dumps({})
+ # Debug flag
+ self.debug = 0
+
+ def set_debug(self, debug):
+ self.debug = debug
+
def new_revision(self):
"""Stabilize the current revision, then start the next one.
(Increments youngest.)"""
@@ -498,7 +511,7 @@
root_key = self.revs_db[str(self.youngest)]
self._stabilize_directory(root_key)
- def probe_path(self, path, revision=-1, debugging=None):
+ def probe_path(self, path, revision=-1):
"""If PATH exists in REVISION of the svn repository mirror,
return its leaf value, else return None.
If DEBUGGING is true, then print trace output to stdout.
@@ -507,8 +520,8 @@
if revision == -1:
revision = self.youngest
- if debugging:
- print "PROBING path: '%s' in %d" % (path, revision)
+ if self.debug:
+ print "RM.probe_path: '%s' in %d" % (path, revision)
parent_key = self.revs_db[str(revision)]
parent = marshal.loads(self.nodes_db[parent_key])
@@ -517,14 +530,14 @@
i = 1
for component in components:
- if debugging:
+ if self.debug:
print " " * i,
print "'%s' key: %s, val:" % (previous_component, parent_key),
parent
if not parent.has_key(component):
- if debugging:
- print " PROBE ABANDONED: '%s' does not contain '%s'" \
- % (previous_component, component)
+ if self.debug:
+ print " Probing path: Failed: '%s' does not contain '%s'" \
+ % (previous_component, component)
return None
this_entry_key = parent[component]
@@ -534,7 +547,7 @@
previous_component = component
i = i + 1
- if debugging:
+ if self.debug:
print " " * i,
print "parent_key: %s, val:" % parent_key, parent
@@ -541,8 +554,8 @@
# It's not actually a parent at this point, it's the leaf node.
return parent
- def change_path(self, path, tags, branches,
- intermediate_dir_func=None,
+ def change_path(self, path, tags, branches,
+ intermediate_dir_func=None, dir_suppress_thresh=0,
copyfrom_path=None, copyfrom_rev=None,
expected_entries=None):
"""Record a change to PATH. PATH may not have a leading slash.
@@ -575,6 +588,10 @@
No action is taken for keys in EXPECTED_ENTRIES but not in the
dst; it is assumed that the caller will compensate for these by
calling change_path again with other arguments."""
+
+ if self.debug:
+ print "RM.change_path: path=", path
+
if ((copyfrom_rev and not copyfrom_path) or
(copyfrom_path and not copyfrom_rev)):
sys.stderr.write("error: change_path() called with one copyfrom "
@@ -592,6 +609,7 @@
self.nodes_db[parent_key] = marshal.dumps(parent)
self.revs_db[str(self.youngest)] = parent_key
+ i = 1
for component in components[:-1]:
# parent is always mutable at the top of the loop
@@ -600,6 +618,9 @@
else:
path_so_far = component
+ if self.debug:
+ print " checking path: %s" % path_so_far
+
# Ensure that the parent has an entry for this component.
if not parent.has_key(component):
new_child_key = gen_key()
@@ -606,9 +627,23 @@
parent[component] = new_child_key
self.nodes_db[new_child_key] =
marshal.dumps(self.empty_mutable_thang)
self.nodes_db[parent_key] = marshal.dumps(parent)
+
if intermediate_dir_func:
- intermediate_dir_func(path_so_far)
+ # if we are generating many dump files we need to prevent
+ # clashes on adding intermediate dirs more than once.
+ # since path_so_far is absolute and we know that all intermediate
+ # dirs are num_root_components + 1 (trunk/bra etc) +
num_subroot_comp - 1
+ if (i > dir_suppress_thresh):
+ if self.debug:
+ print " creating dir: %s" % path_so_far
+ intermediate_dir_func(path_so_far)
+ else:
+ if self.debug:
+ print " NOT creating dir (th:%d) %s" % \
+ (dir_suppress_thresh, path_so_far)
+ i = i + 1
+
# One way or another, parent dir now has an entry for component,
# so grab it, see if it's mutable, and DTRT if it's not. (Note
# it's important to reread the entry value from the db, even
@@ -847,6 +882,8 @@
self.revision = 0
self.dumpfile = open(dumpfile_path, 'wb')
self.repos_mirror = RepositoryMirror()
+ self.dir_suppress_thresh = 0
+ self.debug = 0
# Initialize the dumpfile with the standard headers:
#
@@ -855,7 +892,15 @@
# the dumpfile, we'll tell svnadmin to ignore the UUID below.
self.dumpfile.write('SVN-fs-dump-format-version: 2\n'
'\n')
+ def set_debug(self, debug):
+ self.debug = debug
+ self.repos_mirror.set_debug(debug)
+
+ def set_dir_suppress_threshold(self, thresh):
+ self.dir_suppress_thresh = thresh
+
+
def start_revision(self, props):
"""Write the next revision, with properties, to the dumpfile.
Return the newly started revision."""
@@ -925,6 +970,8 @@
return self.revision
def add_dir(self, path):
+ if self.debug:
+ print "add_dir: %s" % path
self.dumpfile.write("Node-path: %s\n"
"Node-kind: dir\n"
"Node-action: add\n"
@@ -938,6 +985,10 @@
def probe_path(self, path):
"""Return true if PATH exists in the youngest tree of the svn
repository, else return None. PATH does not start with '/'."""
+
+ if self.debug:
+ print "dumper.probe_path: %s " % path
+
if self.repos_mirror.probe_path(path) is None:
return None
else:
@@ -953,14 +1004,20 @@
No action is taken for keys in ENTRIES but not in the dst; it is
assumed that the caller will compensate for these by calling
copy_path again with other arguments."""
+
change = self.repos_mirror.change_path(svn_dst_path,
[], [],
self.add_dir,
+ self.dir_suppress_thresh,
svn_src_path, svn_src_rev,
entries)
if change.op == 'A':
# We don't need to include "Node-kind:" for copies; the loader
# ignores it anyway and just uses the source kind instead.
+ if self.debug:
+ print "copy_path Add: %s (%d) -> %s" % \
+ (svn_src_path, change.copyfrom_rev, svn_dst_path)
+
self.dumpfile.write('Node-path: %s\n'
'Node-action: add\n'
'Node-copyfrom-rev: %d\n'
@@ -969,6 +1026,9 @@
% (svn_dst_path, change.copyfrom_rev,
svn_src_path))
for ent in change.deleted_entries:
+ if self.debug:
+ print "copy_path Delete: %s" % (svn_dst_path + '|' + ent)
+
self.dumpfile.write('Node-path: %s\n'
'Node-action: delete\n'
'\n' % (svn_dst_path + '/' + ent))
@@ -980,6 +1040,7 @@
change = self.repos_mirror.change_path(path,
[], [],
self.add_dir,
+ self.dir_suppress_thresh,
None, None,
expected)
for ent in change.deleted_entries:
@@ -1022,7 +1083,8 @@
# be perfectly reliable, both because of 'cvs commit -r', and also
# the possibility of file resurrection.
change = self.repos_mirror.change_path(svn_path, tags, branches,
- self.add_dir)
+ self.add_dir,
+ self.dir_suppress_thresh)
if change.op == OP_ADD:
action = 'add'
@@ -1029,6 +1091,9 @@
else:
action = 'change'
+ if self.debug:
+ print "add/change path: %s : %s" % (action, svn_path)
+
self.dumpfile.write('Node-path: %s\n'
'Node-kind: file\n'
'Node-action: %s\n'
@@ -1220,18 +1285,18 @@
self.tags_copyfrom_rev_key = "/tags-copyfrom-rev"
self.br_copyfrom_rev_key = "/br-copyfrom-rev"
- def probe_path(self, symbolic_name, path, debugging=None):
+ def probe_path(self, symbolic_name, path):
"""If 'SYMBOLIC_NAME/PATH' exists in the symbolic name tree,
return the value of its last component, else return None.
- PATH may be None, but may not start with '/'.
- If DEBUGGING is true, then print trace output to stdout."""
+ PATH may be None, but may not start with '/'."""
+
if path:
components = [symbolic_name] + string.split(path, '/')
else:
components = [symbolic_name]
- if debugging:
- print "PROBING SYMBOLIC NAME:\n", components
+ if self.debug:
+ print "SNT.probe_path:\n", components
parent_key = self.root_key
parent = marshal.loads(self.db[parent_key])
@@ -1238,7 +1303,7 @@
last_component = "/"
i = 1
for component in components:
- if debugging:
+ if self.debug:
print " " * i,
print "'%s' key: %s, val:" % (last_component, parent_key),
parent
@@ -1254,7 +1319,7 @@
last_component = component
i = i + 1
- if debugging:
+ if self.debug:
print " " * i,
print "parent_key: %s, val:" % parent_key, parent
@@ -1261,6 +1326,7 @@
# It's not actually a parent at this point, it's the leaf node.
return parent
+
def bump_rev_count(self, item_key, rev, revlist_key):
"""Increment REV's count in opening or closing list under KEY.
REVLIST_KEY is self.*_opening_revs_key or self.*_closing_revs_key,
@@ -1471,6 +1537,11 @@
symbolic name anywhere in this descent.
('JIT' == 'Just In Time'.)"""
+
+ if self.debug:
+ print "copy/descend: nm:%s en:%s pr:%d\n\tsp:%s, dp:%s
it:%s\n\tpa:
%s" % \
+ (name, entry_name, parent_rev, src_path, dst_path, is_tag, parent)
+
### Hmmm, is passing [1] instead of 1 an idiomatic way of passing
### a side-effectable boolean in Python? That's how the
### JIT_NEW_REV parameter works here and elsewhere, but maybe
@@ -1489,6 +1560,9 @@
copyfrom_rev_key = self.br_copyfrom_rev_key
if not val.has_key(copyfrom_rev_key):
+ #if self.debug:
+ # print " copy/descend: get best rev"
+
# If not already copied this subdir, calculate its "best rev"
# and see if it differs from parent's best rev.
scores = self.score_revisions(val.get(opening_key),
val.get(closing_key))
@@ -1495,9 +1569,13 @@
rev = self.best_rev(scores)
if rev == SVN_INVALID_REVNUM:
+ # print " CD invalid rev num - END"
return # name is a branch, but we're doing a tag, or vice
versa
else:
+ if self.debug:
+ print " copy/descend: valid rev num %d" % rev
+
if is_tag:
copy_dst = make_path(ctx, dst_path, None, name)
else:
@@ -1508,6 +1586,7 @@
if jit_new_rev and jit_new_rev[0]:
dumper.start_revision(make_revision_props(name, is_tag))
jit_new_rev[0] = None
+
dumper.copy_path(src_path, parent_rev, copy_dst, val)
# Record that this copy is done:
val[copyfrom_rev_key] = parent_rev
@@ -1522,6 +1601,9 @@
# anything that's not part of the symbolic name.
dumper.prune_entries(copy_dst, val)
+ if self.debug:
+ print " copy/descend: iterate over entries"
+
for ent in val.keys():
if not ent[0] == '/':
if src_path:
@@ -1532,6 +1614,10 @@
next_dst = dst_path + '/' + ent
else:
next_dst = ent
+
+ if self.debug:
+ print " copy/descend: ns:%s nd:%s" % (next_src, next_dst)
+
self.copy_descend(dumper, ctx, name, val, ent, parent_rev,
next_src, next_dst, is_tag, jit_new_rev)
@@ -1567,6 +1653,9 @@
# revisions 6028 and 6347). If it changes again, the logic here
# must be adjusted to match.
+ if self.debug:
+ print "fill_name: create non-existant paths %s" % name
+
parent_key = self.root_key
parent = marshal.loads(self.db[parent_key])
@@ -1577,9 +1666,22 @@
sys.stderr.write("No origin records for branch '%s'.\n" % name)
sys.exit(1)
+ # gets child of name (ie skip trunk/branches/foo etc)
parent_key = parent[name]
parent = marshal.loads(self.db[parent_key])
+ comp_sp = []
+ if (ctx.root != ""):
+ comp_sp = string.split(ctx.root, '/')
+
+ # need to chain through ctx.root, not just take ctx.trunk_base
+ for comp in comp_sp:
+ if self.debug:
+ print " fill_name: getting child of %s" % comp
+ k = parent[comp]
+ parent = marshal.loads(self.db[k]) # contains the children of
parent k
+
+
# All Subversion source paths under the branch start with one of
# three things:
#
@@ -1610,13 +1712,65 @@
# overwrite one with the other as anything else -- anyway, isn't
# that what CVS would do if you checked out the branch? <shrug>
+ if self.debug:
+ print " fill_name: nm: %s pk:%s\n\tpa:%s", name, parent_key,
parent
+
if parent.has_key(ctx.trunk_base):
- self.copy_descend(dumper, ctx, name, parent, ctx.trunk_base,
- SVN_INVALID_REVNUM, ctx.trunk_base, "",
- is_tag, jit_new_rev)
+ if self.debug:
+ print " fill_name: trunk_base have_key(%s)" % ctx.trunk_base
+
+ rp = os.path.normpath(os.path.join(ctx.trunk_base, ctx.subroot))
+ ap = os.path.normpath(os.path.join(ctx.root, rp))
+
+ comp_rp = string.split(rp, '/')
+ head = comp_rp[-1]
+
+ if self.debug:
+ print " fill_name: trunk: ap:%s, head:%s" % (ap, head)
+
+ if (ctx.subroot != ""):
+ # need to chain through ctx.subroot, not just take ctx.trunk_base
+ for comp in comp_rp[:-1]:
+ if self.debug:
+ print " fill_name: trunk: sr: getting child of %s" % comp
+ print " fill_name: pa:%s" % (parent)
+
+ k = parent[comp]
+ parent = marshal.loads(self.db[k])
+
+ if self.debug:
+ print " fill_name: CD: en:%s, pa:%s" % (head, parent)
+
+ self.copy_descend(dumper, ctx, name, parent, head,
+ SVN_INVALID_REVNUM, ap, "", is_tag, jit_new_rev)
+
+ if self.debug:
+ print " fill_name: trunk_base END"
+
+ # NOTE: prev block changes parent. Can both parent.has_key(trunk,
branches)
+ # be called one after the other. If so does it matter if parent has
been
+ # changed or must I restore... - Kim
+
if parent.has_key(ctx.branches_base):
+ if self.debug:
+ print " fill_name: branches_base have_key(%s)" %
ctx.branches_base
+
+ # skip "branches" child !? :
branch_base_key = parent[ctx.branches_base]
branch_base = marshal.loads(self.db[branch_base_key])
+
+ comp_sr = string.split(ctx.subroot, '/')
+
+ if (ctx.subroot != ""):
+ # need to chain through ctx.subroot [1:] is just subroot
+ for comp in comp_sr:
+ if self.debug:
+ print " fill_name branches: getting child of: %s" % comp
+ print " fill_name: pa:%s" % (branch_base)
+
+ k = branch_base[comp]
+ branch_base = marshal.loads(self.db[k])
+
for this_source in branch_base.keys():
# We skip special names beginning with '/' for the usual
# reason. We skip cases where (this_source == name) for a
@@ -1625,11 +1779,19 @@
# different branches in an RCS file, which CVS doesn't
# permit. So while it wouldn't hurt to descend, it would be a
# waste of time.
+
+ if self.debug:
+ print " fill_name: branch keys iterator: this_source: %s" %
this_source
+
if (this_source[0] != '/') and (this_source != name):
- src_path = ctx.branches_base + '/' + this_source
+ src_path = os.path.normpath(os.path.join(ctx.root,
ctx.branches_base, ctx.subroot, this_source))
+ if self.debug:
+ print " fill_name: branches: ", src_path
self.copy_descend(dumper, ctx, name, branch_base,
this_source,
SVN_INVALID_REVNUM, src_path, "",
is_tag, jit_new_rev)
+ if self.debug:
+ print " fill_name: END"
def fill_tag(self, dumper, ctx, tag, jit_new_rev=None):
"""Use DUMPER to create all currently available parts of TAG that
@@ -1705,7 +1867,11 @@
self.deletes = [ ]
self.t_min = 1<<30
self.t_max = 0
+ self.debug = 0
+ def set_debug(self, debug):
+ self.debug = debug
+
def has_file(self, fname):
return self.files.has_key(fname)
@@ -1753,7 +1919,7 @@
def commit(self, dumper, ctx, sym_tracker):
# commit this transaction
seconds = self.t_max - self.t_min
- print 'committing: %s, over %d seconds' % (time.ctime(self.t_min),
seconds)
+ print '\ncommitting: %s, over %d seconds' %
(time.ctime(self.t_min),
seconds)
if seconds > COMMIT_THRESHOLD:
print 'WARNING: commit spans more than %d seconds' %
COMMIT_THRESHOLD
@@ -1798,6 +1964,9 @@
# compute a repository path, dropping the ,v from the file name
cvs_path = relative_name(ctx.cvsroot, rcs_file[:-2])
svn_path = make_path(ctx, cvs_path, br)
+
+ if self.debug:
+ print "\nchanges: (cvs_path:%s, br:%s, brs:%s)" % (cvs_path,
br,
branches)
if svn_rev == SVN_INVALID_REVNUM:
svn_rev = dumper.start_revision(props)
sym_tracker.enroot_tags(svn_path, svn_rev, tags)
@@ -1812,6 +1981,7 @@
### constant time query.
if not dumper.probe_path(svn_path):
sym_tracker.fill_branch(dumper, ctx, br)
+
# The first revision on a vendor branch is always the same as
# the revision from which the branch sprouts, e.g., 1.1.1.1 is
# always the same as 1.1, so there's no need to further modify
@@ -1829,6 +1999,9 @@
for rcs_file, cvs_rev, br, tags, branches in self.deletes:
# compute a repository path, dropping the ,v from the file name
+ if self.debug:
+ print "\ndeletes:"
+
cvs_path = relative_name(ctx.cvsroot, rcs_file[:-2])
svn_path = make_path(ctx, cvs_path, br)
print ' deleting %s : %s' % (cvs_rev, svn_path)
@@ -1864,7 +2037,10 @@
else:
print ' no new revision created, as nothing to do'
+ if self.debug:
+ print "end: commit"
+
def read_resync(fname):
"Read the .resync file into memory."
@@ -2002,6 +2178,7 @@
def pass4(ctx):
sym_tracker = SymbolicNameTracker()
+ sym_tracker.debug = ctx.debug
# A dictionary of Commit objects, keyed by digest. Each object
# represents one logical commit, which may involve multiple files.
@@ -2020,6 +2197,8 @@
# Start the dumpfile object.
dumper = Dumper(ctx.dumpfile)
+ dumper.set_debug(ctx.debug)
+ dumper.set_dir_suppress_threshold(ctx.dir_suppress_threshold)
# process the logfiles, creating the target
for line in fileinput.FileInput(ctx.log_fname_base +
SORTED_REVS_SUFFIX):
@@ -2059,6 +2238,7 @@
c = commits[id]
else:
c = commits[id] = Commit()
+ c.set_debug(ctx.debug)
c.add(timestamp, op, fname, rev, branch_name, tags, branches)
# End of the sorted revs file. Flush any remaining commits:
@@ -2126,10 +2306,11 @@
def usage(ctx):
- print 'USAGE: %s [-n] [-v] [-s svn-repos-path] [-p pass]
cvs-repos-path'
\
+ print 'USAGE: %s [-n] [-v] [-d] [-s svn-repos-path] [-p pass]
cvs-repos-path' \
% os.path.basename(sys.argv[0])
print ' -n dry run; parse CVS repos, but do not
construct
SVN repos'
print ' -v verbose'
+ print ' -d debug'
print ' -s PATH path for SVN repos'
print ' -p NUM start at pass NUM of %d' % len(_passes)
print ' --create create a new SVN repository'
@@ -2136,15 +2317,18 @@
print ' --dumpfile=PATH name of intermediate svn dumpfile'
print ' --svnadmin=PATH path to the svnadmin program'
print ' --trunk-only convert only trunk commits, not tags nor
branches'
- print ' --trunk=PATH path for trunk (default: %s)' \
+ print ' --trunk=DIR directory name for trunk (default: %s)'
\
% ctx.trunk_base
- print ' --branches=PATH path for branches (default: %s)' \
+ print ' --branches=DIR directory name for branches (default: %s)'
\
% ctx.branches_base
- print ' --tags=PATH path for tags (default: %s)' \
+ print ' --tags=DIR directory name for tags (default: %s)'
\
% ctx.tags_base
print ' --no-prune don\'t prune empty directories'
print ' --dump-only just produce a dumpfile, don\'t commit to a
repos'
print ' --encoding=ENC encoding of log messages in CVS repos
(default:
%s)' % ctx.encoding
+ print ' --root=PATH svn prefix path before trunk/branches/tags
(default: %s)' % ctx.root
+ print ' --subroot=PATH svn path after trunk/branches/tags
(default:
%s)' % ctx.subroot
+ print ' --suppress-parents suppresses output of parent dirs to
dumpfile (default: disabled)'
sys.exit(1)
@@ -2155,6 +2339,7 @@
ctx.target = None
ctx.log_fname_base = DATAFILE
ctx.dumpfile = DUMPFILE
+ ctx.debug = 0
ctx.verbose = 0
ctx.dry_run = 0
ctx.prune = 1
@@ -2166,10 +2351,15 @@
ctx.branches_base = "branches"
ctx.encoding = "ascii"
ctx.svnadmin = "svnadmin"
+ ctx.root = ""
+ ctx.subroot = ""
+ ctx.dir_suppress_threshold = 0
try:
- opts, args = getopt.getopt(sys.argv[1:], 'p:s:vn',
- [ "create", "trunk=",
+ opts, args = getopt.getopt(sys.argv[1:], 'p:s:vnd',
+ [ "create", "dumpfile=", "svnadmin=",
+ "trunk=", "root=", "subroot=",
+ "suppress-parents",
"branches=", "tags=", "encoding=",
"trunk-only", "no-prune",
"dump-only"])
except getopt.GetoptError:
@@ -2179,6 +2369,7 @@
ctx.cvsroot = args[0]
start_pass = 1
+ enable_suppress = 0
for opt, value in opts:
if opt == '-p':
@@ -2187,6 +2378,8 @@
print 'ERROR: illegal value (%d) for starting pass. ' \
'must be 1 through %d.' % (start_pass, len(_passes))
sys.exit(1)
+ elif opt == '-d':
+ ctx.debug = 1
elif opt == '-v':
ctx.verbose = 1
elif opt == '-n':
@@ -2213,7 +2406,28 @@
ctx.dump_only = 1
elif opt == '--encoding':
ctx.encoding = value
+ elif opt == '--root':
+ ctx.root = value
+ elif opt == '--subroot':
+ ctx.subroot = value
+ elif opt == '--suppress-parents':
+ enable_suppress = 1
+
+ if enable_suppress:
+ thresh = 0
+ if (ctx.root != ""):
+ list = string.split(ctx.root, '/')
+ thresh = thresh + len(list)
+
+ if (ctx.subroot != ""):
+ list = string.split(ctx.subroot, '/')
+ thresh = thresh + len(list)
+ if ctx.debug:
+ print "Thresh level = ", thresh
+
+ ctx.dir_suppress_threshold = thresh
+
# Consistency check for options.
if (not ctx.target) and (not ctx.dump_only):
sys.stderr.write("Error: must pass one of '-s' or
'--dump-only'.\n")
@@ -2230,11 +2444,7 @@
if ((string.find(ctx.trunk_base, '/') > -1)
or (string.find(ctx.tags_base, '/') > -1)
or (string.find(ctx.branches_base, '/') > -1)):
- sys.stderr.write("Error: cannot pass multicomponent path to ")
- sys.stderr.write("--trunk, --tags, or --branches yet.\n")
- sys.stderr.write(" See
http://subversion.tigris.org/issues/show_bug.cgi?")
- sys.stderr.write("id=1409 ")
- sys.stderr.write("for details.\n")
+ sys.stderr.write("Error: --trunk, --tags, --branches must not
contain
'/'")
sys.exit(1)
convert(ctx, start_pass=start_pass)
=================
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Sep 29 15:15:06 2003