Applying mailing list patches with 'git b4'
Published
b4 helps improve the workflow for mailing list based Linux kernel development, but doesn't offer direct git integration. Let's whip up a 'git b4' alias.
It was created by Konstantin Ryabitsev and has become a very frequently used tool for me.
It supports a lot of different ways for interacting with the Linux Kernel mailing lists.
Of these the b4 am
subcommand is what I primarily use. This subcommand downloads all of
the patches belonging to a patch series and drops them into a .mbox
file. But! It doesn't
apply them to the repository we're currently in, and herein lies the itch that I would like
to scratch.
The inspiration for this post is the script that @stellarhopper authored and @widawsky pointed out to me.
The Good, the Bad & the Ugly
After first publishing this post, people on the twittersphere suggested some alternative approaches, and it would seem that there are three different approaches to creating an alias like this. Naturally my original idea is the ugly.
The Good
@gregkh suggested a really short
and to the point approach, where b4 am
simply pipes the .mbox
file to git am
. I think
it is ideal in this specific case since it avoids most the complexity of writing git alias
functions but at the same time doesn't require any external script files.
As you can see the verbosity is really nice, and none of the b4
output is thrown out.
$ cat ~/.gitconfig
... snip ...
[alias]
b4 = "!f() { b4 am -t -o - $1 | git am -s; }; f"
... snip ...
The Bad
When @widawsky first linked the
~/bin/git-b4am
script by @stellarhopper, it looked like
a standalone shell script. This is not the case however, it is automatically integrated
as a subcommand by git. As explained
by @EnJens, git will present any executable accessible
through $PATH/git-XXX
as a subcommand git XXX
.
Using Zsh, I'm seeing some of the output being written after the command has returned.
Using bash, this was less of an issue. I'd think this is due to the really neat way that
processes substitution + tee is
used, tee >(find_apply_mbx)
.
For the general case of running a script as a part of git, I think this is the way to go. The only downside to me is that the script is an external file.
$ cat ~/.local/bin/git-b4am
#!/bin/bash -eE
find_apply_mbx()
{
mbx=$(awk '/^Writing .*\.mbx/{ print $2 }')
if [[ $mbx ]]; then
git am "$mbx"
fi
}
b4 am -cls "$@" 2>&1 | tee >(find_apply_mbx)
The Ugly
Wanting to avoid the external scripts (and not knowing about $PATH/git-XXX
functionality)
I wrote a cursed version of the ~/bin/git-b4am
script.
As you can see, the helpful output from b4 is lost. This is due to
git alias functions being executed in a sh
shell, which doesn't support the really
neat processes substitution approach
that @stellarhopper had used.
I apologize in advance for the escaped hellscape that is this snippet. A hierarchy of escapes is required to conform to the git function syntax when using both multiple lines and quoted strings.
$ cat ~/.gitconfig
... snip ...
[alias]
b4 = "!f() \
{\
b4 am $1 -l -o /tmp/ 2>&1 | \n\
$( \n\
mbx=$( \n\
awk '/^Writing .*\\.mbx/{ print $2 }' \n\
); \n\
[ -z \"$mbx\" ] || \n\
git am \"$mbx\" 1>&2; \n\
); \n\
}; f"
... snip ...
A git syntax escape script written by Tom Hale made the escaping much easier.
Example
After picking your favorite approach, go find the Message-Id
for the LKML
patch or series you want to apply.
$ cd linux
linux$ git b4 1607651182[email protected]