@@ -1316,7 +1316,7 @@ def __init__(self):
13161316 self .needsGit = True
13171317 self .verbose = False
13181318
1319- # This is required for the "append" cloneExclude action
1319+ # This is required for the "append" update_shelve action
13201320 def ensure_value (self , attr , value ):
13211321 if not hasattr (self , attr ) or getattr (self , attr ) is None :
13221322 setattr (self , attr , value )
@@ -2530,6 +2530,11 @@ def map_in_client(self, depot_path):
25302530 die ( "Error: %s is not found in client spec path" % depot_path )
25312531 return ""
25322532
2533+ def cloneExcludeCallback (option , opt_str , value , parser ):
2534+ # prepend "/" because the first "/" was consumed as part of the option itself.
2535+ # ("-//depot/A/..." becomes "/depot/A/..." after option parsing)
2536+ parser .values .cloneExclude += ["/" + re .sub (r"\.\.\.$" , "" , value )]
2537+
25332538class P4Sync (Command , P4UserMap ):
25342539
25352540 def __init__ (self ):
@@ -2553,7 +2558,7 @@ def __init__(self):
25532558 optparse .make_option ("--use-client-spec" , dest = "useClientSpec" , action = 'store_true' ,
25542559 help = "Only sync files that are included in the Perforce Client Spec" ),
25552560 optparse .make_option ("-/" , dest = "cloneExclude" ,
2556- action = "append" , type = "string" ,
2561+ action = "callback" , callback = cloneExcludeCallback , type = "string" ,
25572562 help = "exclude depot path" ),
25582563 ]
25592564 self .description = """Imports from Perforce into a git repository.\n
@@ -2618,20 +2623,25 @@ def checkpoint(self):
26182623 if self .verbose :
26192624 print ("checkpoint finished: " + out )
26202625
2626+ def isPathWanted (self , path ):
2627+ for p in self .cloneExclude :
2628+ if p .endswith ("/" ):
2629+ if p4PathStartsWith (path , p ):
2630+ return False
2631+ # "-//depot/file1" without a trailing "/" should only exclude "file1", but not "file111" or "file1_dir/file2"
2632+ elif path .lower () == p .lower ():
2633+ return False
2634+ for p in self .depotPaths :
2635+ if p4PathStartsWith (path , p ):
2636+ return True
2637+ return False
2638+
26212639 def extractFilesFromCommit (self , commit , shelved = False , shelved_cl = 0 ):
2622- self .cloneExclude = [re .sub (r"\.\.\.$" , "" , path )
2623- for path in self .cloneExclude ]
26242640 files = []
26252641 fnum = 0
26262642 while "depotFile%s" % fnum in commit :
26272643 path = commit ["depotFile%s" % fnum ]
2628-
2629- if [p for p in self .cloneExclude
2630- if p4PathStartsWith (path , p )]:
2631- found = False
2632- else :
2633- found = [p for p in self .depotPaths
2634- if p4PathStartsWith (path , p )]
2644+ found = self .isPathWanted (path )
26352645 if not found :
26362646 fnum = fnum + 1
26372647 continue
@@ -2668,7 +2678,7 @@ def stripRepoPath(self, path, prefixes):
26682678 path = self .clientSpecDirs .map_in_client (path )
26692679 if self .detectBranches :
26702680 for b in self .knownBranches :
2671- if path . startswith ( b + "/" ):
2681+ if p4PathStartsWith ( path , b + "/" ):
26722682 path = path [len (b )+ 1 :]
26732683
26742684 elif self .keepRepoPath :
@@ -2700,8 +2710,7 @@ def splitFilesIntoBranches(self, commit):
27002710 fnum = 0
27012711 while "depotFile%s" % fnum in commit :
27022712 path = commit ["depotFile%s" % fnum ]
2703- found = [p for p in self .depotPaths
2704- if p4PathStartsWith (path , p )]
2713+ found = self .isPathWanted (path )
27052714 if not found :
27062715 fnum = fnum + 1
27072716 continue
@@ -2723,7 +2732,7 @@ def splitFilesIntoBranches(self, commit):
27232732 for branch in self .knownBranches .keys ():
27242733 # add a trailing slash so that a commit into qt/4.2foo
27252734 # doesn't end up in qt/4.2, e.g.
2726- if relPath . startswith ( branch + "/" ):
2735+ if p4PathStartsWith ( relPath , branch + "/" ):
27272736 if branch not in branches :
27282737 branches [branch ] = []
27292738 branches [branch ].append (file )
@@ -3325,7 +3334,9 @@ def gitCommitByP4Change(self, ref, change):
33253334 if currentChange < change :
33263335 earliestCommit = "^%s" % next
33273336 else :
3328- latestCommit = "%s" % next
3337+ if next == latestCommit :
3338+ die ("Infinite loop while looking in ref %s for change %s. Check your branch mappings" % (ref , change ))
3339+ latestCommit = "%s^@" % next
33293340
33303341 return ""
33313342
@@ -3888,7 +3899,6 @@ def run(self, args):
38883899 self .cloneDestination = depotPaths [- 1 ]
38893900 depotPaths = depotPaths [:- 1 ]
38903901
3891- self .cloneExclude = ["/" + p for p in self .cloneExclude ]
38923902 for p in depotPaths :
38933903 if not p .startswith ("//" ):
38943904 sys .stderr .write ('Depot paths must start with "//": %s\n ' % p )
0 commit comments