Skip to content

Commit 8d7ac73

Browse files
committed
Merge branch 'ld/git-p4-branches-and-labels'
* ld/git-p4-branches-and-labels: git-p4: label import fails with multiple labels at the same changelist git-p4: add test for p4 labels git-p4: importing labels should cope with missing owner git-p4: cope with labels with empty descriptions git-p4: handle p4 branches and labels containing shell chars
2 parents 7010146 + a080558 commit 8d7ac73

File tree

3 files changed

+205
-35
lines changed

3 files changed

+205
-35
lines changed

contrib/fast-import/git-p4

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,26 @@ class Command:
563563
class P4UserMap:
564564
def __init__(self):
565565
self.userMapFromPerforceServer = False
566+
self.myP4UserId = None
567+
568+
def p4UserId(self):
569+
if self.myP4UserId:
570+
return self.myP4UserId
571+
572+
results = p4CmdList("user -o")
573+
for r in results:
574+
if r.has_key('User'):
575+
self.myP4UserId = r['User']
576+
return r['User']
577+
die("Could not find your p4 user id")
578+
579+
def p4UserIsMe(self, p4User):
580+
# return True if the given p4 user is actually me
581+
me = self.p4UserId()
582+
if not p4User or p4User != me:
583+
return False
584+
else:
585+
return True
566586

567587
def getUserCacheFilename(self):
568588
home = os.environ.get("HOME", os.environ.get("USERPROFILE"))
@@ -700,7 +720,6 @@ class P4Submit(Command, P4UserMap):
700720
self.verbose = False
701721
self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
702722
self.isWindows = (platform.system() == "Windows")
703-
self.myP4UserId = None
704723

705724
def check(self):
706725
if len(p4CmdList("opened ...")) > 0:
@@ -799,7 +818,7 @@ class P4Submit(Command, P4UserMap):
799818
def canChangeChangelists(self):
800819
# check to see if we have p4 admin or super-user permissions, either of
801820
# which are required to modify changelists.
802-
results = p4CmdList("protects %s" % self.depotPath)
821+
results = p4CmdList(["protects", self.depotPath])
803822
for r in results:
804823
if r.has_key('perm'):
805824
if r['perm'] == 'admin':
@@ -808,25 +827,6 @@ class P4Submit(Command, P4UserMap):
808827
return 1
809828
return 0
810829

811-
def p4UserId(self):
812-
if self.myP4UserId:
813-
return self.myP4UserId
814-
815-
results = p4CmdList("user -o")
816-
for r in results:
817-
if r.has_key('User'):
818-
self.myP4UserId = r['User']
819-
return r['User']
820-
die("Could not find your p4 user id")
821-
822-
def p4UserIsMe(self, p4User):
823-
# return True if the given p4 user is actually me
824-
me = self.p4UserId()
825-
if not p4User or p4User != me:
826-
return False
827-
else:
828-
return True
829-
830830
def prepareSubmitTemplate(self):
831831
# remove lines in the Files section that show changes to files outside the depot path we're committing into
832832
template = ""
@@ -1665,6 +1665,12 @@ class P4Sync(Command, P4UserMap):
16651665
if self.stream_file.has_key('depotFile'):
16661666
self.streamOneP4File(self.stream_file, self.stream_contents)
16671667

1668+
def make_email(self, userid):
1669+
if userid in self.users:
1670+
return self.users[userid]
1671+
else:
1672+
return "%s <a@b>" % userid
1673+
16681674
def commit(self, details, files, branch, branchPrefixes, parent = ""):
16691675
epoch = details["time"]
16701676
author = details["user"]
@@ -1688,10 +1694,7 @@ class P4Sync(Command, P4UserMap):
16881694
committer = ""
16891695
if author not in self.users:
16901696
self.getUserMapFromPerforceServer()
1691-
if author in self.users:
1692-
committer = "%s %s %s" % (self.users[author], epoch, self.tz)
1693-
else:
1694-
committer = "%s <a@b> %s %s" % (author, epoch, self.tz)
1697+
committer = "%s %s %s" % (self.make_email(author), epoch, self.tz)
16951698

16961699
self.gitStream.write("committer %s\n" % committer)
16971700

@@ -1736,15 +1739,21 @@ class P4Sync(Command, P4UserMap):
17361739
self.gitStream.write("from %s\n" % branch)
17371740

17381741
owner = labelDetails["Owner"]
1739-
tagger = ""
1740-
if author in self.users:
1741-
tagger = "%s %s %s" % (self.users[owner], epoch, self.tz)
1742+
1743+
# Try to use the owner of the p4 label, or failing that,
1744+
# the current p4 user id.
1745+
if owner:
1746+
email = self.make_email(owner)
17421747
else:
1743-
tagger = "%s <a@b> %s %s" % (owner, epoch, self.tz)
1748+
email = self.make_email(self.p4UserId())
1749+
tagger = "%s %s %s" % (email, epoch, self.tz)
1750+
17441751
self.gitStream.write("tagger %s\n" % tagger)
1745-
self.gitStream.write("data <<EOT\n")
1746-
self.gitStream.write(labelDetails["Description"])
1747-
self.gitStream.write("EOT\n\n")
1752+
1753+
description = labelDetails["Description"]
1754+
self.gitStream.write("data %d\n" % len(description))
1755+
self.gitStream.write(description)
1756+
self.gitStream.write("\n")
17481757

17491758
else:
17501759
if not self.silent:
@@ -1759,7 +1768,7 @@ class P4Sync(Command, P4UserMap):
17591768
def getLabels(self):
17601769
self.labels = {}
17611770

1762-
l = p4CmdList("labels %s..." % ' '.join (self.depotPaths))
1771+
l = p4CmdList(["labels"] + ["%s..." % p for p in self.depotPaths])
17631772
if len(l) > 0 and not self.silent:
17641773
print "Finding files belonging to labels in %s" % `self.depotPaths`
17651774

@@ -1801,7 +1810,7 @@ class P4Sync(Command, P4UserMap):
18011810
command = "branches"
18021811

18031812
for info in p4CmdList(command):
1804-
details = p4Cmd("branch -o %s" % info["branch"])
1813+
details = p4Cmd(["branch", "-o", info["branch"]])
18051814
viewIdx = 0
18061815
while details.has_key("View%s" % viewIdx):
18071816
paths = details["View%s" % viewIdx].split(" ")
@@ -1939,7 +1948,7 @@ class P4Sync(Command, P4UserMap):
19391948
sourceRef = self.gitRefForBranch(sourceBranch)
19401949
#print "source " + sourceBranch
19411950

1942-
branchParentChange = int(p4Cmd("changes -m 1 %s...@1,%s" % (sourceDepotPath, firstChange))["change"])
1951+
branchParentChange = int(p4Cmd(["changes", "-m", "1", "%s...@1,%s" % (sourceDepotPath, firstChange)])["change"])
19431952
#print "branch parent: %s" % branchParentChange
19441953
gitParent = self.gitCommitByP4Change(sourceRef, branchParentChange)
19451954
if len(gitParent) > 0:

t/t9803-git-p4-shell-metachars.sh

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,54 @@ test_expect_success 'deleting with shell metachars' '
5757
)
5858
'
5959

60+
# Create a branch with a shell metachar in its name
61+
#
62+
# 1. //depot/main
63+
# 2. //depot/branch$3
64+
65+
test_expect_success 'branch with shell char' '
66+
test_when_finished cleanup_git &&
67+
test_create_repo "$git" &&
68+
(
69+
cd "$cli" &&
70+
71+
mkdir -p main &&
72+
73+
echo f1 >main/f1 &&
74+
p4 add main/f1 &&
75+
p4 submit -d "main/f1" &&
76+
77+
p4 integrate //depot/main/... //depot/branch\$3/... &&
78+
p4 submit -d "integrate main to branch\$3" &&
79+
80+
echo f1 >branch\$3/shell_char_branch_file &&
81+
p4 add branch\$3/shell_char_branch_file &&
82+
p4 submit -d "branch\$3/shell_char_branch_file" &&
83+
84+
p4 branch -i <<-EOF &&
85+
Branch: branch\$3
86+
View: //depot/main/... //depot/branch\$3/...
87+
EOF
88+
89+
p4 edit main/f1 &&
90+
echo "a change" >> main/f1 &&
91+
p4 submit -d "a change" main/f1 &&
92+
93+
p4 integrate -b branch\$3 &&
94+
p4 resolve -am branch\$3/... &&
95+
p4 submit -d "integrate main to branch\$3" &&
96+
97+
cd "$git" &&
98+
99+
git config git-p4.branchList main:branch\$3 &&
100+
"$GITP4" clone --dest=. --detect-branches //depot@all &&
101+
git log --all --graph --decorate --stat &&
102+
git reset --hard p4/depot/branch\$3 &&
103+
test -f shell_char_branch_file &&
104+
test -f f1
105+
)
106+
'
107+
60108
test_expect_success 'kill p4d' '
61109
kill_p4d
62110
'

t/t9804-git-p4-label.sh

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
test_description='git-p4 p4 label tests'
2+
3+
. ./lib-git-p4.sh
4+
5+
test_expect_success 'start p4d' '
6+
start_p4d
7+
'
8+
9+
# Basic p4 label tests.
10+
#
11+
# Note: can't have more than one label per commit - others
12+
# are silently discarded.
13+
#
14+
test_expect_success 'basic p4 labels' '
15+
test_when_finished cleanup_git &&
16+
(
17+
cd "$cli" &&
18+
mkdir -p main &&
19+
20+
echo f1 >main/f1 &&
21+
p4 add main/f1 &&
22+
p4 submit -d "main/f1" &&
23+
24+
echo f2 >main/f2 &&
25+
p4 add main/f2 &&
26+
p4 submit -d "main/f2" &&
27+
28+
echo f3 >main/file_with_\$metachar &&
29+
p4 add main/file_with_\$metachar &&
30+
p4 submit -d "file with metachar" &&
31+
32+
p4 tag -l tag_f1_only main/f1 &&
33+
p4 tag -l tag_with\$_shell_char main/... &&
34+
35+
echo f4 >main/f4 &&
36+
p4 add main/f4 &&
37+
p4 submit -d "main/f4" &&
38+
39+
p4 label -i <<-EOF &&
40+
Label: long_label
41+
Description:
42+
A Label first line
43+
A Label second line
44+
View: //depot/...
45+
EOF
46+
47+
p4 tag -l long_label ... &&
48+
49+
p4 labels ... &&
50+
51+
"$GITP4" clone --dest="$git" --detect-labels //depot@all &&
52+
cd "$git" &&
53+
54+
git tag &&
55+
git tag >taglist &&
56+
test_line_count = 3 taglist &&
57+
58+
cd main &&
59+
git checkout tag_tag_f1_only &&
60+
! test -f f2 &&
61+
git checkout tag_tag_with\$_shell_char &&
62+
test -f f1 && test -f f2 && test -f file_with_\$metachar &&
63+
64+
git show tag_long_label | grep -q "A Label second line"
65+
)
66+
'
67+
68+
# Test some label corner cases:
69+
#
70+
# - two tags on the same file; both should be available
71+
# - a tag that is only on one file; this kind of tag
72+
# cannot be imported (at least not easily).
73+
74+
test_expect_failure 'two labels on the same changelist' '
75+
test_when_finished cleanup_git &&
76+
(
77+
cd "$cli" &&
78+
mkdir -p main &&
79+
80+
p4 edit main/f1 main/f2 &&
81+
echo "hello world" >main/f1 &&
82+
echo "not in the tag" >main/f2 &&
83+
p4 submit -d "main/f[12]: testing two labels" &&
84+
85+
p4 tag -l tag_f1_1 main/... &&
86+
p4 tag -l tag_f1_2 main/... &&
87+
88+
p4 labels ... &&
89+
90+
"$GITP4" clone --dest="$git" --detect-labels //depot@all &&
91+
cd "$git" &&
92+
93+
git tag | grep tag_f1 &&
94+
git tag | grep -q tag_f1_1 &&
95+
git tag | grep -q tag_f1_2 &&
96+
97+
cd main &&
98+
99+
git checkout tag_tag_f1_1 &&
100+
ls &&
101+
test -f f1 &&
102+
103+
git checkout tag_tag_f1_2 &&
104+
ls &&
105+
test -f f1
106+
)
107+
'
108+
109+
test_expect_success 'kill p4d' '
110+
kill_p4d
111+
'
112+
113+
test_done

0 commit comments

Comments
 (0)