0

I want to view a git log of commits that obey all of the following:

  1. The commit modifies a file whose name matches a given pattern.
  2. The commit changes the number of occurrences of a pattern in a file (essentially, what --pickaxe-regex -S does).
  3. The change matching rule 2 does not necessarily occur in the file matching rule 1.

Basically, I want to combine Show all commits whose diff contain specific string and Find commits that modify file names matching a pattern in a GIT repository. Just combining those two techniques, as I've done below, satisfies rules 1 & 2, but not 3.

So far I have:

git log --pickaxe-regex -S 'ChangePattern|SomeAlternatePattern' -- '*/filename.txt'

This works as long as the change occurs in filename.txt; however, the change I am looking for is in a different file than the one that is being matched by the pattern.

Ryan M
  • 18,333
  • 31
  • 67
  • 74

1 Answers1

5

You can combine git log and git show :

# have `git log` just output the hash of selected commits :
git log --format="%H" --pickaxe-regex -S 'ChangePattern|SomeAlternatePattern' |\
  # `git show` will not output anything if commit doesn't modify any of the files
  while read sha; do git show $sha -- '*/filename.txt'; done

The formatting options for the end output should be added to git show :

# example :
# '--oneline' : one line per commit
# '-s' : don't output the patch for commit
git show --oneline -s $sha -- '*/filename.txt'

If you want to view the modifications that triggered the -S condition, you can use git log to filter on '*/filename.txt' and pass the -S filter to git show :

git log --format="%H" -- '*/filename.txt' |\
  while read sha; do
    git show --pickaxe-regex -S 'ChangePattern|SomeAlternatePattern' $sha
  done
LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • This works even better if you add `--color --stat` to the `git show` arguments and then pipe the whole thing into `less -R` – Ryan M Aug 02 '22 at 06:41
  • `git log --format="%H"` — isn't it just `git rev-list HEAD` ? – phd Aug 02 '22 at 07:04
  • 2
    @phd : I found out that `git rev-list` doesn't support `-S` (or any of the other pickaxe options) – LeGEC Aug 02 '22 at 07:59
  • 1
    the other way around works though : `git rev-list HEAD -- '*/filename.txt' | while read sha; do git show -S pattern $sha; done` – LeGEC Aug 02 '22 at 08:02
  • It's annoying that there's no `--porcelain` option to `git log`, since we sometimes need to use `git log` as plumbing like this. – torek Aug 02 '22 at 09:51
  • probably this could also be done with `xargs` instead of a loop, so that a single `git show` invocation is used – philb Aug 05 '22 at 11:27