>From 0428b0a1248fb84c584a5a6c1f110770c6615d5e Mon Sep 17 00:00:00 2001 From: Robert Collins <rbtcollins@xxxxxx> Date: Tue, 7 Jul 2015 15:43:24 +1200 Subject: [PATCH] git am: Transform and skip patches via new hook A thing I need to do quite a lot of is extracting stuff from Python to backported libraries. This involves changing nearly every patch but its automatable. Using a new hook (applypatch-transform) was sufficient to meet all my needs and should be acceptable upstream as far as I can tell. Signed-Off-By: Robert Collins <rbtcollins@xxxxxx> --- Documentation/git-am.txt | 6 ++--- Documentation/githooks.txt | 15 ++++++++++++ git-am.sh | 15 ++++++++++++ templates/hooks--applypatch-transform.sample | 36 ++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100755 templates/hooks--applypatch-transform.sample diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index dbea6e7..9ddcd87 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -215,9 +215,9 @@ errors in the "From:" lines). HOOKS ----- -This command can run `applypatch-msg`, `pre-applypatch`, -and `post-applypatch` hooks. See linkgit:githooks[5] for more -information. +This command can run `applypatch-msg`, `applypatch-transform`, +`pre-applypatch`, and `post-applypatch` hooks. See +linkgit:githooks[5] for more information. SEE ALSO -------- diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 7ba0ac9..251b604 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -45,6 +45,21 @@ the commit after inspecting the message file. The default 'applypatch-msg' hook, when enabled, runs the 'commit-msg' hook, if the latter is enabled. +applypatch-transform +~~~~~~~~~~~~~~~~~~~~ + +This hook is invoked by 'git am' before attempting to apply +patches. It takes two parameters - the path to the patch on +disk, and the path to the proposed commit message (which may +be absent). Like applypatch-msg, both files may be edited. + +Exiting with 1 will cause 'git am' to skip the patch. Exiting +with any other non-zero value will cause 'git am' to abort. + +The sample 'applypatch-transform' hook demonstrates mangling +a patch from one tree shape to another while discarding irrelevant +patches. + pre-applypatch ~~~~~~~~~~~~~~ diff --git a/git-am.sh b/git-am.sh index 8733071..796efea 100755 --- a/git-am.sh +++ b/git-am.sh @@ -869,6 +869,21 @@ To restore the original branch and stop patching run \"\$cmdline --abort\"." case "$resolved" in '') + # Attempt to rewrite the patch. + hook="$(git rev-parse --git-path hooks/applypatch-transform)" + if test -x "$hook" + then + "$hook" "$dotest/patch" "$dotest/final-commit" + status="$?" + if test $status -eq 1 + then + go_next + elif test $status -ne 0 + then + stop_here $this + fi + fi + # When we are allowed to fall back to 3-way later, don't give # false errors during the initial attempt. squelch= diff --git a/templates/hooks--applypatch-transform.sample b/templates/hooks--applypatch-transform.sample new file mode 100755 index 0000000..97cd789 --- /dev/null +++ b/templates/hooks--applypatch-transform.sample @@ -0,0 +1,36 @@ +#!/bin/sh +# +# An example hook script to transform a patch taken from an email +# by git am. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the patch file. +# +# To enable this hook, rename this file to "applypatch-transform". +# +# This example changes the path of Lib/unittest/mock.py to mock.py +# Lib/unittest/tests/testmock to tests and Misc/NEWS to NEWS, and +# finally skips any patches that did not alter mock.py or its tests. + +set -eux + +patch_path=$1 + +# Pull out mock.py +filterdiff --clean --strip 3 --addprefix=a/ -i 'a/Lib/unittest/mock.py' $patch_path > $patch_path.mock +# And the tests +filterdiff --clean --strip 5 --addprefix=a/tests/ -i 'a/Lib/unittest/test/testmock/' $patch_path > $patch_path.tests +# Lastly we want to pick up any NEWS entries. +filterdiff --strip 2 --addprefix=a/ -i a/Misc/NEWS $patch_path > $patch_path.NEWS +cat $patch_path.mock $patch_path.tests > $patch_path +filtered=$(cat $patch_path) +if [ -n "${filtered}" ]; then + cat $patch_path.NEWS >> $patch_path + exitcode=0 +else + exitcode=1 +fi + +rm $patch_path.mock $patch_path.tests $patch_path.NEWS +exit $exitcode -- 2.1.0 -- Robert Collins <rbtcollins@xxxxxx> Distinguished Technologist HP Converged Cloud -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html