Skip to content

Commit 7c88ec0

Browse files
committed
Merge branch 'pw/p4-use-client-spec-branch-detection'
Fix "git p4" when "--use-client-spec" and "--detect-branches" are used together (the command used to misdetect branches). * pw/p4-use-client-spec-branch-detection: git p4: make branch detection work with --use-client-spec git p4: do wildcard decoding in stripRepoPath git p4: set self.branchPrefixes in initialization git p4 test: add broken --use-client-spec --detect-branches tests git p4 test: move client_view() function to library
2 parents 800981f + 21ef5df commit 7c88ec0

File tree

4 files changed

+145
-41
lines changed

4 files changed

+145
-41
lines changed

git-p4.py

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,19 +1818,41 @@ def extractFilesFromCommit(self, commit):
18181818
return files
18191819

18201820
def stripRepoPath(self, path, prefixes):
1821-
if self.useClientSpec:
1822-
return self.clientSpecDirs.map_in_client(path)
1821+
"""When streaming files, this is called to map a p4 depot path
1822+
to where it should go in git. The prefixes are either
1823+
self.depotPaths, or self.branchPrefixes in the case of
1824+
branch detection."""
18231825

1824-
if self.keepRepoPath:
1825-
prefixes = [re.sub("^(//[^/]+/).*", r'\1', prefixes[0])]
1826+
if self.useClientSpec:
1827+
# branch detection moves files up a level (the branch name)
1828+
# from what client spec interpretation gives
1829+
path = self.clientSpecDirs.map_in_client(path)
1830+
if self.detectBranches:
1831+
for b in self.knownBranches:
1832+
if path.startswith(b + "/"):
1833+
path = path[len(b)+1:]
1834+
1835+
elif self.keepRepoPath:
1836+
# Preserve everything in relative path name except leading
1837+
# //depot/; just look at first prefix as they all should
1838+
# be in the same depot.
1839+
depot = re.sub("^(//[^/]+/).*", r'\1', prefixes[0])
1840+
if p4PathStartsWith(path, depot):
1841+
path = path[len(depot):]
18261842

1827-
for p in prefixes:
1828-
if p4PathStartsWith(path, p):
1829-
path = path[len(p):]
1843+
else:
1844+
for p in prefixes:
1845+
if p4PathStartsWith(path, p):
1846+
path = path[len(p):]
1847+
break
18301848

1849+
path = wildcard_decode(path)
18311850
return path
18321851

18331852
def splitFilesIntoBranches(self, commit):
1853+
"""Look at each depotFile in the commit to figure out to what
1854+
branch it belongs."""
1855+
18341856
branches = {}
18351857
fnum = 0
18361858
while commit.has_key("depotFile%s" % fnum):
@@ -1848,12 +1870,16 @@ def splitFilesIntoBranches(self, commit):
18481870
file["type"] = commit["type%s" % fnum]
18491871
fnum = fnum + 1
18501872

1851-
relPath = self.stripRepoPath(path, self.depotPaths)
1852-
relPath = wildcard_decode(relPath)
1873+
# start with the full relative path where this file would
1874+
# go in a p4 client
1875+
if self.useClientSpec:
1876+
relPath = self.clientSpecDirs.map_in_client(path)
1877+
else:
1878+
relPath = self.stripRepoPath(path, self.depotPaths)
18531879

18541880
for branch in self.knownBranches.keys():
1855-
1856-
# add a trailing slash so that a commit into qt/4.2foo doesn't end up in qt/4.2
1881+
# add a trailing slash so that a commit into qt/4.2foo
1882+
# doesn't end up in qt/4.2, e.g.
18571883
if relPath.startswith(branch + "/"):
18581884
if branch not in branches:
18591885
branches[branch] = []
@@ -1867,7 +1893,6 @@ def splitFilesIntoBranches(self, commit):
18671893

18681894
def streamOneP4File(self, file, contents):
18691895
relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)
1870-
relPath = wildcard_decode(relPath)
18711896
if verbose:
18721897
sys.stderr.write("%s\n" % relPath)
18731898

@@ -1936,7 +1961,6 @@ def streamOneP4File(self, file, contents):
19361961

19371962
def streamOneP4Deletion(self, file):
19381963
relPath = self.stripRepoPath(file['path'], self.branchPrefixes)
1939-
relPath = wildcard_decode(relPath)
19401964
if verbose:
19411965
sys.stderr.write("delete %s\n" % relPath)
19421966
self.gitStream.write("D %s\n" % relPath)
@@ -2041,10 +2065,9 @@ def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):
20412065
gitStream.write(description)
20422066
gitStream.write("\n")
20432067

2044-
def commit(self, details, files, branch, branchPrefixes, parent = ""):
2068+
def commit(self, details, files, branch, parent = ""):
20452069
epoch = details["time"]
20462070
author = details["user"]
2047-
self.branchPrefixes = branchPrefixes
20482071

20492072
if self.verbose:
20502073
print "commit into %s" % branch
@@ -2053,7 +2076,7 @@ def commit(self, details, files, branch, branchPrefixes, parent = ""):
20532076
# create a commit.
20542077
new_files = []
20552078
for f in files:
2056-
if [p for p in branchPrefixes if p4PathStartsWith(f['path'], p)]:
2079+
if [p for p in self.branchPrefixes if p4PathStartsWith(f['path'], p)]:
20572080
new_files.append (f)
20582081
else:
20592082
sys.stderr.write("Ignoring file outside of prefix: %s\n" % f['path'])
@@ -2070,8 +2093,8 @@ def commit(self, details, files, branch, branchPrefixes, parent = ""):
20702093

20712094
self.gitStream.write("data <<EOT\n")
20722095
self.gitStream.write(details["desc"])
2073-
self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s"
2074-
% (','.join (branchPrefixes), details["change"]))
2096+
self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s" %
2097+
(','.join(self.branchPrefixes), details["change"]))
20752098
if len(details['options']) > 0:
20762099
self.gitStream.write(": options = %s" % details['options'])
20772100
self.gitStream.write("]\nEOT\n\n")
@@ -2094,7 +2117,7 @@ def commit(self, details, files, branch, branchPrefixes, parent = ""):
20942117
print "Change %s is labelled %s" % (change, labelDetails)
20952118

20962119
files = p4CmdList(["files"] + ["%s...@%s" % (p, change)
2097-
for p in branchPrefixes])
2120+
for p in self.branchPrefixes])
20982121

20992122
if len(files) == len(labelRevisions):
21002123

@@ -2405,6 +2428,7 @@ def importChanges(self, changes):
24052428
for branch in branches.keys():
24062429
## HACK --hwn
24072430
branchPrefix = self.depotPaths[0] + branch + "/"
2431+
self.branchPrefixes = [ branchPrefix ]
24082432

24092433
parent = ""
24102434

@@ -2449,19 +2473,19 @@ def importChanges(self, changes):
24492473
tempBranch = os.path.join(self.tempBranchLocation, "%d" % (change))
24502474
if self.verbose:
24512475
print "Creating temporary branch: " + tempBranch
2452-
self.commit(description, filesForCommit, tempBranch, [branchPrefix])
2476+
self.commit(description, filesForCommit, tempBranch)
24532477
self.tempBranches.append(tempBranch)
24542478
self.checkpoint()
24552479
blob = self.searchParent(parent, branch, tempBranch)
24562480
if blob:
2457-
self.commit(description, filesForCommit, branch, [branchPrefix], blob)
2481+
self.commit(description, filesForCommit, branch, blob)
24582482
else:
24592483
if self.verbose:
24602484
print "Parent of %s not found. Committing into head of %s" % (branch, parent)
2461-
self.commit(description, filesForCommit, branch, [branchPrefix], parent)
2485+
self.commit(description, filesForCommit, branch, parent)
24622486
else:
24632487
files = self.extractFilesFromCommit(description)
2464-
self.commit(description, files, self.branch, self.depotPaths,
2488+
self.commit(description, files, self.branch,
24652489
self.initialParent)
24662490
self.initialParent = ""
24672491
except IOError:
@@ -2525,7 +2549,7 @@ def importHeadRevision(self, revision):
25252549

25262550
self.updateOptionDict(details)
25272551
try:
2528-
self.commit(details, self.extractFilesFromCommit(details), self.branch, self.depotPaths)
2552+
self.commit(details, self.extractFilesFromCommit(details), self.branch)
25292553
except IOError:
25302554
print "IO error with git fast-import. Is your git version recent enough?"
25312555
print self.gitError.read()
@@ -2683,6 +2707,9 @@ def run(self, args):
26832707

26842708
self.depotPaths = newPaths
26852709

2710+
# --detect-branches may change this for each branch
2711+
self.branchPrefixes = self.depotPaths
2712+
26862713
self.loadUserMapFromCache()
26872714
self.labels = {}
26882715
if self.detectLabels:

t/lib-git-p4.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,20 @@ marshal_dump() {
115115
EOF
116116
"$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py"
117117
}
118+
119+
#
120+
# Construct a client with this list of View lines
121+
#
122+
client_view() {
123+
(
124+
cat <<-EOF &&
125+
Client: client
126+
Description: client
127+
Root: $cli
128+
View:
129+
EOF
130+
for arg ; do
131+
printf "\t$arg\n"
132+
done
133+
) | p4 client -i
134+
}

t/t9801-git-p4-branch.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,83 @@ test_expect_failure 'git p4 clone file subset branch' '
410410
test_path_is_missing file3
411411
)
412412
'
413+
414+
# From a report in http://stackoverflow.com/questions/11893688
415+
# where --use-client-spec caused branch prefixes not to be removed;
416+
# every file in git appeared into a subdirectory of the branch name.
417+
test_expect_success 'use-client-spec detect-branches setup' '
418+
rm -rf "$cli" &&
419+
mkdir "$cli" &&
420+
(
421+
cd "$cli" &&
422+
client_view "//depot/usecs/... //client/..." &&
423+
mkdir b1 &&
424+
echo b1/b1-file1 >b1/b1-file1 &&
425+
p4 add b1/b1-file1 &&
426+
p4 submit -d "b1/b1-file1" &&
427+
428+
p4 integrate //depot/usecs/b1/... //depot/usecs/b2/... &&
429+
p4 submit -d "b1 -> b2" &&
430+
p4 branch -i <<-EOF &&
431+
Branch: b2
432+
View: //depot/usecs/b1/... //depot/usecs/b2/...
433+
EOF
434+
435+
echo b2/b2-file2 >b2/b2-file2 &&
436+
p4 add b2/b2-file2 &&
437+
p4 submit -d "b2/b2-file2"
438+
)
439+
'
440+
441+
test_expect_success 'use-client-spec detect-branches files in top-level' '
442+
test_when_finished cleanup_git &&
443+
test_create_repo "$git" &&
444+
(
445+
cd "$git" &&
446+
git p4 sync --detect-branches --use-client-spec //depot/usecs@all &&
447+
git checkout -b master p4/usecs/b1 &&
448+
test_path_is_file b1-file1 &&
449+
test_path_is_missing b2-file2 &&
450+
test_path_is_missing b1 &&
451+
test_path_is_missing b2 &&
452+
453+
git checkout -b b2 p4/usecs/b2 &&
454+
test_path_is_file b1-file1 &&
455+
test_path_is_file b2-file2 &&
456+
test_path_is_missing b1 &&
457+
test_path_is_missing b2
458+
)
459+
'
460+
461+
test_expect_success 'use-client-spec detect-branches skips branches setup' '
462+
(
463+
cd "$cli" &&
464+
465+
p4 integrate //depot/usecs/b1/... //depot/usecs/b3/... &&
466+
p4 submit -d "b1 -> b3" &&
467+
p4 branch -i <<-EOF &&
468+
Branch: b3
469+
View: //depot/usecs/b1/... //depot/usecs/b3/...
470+
EOF
471+
472+
echo b3/b3-file3 >b3/b3-file3 &&
473+
p4 add b3/b3-file3 &&
474+
p4 submit -d "b3/b3-file3"
475+
)
476+
'
477+
478+
test_expect_success 'use-client-spec detect-branches skips branches' '
479+
client_view "//depot/usecs/... //client/..." \
480+
"-//depot/usecs/b3/... //client/b3/..." &&
481+
test_when_finished cleanup_git &&
482+
test_create_repo "$git" &&
483+
(
484+
cd "$git" &&
485+
git p4 sync --detect-branches --use-client-spec //depot/usecs@all &&
486+
test_must_fail git rev-parse refs/remotes/p4/usecs/b3
487+
)
488+
'
489+
413490
test_expect_success 'kill p4d' '
414491
kill_p4d
415492
'

t/t9809-git-p4-client-view.sh

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,6 @@ test_expect_success 'start p4d' '
88
start_p4d
99
'
1010

11-
#
12-
# Construct a client with this list of View lines
13-
#
14-
client_view() {
15-
(
16-
cat <<-EOF &&
17-
Client: client
18-
Description: client
19-
Root: $cli
20-
View:
21-
EOF
22-
for arg ; do
23-
printf "\t$arg\n"
24-
done
25-
) | p4 client -i
26-
}
27-
2811
#
2912
# Verify these files exist, exactly. Caller creates
3013
# a list of files in file "files".

0 commit comments

Comments
 (0)