Document some implementation details, for the curious... :)
[gitweb.git] / contrib / fast-import / git-p4
index b77cb20e3feafa7b58fdd76fa4f6416ae1acabab..9927fa142ead96f55087d6036e9ca6fdd47b7ffb 100755 (executable)
@@ -74,7 +74,7 @@ def extractLogMessageFromGitCommit(commit):
     for log in os.popen("git cat-file commit %s" % commit).readlines():
        if not foundTitle:
            if len(log) == 1:
-               foundTitle = 1
+               foundTitle = True
            continue
 
        logMessage += log
@@ -244,7 +244,33 @@ class P4Submit(Command):
             else:
                 die("unknown modifier %s for %s" % (modifier, path))
 
-        system("git diff-tree -p --diff-filter=ACMRTUXB \"%s^\" \"%s\" | patch -p1" % (id, id))
+        diffcmd = "git diff-tree -p --diff-filter=ACMRTUXB \"%s^\" \"%s\"" % (id, id)
+        patchcmd = diffcmd + " | patch -p1"
+
+        if os.system(patchcmd + " --dry-run --silent") != 0:
+            print "Unfortunately applying the change failed!"
+            print "What do you want to do?"
+            response = "x"
+            while response != "s" and response != "a" and response != "w":
+                response = raw_input("[s]kip this patch / [a]pply the patch forcibly and with .rej files / [w]rite the patch to a file (patch.txt) ")
+            if response == "s":
+                print "Skipping! Good luck with the next patches..."
+                return
+            elif response == "a":
+                os.system(patchcmd)
+                if len(filesToAdd) > 0:
+                    print "You may also want to call p4 add on the following files:"
+                    print " ".join(filesToAdd)
+                if len(filesToDelete):
+                    print "The following files should be scheduled for deletion with p4 delete:"
+                    print " ".join(filesToDelete)
+                die("Please resolve and submit the conflict manually and continue afterwards with git-p4 submit --continue")
+            elif response == "w":
+                system(diffcmd + " > patch.txt")
+                print "Patch saved to patch.txt in %s !" % self.clientPath
+                die("Please resolve and submit the conflict manually and continue afterwards with git-p4 submit --continue")
+
+        system(patchcmd)
 
         for f in filesToAdd:
             system("p4 add %s" % f)
@@ -335,16 +361,16 @@ class P4Submit(Command):
             print "Internal error: cannot locate perforce depot path from existing branches"
             sys.exit(128)
 
-        clientPath = p4Where(depotPath)
+        self.clientPath = p4Where(depotPath)
 
-        if len(clientPath) == 0:
+        if len(self.clientPath) == 0:
             print "Error: Cannot locate perforce checkout of %s in client view" % depotPath
             sys.exit(128)
 
-        print "Perforce checkout for depot path %s located at %s" % (depotPath, clientPath)
+        print "Perforce checkout for depot path %s located at %s" % (depotPath, self.clientPath)
         oldWorkingDirectory = os.getcwd()
-        os.chdir(clientPath)
-        response = raw_input("Do you want to sync %s with p4 sync? [y]es/[n]o " % clientPath)
+        os.chdir(self.clientPath)
+        response = raw_input("Do you want to sync %s with p4 sync? [y]es/[n]o " % self.clientPath)
         if response == "y" or response == "yes":
             system("p4 sync ...")
 
@@ -429,7 +455,6 @@ class P4Sync(Command):
         self.detectBranches = False
         self.detectLabels = False
         self.changesFile = ""
-        self.tagLastChange = True
 
     def p4File(self, depotPath):
         return os.popen("p4 print -q \"%s\"" % depotPath, "rb").read()
@@ -439,9 +464,9 @@ class P4Sync(Command):
         fnum = 0
         while commit.has_key("depotFile%s" % fnum):
             path =  commit["depotFile%s" % fnum]
-            if not path.startswith(self.globalPrefix):
+            if not path.startswith(self.depotPath):
     #            if not self.silent:
-    #                print "\nchanged files: ignoring path %s outside of %s in change %s" % (path, self.globalPrefix, change)
+    #                print "\nchanged files: ignoring path %s outside of %s in change %s" % (path, self.depotPath, change)
                 fnum = fnum + 1
                 continue
 
@@ -465,7 +490,7 @@ class P4Sync(Command):
         branches = Set()
 
         for file in files:
-            relativePath = file["path"][len(self.globalPrefix):]
+            relativePath = file["path"][len(self.depotPath):]
             # strip off the filename
             relativePath = relativePath[0:relativePath.rfind("/")]
 
@@ -551,7 +576,7 @@ class P4Sync(Command):
                 sys.exit(1);
             sourceLog = sourceLog[0]
 
-            relPath = source[len(self.globalPrefix):]
+            relPath = source[len(self.depotPath):]
             # strip off the filename
             relPath = relPath[0:relPath.rfind("/")]
 
@@ -711,7 +736,7 @@ class P4Sync(Command):
                 sys.exit(1);
             sourceLog = sourceLog[0]
 
-            relPath = source[len(self.globalPrefix):]
+            relPath = source[len(self.depotPath):]
             # strip off the filename
             relPath = relPath[0:relPath.rfind("/")]
 
@@ -723,13 +748,13 @@ class P4Sync(Command):
 
     def changeIsBranchMerge(self, sourceBranch, destinationBranch, change):
         sourceFiles = {}
-        for file in p4CmdList("files %s...@%s" % (self.globalPrefix + sourceBranch + "/", change)):
+        for file in p4CmdList("files %s...@%s" % (self.depotPath + sourceBranch + "/", change)):
             if file["action"] == "delete":
                 continue
             sourceFiles[file["depotFile"]] = file
 
         destinationFiles = {}
-        for file in p4CmdList("files %s...@%s" % (self.globalPrefix + destinationBranch + "/", change)):
+        for file in p4CmdList("files %s...@%s" % (self.depotPath + destinationBranch + "/", change)):
             destinationFiles[file["depotFile"]] = file
 
         for fileName in sourceFiles.keys():
@@ -796,9 +821,9 @@ class P4Sync(Command):
     def getLabels(self):
         self.labels = {}
 
-        l = p4CmdList("labels %s..." % self.globalPrefix)
+        l = p4CmdList("labels %s..." % self.depotPath)
         if len(l) > 0 and not self.silent:
-            print "Finding files belonging to labels in %s" % self.globalPrefix
+            print "Finding files belonging to labels in %s" % self.depotPath
 
         for output in l:
             label = output["label"]
@@ -813,7 +838,7 @@ class P4Sync(Command):
             self.labels[newestChange] = [output, revisions]
 
     def run(self, args):
-        self.globalPrefix = ""
+        self.depotPath = ""
         self.changeRange = ""
         self.initialParent = ""
 
@@ -829,58 +854,53 @@ class P4Sync(Command):
             [self.previousDepotPath, p4Change] = extractDepotPathAndChangeFromGitLog(extractLogMessageFromGitCommit(self.branch))
             if len(self.previousDepotPath) > 0 and len(p4Change) > 0:
                 p4Change = int(p4Change) + 1
-                self.globalPrefix = self.previousDepotPath
+                self.depotPath = self.previousDepotPath
                 self.changeRange = "@%s,#head" % p4Change
                 self.initialParent = self.branch
-                self.tagLastChange = False
                 if not self.silent:
                     print "Performing incremental import into %s git branch" % self.branch
 
         self.branch = "refs/heads/" + self.branch
 
-        if len(self.globalPrefix) == 0:
-            self.globalPrefix = self.previousDepotPath = os.popen("git repo-config --get p4.depotpath").read()
+        if len(self.depotPath) != 0:
+            self.depotPath = self.depotPath[:-1]
 
-        if len(self.globalPrefix) != 0:
-            self.globalPrefix = self.globalPrefix[:-1]
-
-        if len(args) == 0 and len(self.globalPrefix) != 0:
+        if len(args) == 0 and len(self.depotPath) != 0:
             if not self.silent:
-                print "Depot path: %s" % self.globalPrefix
+                print "Depot path: %s" % self.depotPath
         elif len(args) != 1:
             return False
         else:
-            if len(self.globalPrefix) != 0 and self.globalPrefix != args[0]:
-                print "previous import used depot path %s and now %s was specified. this doesn't work!" % (self.globalPrefix, args[0])
+            if len(self.depotPath) != 0 and self.depotPath != args[0]:
+                print "previous import used depot path %s and now %s was specified. this doesn't work!" % (self.depotPath, args[0])
                 sys.exit(1)
-            self.globalPrefix = args[0]
+            self.depotPath = args[0]
 
         self.revision = ""
         self.users = {}
         self.lastChange = 0
-        self.initialTag = ""
 
-        if self.globalPrefix.find("@") != -1:
-            atIdx = self.globalPrefix.index("@")
-            self.changeRange = self.globalPrefix[atIdx:]
+        if self.depotPath.find("@") != -1:
+            atIdx = self.depotPath.index("@")
+            self.changeRange = self.depotPath[atIdx:]
             if self.changeRange == "@all":
                 self.changeRange = ""
             elif self.changeRange.find(",") == -1:
                 self.revision = self.changeRange
                 self.changeRange = ""
-            self.globalPrefix = self.globalPrefix[0:atIdx]
-        elif self.globalPrefix.find("#") != -1:
-            hashIdx = self.globalPrefix.index("#")
-            self.revision = self.globalPrefix[hashIdx:]
-            self.globalPrefix = self.globalPrefix[0:hashIdx]
+            self.depotPath = self.depotPath[0:atIdx]
+        elif self.depotPath.find("#") != -1:
+            hashIdx = self.depotPath.index("#")
+            self.revision = self.depotPath[hashIdx:]
+            self.depotPath = self.depotPath[0:hashIdx]
         elif len(self.previousDepotPath) == 0:
             self.revision = "#head"
 
-        if self.globalPrefix.endswith("..."):
-            self.globalPrefix = self.globalPrefix[:-3]
+        if self.depotPath.endswith("..."):
+            self.depotPath = self.depotPath[:-3]
 
-        if not self.globalPrefix.endswith("/"):
-            self.globalPrefix += "/"
+        if not self.depotPath.endswith("/"):
+            self.depotPath += "/"
 
         self.getUserMap()
         self.labels = {}
@@ -901,7 +921,6 @@ class P4Sync(Command):
                 self.rev = int(output[tagIdx + 9 : endPos]) + 1
                 self.changeRange = "@%s,#head" % self.rev
                 self.initialParent = os.popen("git rev-parse %s" % self.branch).read()[:-1]
-                self.initialTag = "p4/%s" % (int(self.rev) - 1)
             except:
                 pass
 
@@ -913,15 +932,15 @@ class P4Sync(Command):
         self.gitError = importProcess.childerr
 
         if len(self.revision) > 0:
-            print "Doing initial import of %s from revision %s" % (self.globalPrefix, self.revision)
+            print "Doing initial import of %s from revision %s" % (self.depotPath, self.revision)
 
             details = { "user" : "git perforce import user", "time" : int(time.time()) }
-            details["desc"] = "Initial import of %s from the state at revision %s" % (self.globalPrefix, self.revision)
+            details["desc"] = "Initial import of %s from the state at revision %s" % (self.depotPath, self.revision)
             details["change"] = self.revision
             newestRevision = 0
 
             fileCnt = 0
-            for info in p4CmdList("files %s...%s" % (self.globalPrefix, self.revision)):
+            for info in p4CmdList("files %s...%s" % (self.depotPath, self.revision)):
                 change = int(info["change"])
                 if change > newestRevision:
                     newestRevision = change
@@ -939,7 +958,7 @@ class P4Sync(Command):
             details["change"] = newestRevision
 
             try:
-                self.commit(details, self.extractFilesFromCommit(details), self.branch, self.globalPrefix)
+                self.commit(details, self.extractFilesFromCommit(details), self.branch, self.depotPath)
             except IOError:
                 print "IO error with git fast-import. Is your git version recent enough?"
                 print self.gitError.read()
@@ -958,7 +977,7 @@ class P4Sync(Command):
 
                 changes.sort()
             else:
-                output = os.popen("p4 changes %s...%s" % (self.globalPrefix, self.changeRange)).readlines()
+                output = os.popen("p4 changes %s...%s" % (self.depotPath, self.changeRange)).readlines()
 
                 for line in output:
                     changeNum = line.split(" ")[1]
@@ -985,7 +1004,7 @@ class P4Sync(Command):
                     if self.detectBranches:
                         for branch in self.branchesForCommit(files):
                             self.knownBranches.add(branch)
-                            branchPrefix = self.globalPrefix + branch + "/"
+                            branchPrefix = self.depotPath + branch + "/"
 
                             filesForCommit = self.extractFilesInCommitToBranch(files, branchPrefix)
 
@@ -1014,7 +1033,7 @@ class P4Sync(Command):
                                 merged = "refs/heads/" + merged
                             self.commit(description, files, branch, branchPrefix, parent, merged)
                     else:
-                        self.commit(description, files, self.branch, self.globalPrefix, self.initialParent)
+                        self.commit(description, files, self.branch, self.depotPath, self.initialParent)
                         self.initialParent = ""
                 except IOError:
                     print self.gitError.read()
@@ -1023,20 +1042,12 @@ class P4Sync(Command):
         if not self.silent:
             print ""
 
-        if self.tagLastChange:
-            self.gitStream.write("reset refs/tags/p4/%s\n" % self.lastChange)
-            self.gitStream.write("from %s\n\n" % self.branch);
-
 
         self.gitStream.close()
         self.gitOutput.close()
         self.gitError.close()
         importProcess.wait()
 
-        os.popen("git repo-config p4.depotpath %s" % self.globalPrefix).read()
-        if len(self.initialTag) > 0:
-            os.popen("git tag -d %s" % self.initialTag).read()
-
         return True
 
 class P4Rebase(Command):
@@ -1060,7 +1071,6 @@ class P4Clone(P4Sync):
         self.description = "Creates a new git repository and imports from Perforce into it"
         self.usage = "usage: %prog [options] //depot/path[@revRange] [directory]"
         self.needsGit = False
-        self.tagLastChange = False
 
     def run(self, args):
         if len(args) < 1: