]> thyrsus.com Git - src.git/commitdiff
Halfway to fast-export.
authorEric S. Raymond <esr@thyrsus.com>
Fri, 7 Nov 2014 13:41:54 +0000 (08:41 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Fri, 7 Nov 2014 13:41:54 +0000 (08:41 -0500)
src

diff --git a/src b/src
index df15ecb4d50f1ec028dd39da7a1cec5dc7ee2bc5..29dccf4939836ad39ab630ababc224db4096f116 100755 (executable)
--- a/src
+++ b/src
@@ -178,6 +178,12 @@ class RCSLog:
             if item.revision == revision:
                 return item.revno
         return None
+    def by_revno(self, revno):
+        "Map a revno to a revision item."
+        for item in self.revlist:
+            if item.revno == revno:
+                return item
+        croak("{0} has no revno {1}".format(self.name, revno))
     def revno_to_rcs(self, revno):
         "Map a revno to an RCS ID"
         for item in self.revlist:
@@ -495,19 +501,64 @@ def tag_method(*args):
             return
     set_tags(args)
 
+def fast_export_method(*args):
+    "Dump revision content to standard output."
+    (revspec, args) = preamble("cat", args)
+    if revspec and len(revspec) > 1:
+        croak("checkout needs an empty or singleton revision spec")
+    mark = 0
+    for arg in args:
+        master = RCSLog(arg)
+        revspec = master.resolve(revspec)
+        if revspec is None:
+            revspec = 1
+        revrange = range(1, len(master))
+        with lifted(arg):
+            markmap = {}
+            last_commit_mark = 0
+            if len(args) == 1:
+                branch = "master"
+            else:
+                # FIXME: Sanitize branch names
+                branch = arg + "master"
+            for revno in revrange:
+                scratchfile = "/tmp/src%dtmp" % os.getpid()
+                do_or_die("co -q -p -r{1} {0} >{2}".format(arg, master.revno_to_rcs(revno), scratchfile))
+                size = os.path.getsize(scratchfile)
+                mark += 1
+                markmap[revno] = mark
+                sys.stdout.write("blob\nmark :%d\ndata %d\n" % (mark, size))
+                sys.stdout.write(open(scratchfile).read() + "\n\n")
+                sys.stdout.write("commit refs/heads/%s\n" % branch)
+                item = master.by_revno(revno)
+                sys.stdout.write("mark :%d\n" % (mark + 1))
+                sys.stdout.write("data %s\n%s\n" % (len(item.log), item.log))
+                if last_commit_mark:
+                    sys.stdout.write("from :%d\n" % last_commit_mark)
+                perms = "10064"
+                sys.stdout.write("M %s :%d '%s'\n\n" % (perms, mark, arg))
+                last_commit_mark = mark
+                mark += 1
+                markmap[revno] = mark
+            for (key, val) in master.symbols.items():
+                val = master.rcs_to_revno(val)
+                if val in revrange:
+                    sys.stdout.write("reset refs/tags/%s\nfrom :%d\n\n" % (key, markmap[val]))
+
 dispatch = {
-    "help":     help_method,
-    "init":     init_method,
-    "add":      add_method,
-    "commit":   commit_method,
-    "ci":       commit_method,
-    "list":     list_method,
-    "log":      log_method,
-    "checkout": checkout_method,
-    "co":       checkout_method,
-    "cat":      cat_method,
-    "diff":     diff_method,
-    "tag":      tag_method,
+    "help":        help_method,
+    "init":        init_method,
+    "add":         add_method,
+    "commit":      commit_method,
+    "ci":          commit_method,
+    "list":        list_method,
+    "log":         log_method,
+    "checkout":    checkout_method,
+    "co":          checkout_method,
+    "cat":         cat_method,
+    "diff":        diff_method,
+    "tag":         tag_method,
+    "fast-export": fast_export_method,
 }
 
 if __name__ == "__main__":