You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by es...@apache.org on 2012/12/11 21:15:00 UTC
svn commit: r1420379 -
/subversion/trunk/contrib/server-side/svncutter/svncutter
Author: esr
Date: Tue Dec 11 20:14:58 2012
New Revision: 1420379
URL: http://svn.apache.org/viewvc?rev=1420379&view=rev
Log:
Refactor the skeleton operation of svncutter. Add a branch deletion operation.
* contrib/server-side/svncutter/svncutter
(branchdel, report): New function
(skeletonize): refactored to use report()
Modified:
subversion/trunk/contrib/server-side/svncutter/svncutter
Modified: subversion/trunk/contrib/server-side/svncutter/svncutter
URL: http://svn.apache.org/viewvc/subversion/trunk/contrib/server-side/svncutter/svncutter?rev=1420379&r1=1420378&r2=1420379&view=diff
==============================================================================
--- subversion/trunk/contrib/server-side/svncutter/svncutter (original)
+++ subversion/trunk/contrib/server-side/svncutter/svncutter Tue Dec 11 20:14:58 2012
@@ -30,6 +30,7 @@ Available subcommands:
log
setlog
skeleton
+ branchdel
"""
oneliners = {
@@ -40,7 +41,8 @@ oneliners = {
"proprename": "Renaming revision properties",
"log": "Extracting log entries",
"setlog": "Mutating log entries",
- "skeleton": "strip content, leave only headers",
+ "skeleton": "Strip content, leave only headers",
+ "branchdel": "Delete a specified branch",
}
helpdict = {
@@ -129,6 +131,11 @@ skeleton: usage: svncutter [-r SELECTION
Strip out all content. Does not produce a valid dumpfile, but may be useful
when you need to examine a particularly complex node structure.
""",
+ "branchdel": """\
+branchdelete: usage: svncutter [-r SELECTION ] branchdel BRANCHNAME
+
+Delete all operations on the specified branch.
+""",
}
import os, sys, calendar, time, getopt, re
@@ -280,10 +287,10 @@ class DumpfileSource(LineBufferedSource)
#print "I see contents line", repr(line)
if not line:
break
- content += line
if line.startswith("Node-path:") or line.startswith("Revision-number"):
self.push(line)
break
+ content += line
#print "READ NODE ENDS"
return (header, properties, content)
def read_until_next(self, prefix, revmap=None):
@@ -431,6 +438,43 @@ def reference_mapper(value, mutator, fla
value = value[:m.start(1)] + new + value[m.end(1):]
return value
+def report(source, selection, hook):
+ "Apply hook to a portion of the dump file defined by a revision selection."
+ emit = 0 in selection
+ stash = source.read_until_next("Revision-number:")
+ if emit:
+ sys.stdout.write(stash)
+ if not source.has_line_buffered():
+ return
+ while True:
+ (revision,stash,properties) = source.read_revision_header()
+ if revision in selection:
+ sys.stdout.write(stash)
+ emit = True
+ elif revision == selection.upperbound()+1:
+ return
+ else:
+ source.read_until_next("Revision-number:")
+ continue
+ while True:
+ line = source.readline()
+ if not line:
+ return
+ elif line == '\n':
+ sys.stdout.write(line)
+ continue
+ elif line.startswith("Revision-number:"):
+ source.push(line)
+ break
+ elif line.startswith("Node-path:"):
+ source.push(line)
+ (header, properties, content) = source.read_node()
+ hook(header, properties, content)
+ continue
+ else:
+ sys.stderr.write("svncutter: parse at %s doesn't look right (%s), aborting!\n" % (revision, repr(line)))
+ sys.exit(1)
+
# Generic machinery ends here, actual command implementations begin
def squash(source, timefuzz,
@@ -657,40 +701,14 @@ def setlog(source, logpatch, selection):
def skeletonize(source, selection):
"Skeletonize a portion of the dump file defined by a revision selection."
- emit = 0 in selection
- stash = source.read_until_next("Revision-number:")
- if emit:
- sys.stdout.write(stash)
- if not source.has_line_buffered():
- return
- while True:
- (revision,stash,properties) = source.read_revision_header()
- if revision in selection:
- sys.stdout.write(stash)
- emit = True
- elif revision == selection.upperbound()+1:
- return
- else:
- source.read_until_next("Revision-number:")
- continue
- while True:
- line = source.readline()
- if not line:
- return
- elif line == '\n':
- sys.stdout.write(line)
- continue
- elif line.startswith("Revision-number:"):
- source.push(line)
- break
- elif line.startswith("Node-path:"):
- source.push(line)
- (header, properties, content) = source.read_node()
- sys.stdout.write(header + properties)
- continue
- else:
- sys.stderr.write("svncutter: parse at %s doesn't look right (%s), aborting!\n" % (revision, repr(line)))
- sys.exit(1)
+ report(source, selection, lambda h, p, c: sys.stdout.write(h + p))
+
+def branchdel(source, selection, branchname):
+ "Strip out ops defined by a revision selection and a branch name."
+ def __branchdel(header, properties, content):
+ if not re.search("Node-path: " + branchname, header):
+ sys.stdout.write(header + properties + content)
+ report(source, selection, __branchdel)
if __name__ == '__main__':
try:
@@ -761,7 +779,9 @@ if __name__ == '__main__':
sys.stderr.write("svncutter: setlog requires a log entries file.\n")
setlog(DumpfileSource(sys.stdin, baton), logpatch, selection)
elif arguments[0] == "skeleton":
- skeletonize(DumpfileSource(sys.stdin, baton), selection)
+ skeletonize(DumpfileSource(sys.stdin, baton), selection)
+ elif arguments[0] == "branchdel":
+ branchdel(DumpfileSource(sys.stdin, baton), selection, arguments[1])
elif arguments[0] == "help":
if len(arguments) == 1:
sys.stdout.write(__doc__)