зеркало из https://github.com/microsoft/git.git
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
This commit is contained in:
Коммит
8d7ac73014
|
@ -563,6 +563,26 @@ class Command:
|
||||||
class P4UserMap:
|
class P4UserMap:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.userMapFromPerforceServer = False
|
self.userMapFromPerforceServer = False
|
||||||
|
self.myP4UserId = None
|
||||||
|
|
||||||
|
def p4UserId(self):
|
||||||
|
if self.myP4UserId:
|
||||||
|
return self.myP4UserId
|
||||||
|
|
||||||
|
results = p4CmdList("user -o")
|
||||||
|
for r in results:
|
||||||
|
if r.has_key('User'):
|
||||||
|
self.myP4UserId = r['User']
|
||||||
|
return r['User']
|
||||||
|
die("Could not find your p4 user id")
|
||||||
|
|
||||||
|
def p4UserIsMe(self, p4User):
|
||||||
|
# return True if the given p4 user is actually me
|
||||||
|
me = self.p4UserId()
|
||||||
|
if not p4User or p4User != me:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
def getUserCacheFilename(self):
|
def getUserCacheFilename(self):
|
||||||
home = os.environ.get("HOME", os.environ.get("USERPROFILE"))
|
home = os.environ.get("HOME", os.environ.get("USERPROFILE"))
|
||||||
|
@ -700,7 +720,6 @@ class P4Submit(Command, P4UserMap):
|
||||||
self.verbose = False
|
self.verbose = False
|
||||||
self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
|
self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
|
||||||
self.isWindows = (platform.system() == "Windows")
|
self.isWindows = (platform.system() == "Windows")
|
||||||
self.myP4UserId = None
|
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
if len(p4CmdList("opened ...")) > 0:
|
if len(p4CmdList("opened ...")) > 0:
|
||||||
|
@ -799,7 +818,7 @@ class P4Submit(Command, P4UserMap):
|
||||||
def canChangeChangelists(self):
|
def canChangeChangelists(self):
|
||||||
# check to see if we have p4 admin or super-user permissions, either of
|
# check to see if we have p4 admin or super-user permissions, either of
|
||||||
# which are required to modify changelists.
|
# which are required to modify changelists.
|
||||||
results = p4CmdList("protects %s" % self.depotPath)
|
results = p4CmdList(["protects", self.depotPath])
|
||||||
for r in results:
|
for r in results:
|
||||||
if r.has_key('perm'):
|
if r.has_key('perm'):
|
||||||
if r['perm'] == 'admin':
|
if r['perm'] == 'admin':
|
||||||
|
@ -808,25 +827,6 @@ class P4Submit(Command, P4UserMap):
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def p4UserId(self):
|
|
||||||
if self.myP4UserId:
|
|
||||||
return self.myP4UserId
|
|
||||||
|
|
||||||
results = p4CmdList("user -o")
|
|
||||||
for r in results:
|
|
||||||
if r.has_key('User'):
|
|
||||||
self.myP4UserId = r['User']
|
|
||||||
return r['User']
|
|
||||||
die("Could not find your p4 user id")
|
|
||||||
|
|
||||||
def p4UserIsMe(self, p4User):
|
|
||||||
# return True if the given p4 user is actually me
|
|
||||||
me = self.p4UserId()
|
|
||||||
if not p4User or p4User != me:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def prepareSubmitTemplate(self):
|
def prepareSubmitTemplate(self):
|
||||||
# remove lines in the Files section that show changes to files outside the depot path we're committing into
|
# remove lines in the Files section that show changes to files outside the depot path we're committing into
|
||||||
template = ""
|
template = ""
|
||||||
|
@ -1665,6 +1665,12 @@ class P4Sync(Command, P4UserMap):
|
||||||
if self.stream_file.has_key('depotFile'):
|
if self.stream_file.has_key('depotFile'):
|
||||||
self.streamOneP4File(self.stream_file, self.stream_contents)
|
self.streamOneP4File(self.stream_file, self.stream_contents)
|
||||||
|
|
||||||
|
def make_email(self, userid):
|
||||||
|
if userid in self.users:
|
||||||
|
return self.users[userid]
|
||||||
|
else:
|
||||||
|
return "%s <a@b>" % userid
|
||||||
|
|
||||||
def commit(self, details, files, branch, branchPrefixes, parent = ""):
|
def commit(self, details, files, branch, branchPrefixes, parent = ""):
|
||||||
epoch = details["time"]
|
epoch = details["time"]
|
||||||
author = details["user"]
|
author = details["user"]
|
||||||
|
@ -1688,10 +1694,7 @@ class P4Sync(Command, P4UserMap):
|
||||||
committer = ""
|
committer = ""
|
||||||
if author not in self.users:
|
if author not in self.users:
|
||||||
self.getUserMapFromPerforceServer()
|
self.getUserMapFromPerforceServer()
|
||||||
if author in self.users:
|
committer = "%s %s %s" % (self.make_email(author), epoch, self.tz)
|
||||||
committer = "%s %s %s" % (self.users[author], epoch, self.tz)
|
|
||||||
else:
|
|
||||||
committer = "%s <a@b> %s %s" % (author, epoch, self.tz)
|
|
||||||
|
|
||||||
self.gitStream.write("committer %s\n" % committer)
|
self.gitStream.write("committer %s\n" % committer)
|
||||||
|
|
||||||
|
@ -1736,15 +1739,21 @@ class P4Sync(Command, P4UserMap):
|
||||||
self.gitStream.write("from %s\n" % branch)
|
self.gitStream.write("from %s\n" % branch)
|
||||||
|
|
||||||
owner = labelDetails["Owner"]
|
owner = labelDetails["Owner"]
|
||||||
tagger = ""
|
|
||||||
if author in self.users:
|
# Try to use the owner of the p4 label, or failing that,
|
||||||
tagger = "%s %s %s" % (self.users[owner], epoch, self.tz)
|
# the current p4 user id.
|
||||||
|
if owner:
|
||||||
|
email = self.make_email(owner)
|
||||||
else:
|
else:
|
||||||
tagger = "%s <a@b> %s %s" % (owner, epoch, self.tz)
|
email = self.make_email(self.p4UserId())
|
||||||
|
tagger = "%s %s %s" % (email, epoch, self.tz)
|
||||||
|
|
||||||
self.gitStream.write("tagger %s\n" % tagger)
|
self.gitStream.write("tagger %s\n" % tagger)
|
||||||
self.gitStream.write("data <<EOT\n")
|
|
||||||
self.gitStream.write(labelDetails["Description"])
|
description = labelDetails["Description"]
|
||||||
self.gitStream.write("EOT\n\n")
|
self.gitStream.write("data %d\n" % len(description))
|
||||||
|
self.gitStream.write(description)
|
||||||
|
self.gitStream.write("\n")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not self.silent:
|
if not self.silent:
|
||||||
|
@ -1759,7 +1768,7 @@ class P4Sync(Command, P4UserMap):
|
||||||
def getLabels(self):
|
def getLabels(self):
|
||||||
self.labels = {}
|
self.labels = {}
|
||||||
|
|
||||||
l = p4CmdList("labels %s..." % ' '.join (self.depotPaths))
|
l = p4CmdList(["labels"] + ["%s..." % p for p in self.depotPaths])
|
||||||
if len(l) > 0 and not self.silent:
|
if len(l) > 0 and not self.silent:
|
||||||
print "Finding files belonging to labels in %s" % `self.depotPaths`
|
print "Finding files belonging to labels in %s" % `self.depotPaths`
|
||||||
|
|
||||||
|
@ -1801,7 +1810,7 @@ class P4Sync(Command, P4UserMap):
|
||||||
command = "branches"
|
command = "branches"
|
||||||
|
|
||||||
for info in p4CmdList(command):
|
for info in p4CmdList(command):
|
||||||
details = p4Cmd("branch -o %s" % info["branch"])
|
details = p4Cmd(["branch", "-o", info["branch"]])
|
||||||
viewIdx = 0
|
viewIdx = 0
|
||||||
while details.has_key("View%s" % viewIdx):
|
while details.has_key("View%s" % viewIdx):
|
||||||
paths = details["View%s" % viewIdx].split(" ")
|
paths = details["View%s" % viewIdx].split(" ")
|
||||||
|
@ -1939,7 +1948,7 @@ class P4Sync(Command, P4UserMap):
|
||||||
sourceRef = self.gitRefForBranch(sourceBranch)
|
sourceRef = self.gitRefForBranch(sourceBranch)
|
||||||
#print "source " + sourceBranch
|
#print "source " + sourceBranch
|
||||||
|
|
||||||
branchParentChange = int(p4Cmd("changes -m 1 %s...@1,%s" % (sourceDepotPath, firstChange))["change"])
|
branchParentChange = int(p4Cmd(["changes", "-m", "1", "%s...@1,%s" % (sourceDepotPath, firstChange)])["change"])
|
||||||
#print "branch parent: %s" % branchParentChange
|
#print "branch parent: %s" % branchParentChange
|
||||||
gitParent = self.gitCommitByP4Change(sourceRef, branchParentChange)
|
gitParent = self.gitCommitByP4Change(sourceRef, branchParentChange)
|
||||||
if len(gitParent) > 0:
|
if len(gitParent) > 0:
|
||||||
|
|
|
@ -57,6 +57,54 @@ test_expect_success 'deleting with shell metachars' '
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# Create a branch with a shell metachar in its name
|
||||||
|
#
|
||||||
|
# 1. //depot/main
|
||||||
|
# 2. //depot/branch$3
|
||||||
|
|
||||||
|
test_expect_success 'branch with shell char' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
test_create_repo "$git" &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
|
||||||
|
mkdir -p main &&
|
||||||
|
|
||||||
|
echo f1 >main/f1 &&
|
||||||
|
p4 add main/f1 &&
|
||||||
|
p4 submit -d "main/f1" &&
|
||||||
|
|
||||||
|
p4 integrate //depot/main/... //depot/branch\$3/... &&
|
||||||
|
p4 submit -d "integrate main to branch\$3" &&
|
||||||
|
|
||||||
|
echo f1 >branch\$3/shell_char_branch_file &&
|
||||||
|
p4 add branch\$3/shell_char_branch_file &&
|
||||||
|
p4 submit -d "branch\$3/shell_char_branch_file" &&
|
||||||
|
|
||||||
|
p4 branch -i <<-EOF &&
|
||||||
|
Branch: branch\$3
|
||||||
|
View: //depot/main/... //depot/branch\$3/...
|
||||||
|
EOF
|
||||||
|
|
||||||
|
p4 edit main/f1 &&
|
||||||
|
echo "a change" >> main/f1 &&
|
||||||
|
p4 submit -d "a change" main/f1 &&
|
||||||
|
|
||||||
|
p4 integrate -b branch\$3 &&
|
||||||
|
p4 resolve -am branch\$3/... &&
|
||||||
|
p4 submit -d "integrate main to branch\$3" &&
|
||||||
|
|
||||||
|
cd "$git" &&
|
||||||
|
|
||||||
|
git config git-p4.branchList main:branch\$3 &&
|
||||||
|
"$GITP4" clone --dest=. --detect-branches //depot@all &&
|
||||||
|
git log --all --graph --decorate --stat &&
|
||||||
|
git reset --hard p4/depot/branch\$3 &&
|
||||||
|
test -f shell_char_branch_file &&
|
||||||
|
test -f f1
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'kill p4d' '
|
test_expect_success 'kill p4d' '
|
||||||
kill_p4d
|
kill_p4d
|
||||||
'
|
'
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
test_description='git-p4 p4 label tests'
|
||||||
|
|
||||||
|
. ./lib-git-p4.sh
|
||||||
|
|
||||||
|
test_expect_success 'start p4d' '
|
||||||
|
start_p4d
|
||||||
|
'
|
||||||
|
|
||||||
|
# Basic p4 label tests.
|
||||||
|
#
|
||||||
|
# Note: can't have more than one label per commit - others
|
||||||
|
# are silently discarded.
|
||||||
|
#
|
||||||
|
test_expect_success 'basic p4 labels' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
mkdir -p main &&
|
||||||
|
|
||||||
|
echo f1 >main/f1 &&
|
||||||
|
p4 add main/f1 &&
|
||||||
|
p4 submit -d "main/f1" &&
|
||||||
|
|
||||||
|
echo f2 >main/f2 &&
|
||||||
|
p4 add main/f2 &&
|
||||||
|
p4 submit -d "main/f2" &&
|
||||||
|
|
||||||
|
echo f3 >main/file_with_\$metachar &&
|
||||||
|
p4 add main/file_with_\$metachar &&
|
||||||
|
p4 submit -d "file with metachar" &&
|
||||||
|
|
||||||
|
p4 tag -l tag_f1_only main/f1 &&
|
||||||
|
p4 tag -l tag_with\$_shell_char main/... &&
|
||||||
|
|
||||||
|
echo f4 >main/f4 &&
|
||||||
|
p4 add main/f4 &&
|
||||||
|
p4 submit -d "main/f4" &&
|
||||||
|
|
||||||
|
p4 label -i <<-EOF &&
|
||||||
|
Label: long_label
|
||||||
|
Description:
|
||||||
|
A Label first line
|
||||||
|
A Label second line
|
||||||
|
View: //depot/...
|
||||||
|
EOF
|
||||||
|
|
||||||
|
p4 tag -l long_label ... &&
|
||||||
|
|
||||||
|
p4 labels ... &&
|
||||||
|
|
||||||
|
"$GITP4" clone --dest="$git" --detect-labels //depot@all &&
|
||||||
|
cd "$git" &&
|
||||||
|
|
||||||
|
git tag &&
|
||||||
|
git tag >taglist &&
|
||||||
|
test_line_count = 3 taglist &&
|
||||||
|
|
||||||
|
cd main &&
|
||||||
|
git checkout tag_tag_f1_only &&
|
||||||
|
! test -f f2 &&
|
||||||
|
git checkout tag_tag_with\$_shell_char &&
|
||||||
|
test -f f1 && test -f f2 && test -f file_with_\$metachar &&
|
||||||
|
|
||||||
|
git show tag_long_label | grep -q "A Label second line"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
# Test some label corner cases:
|
||||||
|
#
|
||||||
|
# - two tags on the same file; both should be available
|
||||||
|
# - a tag that is only on one file; this kind of tag
|
||||||
|
# cannot be imported (at least not easily).
|
||||||
|
|
||||||
|
test_expect_failure 'two labels on the same changelist' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
mkdir -p main &&
|
||||||
|
|
||||||
|
p4 edit main/f1 main/f2 &&
|
||||||
|
echo "hello world" >main/f1 &&
|
||||||
|
echo "not in the tag" >main/f2 &&
|
||||||
|
p4 submit -d "main/f[12]: testing two labels" &&
|
||||||
|
|
||||||
|
p4 tag -l tag_f1_1 main/... &&
|
||||||
|
p4 tag -l tag_f1_2 main/... &&
|
||||||
|
|
||||||
|
p4 labels ... &&
|
||||||
|
|
||||||
|
"$GITP4" clone --dest="$git" --detect-labels //depot@all &&
|
||||||
|
cd "$git" &&
|
||||||
|
|
||||||
|
git tag | grep tag_f1 &&
|
||||||
|
git tag | grep -q tag_f1_1 &&
|
||||||
|
git tag | grep -q tag_f1_2 &&
|
||||||
|
|
||||||
|
cd main &&
|
||||||
|
|
||||||
|
git checkout tag_tag_f1_1 &&
|
||||||
|
ls &&
|
||||||
|
test -f f1 &&
|
||||||
|
|
||||||
|
git checkout tag_tag_f1_2 &&
|
||||||
|
ls &&
|
||||||
|
test -f f1
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'kill p4d' '
|
||||||
|
kill_p4d
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Загрузка…
Ссылка в новой задаче