Merge branch 'master' of git://git.kernel.org/pub/scm/gitk/gitk
[gitweb.git] / contrib / fast-import / git-p4
index adaaae66335c5d500f7bf852e2f46931949726a7..bf33f74b70a0514ebb3e3f3c31fbace65d26ff8a 100755 (executable)
@@ -63,6 +63,14 @@ def system(cmd):
     if os.system(cmd) != 0:
         die("command failed: %s" % cmd)
 
+def isP4Exec(kind):
+    """Determine if a Perforce 'kind' should have execute permission
+
+    'p4 help filetypes' gives a list of the types.  If it starts with 'x',
+    or x follows one of a few letters.  Otherwise, if there is an 'x' after
+    a plus sign, it is also executable"""
+    return (re.search(r"(^[cku]?x)|\+.*x", kind) != None)
+
 def p4CmdList(cmd, stdin=None, stdin_mode='w+b'):
     cmd = "p4 -G %s" % cmd
     if verbose:
@@ -391,6 +399,7 @@ class P4Submit(Command):
                 optparse.make_option("--dry-run", action="store_true"),
                 optparse.make_option("--direct", dest="directSubmit", action="store_true"),
                 optparse.make_option("--trust-me-like-a-fool", dest="trustMeLikeAFool", action="store_true"),
+                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]"
@@ -403,6 +412,7 @@ class P4Submit(Command):
         self.origin = ""
         self.directSubmit = False
         self.trustMeLikeAFool = False
+        self.detectRename = False
         self.verbose = False
         self.isWindows = (platform.system() == "Windows")
 
@@ -483,7 +493,8 @@ class P4Submit(Command):
             diff = self.diffStatus
         else:
             print "Applying %s" % (read_pipe("git log --max-count=1 --pretty=oneline %s" % id))
-            diff = read_pipe_lines("git diff-tree -r --name-status \"%s^\" \"%s\"" % (id, id))
+            diffOpts = ("", "-M")[self.detectRename]
+            diff = read_pipe_lines("git diff-tree -r --name-status %s \"%s^\" \"%s\"" % (diffOpts, id, id))
         filesToAdd = set()
         filesToDelete = set()
         editedFiles = set()
@@ -501,6 +512,13 @@ class P4Submit(Command):
                 filesToDelete.add(path)
                 if path in filesToAdd:
                     filesToAdd.remove(path)
+            elif modifier == "R":
+                src, dest = line.strip().split("\t")[1:3]
+                system("p4 integrate -Dt \"%s\" \"%s\"" % (src, dest))
+                system("p4 edit \"%s\"" % (dest))
+                os.unlink(dest)
+                editedFiles.add(dest)
+                filesToDelete.add(src)
             else:
                 die("unknown modifier %s for %s" % (modifier, path))
 
@@ -521,6 +539,10 @@ class P4Submit(Command):
                                      "and with .rej files / [w]rite the patch to a file (patch.txt) ")
             if response == "s":
                 print "Skipping! Good luck with the next patches..."
+                for f in editedFiles:
+                    system("p4 revert \"%s\"" % f);
+                for f in filesToAdd:
+                    system("rm %s" %f)
                 return
             elif response == "a":
                 os.system(applyPatchCmd)
@@ -932,7 +954,7 @@ class P4Sync(Command):
                 data = file['data']
 
                 mode = "644"
-                if file["type"].startswith("x"):
+                if isP4Exec(file["type"]):
                     mode = "755"
                 elif file["type"] == "symlink":
                     mode = "120000"
@@ -1643,6 +1665,7 @@ def printUsage(commands):
 commands = {
     "debug" : P4Debug,
     "submit" : P4Submit,
+    "commit" : P4Submit,
     "sync" : P4Sync,
     "rebase" : P4Rebase,
     "clone" : P4Clone,