git-p4: add the `p4-pre-submit` hook

The `p4-pre-submit` hook is executed before git-p4 submits code. If the hook exits with non-zero value, submit process not start. Signed-off-by: Chen Bin <chenbin.sh@gmail.com> Reviewed-by: Luke Diamand <luke@diamand.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Chen Bin committed Jul 27, 2018 at 21:22 UTC 251c8c501faf7a7910edb7c9e19692988dcac6a8
4 files changed +59 -1
Documentation/git-p4.txt
+8
@@ -374,6 +374,14 @@ These options can be used to modify 'git p4 submit' behavior.
374 been submitted. Implies --disable-rebase. Can also be set with
375 git-p4.disableP4Sync. Sync with origin/master still goes ahead if possible.
376
377 +Hook for submit
378 +~~~~~~~~~~~~~~~
379 +The `p4-pre-submit` hook is executed if it exists and is executable.
380 +The hook takes no parameters and nothing from standard input. Exiting with
381 +non-zero status from this script prevents `git-p4 submit` from launching.
382 +
383 +One usage scenario is to run unit tests in the hook.
384 +
385 Rebase options
386 ~~~~~~~~~~~~~~
387 These options can be used to modify 'git p4 rebase' behavior.
Documentation/githooks.txt
+7
@@ -485,6 +485,13 @@ The exit status determines whether git will use the data from the
485 hook to limit its search. On error, it will fall back to verifying
486 all files and folders.
487
488 +p4-pre-submit
489 +~~~~~~~~~~~~~
490 +
491 +This hook is invoked by `git-p4 submit`. It takes no parameters and nothing
492 +from standard input. Exiting with non-zero status from this script prevent
493 +`git-p4 submit` from launching. Run `git-p4 submit --help` for details.
494 +
495 GIT
496 ---
497 Part of the linkgit:git[1] suite
git-p4.py
+15 -1
@@ -1494,7 +1494,13 @@ class P4Submit(Command, P4UserMap):
1494 optparse.make_option("--disable-p4sync", dest="disable_p4sync", action="store_true",
1495 help="Skip Perforce sync of p4/master after submit or shelve"),
1496 ]
1497 - self.description = "Submit changes from git to the perforce depot."
1497 + self.description = """Submit changes from git to the perforce depot.\n
1498 + The `p4-pre-submit` hook is executed if it exists and is executable.
1499 + The hook takes no parameters and nothing from standard input. Exiting with
1500 + non-zero status from this script prevents `git-p4 submit` from launching.
1501 +
1502 + One usage scenario is to run unit tests in the hook."""
1503 +
1504 self.usage += " [name of git branch to submit into perforce depot]"
1505 self.origin = ""
1506 self.detectRenames = False
@@ -2303,6 +2309,14 @@ class P4Submit(Command, P4UserMap):
2309 sys.exit("number of commits (%d) must match number of shelved changelist (%d)" %
2310 (len(commits), num_shelves))
2311
2312 + hooks_path = gitConfig("core.hooksPath")
2313 + if len(hooks_path) <= 0:
2314 + hooks_path = os.path.join(os.environ.get("GIT_DIR", ".git"), "hooks")
2315 +
2316 + hook_file = os.path.join(hooks_path, "p4-pre-submit")
2317 + if os.path.isfile(hook_file) and os.access(hook_file, os.X_OK) and subprocess.call([hook_file]) != 0:
2318 + sys.exit(1)
2319 +
2320 #
2321 # Apply the commits, one at a time. On failure, ask if should
2322 # continue to try the rest of the patches, or quit.
t/t9800-git-p4-basic.sh
+29
@@ -261,6 +261,35 @@ test_expect_success 'unresolvable host in P4PORT should display error' '
261 )
262 '
263
264 +# Test following scenarios:
265 +# - Without ".git/hooks/p4-pre-submit" , submit should continue
266 +# - With the hook returning 0, submit should continue
267 +# - With the hook returning 1, submit should abort
268 +test_expect_success 'run hook p4-pre-submit before submit' '
269 + test_when_finished cleanup_git &&
270 + git p4 clone --dest="$git" //depot &&
271 + (
272 + cd "$git" &&
273 + echo "hello world" >hello.txt &&
274 + git add hello.txt &&
275 + git commit -m "add hello.txt" &&
276 + git config git-p4.skipSubmitEdit true &&
277 + git p4 submit --dry-run >out &&
278 + grep "Would apply" out &&
279 + mkdir -p .git/hooks &&
280 + write_script .git/hooks/p4-pre-submit <<-\EOF &&
281 + exit 0
282 + EOF
283 + git p4 submit --dry-run >out &&
284 + grep "Would apply" out &&
285 + write_script .git/hooks/p4-pre-submit <<-\EOF &&
286 + exit 1
287 + EOF
288 + test_must_fail git p4 submit --dry-run >errs 2>&1 &&
289 + ! grep "Would apply" errs
290 + )
291 +'
292 +
293 test_expect_success 'submit from detached head' '
294 test_when_finished cleanup_git &&
295 git p4 clone --dest="$git" //depot &&