Reputation: 1043
The following will search commits for changes involving "foo":
$ git log -S foo
How can I:
foo
and bar
#!/bin/bash
cd $GITDIR
declare -a myhashes=($(git log --all --pretty=%H))
for myhash in "${myhashes[@]}";do
declare -a myfiles=($(git diff --pickaxe-regex -S "foo|bar" --name-only $myhash))
echo found "${#myfiles[@]}" files starting with ${myfiles[1]}
# Files with Foo
declare -a fwf=($(git grep -l -e foo $myhash -- $myfiles))
# Files with Bar
declare -a fwb=($(git grep -l -e bar $myhash -- $myfiles))
# how to intersect fwf,fwb?
done
Upvotes: 1
Views: 902
Reputation: 52111
foo
and bar
:If you add --pickaxe-regex
, the argumet to -S
will be treated as a regexp :
git log --pickaxe-regex -S "foo|bar"
(see "a note about -S
" below)
you can use git log
to list all potential commits, and then refine from there (see "About your second point" below)
simply add --all
to git log
:
git log --all --pickaxe-regex -S "foo|bar"
About your first point :
a note about -S
:
-S
spots commits that change the number of lines matching the pattern. So using -S "foo|bar"
(with regexes on) would overlook a commit where one line containing foo
is turned into one line containing bar
.
If that's not what you wish, you may be looking for -G
, or you may want to make something out of the output of the two commands git log -S foo
and git log -S bar
.
About your second point :
if you add --pretty=%H
to your git log
command, you will have, as an output, only a list of hashes, for all the commits that may interest you.
To list the files within those commits that may interest you, you may either add --name-only
to the git log
command, or take these commits one by one, and re-run them through git diff --pickaxe-regex -S "foo|bar" --name-only <sha>
.
Once you have a list of target commits, and a list of file names for all commits, you can check the content of each file within its target commit to see if it has both foo
and bar
within its content.
You can for example use git grep -l -e foo <sha> -- <list of files>
and git grep -l -e bar <sha> -- <list of files>
and combine the outputs to see what files contain both patterns.
You may also want to check the content of each file before the commit ; e.g : do you want to keep a file where foo
was changed to bar
?
If such is the case, file
could contain only bar
in the target commit (<sha>
), and could contain only foo
in the parent commit : <sha>^
:
# you may want to check the content of target files in the parent commit :
git grep ... <sha>^
You will need some scripting on top of those git commands to get a complete solution.
Upvotes: 2