5 # Author: Simon Hausmann <hausmann@kde.org>
6 # License: MIT <http://www.opensource.org/licenses/mit-license.php>
8 # TODO: - fix date parsing (how hard can it be?)
9 # - support integrations (at least p4i)
10 # - support incremental imports
12 # - instead of reading all files into a variable try to pipe from
13 # - p4 print directly to stdout. need to figure out file size somehow
15 # - support p4 submit (hah!)
16 # - don't hardcode the import to master
18 import os
, string
, sys
20 if len(sys
.argv
) != 2:
21 sys
.stderr
.write("usage: %s //depot/path[@revRange]\n" % sys
.argv
[0]);
22 sys
.stderr
.write("\n example:\n");
23 sys
.stderr
.write(" %s //depot/my/project -- to import everything\n");
24 sys
.stderr
.write(" %s //depot/my/project@1,6 -- to import only from revision 1 to 6\n");
25 sys
.stderr
.write("\n");
31 atIdx
= prefix
.index("@")
32 changeRange
= prefix
[atIdx
:]
33 prefix
= prefix
[0:atIdx
]
38 output
= os
.popen("p4 describe %s" % change
).readlines()
42 author
= firstLine
.split(" ")[3]
43 author
= author
[:author
.find("@")]
47 filesSection
= output
.index("Affected files ...\n")
49 sys
.stderr
.write("Change %s doesn't seem to affect any files. Weird.\n" % change
)
52 differencesSection
= 0
54 differencesSection
= output
.index("Differences ...\n")
56 sys
.stderr
.write("Change %s doesn't seem to have a differences section. Weird.\n" % change
)
59 log
= output
[2:filesSection
- 1]
61 lines
= output
[filesSection
+ 2:differencesSection
- 1]
67 # chop off "... " and trailing newline
68 line
= line
[4:len(line
) - 1]
70 lastSpace
= line
.rfind(" ")
72 sys
.stderr
.write("trouble parsing line %s, skipping!\n" % line
)
75 operation
= line
[lastSpace
+ 1:]
76 path
= line
[:lastSpace
]
78 if operation
== "delete":
83 return author
, log
, changed
, removed
86 return os
.popen("p4 print -q \"%s\"" % path
).read()
88 def stripRevision(path
):
89 hashPos
= path
.rindex("#")
94 output
= os
.popen("p4 users")
96 firstSpace
= line
.index(" ")
97 secondSpace
= line
.index(" ", firstSpace
+ 1)
98 key
= line
[:firstSpace
]
99 email
= line
[firstSpace
+ 1:secondSpace
]
100 openParenPos
= line
.index("(", secondSpace
)
101 closedParenPos
= line
.index(")", openParenPos
)
102 name
= line
[openParenPos
+ 1:closedParenPos
]
104 users
[key
] = name
+ " " + email
111 output
= os
.popen("p4 changes %s...%s" % (prefix
, changeRange
)).readlines()
115 changeNum
= line
.split(" ")[1]
116 changes
.append(changeNum
)
120 sys
.stderr
.write("\n")
123 for change
in changes
:
124 [ author
, log
, changedFiles
, removedFiles
] = describe(change
)
125 sys
.stderr
.write("\rimporting revision %s (%s%%)" % (change
, cnt
* 100 / len(changes
)))
127 # sys.stderr.write("%s\n" % log)
128 # sys.stderr.write("%s\n" % changedFiles)
129 # sys.stderr.write("%s\n" % removedFiles)
131 print "commit refs/heads/master"
133 print "committer %s 1 2" % users
[author
]
135 print "committer %s <a@b> 1 2" % author
143 for f
in changedFiles
:
144 if not f
.startswith(prefix
):
145 sys
.stderr
.write("\nchanged files: ignoring path %s outside of %s in change %s\n" % (f
, prefix
, change
))
147 relpath
= f
[len(prefix
):]
148 print "M 644 inline %s" % stripRevision(relpath
)
150 print "data %s" % len(data
)
151 sys
.stdout
.write(data
)
154 for f
in removedFiles
:
155 if not f
.startswith(prefix
):
156 sys
.stderr
.write("\ndeleted files: ignoring path %s outside of %s in change %s\n" % (f
, prefix
, change
))
158 relpath
= f
[len(prefix
):]
159 print "D %s" % stripRevision(relpath
)