Merge branch 'maint'
[gitweb.git] / contrib / fast-import / git-p4
index 087f4229a030d3b2f7a1645d9906d44215b0ee4e..650ea341762650cc9a6b517322d9ee3d7aa3b604 100755 (executable)
@@ -464,18 +464,13 @@ class P4Submit(Command):
     def __init__(self):
         Command.__init__(self)
         self.options = [
-                optparse.make_option("--continue", action="store_false", dest="firstTime"),
                 optparse.make_option("--verbose", dest="verbose", action="store_true"),
                 optparse.make_option("--origin", dest="origin"),
-                optparse.make_option("--reset", action="store_true", dest="reset"),
                 optparse.make_option("-M", dest="detectRename", action="store_true"),
         ]
         self.description = "Submit changes from git to the perforce depot."
         self.usage += " [name of git branch to submit into perforce depot]"
-        self.firstTime = True
-        self.reset = False
         self.interactive = True
-        self.firstTime = True
         self.origin = ""
         self.detectRename = False
         self.verbose = False
@@ -485,19 +480,6 @@ class P4Submit(Command):
         if len(p4CmdList("opened ...")) > 0:
             die("You have files opened with perforce! Close them before starting the sync.")
 
-    def start(self):
-        if len(self.config) > 0 and not self.reset:
-            die("Cannot start sync. Previous sync config found at %s\n"
-                "If you want to start submitting again from scratch "
-                "maybe you want to call git-p4 submit --reset" % self.configFile)
-
-        commits = []
-        for line in read_pipe_lines("git rev-list --no-merges %s..%s" % (self.origin, self.master)):
-            commits.append(line.strip())
-        commits.reverse()
-
-        self.config["commits"] = commits
-
     # replaces everything between 'Description:' and the next P4 submit template field with the
     # commit message
     def prepareLogMessage(self, template, message):
@@ -723,42 +705,29 @@ class P4Submit(Command):
         print "Syncronizing p4 checkout..."
         system("p4 sync ...")
 
-        if self.reset:
-            self.firstTime = True
-
         self.check()
-        self.configFile = self.gitdir + "/p4-git-sync.cfg"
-        self.config = shelve.open(self.configFile, writeback=True)
 
-        if self.firstTime:
-            self.start()
-
-        commits = self.config.get("commits", [])
+        commits = []
+        for line in read_pipe_lines("git rev-list --no-merges %s..%s" % (self.origin, self.master)):
+            commits.append(line.strip())
+        commits.reverse()
 
         while len(commits) > 0:
-            self.firstTime = False
             commit = commits[0]
             commits = commits[1:]
-            self.config["commits"] = commits
             self.applyCommit(commit)
             if not self.interactive:
                 break
 
-        self.config.close()
-
         if len(commits) == 0:
-            if self.firstTime:
-                print "No changes found to apply between %s and current HEAD" % self.origin
-            else:
-                print "All changes applied!"
-                os.chdir(self.oldWorkingDirectory)
+            print "All changes applied!"
+            os.chdir(self.oldWorkingDirectory)
 
-                sync = P4Sync()
-                sync.run([])
+            sync = P4Sync()
+            sync.run([])
 
-                rebase = P4Rebase()
-                rebase.rebase()
-            os.remove(self.configFile)
+            rebase = P4Rebase()
+            rebase.rebase()
 
         return True
 
@@ -776,7 +745,9 @@ class P4Sync(Command):
                                      help="Import into refs/heads/ , not refs/remotes"),
                 optparse.make_option("--max-changes", dest="maxChanges"),
                 optparse.make_option("--keep-path", dest="keepRepoPath", action='store_true',
-                                     help="Keep entire BRANCH/DIR/SUBDIR prefix during import")
+                                     help="Keep entire BRANCH/DIR/SUBDIR prefix during import"),
+                optparse.make_option("--use-client-spec", dest="useClientSpec", action='store_true',
+                                     help="Only sync files that are included in the Perforce Client Spec")
         ]
         self.description = """Imports from Perforce into a git repository.\n
     example:
@@ -803,6 +774,8 @@ class P4Sync(Command):
         self.depotPaths = None
         self.p4BranchesInGit = []
         self.cloneExclude = []
+        self.useClientSpec = False
+        self.clientSpecDirs = []
 
         if gitConfig("git-p4.syncFromOrigin") == "false":
             self.syncWithOrigin = False
@@ -877,19 +850,32 @@ class P4Sync(Command):
 
     ## Should move this out, doesn't use SELF.
     def readP4Files(self, files):
-        files = [f for f in files
-                 if f['action'] != 'delete']
+        filesForCommit = []
+        filesToRead = []
 
-        if not files:
-            return
+        for f in files:
+            includeFile = True
+            for val in self.clientSpecDirs:
+                if f['path'].startswith(val[0]):
+                    if val[1] <= 0:
+                        includeFile = False
+                    break
+
+            if includeFile:
+                filesForCommit.append(f)
+                if f['action'] != 'delete':
+                    filesToRead.append(f)
 
-        filedata = p4CmdList('-x - print',
-                             stdin='\n'.join(['%s#%s' % (f['path'], f['rev'])
-                                              for f in files]),
-                             stdin_mode='w+')
-        if "p4ExitCode" in filedata[0]:
-            die("Problems executing p4. Error: [%d]."
-                % (filedata[0]['p4ExitCode']));
+        filedata = []
+        if len(filesToRead) > 0:
+            filedata = p4CmdList('-x - print',
+                                 stdin='\n'.join(['%s#%s' % (f['path'], f['rev'])
+                                                  for f in filesToRead]),
+                                 stdin_mode='w+')
+
+            if "p4ExitCode" in filedata[0]:
+                die("Problems executing p4. Error: [%d]."
+                    % (filedata[0]['p4ExitCode']));
 
         j = 0;
         contents = {}
@@ -913,9 +899,12 @@ class P4Sync(Command):
 
             contents[stat['depotFile']] = text
 
-        for f in files:
-            assert not f.has_key('data')
-            f['data'] = contents[f['path']]
+        for f in filesForCommit:
+            path = f['path']
+            if contents.has_key(path):
+                f['data'] = contents[path]
+
+        return filesForCommit
 
     def commit(self, details, files, branch, branchPrefixes, parent = ""):
         epoch = details["time"]
@@ -932,11 +921,7 @@ class P4Sync(Command):
                 new_files.append (f)
             else:
                 sys.stderr.write("Ignoring file outside of prefix: %s\n" % path)
-        files = new_files
-        self.readP4Files(files)
-
-
-
+        files = self.readP4Files(new_files)
 
         self.gitStream.write("commit %s\n" % branch)
 #        gitStream.write("mark :%s\n" % details["change"])
@@ -1351,6 +1336,26 @@ class P4Sync(Command):
             print self.gitError.read()
 
 
+    def getClientSpec(self):
+        specList = p4CmdList( "client -o" )
+        temp = {}
+        for entry in specList:
+            for k,v in entry.iteritems():
+                if k.startswith("View"):
+                    if v.startswith('"'):
+                        start = 1
+                    else:
+                        start = 0
+                    index = v.find("...")
+                    v = v[start:index]
+                    if v.startswith("-"):
+                        v = v[1:]
+                        temp[v] = -len(v)
+                    else:
+                        temp[v] = len(v)
+        self.clientSpecDirs = temp.items()
+        self.clientSpecDirs.sort( lambda x, y: abs( y[1] ) - abs( x[1] ) )
+
     def run(self, args):
         self.depotPaths = []
         self.changeRange = ""
@@ -1383,6 +1388,9 @@ class P4Sync(Command):
             if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes and gitBranchExists(self.branch):
                 system("git symbolic-ref %sHEAD %s" % (self.refPrefix, self.branch))
 
+        if self.useClientSpec or gitConfig("p4.useclientspec") == "true":
+            self.getClientSpec()
+
         # TODO: should always look at previous commits,
         # merge with previous imports, if possible.
         if args == []: