Merge branch 'ph/mergetool'
[gitweb.git] / contrib / fast-import / git-p4
index be96600753fa3a963ea5a260e0b0f23b4ff1ed16..87ca51e401cc7f00a2e75acdc205fc49ee54231b 100755 (executable)
@@ -90,11 +90,11 @@ def getP4OpenedType(file):
     # Returns the perforce file type for the given file.
 
     result = read_pipe("p4 opened %s" % file)
-    match = re.match(".*\((.+)\)$", result)
+    match = re.match(".*\((.+)\)\r?$", result)
     if match:
         return match.group(1)
     else:
-        die("Could not determine file type for %s" % file)
+        die("Could not determine file type for %s (result: '%s')" % (file, result))
 
 def diffTreePattern():
     # This is a simple generator for the diff tree regex pattern. This could be
@@ -513,6 +513,8 @@ class P4Submit(Command):
         template = ""
         inFilesSection = False
         for line in read_pipe_lines("p4 change -o"):
+            if line.endswith("\r\n"):
+                line = line[:-2] + "\n"
             if inFilesSection:
                 if line.startswith("\t"):
                     # path starts and ends with a tab
@@ -619,38 +621,43 @@ class P4Submit(Command):
             setP4ExecBit(f, mode)
 
         logMessage = extractLogMessageFromGitCommit(id)
-        if self.isWindows:
-            logMessage = logMessage.replace("\n", "\r\n")
         logMessage = logMessage.strip()
 
         template = self.prepareSubmitTemplate()
 
         if self.interactive:
             submitTemplate = self.prepareLogMessage(template, logMessage)
+            if os.environ.has_key("P4DIFF"):
+                del(os.environ["P4DIFF"])
             diff = read_pipe("p4 diff -du ...")
 
+            newdiff = ""
             for newFile in filesToAdd:
-                diff += "==== new file ====\n"
-                diff += "--- /dev/null\n"
-                diff += "+++ %s\n" % newFile
+                newdiff += "==== new file ====\n"
+                newdiff += "--- /dev/null\n"
+                newdiff += "+++ %s\n" % newFile
                 f = open(newFile, "r")
                 for line in f.readlines():
-                    diff += "+" + line
+                    newdiff += "+" + line
                 f.close()
 
-            separatorLine = "######## everything below this line is just the diff #######"
-            if platform.system() == "Windows":
-                separatorLine += "\r"
-            separatorLine += "\n"
+            separatorLine = "######## everything below this line is just the diff #######\n"
 
             [handle, fileName] = tempfile.mkstemp()
             tmpFile = os.fdopen(handle, "w+")
-            tmpFile.write(submitTemplate + separatorLine + diff)
+            if self.isWindows:
+                submitTemplate = submitTemplate.replace("\n", "\r\n")
+                separatorLine = separatorLine.replace("\n", "\r\n")
+                newdiff = newdiff.replace("\n", "\r\n")
+            tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
             tmpFile.close()
             defaultEditor = "vi"
             if platform.system() == "Windows":
                 defaultEditor = "notepad"
-            editor = os.environ.get("EDITOR", defaultEditor);
+            if os.environ.has_key("P4EDITOR"):
+                editor = os.environ.get("P4EDITOR")
+            else:
+                editor = os.environ.get("EDITOR", defaultEditor);
             system(editor + " " + fileName)
             tmpFile = open(fileName, "rb")
             message = tmpFile.read()
@@ -680,6 +687,10 @@ class P4Submit(Command):
         else:
             return False
 
+        allowSubmit = gitConfig("git-p4.allowSubmit")
+        if len(allowSubmit) > 0 and not self.master in allowSubmit.split(","):
+            die("%s is not in git-p4.allowSubmit" % self.master)
+
         [upstream, settings] = findUpstreamBranchPoint()
         self.depotPath = settings['depot-paths'][0]
         if len(self.origin) == 0:
@@ -850,56 +861,61 @@ class P4Sync(Command):
 
     ## Should move this out, doesn't use SELF.
     def readP4Files(self, files):
+        filesForCommit = []
+        filesToRead = []
+
         for f in files:
+            includeFile = True
             for val in self.clientSpecDirs:
                 if f['path'].startswith(val[0]):
-                    if val[1] > 0:
-                        f['include'] = True
-                    else:
-                        f['include'] = False
+                    if val[1] <= 0:
+                        includeFile = False
                     break
 
-        files = [f for f in files
-                 if f['action'] != 'delete' and
-                 (f.has_key('include') == False or f['include'] == True)]
+            if includeFile:
+                filesForCommit.append(f)
+                if f['action'] != 'delete':
+                    filesToRead.append(f)
 
-        if not files:
-            return []
+        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+')
 
-        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']));
+            if "p4ExitCode" in filedata[0]:
+                die("Problems executing p4. Error: [%d]."
+                    % (filedata[0]['p4ExitCode']));
 
         j = 0;
         contents = {}
         while j < len(filedata):
             stat = filedata[j]
             j += 1
-            text = ''
+            text = [];
             while j < len(filedata) and filedata[j]['code'] in ('text', 'unicode', 'binary'):
-                tmp = filedata[j]['data']
-                if stat['type'] in ('text+ko', 'unicode+ko', 'binary+ko'):
-                    tmp = re.sub(r'(?i)\$(Id|Header):[^$]*\$',r'$\1$', tmp)
-                elif stat['type'] in ('text+k', 'ktext', 'kxtext', 'unicode+k', 'binary+k'):
-                    tmp = re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$',r'$\1$', tmp)
-                text += tmp
+                text.append(filedata[j]['data'])
                 j += 1
-
+            text = ''.join(text)
 
             if not stat.has_key('depotFile'):
                 sys.stderr.write("p4 print fails with: %s\n" % repr(stat))
                 continue
 
+            if stat['type'] in ('text+ko', 'unicode+ko', 'binary+ko'):
+                text = re.sub(r'(?i)\$(Id|Header):[^$]*\$',r'$\1$', text)
+            elif stat['type'] in ('text+k', 'ktext', 'kxtext', 'unicode+k', 'binary+k'):
+                text = re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$',r'$\1$', text)
+
             contents[stat['depotFile']] = text
 
-        for f in files:
-            assert not f.has_key('data')
-            f['data'] = contents[f['path']]
-        return files
+        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"]