Merge branch 'ld/git-p4-tags-and-labels'
authorJunio C Hamano <gitster@pobox.com>
Thu, 17 May 2012 22:21:46 +0000 (15:21 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 17 May 2012 22:21:46 +0000 (15:21 -0700)
By Luke Diamand
* ld/git-p4-tags-and-labels:
git p4: fix bug when enabling tag import/export via config variables
git p4: fix bug when verbose enabled with tag export
git p4: add test for tag import/export enabled via config

1  2 
git-p4.py
diff --combined git-p4.py
index 565cfbcc78aac31f3e799967c0746a41063bf501,78ec9f8fb8a462027f25ae8e15e7a38543c79ef4..f895a2412bd5723d72f3bcfdcddbce495070d5e6
+++ b/git-p4.py
@@@ -133,29 -133,25 +133,29 @@@ def p4_system(cmd)
      subprocess.check_call(real_cmd, shell=expand)
  
  def p4_integrate(src, dest):
 -    p4_system(["integrate", "-Dt", src, dest])
 +    p4_system(["integrate", "-Dt", wildcard_encode(src), wildcard_encode(dest)])
  
 -def p4_sync(path):
 -    p4_system(["sync", path])
 +def p4_sync(f, *options):
 +    p4_system(["sync"] + list(options) + [wildcard_encode(f)])
  
  def p4_add(f):
 -    p4_system(["add", f])
 +    # forcibly add file names with wildcards
 +    if wildcard_present(f):
 +        p4_system(["add", "-f", f])
 +    else:
 +        p4_system(["add", f])
  
  def p4_delete(f):
 -    p4_system(["delete", f])
 +    p4_system(["delete", wildcard_encode(f)])
  
  def p4_edit(f):
 -    p4_system(["edit", f])
 +    p4_system(["edit", wildcard_encode(f)])
  
  def p4_revert(f):
 -    p4_system(["revert", f])
 +    p4_system(["revert", wildcard_encode(f)])
  
 -def p4_reopen(type, file):
 -    p4_system(["reopen", "-t", type, file])
 +def p4_reopen(type, f):
 +    p4_system(["reopen", "-t", type, wildcard_encode(f)])
  
  #
  # Canonicalize the p4 type and return a tuple of the
@@@ -252,7 -248,7 +252,7 @@@ def setP4ExecBit(file, mode)
  def getP4OpenedType(file):
      # Returns the perforce file type for the given file.
  
 -    result = p4_read_pipe(["opened", file])
 +    result = p4_read_pipe(["opened", wildcard_encode(file)])
      match = re.match(".*\((.+)\)\r?$", result)
      if match:
          return match.group(1)
@@@ -662,34 -658,6 +662,34 @@@ def getClientRoot()
  
      return entry["Root"]
  
 +#
 +# P4 wildcards are not allowed in filenames.  P4 complains
 +# if you simply add them, but you can force it with "-f", in
 +# which case it translates them into %xx encoding internally.
 +#
 +def wildcard_decode(path):
 +    # Search for and fix just these four characters.  Do % last so
 +    # that fixing it does not inadvertently create new %-escapes.
 +    # Cannot have * in a filename in windows; untested as to
 +    # what p4 would do in such a case.
 +    if not platform.system() == "Windows":
 +        path = path.replace("%2A", "*")
 +    path = path.replace("%23", "#") \
 +               .replace("%40", "@") \
 +               .replace("%25", "%")
 +    return path
 +
 +def wildcard_encode(path):
 +    # do % first to avoid double-encoding the %s introduced here
 +    path = path.replace("%", "%25") \
 +               .replace("*", "%2A") \
 +               .replace("#", "%23") \
 +               .replace("@", "%40")
 +    return path
 +
 +def wildcard_present(path):
 +    return path.translate(None, "*#@%") != path
 +
  class Command:
      def __init__(self):
          self.usage = "usage: %prog [options]"
@@@ -1070,7 -1038,6 +1070,7 @@@ class P4Submit(Command, P4UserMap)
          filesToAdd = set()
          filesToDelete = set()
          editedFiles = set()
 +        pureRenameCopy = set()
          filesToChangeExecBit = {}
  
          for line in diff:
              elif modifier == "C":
                  src, dest = diff['src'], diff['dst']
                  p4_integrate(src, dest)
 +                pureRenameCopy.add(dest)
                  if diff['src_sha1'] != diff['dst_sha1']:
                      p4_edit(dest)
 +                    pureRenameCopy.discard(dest)
                  if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
                      p4_edit(dest)
 +                    pureRenameCopy.discard(dest)
                      filesToChangeExecBit[dest] = diff['dst_mode']
                  os.unlink(dest)
                  editedFiles.add(dest)
                  p4_integrate(src, dest)
                  if diff['src_sha1'] != diff['dst_sha1']:
                      p4_edit(dest)
 +                else:
 +                    pureRenameCopy.add(dest)
                  if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
                      p4_edit(dest)
                      filesToChangeExecBit[dest] = diff['dst_mode']
                  del(os.environ["P4DIFF"])
              diff = ""
              for editedFile in editedFiles:
 -                diff += p4_read_pipe(['diff', '-du', editedFile])
 +                diff += p4_read_pipe(['diff', '-du',
 +                                      wildcard_encode(editedFile)])
  
              newdiff = ""
              for newFile in filesToAdd:
                          # unmarshalled.
                          changelist = self.lastP4Changelist()
                          self.modifyChangelistUser(changelist, p4User)
 +
 +                # The rename/copy happened by applying a patch that created a
 +                # new file.  This leaves it writable, which confuses p4.
 +                for f in pureRenameCopy:
 +                    p4_sync(f, "-f")
 +
              else:
                  # skip this patch
                  print "Submission cancelled, undoing p4 changes."
  
              if not m.match(name):
                  if verbose:
-                     print "tag %s does not match regexp %s" % (name, validTagRegexp)
+                     print "tag %s does not match regexp %s" % (name, validLabelRegexp)
                  continue
  
              # Get the p4 commit this corresponds to
          self.oldWorkingDirectory = os.getcwd()
  
          # ensure the clientPath exists
 +        new_client_dir = False
          if not os.path.exists(self.clientPath):
 +            new_client_dir = True
              os.makedirs(self.clientPath)
  
          chdir(self.clientPath)
          print "Synchronizing p4 checkout..."
 -        p4_sync("...")
 +        if new_client_dir:
 +            # old one was destroyed, and maybe nobody told p4
 +            p4_sync("...", "-f")
 +        else:
 +            p4_sync("...")
          self.check()
  
          commits = []
              rebase.rebase()
  
          if gitConfig("git-p4.exportLabels", "--bool") == "true":
-             self.exportLabels = true
+             self.exportLabels = True
  
          if self.exportLabels:
              p4Labels = getP4Labels(self.depotPath)
@@@ -1730,6 -1679,23 +1730,6 @@@ class P4Sync(Command, P4UserMap)
          if gitConfig("git-p4.syncFromOrigin") == "false":
              self.syncWithOrigin = False
  
 -    #
 -    # P4 wildcards are not allowed in filenames.  P4 complains
 -    # if you simply add them, but you can force it with "-f", in
 -    # which case it translates them into %xx encoding internally.
 -    # Search for and fix just these four characters.  Do % last so
 -    # that fixing it does not inadvertently create new %-escapes.
 -    #
 -    def wildcard_decode(self, path):
 -        # Cannot have * in a filename in windows; untested as to
 -        # what p4 would do in such a case.
 -        if not self.isWindows:
 -            path = path.replace("%2A", "*")
 -        path = path.replace("%23", "#") \
 -                   .replace("%40", "@") \
 -                   .replace("%25", "%")
 -        return path
 -
      # Force a checkpoint in fast-import and wait for it to finish
      def checkpoint(self):
          self.gitStream.write("checkpoint\n\n")
              fnum = fnum + 1
  
              relPath = self.stripRepoPath(path, self.depotPaths)
 +            relPath = wildcard_decode(relPath)
  
              for branch in self.knownBranches.keys():
  
  
      def streamOneP4File(self, file, contents):
          relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)
 -        relPath = self.wildcard_decode(relPath)
 +        relPath = wildcard_decode(relPath)
          if verbose:
              sys.stderr.write("%s\n" % relPath)
  
  
      def streamOneP4Deletion(self, file):
          relPath = self.stripRepoPath(file['path'], self.branchPrefixes)
 +        relPath = wildcard_decode(relPath)
          if verbose:
              sys.stderr.write("delete %s\n" % relPath)
          self.gitStream.write("D %s\n" % relPath)
                          sys.stdout.write("\n")
  
          if gitConfig("git-p4.importLabels", "--bool") == "true":
-             self.importLabels = true
+             self.importLabels = True
  
          if self.importLabels:
              p4Labels = getP4Labels(self.depotPaths)