Merge branch 'jd/p4-jobs-in-commit'

"git p4" learned to record P4 jobs in Git commit that imports from
the history in Perforce.

* jd/p4-jobs-in-commit:
  git-p4: add P4 jobs to git commit message
  git-p4: clean-up code style in tests
This commit is contained in:
Junio C Hamano 2016-05-03 14:08:12 -07:00
commit e61f75fe19
4 changed files with 162 additions and 42 deletions

View File

@ -2320,6 +2320,15 @@ class P4Sync(Command, P4UserMap):
fnum = fnum + 1 fnum = fnum + 1
return files return files
def extractJobsFromCommit(self, commit):
jobs = []
jnum = 0
while commit.has_key("job%s" % jnum):
job = commit["job%s" % jnum]
jobs.append(job)
jnum = jnum + 1
return jobs
def stripRepoPath(self, path, prefixes): def stripRepoPath(self, path, prefixes):
"""When streaming files, this is called to map a p4 depot path """When streaming files, this is called to map a p4 depot path
to where it should go in git. The prefixes are either to where it should go in git. The prefixes are either
@ -2665,6 +2674,7 @@ class P4Sync(Command, P4UserMap):
def commit(self, details, files, branch, parent = ""): def commit(self, details, files, branch, parent = ""):
epoch = details["time"] epoch = details["time"]
author = details["user"] author = details["user"]
jobs = self.extractJobsFromCommit(details)
if self.verbose: if self.verbose:
print('commit into {0}'.format(branch)) print('commit into {0}'.format(branch))
@ -2692,6 +2702,8 @@ class P4Sync(Command, P4UserMap):
self.gitStream.write("data <<EOT\n") self.gitStream.write("data <<EOT\n")
self.gitStream.write(details["desc"]) self.gitStream.write(details["desc"])
if len(jobs) > 0:
self.gitStream.write("\nJobs: %s" % (' '.join(jobs)))
self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s" % self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s" %
(','.join(self.branchPrefixes), details["change"])) (','.join(self.branchPrefixes), details["change"]))
if len(details['options']) > 0: if len(details['options']) > 0:

View File

@ -33,7 +33,7 @@ fi
# Older versions of perforce were available compiled natively for # Older versions of perforce were available compiled natively for
# cygwin. Those do not accept native windows paths, so make sure # cygwin. Those do not accept native windows paths, so make sure
# not to convert for them. # not to convert for them.
native_path() { native_path () {
path="$1" && path="$1" &&
if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN
then then
@ -49,7 +49,7 @@ native_path() {
# Attention: This function is not safe again against time offset updates # Attention: This function is not safe again against time offset updates
# at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)' # at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)'
# function could fix that but it is not in Python until 3.3. # function could fix that but it is not in Python until 3.3.
time_in_seconds() { time_in_seconds () {
python -c 'import time; print int(time.time())' python -c 'import time; print int(time.time())'
} }
@ -75,7 +75,7 @@ git="$TRASH_DIRECTORY/git"
pidfile="$TRASH_DIRECTORY/p4d.pid" pidfile="$TRASH_DIRECTORY/p4d.pid"
# Sometimes "prove" seems to hang on exit because p4d is still running # Sometimes "prove" seems to hang on exit because p4d is still running
cleanup() { cleanup () {
if test -f "$pidfile" if test -f "$pidfile"
then then
kill -9 $(cat "$pidfile") 2>/dev/null && exit 255 kill -9 $(cat "$pidfile") 2>/dev/null && exit 255
@ -89,7 +89,7 @@ trap cleanup EXIT
TMPDIR="$TRASH_DIRECTORY" TMPDIR="$TRASH_DIRECTORY"
export TMPDIR export TMPDIR
start_p4d() { start_p4d () {
mkdir -p "$db" "$cli" "$git" && mkdir -p "$db" "$cli" "$git" &&
rm -f "$pidfile" && rm -f "$pidfile" &&
( (
@ -151,7 +151,7 @@ start_p4d() {
return 0 return 0
} }
p4_add_user() { p4_add_user () {
name=$1 && name=$1 &&
p4 user -f -i <<-EOF p4 user -f -i <<-EOF
User: $name User: $name
@ -160,7 +160,16 @@ p4_add_user() {
EOF EOF
} }
retry_until_success() { p4_add_job () {
p4 job -f -i <<-EOF
Job: $1
Status: open
User: dummy
Description:
EOF
}
retry_until_success () {
timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT)) timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
do do
@ -168,7 +177,7 @@ retry_until_success() {
done done
} }
retry_until_fail() { retry_until_fail () {
timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT)) timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
do do
@ -176,7 +185,7 @@ retry_until_fail() {
done done
} }
kill_p4d() { kill_p4d () {
pid=$(cat "$pidfile") pid=$(cat "$pidfile")
retry_until_fail kill $pid retry_until_fail kill $pid
retry_until_fail kill -9 $pid retry_until_fail kill -9 $pid
@ -186,13 +195,13 @@ kill_p4d() {
retry_until_fail kill -9 $watchdog_pid retry_until_fail kill -9 $watchdog_pid
} }
cleanup_git() { cleanup_git () {
retry_until_success rm -r "$git" retry_until_success rm -r "$git"
test_must_fail test -d "$git" && test_must_fail test -d "$git" &&
retry_until_success mkdir "$git" retry_until_success mkdir "$git"
} }
marshal_dump() { marshal_dump () {
what=$1 && what=$1 &&
line=${2:-1} && line=${2:-1} &&
cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF && cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF &&
@ -208,7 +217,7 @@ marshal_dump() {
# #
# Construct a client with this list of View lines # Construct a client with this list of View lines
# #
client_view() { client_view () {
( (
cat <<-EOF && cat <<-EOF &&
Client: $P4CLIENT Client: $P4CLIENT
@ -222,7 +231,7 @@ client_view() {
) | p4 client -i ) | p4 client -i
} }
is_cli_file_writeable() { is_cli_file_writeable () {
# cygwin version of p4 does not set read-only attr, # cygwin version of p4 does not set read-only attr,
# will be marked 444 but -w is true # will be marked 444 but -w is true
file="$1" && file="$1" &&

View File

@ -47,23 +47,23 @@ test_expect_success 'Clone repo root path with all history' '
git init . && git init . &&
git p4 clone --use-client-spec --destination="$git" //depot@all && git p4 clone --use-client-spec --destination="$git" //depot@all &&
cat >expect <<-\EOF && cat >expect <<-\EOF &&
Remove file 4 Remove file 4
[git-p4: depot-paths = "//depot/": change = 6] [git-p4: depot-paths = "//depot/": change = 6]
Remove file 3 Remove file 3
[git-p4: depot-paths = "//depot/": change = 5] [git-p4: depot-paths = "//depot/": change = 5]
Add file 4 Add file 4
[git-p4: depot-paths = "//depot/": change = 4] [git-p4: depot-paths = "//depot/": change = 4]
Add file 3 Add file 3
[git-p4: depot-paths = "//depot/": change = 3] [git-p4: depot-paths = "//depot/": change = 3]
Add file 2 Add file 2
[git-p4: depot-paths = "//depot/": change = 2] [git-p4: depot-paths = "//depot/": change = 2]
Add file 1 Add file 1
[git-p4: depot-paths = "//depot/": change = 1] [git-p4: depot-paths = "//depot/": change = 1]
EOF EOF
git log --format=%B >actual && git log --format=%B >actual &&
@ -80,23 +80,23 @@ test_expect_success 'Clone repo subdir with all history but keep empty commits'
git config git-p4.keepEmptyCommits true && git config git-p4.keepEmptyCommits true &&
git p4 clone --use-client-spec --destination="$git" //depot@all && git p4 clone --use-client-spec --destination="$git" //depot@all &&
cat >expect <<-\EOF && cat >expect <<-\EOF &&
Remove file 4 Remove file 4
[git-p4: depot-paths = "//depot/": change = 6] [git-p4: depot-paths = "//depot/": change = 6]
Remove file 3 Remove file 3
[git-p4: depot-paths = "//depot/": change = 5] [git-p4: depot-paths = "//depot/": change = 5]
Add file 4 Add file 4
[git-p4: depot-paths = "//depot/": change = 4] [git-p4: depot-paths = "//depot/": change = 4]
Add file 3 Add file 3
[git-p4: depot-paths = "//depot/": change = 3] [git-p4: depot-paths = "//depot/": change = 3]
Add file 2 Add file 2
[git-p4: depot-paths = "//depot/": change = 2] [git-p4: depot-paths = "//depot/": change = 2]
Add file 1 Add file 1
[git-p4: depot-paths = "//depot/": change = 1] [git-p4: depot-paths = "//depot/": change = 1]
EOF EOF
git log --format=%B >actual && git log --format=%B >actual &&
@ -112,14 +112,14 @@ test_expect_success 'Clone repo subdir with all history' '
git init . && git init . &&
git p4 clone --use-client-spec --destination="$git" --verbose //depot@all && git p4 clone --use-client-spec --destination="$git" --verbose //depot@all &&
cat >expect <<-\EOF && cat >expect <<-\EOF &&
Remove file 3 Remove file 3
[git-p4: depot-paths = "//depot/": change = 5] [git-p4: depot-paths = "//depot/": change = 5]
Add file 3 Add file 3
[git-p4: depot-paths = "//depot/": change = 3] [git-p4: depot-paths = "//depot/": change = 3]
Add file 1 Add file 1
[git-p4: depot-paths = "//depot/": change = 1] [git-p4: depot-paths = "//depot/": change = 1]
EOF EOF
git log --format=%B >actual && git log --format=%B >actual &&

99
t/t9829-git-p4-jobs.sh Executable file
View File

@ -0,0 +1,99 @@
#!/bin/sh
test_description='git p4 retrieve job info'
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
start_p4d
'
test_expect_success 'add p4 jobs' '
(
p4_add_job TESTJOB-A &&
p4_add_job TESTJOB-B
)
'
test_expect_success 'add p4 files' '
client_view "//depot/... //client/..." &&
(
cd "$cli" &&
>file1 &&
p4 add file1 &&
p4 submit -d "Add file 1"
)
'
test_expect_success 'check log message of changelist with no jobs' '
client_view "//depot/... //client/..." &&
test_when_finished cleanup_git &&
(
cd "$git" &&
git init . &&
git p4 clone --use-client-spec --destination="$git" //depot@all &&
cat >expect <<-\EOF &&
Add file 1
[git-p4: depot-paths = "//depot/": change = 1]
EOF
git log --format=%B >actual &&
test_cmp expect actual
)
'
test_expect_success 'add TESTJOB-A to change 1' '
(
cd "$cli" &&
p4 fix -c 1 TESTJOB-A
)
'
test_expect_success 'check log message of changelist with one job' '
client_view "//depot/... //client/..." &&
test_when_finished cleanup_git &&
(
cd "$git" &&
git init . &&
git p4 clone --use-client-spec --destination="$git" //depot@all &&
cat >expect <<-\EOF &&
Add file 1
Jobs: TESTJOB-A
[git-p4: depot-paths = "//depot/": change = 1]
EOF
git log --format=%B >actual &&
test_cmp expect actual
)
'
test_expect_success 'add TESTJOB-B to change 1' '
(
cd "$cli" &&
p4 fix -c 1 TESTJOB-B
)
'
test_expect_success 'check log message of changelist with more jobs' '
client_view "//depot/... //client/..." &&
test_when_finished cleanup_git &&
(
cd "$git" &&
git init . &&
git p4 clone --use-client-spec --destination="$git" //depot@all &&
cat >expect <<-\EOF &&
Add file 1
Jobs: TESTJOB-A TESTJOB-B
[git-p4: depot-paths = "//depot/": change = 1]
EOF
git log --format=%B >actual &&
test_cmp expect actual
)
'
test_expect_success 'kill p4d' '
kill_p4d
'
test_done