]> thyrsus.com Git - src.git/commitdiff
Another step on the way to fast-export.
authorEric S. Raymond <esr@thyrsus.com>
Fri, 7 Nov 2014 14:59:24 +0000 (09:59 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Fri, 7 Nov 2014 14:59:24 +0000 (09:59 -0500)
src

diff --git a/src b/src
index 29dccf4939836ad39ab630ababc224db4096f116..303e89190b30af515259a4199e1b5e48d6d49c2b 100755 (executable)
--- a/src
+++ b/src
@@ -2,7 +2,7 @@
 #
 # src - simple revision control.
 #
-import sys, os, subprocess, time
+import sys, os, subprocess, time, calendar, stat
 
 version=0.1
 
@@ -78,6 +78,18 @@ class popen_or_die:
             complain(b"%s%s returned error." % (self.command, self.legend))
         return False
 
+def capture_or_die(command):
+    "Run a specified command, capturing the output."
+    if debug >= DEBUG_COMMANDS:
+        announce(b"%s: capturing %s" % (rfc3339(time.time()), command))
+    try:
+        content = subprocess.check_output(command, shell=True)
+    except (subprocess.CalledProcessError, OSError) as oe:
+        croak(b"execution of '%s' failed: %s" % (command, oe))
+    if debug >= DEBUG_COMMANDS:
+        sys.stderr.write(content)
+    return content
+
 class RCSRevisionItem:
     "Capture the state of an RCS revision item in the log."
     def __init__(self, master, revno):
@@ -88,6 +100,11 @@ class RCSRevisionItem:
         self.date = None
     def selected(self):
         return self.revision == self.master.lockrevs[0]
+    def unixtime(self):
+        try:
+            return calendar.timegm(time.strptime(self.date, "%Y-%m-%dT%H:%M:%SZ"))
+        except TypeError, ValueError:
+            croak("garbled date %s" % self.date)
 
 class RCSLog:
     "Encapsulate a revision list and some methods on it"
@@ -258,6 +275,7 @@ src diff ['revision-spec'] ['file'...]
 
 src fast-export ['file'...]
    Export one or more projects to standard output as a git fast-import stream.
+   The committer identification is copied from your Git configuration.
 """
 
 def init_method(*args):
@@ -507,7 +525,15 @@ def fast_export_method(*args):
     if revspec and len(revspec) > 1:
         croak("checkout needs an empty or singleton revision spec")
     mark = 0
+    username = capture_or_die("git config --get user.name").strip()
+    useremail = capture_or_die("git config --get user.email").strip()
+    attribution = "%s <%s>" % (username, useremail)
     for arg in args:
+        executable = os.stat(arg).st_mode & stat.S_IXUSR
+        if executable:
+            perms = "100755"
+        else:
+            perms = "100644"
         master = RCSLog(arg)
         revspec = master.resolve(revspec)
         if revspec is None:
@@ -527,15 +553,16 @@ def fast_export_method(*args):
                 size = os.path.getsize(scratchfile)
                 mark += 1
                 markmap[revno] = mark
+                item = master.by_revno(revno)
                 sys.stdout.write("blob\nmark :%d\ndata %d\n" % (mark, size))
-                sys.stdout.write(open(scratchfile).read() + "\n\n")
+                sys.stdout.write(open(scratchfile).read() + "\n")
                 sys.stdout.write("commit refs/heads/%s\n" % branch)
-                item = master.by_revno(revno)
+                sys.stdout.write("committer %s %d +0000\n" % (attribution, item.unixtime()))
                 sys.stdout.write("mark :%d\n" % (mark + 1))
-                sys.stdout.write("data %s\n%s\n" % (len(item.log), item.log))
+                sys.stdout.write("data %s\n%s" % (len(item.log), item.log))
                 if last_commit_mark:
                     sys.stdout.write("from :%d\n" % last_commit_mark)
-                perms = "10064"
+                # FIXME: Process executable bit
                 sys.stdout.write("M %s :%d '%s'\n\n" % (perms, mark, arg))
                 last_commit_mark = mark
                 mark += 1