X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=contrib%2Ffast-import%2Fp4-fast-export.py;h=72e01224bf3d75e697479a59b4c2a7d50bab1c81;hb=f26037dce365b3e525596c6f0236ab203d87a872;hp=689349d551aa62d4ddc9dff40b238dc0c3086438;hpb=72b2f0ada30adbb2880d551bd92d9519396897dd;p=git.git diff --git a/contrib/fast-import/p4-fast-export.py b/contrib/fast-import/p4-fast-export.py index 689349d55..72e01224b 100644 --- a/contrib/fast-import/p4-fast-export.py +++ b/contrib/fast-import/p4-fast-export.py @@ -5,25 +5,25 @@ # Author: Simon Hausmann # License: MIT # -# TODO: - support integrations (at least p4i) +# TODO: +# - support integrations (at least p4i) # - support incremental imports # - create tags # - instead of reading all files into a variable try to pipe from -# - p4 print directly to stdout. need to figure out file size somehow -# though. # - support p4 submit (hah!) # - don't hardcode the import to master # import os, string, sys, time +import marshal, popen2 if len(sys.argv) != 2: - sys.stderr.write("usage: %s //depot/path[@revRange]\n" % sys.argv[0]); - sys.stderr.write("\n example:\n"); - sys.stderr.write(" %s //depot/my/project/ -- to import everything\n"); - sys.stderr.write(" %s //depot/my/project/@1,6 -- to import only from revision 1 to 6\n"); - sys.stderr.write("\n"); - sys.stderr.write(" (a ... is not needed in the path p4 specification, it's added implicitly)\n"); - sys.stderr.write("\n"); + print "usage: %s //depot/path[@revRange]" % sys.argv[0] + print "\n example:" + print " %s //depot/my/project/ -- to import everything" + print " %s //depot/my/project/@1,6 -- to import only from revision 1 to 6" + print "" + print " (a ... is not needed in the path p4 specification, it's added implicitly)" + print "" sys.exit(1) prefix = sys.argv[1] @@ -35,84 +35,40 @@ try: except ValueError: changeRange = "" +if prefix.endswith("..."): + prefix = prefix[:-3] + if not prefix.endswith("/"): prefix += "/" -def describe(change): - output = os.popen("p4 describe %s" % change).readlines() - - firstLine = output[0] - - splitted = firstLine.split(" ") - author = splitted[3] - author = author[:author.find("@")] - tm = time.strptime(splitted[5] + " " + splitted[6] + time.tzname[0], "%Y/%m/%d %H:%M:%S %Z") - epoch = int(time.mktime(tm)) - - filesSection = 0 - try: - filesSection = output.index("Affected files ...\n") - except ValueError: - sys.stderr.write("Change %s doesn't seem to affect any files. Weird.\n" % change) - return [], [], [], [], [] - - differencesSection = 0 +def p4CmdList(cmd): + pipe = os.popen("p4 -G %s" % cmd, "rb") + result = [] try: - differencesSection = output.index("Differences ...\n") - except ValueError: - sys.stderr.write("Change %s doesn't seem to have a differences section. Weird.\n" % change) - return [], [], [], [], [] - - log = output[2:filesSection - 1] - - lines = output[filesSection + 2:differencesSection - 1] - - changed = [] - removed = [] - - for line in lines: - # chop off "... " and trailing newline - line = line[4:len(line) - 1] - - lastSpace = line.rfind(" ") - if lastSpace == -1: - sys.stderr.write("trouble parsing line %s, skipping!\n" % line) - continue - - operation = line[lastSpace + 1:] - path = line[:lastSpace] - - if operation == "delete": - removed.append(path) - else: - changed.append(path) - - return author, log, epoch, changed, removed - -def p4cat(path): - return os.popen("p4 print -q \"%s\"" % path).read() - -def stripRevision(path): - hashPos = path.rindex("#") - return path[:hashPos] + while True: + entry = marshal.load(pipe) + result.append(entry) + except EOFError: + pass + pipe.close() + return result + +def p4Cmd(cmd): + list = p4CmdList(cmd) + result = {} + for entry in list: + result.update(entry) + return result; def getUserMap(): users = {} - output = os.popen("p4 users") - for line in output: - firstSpace = line.index(" ") - secondSpace = line.index(" ", firstSpace + 1) - key = line[:firstSpace] - email = line[firstSpace + 1:secondSpace] - openParenPos = line.index("(", secondSpace) - closedParenPos = line.index(")", openParenPos) - name = line[openParenPos + 1:closedParenPos] - - users[key] = name + " " + email + for output in p4CmdList("users"): + if not output.has_key("User"): + continue + users[output["User"]] = output["FullName"] + " <" + output["Email"] + ">" return users - users = getUserMap() output = os.popen("p4 changes %s...%s" % (prefix, changeRange)).readlines() @@ -126,46 +82,62 @@ changes.reverse() sys.stderr.write("\n") +tz = - time.timezone / 36 + +gitOutput, gitStream, gitError = popen2.popen3("git-fast-import") + cnt = 1 for change in changes: - [ author, log, epoch, changedFiles, removedFiles ] = describe(change) - sys.stderr.write("\rimporting revision %s (%s%%)" % (change, cnt * 100 / len(changes))) + description = p4Cmd("describe %s" % change) + + sys.stdout.write("\rimporting revision %s (%s%%)" % (change, cnt * 100 / len(changes))) cnt = cnt + 1 -# sys.stderr.write("%s\n" % log) -# sys.stderr.write("%s\n" % changedFiles) -# sys.stderr.write("%s\n" % removedFiles) - print "commit refs/heads/master" + epoch = description["time"] + author = description["user"] + + gitStream.write("commit refs/heads/master\n") if author in users: - print "committer %s %s +0000" % (users[author], epoch) + gitStream.write("committer %s %s %s\n" % (users[author], epoch, tz)) else: - print "committer %s %s +0000" % (author, epoch) - print "data < %s %s\n" % (author, epoch, tz)) + gitStream.write("data <