Skip to content

Commit fed2369

Browse files
vhdagitster
authored andcommitted
git-p4: Search for parent commit on branch creation
To find out which is its parent the commit of the new branch is compared sequentially to each blob of the parent branch from the newest to the oldest. The first blob which results in a zero diff is considered the parent commit. If none is found, then the commit is applied to the top of the parent branch. A fast-import "checkpoint" call is required because diff-tree is only able to work with blobs on disk. But most of these commits will not be part of the final imported tree, making fast-import fail. To avoid this, the temporary branches are tracked and then removed at the end of the import process. Signed-off-by: Vitor Antunes <[email protected]> Acked-by: Pete Wyckoff <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a080558 commit fed2369

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

contrib/fast-import/git-p4

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,8 @@ class P4Sync(Command, P4UserMap):
14291429
self.cloneExclude = []
14301430
self.useClientSpec = False
14311431
self.clientSpecDirs = None
1432+
self.tempBranches = []
1433+
self.tempBranchLocation = "git-p4-tmp"
14321434

14331435
if gitConfig("git-p4.syncFromOrigin") == "false":
14341436
self.syncWithOrigin = False
@@ -1450,6 +1452,14 @@ class P4Sync(Command, P4UserMap):
14501452
.replace("%25", "%")
14511453
return path
14521454

1455+
# Force a checkpoint in fast-import and wait for it to finish
1456+
def checkpoint(self):
1457+
self.gitStream.write("checkpoint\n\n")
1458+
self.gitStream.write("progress checkpoint\n\n")
1459+
out = self.gitOutput.readline()
1460+
if self.verbose:
1461+
print "checkpoint finished: " + out
1462+
14531463
def extractFilesFromCommit(self, commit):
14541464
self.cloneExclude = [re.sub(r"\.\.\.$", "", path)
14551465
for path in self.cloneExclude]
@@ -1957,6 +1967,20 @@ class P4Sync(Command, P4UserMap):
19571967
self.importChanges(changes)
19581968
return True
19591969

1970+
def searchParent(self, parent, branch, target):
1971+
parentFound = False
1972+
for blob in read_pipe_lines(["git", "rev-list", "--reverse", "--no-merges", parent]):
1973+
blob = blob.strip()
1974+
if len(read_pipe(["git", "diff-tree", blob, target])) == 0:
1975+
parentFound = True
1976+
if self.verbose:
1977+
print "Found parent of %s in commit %s" % (branch, blob)
1978+
break
1979+
if parentFound:
1980+
return blob
1981+
else:
1982+
return None
1983+
19601984
def importChanges(self, changes):
19611985
cnt = 1
19621986
for change in changes:
@@ -2013,7 +2037,21 @@ class P4Sync(Command, P4UserMap):
20132037
parent = self.initialParents[branch]
20142038
del self.initialParents[branch]
20152039

2016-
self.commit(description, filesForCommit, branch, [branchPrefix], parent)
2040+
blob = None
2041+
if len(parent) > 0:
2042+
tempBranch = os.path.join(self.tempBranchLocation, "%d" % (change))
2043+
if self.verbose:
2044+
print "Creating temporary branch: " + tempBranch
2045+
self.commit(description, filesForCommit, tempBranch, [branchPrefix])
2046+
self.tempBranches.append(tempBranch)
2047+
self.checkpoint()
2048+
blob = self.searchParent(parent, branch, tempBranch)
2049+
if blob:
2050+
self.commit(description, filesForCommit, branch, [branchPrefix], blob)
2051+
else:
2052+
if self.verbose:
2053+
print "Parent of %s not found. Committing into head of %s" % (branch, parent)
2054+
self.commit(description, filesForCommit, branch, [branchPrefix], parent)
20172055
else:
20182056
files = self.extractFilesFromCommit(description)
20192057
self.commit(description, files, self.branch, self.depotPaths,
@@ -2348,6 +2386,12 @@ class P4Sync(Command, P4UserMap):
23482386
self.gitOutput.close()
23492387
self.gitError.close()
23502388

2389+
# Cleanup temporary branches created during import
2390+
if self.tempBranches != []:
2391+
for branch in self.tempBranches:
2392+
read_pipe("git update-ref -d %s" % branch)
2393+
os.rmdir(os.path.join(os.environ.get("GIT_DIR", ".git"), self.tempBranchLocation))
2394+
23512395
return True
23522396

23532397
class P4Rebase(Command):

0 commit comments

Comments
 (0)