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__)