@@ -129,6 +129,25 @@ def p4_has_command(cmd):
129129 p .communicate ()
130130 return p .returncode == 0
131131
132+ def p4_has_move_command ():
133+ """See if the move command exists, that it supports -k, and that
134+ it has not been administratively disabled. The arguments
135+ must be correct, but the filenames do not have to exist. Use
136+ ones with wildcards so even if they exist, it will fail."""
137+
138+ if not p4_has_command ("move" ):
139+ return False
140+ cmd = p4_build_cmd (["move" , "-k" , "@from" , "@to" ])
141+ p = subprocess .Popen (cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
142+ (out , err ) = p .communicate ()
143+ # return code will be 1 in either case
144+ if err .find ("Invalid option" ) >= 0 :
145+ return False
146+ if err .find ("disabled" ) >= 0 :
147+ return False
148+ # assume it failed because @... was invalid changelist
149+ return True
150+
132151def system (cmd ):
133152 expand = isinstance (cmd ,basestring )
134153 if verbose :
@@ -169,6 +188,29 @@ def p4_reopen(type, f):
169188def p4_move (src , dest ):
170189 p4_system (["move" , "-k" , wildcard_encode (src ), wildcard_encode (dest )])
171190
191+ def p4_describe (change ):
192+ """Make sure it returns a valid result by checking for
193+ the presence of field "time". Return a dict of the
194+ results."""
195+
196+ ds = p4CmdList (["describe" , "-s" , str (change )])
197+ if len (ds ) != 1 :
198+ die ("p4 describe -s %d did not return 1 result: %s" % (change , str (ds )))
199+
200+ d = ds [0 ]
201+
202+ if "p4ExitCode" in d :
203+ die ("p4 describe -s %d exited with %d: %s" % (change , d ["p4ExitCode" ],
204+ str (d )))
205+ if "code" in d :
206+ if d ["code" ] == "error" :
207+ die ("p4 describe -s %d returned error code: %s" % (change , str (d )))
208+
209+ if "time" not in d :
210+ die ("p4 describe -s %d returned no \" time\" : %s" % (change , str (d )))
211+
212+ return d
213+
172214#
173215# Canonicalize the p4 type and return a tuple of the
174216# base type, plus any modifiers. See "p4 help filetypes"
@@ -871,7 +913,7 @@ def __init__(self):
871913 self .conflict_behavior = None
872914 self .isWindows = (platform .system () == "Windows" )
873915 self .exportLabels = False
874- self .p4HasMoveCommand = p4_has_command ( "move" )
916+ self .p4HasMoveCommand = p4_has_move_command ( )
875917
876918 def check (self ):
877919 if len (p4CmdList ("opened ..." )) > 0 :
@@ -2097,6 +2139,29 @@ def streamOneP4Deletion(self, file):
20972139 # handle another chunk of streaming data
20982140 def streamP4FilesCb (self , marshalled ):
20992141
2142+ # catch p4 errors and complain
2143+ err = None
2144+ if "code" in marshalled :
2145+ if marshalled ["code" ] == "error" :
2146+ if "data" in marshalled :
2147+ err = marshalled ["data" ].rstrip ()
2148+ if err :
2149+ f = None
2150+ if self .stream_have_file_info :
2151+ if "depotFile" in self .stream_file :
2152+ f = self .stream_file ["depotFile" ]
2153+ # force a failure in fast-import, else an empty
2154+ # commit will be made
2155+ self .gitStream .write ("\n " )
2156+ self .gitStream .write ("die-now\n " )
2157+ self .gitStream .close ()
2158+ # ignore errors, but make sure it exits first
2159+ self .importProcess .wait ()
2160+ if f :
2161+ die ("Error from p4 print for %s: %s" % (f , err ))
2162+ else :
2163+ die ("Error from p4 print: %s" % err )
2164+
21002165 if marshalled .has_key ('depotFile' ) and self .stream_have_file_info :
21012166 # start of a new file - output the old one first
21022167 self .streamOneP4File (self .stream_file , self .stream_contents )
@@ -2341,7 +2406,7 @@ def importP4Labels(self, stream, p4Labels):
23412406 try :
23422407 tmwhen = time .strptime (labelDetails ['Update' ], "%Y/%m/%d %H:%M:%S" )
23432408 except ValueError :
2344- print "Could not convert label time %s" % labelDetail ['Update' ]
2409+ print "Could not convert label time %s" % labelDetails ['Update' ]
23452410 tmwhen = 1
23462411
23472412 when = int (time .mktime (tmwhen ))
@@ -2543,7 +2608,7 @@ def searchParent(self, parent, branch, target):
25432608 def importChanges (self , changes ):
25442609 cnt = 1
25452610 for change in changes :
2546- description = p4Cmd ([ "describe" , str ( change )] )
2611+ description = p4_describe ( change )
25472612 self .updateOptionDict (description )
25482613
25492614 if not self .silent :
@@ -2667,14 +2732,8 @@ def importHeadRevision(self, revision):
26672732
26682733 # Use time from top-most change so that all git p4 clones of
26692734 # the same p4 repo have the same commit SHA1s.
2670- res = p4CmdList ("describe -s %d" % newestRevision )
2671- newestTime = None
2672- for r in res :
2673- if r .has_key ('time' ):
2674- newestTime = int (r ['time' ])
2675- if newestTime is None :
2676- die ("\" describe -s\" on newest change %d did not give a time" )
2677- details ["time" ] = newestTime
2735+ res = p4_describe (newestRevision )
2736+ details ["time" ] = res ["time" ]
26782737
26792738 self .updateOptionDict (details )
26802739 try :
@@ -2864,12 +2923,13 @@ def run(self, args):
28642923
28652924 self .tz = "%+03d%02d" % (- time .timezone / 3600 , ((- time .timezone % 3600 ) / 60 ))
28662925
2867- importProcess = subprocess .Popen (["git" , "fast-import" ],
2868- stdin = subprocess .PIPE , stdout = subprocess .PIPE ,
2869- stderr = subprocess .PIPE );
2870- self .gitOutput = importProcess .stdout
2871- self .gitStream = importProcess .stdin
2872- self .gitError = importProcess .stderr
2926+ self .importProcess = subprocess .Popen (["git" , "fast-import" ],
2927+ stdin = subprocess .PIPE ,
2928+ stdout = subprocess .PIPE ,
2929+ stderr = subprocess .PIPE );
2930+ self .gitOutput = self .importProcess .stdout
2931+ self .gitStream = self .importProcess .stdin
2932+ self .gitError = self .importProcess .stderr
28732933
28742934 if revision :
28752935 self .importHeadRevision (revision )
@@ -2929,7 +2989,7 @@ def run(self, args):
29292989 self .importP4Labels (self .gitStream , missingP4Labels )
29302990
29312991 self .gitStream .close ()
2932- if importProcess .wait () != 0 :
2992+ if self . importProcess .wait () != 0 :
29332993 die ("fast-import failed: %s" % self .gitError .read ())
29342994 self .gitOutput .close ()
29352995 self .gitError .close ()
@@ -3128,7 +3188,6 @@ def main():
31283188 printUsage (commands .keys ())
31293189 sys .exit (2 )
31303190
3131- cmd = ""
31323191 cmdName = sys .argv [1 ]
31333192 try :
31343193 klass = commands [cmdName ]
0 commit comments