[PATCH 1/3] email-test-patchset: automatically obtain a base commit to test against

Jacob Keller jacob.e.keller at intel.com
Tue Mar 11 08:27:17 PDT 2014

In our environment, a queue of patches is used. Often, developers will
submit a v2 of a patch already in the queue before the maintainer can
"pop" this patch off the queue. This function setup here enables
determining if a patch with the same canonical subject is already
applied to the tree. A special parameter "base" is used to prevent going
back before the "published" upstream branch of the tree.

This enables aiaiai to be smart enough to figure out when a patch should
be tested against the tip of queue, or against the parent of a previous
version. This relies on new patch versions having identical canonical
subject lines, though. (Equivalent except for the [... PATCH ...]

Signed-off-by: Jacob Keller <jacob.e.keller at intel.com>
 doc/email/example-aiaiai.cfg     |  5 +++++
 email/aiaiai-email-sh-functions  |  3 +++
 email/aiaiai-email-test-patchset | 43 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/doc/email/example-aiaiai.cfg b/doc/email/example-aiaiai.cfg
index e41c36143137..1b7fad66e65b 100644
--- a/doc/email/example-aiaiai.cfg
+++ b/doc/email/example-aiaiai.cfg
@@ -78,6 +78,11 @@
 	# part of this git refspec.
 	branch = origin/master
+	# Git refspec which indicates a base of a patch queue. For use with
+	# detection of new patch versions, this limits the scope of how far
+	# back the version check will go
+	branch_base = origin/master
 	# Comma-separated list of e-mail addresses to always CC when replying.
 	# These are maintainers or other project supervisors. This may be a
 	# separate mailing list for replies from Aiaiai.
diff --git a/email/aiaiai-email-sh-functions b/email/aiaiai-email-sh-functions
index 440e358daff9..5f8fd4952110 100644
--- a/email/aiaiai-email-sh-functions
+++ b/email/aiaiai-email-sh-functions
@@ -194,6 +194,7 @@ __parse_default_config()
 	__dcfg_configs="$(ini_config_get "$cfgfile" "defaults" "configs")"
 	__dcfg_branch="$(ini_config_get "$cfgfile" "defaults" "branch")"
+	__dcfg_branch_base="$(ini_config_get "$cfgfile" "defaults" "branch_base")"
 	__dcfg_always_cc="$(ini_config_get "$cfgfile" "defaults" "always_cc")"
 	__dcfg_reply_to_all="$(ini_config_get "$cfgfile" "defaults" "reply_to_all")"
 	__dcfg_accept_notify="$(ini_config_get "$cfgfile" "defaults" "accept_notify")"
@@ -252,6 +253,8 @@ parse_prj_config()
 	ini_config_is_set "$cfgfile" "prj_$prj" "configs" || pcfg_configs="$__dcfg_configs"
 	pcfg_branch="$(ini_config_get "$cfgfile" "prj_$prj" "branch")"
 	ini_config_is_set "$cfgfile" "prj_$prj" "branch" || pcfg_branch="$__dcfg_branch"
+	pcfg_branch_base="$(ini_config_get "$cfgfile" "prj_$prj" "branch_base")"
+	ini_config_is_set "$cfgfile" "prj_$prj" "branch_base" || pcfg_branch_base="$__dcfg_branch_base"
 	pcfg_reply_to_all="$(ini_config_get "$cfgfile" "prj_$prj" "reply_to_all")"
 	ini_config_is_set "$cfgfile" "prj_$prj" "reply_to_all" || pcfg_reply_to_all="$__dcfg_reply_to_all"
 	pcfg_accept_notify="$(ini_config_get "$cfgfile" "prj_$prj" "accept_notify")"
diff --git a/email/aiaiai-email-test-patchset b/email/aiaiai-email-test-patchset
index dd5dff47c85b..c92bfc2420dd 100755
--- a/email/aiaiai-email-test-patchset
+++ b/email/aiaiai-email-test-patchset
@@ -298,11 +298,52 @@ if [ "$pcfg_accept_notify" = "1" ]; then
+# Find the most recent commit which the patch series will apply on top of. The
+# assumption is that a new spin of a patch already in the queue will have an
+# identical subject. Otherwise this check fails. The process for determining
+# this is outlined here
+# 1. Obtain the subject (patch title) using git-mailinfo
+# 2. create --grep options for git log
+# 3. Use git log on the master git dir using the base and branch to limit scope
+# 4. Take the oldest commit which shows up, using tail -1
+# 5. Append a "^" so git uses this commit's parent
+# 6. Fall back to using the branch name if this fails
+while read -r subject; do
+	greplog+=" --grep=\"$subject\""
+done <<< "$(cat "$mbox" | formail -s git mailinfo /dev/null /dev/null | sed -n 's/^Subject: //p')"
+if [[ -n $greplog ]]; then
+	#
+	# We have to use a nasty eval here because otherwise bash eats the
+	# quotes around git-dir and pretty. In addition, bash also "protects"
+	# the quotes in the greplog array by puting '' around non-whitespace
+	# segments which contain a ". However, this royally screws up git,
+	# which does not want those single quotes at all. The fix is to create
+	# the string and \quote the double-quotes and then use eval to process
+	# the command. It is ugly, but it works.
+	#
+	commit=$(eval "git --git-dir=\"$(git_dir "$pcfg_path")\" log --pretty=\"format:%H\" -F ${greplog[@]} ${pcfg_branch_base:+$pcfg_branch_base..}$pcfg_branch | tail -1")
+if [[ -z $commit ]]; then
+	commit=$pcfg_branch
+	verbose "Found patch with same subject already on queue:"
+	verbose "$(git --git-dir="$(git_dir "$pcfg_path")" log -1 --pretty='%h ("%s")' $commit)"
+	# We need to cleanup the '^' using git-rev-parse
+	commit="$(git --git-dir="$(git_dir "$pcfg_path")" rev-parse "$commit^")"
 # Test the path (or patch-set)
 verbose "Test configs \"$pcfg_configs\" branch \"$pcfg_branch\" of \"$pcfg_path\""
 aiaiai-test-patchset $verbose ${cfg_preserve_files:+--preserve} \
 	${pcfg_targets:+--targets "$pcfg_targets"} $bisectability $sparse $smatch $cppcheck $coccinelle \
-	-i "$mbox" -j "$cfg_jobs" -c "$pcfg_branch" -w "$tmpdir" \
+	-i "$mbox" -j "$cfg_jobs" -c "$commit" -w "$tmpdir" \
 	${pcfg_defconfigdir:+-C "$pcfg_defconfigdir"} \
 	${pcfg_unwanted_keywords:+-K "$pcfg_unwanted_keywords"} \
 	${pcfg_kmake_opts:+-M "$pcfg_kmake_opts"} -- \

More information about the aiaiai mailing list