Subject: [PATCH] git am: Transform and skip patches via new hook

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>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



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]