You can use the --grep
option to git log
, which only outputs commits with log messages that match a particular regular expression. In your case you could do:
git log --oneline --grep='bug #1'
... if you want to see the patches introduced by each of those commits, of course, you should do:
git log -p --grep='bug #1'
In the comments below, you explain that you really want one patch as output, which represents the cumulative effect of the patches introduce by those three commits. In that case, you could try one of the following:
- Using the
combinediff
tool from patchutils to combine the diffs. (This may not work, depending on what the intermediate commits have changed.)
- Create a temporary new branch, and use interactive rebase (possibly with a cunningly constructed command in the
GIT_EDITOR
environment variable) to reorder and squash the commits.
To expand a bit on the latter option, this script is based on a ("super-kludgy") example by Jefromi:
#!/bin/sh
set -e
if [ $# -ne 2 ]
then
echo "Usage: $0 REGEX TEMPORARY_BRANCH_NAME"
exit 1
fi
REGEX="$1"
BRANCH_NAME="$2"
git checkout -b "$BRANCH_NAME"
FIRST_COMMIT=$(git log --grep="$REGEX" --pretty=format:%H | tail -1)
if [ -z "$FIRST_COMMIT" ]
then
echo "No commits matched '$REGEX'"
exit 2
fi
export GIT_EDITOR="f() { if [ \"\$(basename \$1)\" = \"git-rebase-todo\" ]; then sed -i -n '/${REGEX}/p' \$1 && sed -i '2,\$s/pick/squash/' \$1; else vim $1; fi }; f"
git rebase -i ${FIRST_COMMIT}^
... which you might invoke as:
squash-matching-commits 'bug #1' tmp-branch
... which will then create the branch tmp-branch
, rebase back to the parent of the first commit that matches bug #1
, only picking commits that match bug #1
and squash all but the first one. (You may have to fix some conflicts, and provide a commit message for the squashed commits.) If that succeeds, then you can just do:
git show
... to see the combined patch. I don't seriously recommend anyone use this script, but it's a fun and hacky way of doing what you want, I think :)