I do have aliases found on the web:
find = "log --decorate -i --all --date=short --grep"
search = "!f() { git log --decorate --grep=$1 -i --all --date=short; }; f"
They both do the same: search within commit messages. Is there one somehow one "superior" to the other? Why?
QUESTION -- How could we write an alias for searching for commits that contain particular words in the message?
For example, where:
git search-msg foo bar baz
would match commits containing the words foo, bar and baz, in whichever order?
ANSWER -- Better formatting here (from LeGEC):
search-msg = "!f() { str=\"git log --all-match\"; \
for var in \"$@\"; do \
str=\"$str --grep '$var'\"; \
done; \
eval $str; }; f"
First a word about git log's --grep option :
--all-match flag, which indicates "match all of the patterns"Example :
# two commits contain 'foo' in their message (one of them also contains 'bar'):
$ git log --oneline --grep foo
b76121c bar baz foo
b7a342f foo
# two commits contain 'bar' in their message (one of them also contains 'foo'):
$ git log --oneline --grep bar
bbb27f3 (HEAD -> master) bar
b76121c bar baz foo
# if I look for both patterns : I get the union of both searches (3 commits)
$ git log --oneline --grep foo --grep bar
bbb27f3 (HEAD -> master) bar
b76121c bar baz foo
b7a342f foo
# if I add '--all-match' : only the commit which contains both is kept
$ git log --oneline --grep foo --grep bar --all-match
b76121c bar baz foo
To answer your question : here is a sample script that takes a list of arguments, and turns them into a git log --all-match --grep aaa --grep bbb command :
# in file git-search-msg :
#!/bin/bash
cmd=("log" "--all-match")
for var in "$@"
do
cmd+=('--grep')
cmd+=("$var")
done
git "${cmd[@]}"
If you paste this in a file named git-search-msg, and put it somewhere on your PATH, then git search-msg foo bar baz will do what you want.
The following works in plain sh, but uses eval :
#!/bin/sh
str="git log --all-match"
for var in "$@"
do
# This loops takes arguments one by one and adds
# them as '--grep' args to the 'git log' command.
str="$str --grep '$var'"
done
# tech note : this sample script does not escape single quotes
eval $str
If you manage to oneline it (and escape it correctly), you can use it in an alias.
Beware the escaping problems mixed with eval though ...
You may want to add history to search through the whole repository, by adding rev-list to your git log
git log --grep 'Something relevant in my commits' $(git rev-list --all)
Something like should work in the .gitconfig file
[alias]
search = "!f() { git log --grep \"$1\" $(git rev-list --all); }; f"
[log]
date = iso
The date = iso thing is here to get a better date (current format is 2019-11-26 17:35:30 +0100)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With