Merge branch 'va/git-p4-branch'
authorJunio C Hamano <gitster@pobox.com>
Wed, 1 Feb 2012 06:01:16 +0000 (22:01 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 1 Feb 2012 06:01:16 +0000 (22:01 -0800)
* va/git-p4-branch:
t9801: do not overuse test_must_fail
git-p4: Change p4 command invocation
git-p4: Add test case for complex branch import
git-p4: Search for parent commit on branch creation

1  2 
contrib/fast-import/git-p4
index 27e06c1e9b2844d617a14c782d2e5fa7ec8a42d5,b951ce58bbc199a122f806377fd42563118969e5..a78d9c54931c7fc1f6a693a7f185f08bcb8f6861
@@@ -1207,8 -1207,8 +1207,8 @@@ class View(object)
                  die("Can't handle * wildcards in view: %s" % self.path)
              triple_dot_index = self.path.find("...")
              if triple_dot_index >= 0:
 -                if not self.path.endswith("..."):
 -                    die("Can handle ... wildcard only at end of path: %s" %
 +                if triple_dot_index != len(self.path) - 3:
 +                    die("Can handle only single ... wildcard, at end: %s" %
                          self.path)
                  self.ends_triple_dot = True
  
              if self.exclude:
                  c = "-"
              return "View.Mapping: %s%s -> %s" % \
 -                   (c, self.depot_side, self.client_side)
 +                   (c, self.depot_side.path, self.client_side.path)
  
          def map_depot_to_client(self, depot_path):
              """Calculate the client path if using this mapping on the
              else:
                  # This mapping matched; no need to search any further.
                  # But, the mapping could be rejected if the client path
 -                # has already been claimed by an earlier mapping.
 +                # has already been claimed by an earlier mapping (i.e.
 +                # one later in the list, which we are walking backwards).
                  already_mapped_in_client = False
                  for f in paths_filled:
                      # this is View.Path.match
@@@ -1430,6 -1429,8 +1430,8 @@@ class P4Sync(Command, P4UserMap)
          self.cloneExclude = []
          self.useClientSpec = False
          self.clientSpecDirs = None
+         self.tempBranches = []
+         self.tempBranchLocation = "git-p4-tmp"
  
          if gitConfig("git-p4.syncFromOrigin") == "false":
              self.syncWithOrigin = False
                     .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")
+         self.gitStream.write("progress checkpoint\n\n")
+         out = self.gitOutput.readline()
+         if self.verbose:
+             print "checkpoint finished: " + out
      def extractFilesFromCommit(self, commit):
          self.cloneExclude = [re.sub(r"\.\.\.$", "", path)
                               for path in self.cloneExclude]
          self.importChanges(changes)
          return True
  
+     def searchParent(self, parent, branch, target):
+         parentFound = False
+         for blob in read_pipe_lines(["git", "rev-list", "--reverse", "--no-merges", parent]):
+             blob = blob.strip()
+             if len(read_pipe(["git", "diff-tree", blob, target])) == 0:
+                 parentFound = True
+                 if self.verbose:
+                     print "Found parent of %s in commit %s" % (branch, blob)
+                 break
+         if parentFound:
+             return blob
+         else:
+             return None
      def importChanges(self, changes):
          cnt = 1
          for change in changes:
-             description = p4Cmd("describe %s" % change)
+             description = p4Cmd(["describe", str(change)])
              self.updateOptionDict(description)
  
              if not self.silent:
                              parent = self.initialParents[branch]
                              del self.initialParents[branch]
  
-                         self.commit(description, filesForCommit, branch, [branchPrefix], parent)
+                         blob = None
+                         if len(parent) > 0:
+                             tempBranch = os.path.join(self.tempBranchLocation, "%d" % (change))
+                             if self.verbose:
+                                 print "Creating temporary branch: " + tempBranch
+                             self.commit(description, filesForCommit, tempBranch, [branchPrefix])
+                             self.tempBranches.append(tempBranch)
+                             self.checkpoint()
+                             blob = self.searchParent(parent, branch, tempBranch)
+                         if blob:
+                             self.commit(description, filesForCommit, branch, [branchPrefix], blob)
+                         else:
+                             if self.verbose:
+                                 print "Parent of %s not found. Committing into head of %s" % (branch, parent)
+                             self.commit(description, filesForCommit, branch, [branchPrefix], parent)
                  else:
                      files = self.extractFilesFromCommit(description)
                      self.commit(description, files, self.branch, self.depotPaths,
          self.gitOutput.close()
          self.gitError.close()
  
+         # Cleanup temporary branches created during import
+         if self.tempBranches != []:
+             for branch in self.tempBranches:
+                 read_pipe("git update-ref -d %s" % branch)
+             os.rmdir(os.path.join(os.environ.get("GIT_DIR", ".git"), self.tempBranchLocation))
          return True
  
  class P4Rebase(Command):