Git: autocomplete –trailer and –cc in zsh
Introduction
When working on a Git repository developped through email-based workflow (e.g. Git, Linux kernel, Emacs, notmuch etc.), it is often needed
- to
git commitwith the--traileroption to acknowledge people, - and to
git send-emailwith the--to&-ccoptions to indicate the recipients of the patch series to send.
Newcomers of such workflow, as me, would copy one by one the email addresses
from git-log or the project mailing list at the beginning. But it becomes
quickly tiresome. The good news is that this process can be automatized with
fzf and zsh (see the Screencasts section).
Let’s make a fake Git repository to illustrate how it works. The following
snippet will create at most 1500 empty commits from 150 distinct developers.
It uses rig1 to create fake identities.
DIR=~/tmp/Git_fzf/ mkdir -p $DIR && cd $DIR
git init
rig -c 150 | awk -v RS='\n\n' '{print $1 " " $2}' |
while read name; do
for i in {1..$(( RANDOM % 10 + 1 ))}; do
git commit --author "$name <${${name// /.}:l}@domain.com>" --allow-empty --allow-empty-message -m "";
done
done

Figure 1: Creating a fake Git repository with distinct authors.
Fetching email addresses of developers
The following command returns all email addresses of the current Git repository’s developers.
git shortlog -sne --all | cut -f2
Breaking it down, we instruct git shortlog
- to suppress commit descriptions (
-s), - to sort the contributors by the number of commits (
-n), - to provide contributors’ email (
-e), - and to consider the developers of all branches (
--all).
Piping the result to cut -f2 helps us to get rid of the commits count.
Select email addresses
Now, we want to pick out some addresses we are interested in. This step requires that the fuzzy filter fzf is installed.
It’s pretty simple: we just have to pipe the result of git-shortlog to fzf and
use the option -m to enable multiple choices. The --reverse option makes a
drop-down menu which I find less disruptive.
git shortlog -sne --all | cut -f2 | fzf -m --reverse
Now you can select/unselect emails with TAB / Shift+TAB. Once you are done, press RET. It will output the selected entries.
Select git-commit trailers and git-send-email recipients options
We can also make a drop-down menu to select git-commit trailers and
recipients options. Let’s wrap it in a function.
__fzf_git_trailer_and_option() {
cat <<- EOF | fzf --reverse
--to=
--bcc=
--cc=
--trailer Thanks-to:
--trailer Reviewed-by:
--trailer Reported-by:
--trailer Acked-by:
--trailer Tested-by:
--trailer Based-on-patch-by:
--trailer Mentored-by:
EOF
}
Detect if we are under a Git repository
The command git rev-parse --is-inside-work-tree can tell whether we are under
a Git repository. Let’s enable autocompletion only in such situation. We wrap
this into a function which, given a selected trailer or option and potentially
multiple addresses, returns addresses prefixed by the selected trailer or
option.
__fzf_git_authors() {
if $(git rev-parse --is-inside-work-tree 2>/dev/null); then
local trailer_or_option=$(__fzf_git_trailer_and_option)
git shortlog -sne --all | cut -f2 | fzf -m --reverse |
while read item; do
echo -n "${trailer_or_option}'${item}' "
done
fi
}
Bind autocompletion to a shortcut
So far, the result is outputted to the terminal, but we actually want that it appends the current command line. So, we keep the content on the left of the buffer and redisplay it.
fzf-git-authors() {
LBUFFER="${LBUFFER}$(__fzf_git_authors)"
zle redisplay
typeset -f zle-line-init >/dev/null && zle zle-line-init
}
Finally, I bound that function to Alt-E`.
zle -N fzf-git-authors
bindkey '\ee' fzf-git-authors
Screencasts

Figure 2: git-commit with --trailer autocompletion.

Figure 3: git-send-email with recipients autocompletion.
Footnotes
-
On Ubuntu,
sudo apt install rig. ↩