5 # Author: Simon Hausmann <hausmann@kde.org>
6 # License: MIT <http://www.opensource.org/licenses/mit-license.php>
9 # - support integrations (at least p4i)
10 # - support incremental imports
12 # - instead of reading all files into a variable try to pipe from
13 # - support p4 submit (hah!)
14 # - don't hardcode the import to master
16 import os
, string
, sys
, time
18 if len(sys
.argv
) != 2:
19 sys
.stderr
.write("usage: %s //depot/path[@revRange]\n" % sys
.argv
[0]);
20 sys
.stderr
.write("\n example:\n");
21 sys
.stderr
.write(" %s //depot/my/project/ -- to import everything\n");
22 sys
.stderr
.write(" %s //depot/my/project/@1,6 -- to import only from revision 1 to 6\n");
23 sys
.stderr
.write("\n");
24 sys
.stderr
.write(" (a ... is not needed in the path p4 specification, it's added implicitly)\n");
25 sys
.stderr
.write("\n");
31 atIdx
= prefix
.index("@")
32 changeRange
= prefix
[atIdx
:]
33 prefix
= prefix
[0:atIdx
]
37 if not prefix
.endswith("/"):
41 output
= os
.popen("p4 describe %s" % change
).readlines()
45 splitted
= firstLine
.split(" ")
47 author
= author
[:author
.find("@")]
48 tm
= time
.strptime(splitted
[5] + " " + splitted
[6], "%Y/%m/%d %H:%M:%S ")
49 epoch
= int(time
.mktime(tm
))
53 filesSection
= output
.index("Affected files ...\n")
55 sys
.stderr
.write("Change %s doesn't seem to affect any files. Weird.\n" % change
)
56 return [], [], [], [], []
58 differencesSection
= 0
60 differencesSection
= output
.index("Differences ...\n")
62 sys
.stderr
.write("Change %s doesn't seem to have a differences section. Weird.\n" % change
)
63 return [], [], [], [], []
65 log
= output
[2:filesSection
- 1]
67 lines
= output
[filesSection
+ 2:differencesSection
- 1]
73 # chop off "... " and trailing newline
74 line
= line
[4:len(line
) - 1]
76 lastSpace
= line
.rfind(" ")
78 sys
.stderr
.write("trouble parsing line %s, skipping!\n" % line
)
81 operation
= line
[lastSpace
+ 1:]
82 path
= line
[:lastSpace
]
84 if operation
== "delete":
89 return author
, log
, epoch
, changed
, removed
92 return os
.popen("p4 print -q \"%s\"" % path
).read()
95 output
= os
.popen("p4 fstat -Ol \"%s\"" % path
).readlines()
99 if line
.startswith("... headType x"):
101 elif line
.startswith("... fileSize "):
102 fileSize
= long(line
[12:])
103 return mode
, fileSize
105 def stripRevision(path
):
106 hashPos
= path
.rindex("#")
107 return path
[:hashPos
]
111 output
= os
.popen("p4 users")
113 firstSpace
= line
.index(" ")
114 secondSpace
= line
.index(" ", firstSpace
+ 1)
115 key
= line
[:firstSpace
]
116 email
= line
[firstSpace
+ 1:secondSpace
]
117 openParenPos
= line
.index("(", secondSpace
)
118 closedParenPos
= line
.index(")", openParenPos
)
119 name
= line
[openParenPos
+ 1:closedParenPos
]
121 users
[key
] = name
+ " " + email
127 output
= os
.popen("p4 changes %s...%s" % (prefix
, changeRange
)).readlines()
131 changeNum
= line
.split(" ")[1]
132 changes
.append(changeNum
)
136 sys
.stderr
.write("\n")
138 tz
= - time
.timezone
/ 36
141 for change
in changes
:
142 [ author
, log
, epoch
, changedFiles
, removedFiles
] = describe(change
)
143 sys
.stderr
.write("\rimporting revision %s (%s%%)" % (change
, cnt
* 100 / len(changes
)))
146 print "commit refs/heads/master"
148 print "committer %s %s %s" % (users
[author
], epoch
, tz
)
150 print "committer %s <a@b> %s %s" % (author
, epoch
, tz
)
158 for f
in changedFiles
:
159 if not f
.startswith(prefix
):
160 sys
.stderr
.write("\nchanged files: ignoring path %s outside of %s in change %s\n" % (f
, prefix
, change
))
162 relpath
= f
[len(prefix
):]
164 [mode
, fileSize
] = p4Stat(f
)
166 print "M %s inline %s" % (mode
, stripRevision(relpath
))
167 print "data %s" % fileSize
169 os
.system("p4 print -q \"%s\"" % f
)
172 for f
in removedFiles
:
173 if not f
.startswith(prefix
):
174 sys
.stderr
.write("\ndeleted files: ignoring path %s outside of %s in change %s\n" % (f
, prefix
, change
))
176 relpath
= f
[len(prefix
):]
177 print "D %s" % stripRevision(relpath
)
181 sys
.stderr
.write("\n")