Subject: [PATCH] git am: Transform and skip patches via new hook
From: Robert Collins <hidden>
Date: 2016-06-15 23:05:40
From 0428b0a1248fb84c584a5a6c1f110770c6615d5e Mon Sep 17 00:00:00 2001
From: Robert Collins <redacted> 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 <redacted> --- 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 patchingrun \"\$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.sampleb/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 [off-list ref]
Distinguished Technologist
HP Converged Cloud