Home > Back-end >  How to use git to grep but restrict in certain commits?
How to use git to grep but restrict in certain commits?

Time:10-30

Say I'm in the master branch, I only want to grep words from certain commits but those words are still in the master branch. In other words, I want to find those words added in certain commits and still exist.

Ex,

commit 76894a679551e1c9e98593219033a2cf115b163d (HEAD -> master)
   
    Change to fruit

-Apple apple dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
 Banana apple dolor apple amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.


commit e3e0a64cf46cbe49eea17205f679e98ca213a50b

    Change to apple

-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
 Apple apple dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.


commit 71b609da3fe64092dd598a69e36770eb5636afec

    Init

 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
(END)

I want to find out the apple added in 76894 so only the quoted is I'm looking for, Banana "apple" dolor apple amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. not Banana apple dolor "apple" amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.

CodePudding user response:

  • If you want to grep for a word in any file of a specific commit, you can use :
git grep -e "word" <sha>

if you want to do that on a range of commits, you would have to get all hashes for this range, and iterate through that range :

# for example, using a 'while' loop in bash :
git rev-list a..b | while read sha; do git grep -e "word" $sha; done
  • If you want to spot that word only in the diff of specific commits, use one of the pickaxe options of git log :
git log -Sword a..b
# or
git log -Gword a..b

CodePudding user response:

I think all you need is a simple git grep:

git grep apple master

for instance. The git grep command takes an optional tree argument, and a "tree" is what is stored in a commit as a snapshot.

You specifically asked for:

words added in certain commits and still exist

Because Git stores snapshots, not diffs, words that were added in any previous commit and still exist are, by definition, in the snapshot.

If, on the other hand, you mean for instance:

  • I want to find "apple" if:
    1. It existed in file F in commits C1, C2, or C3 and
    2. It exists now in the tip of master in file F as well

then you need a two-pass algorithm: first, check to see if the regular expression matches in any particular file(s) in the non-tip commits, then check again in the tip commit. Print the tip commit's hash ID (and perhaps file and matching line) if and only if you find this in both steps 1 and 2.

Note that git grep can search more than one commit at a time. To see if the word apple appears in any file in any of those three commits, simply run:

git grep apple C1 C2 C3

The output will contain the raw commit hash ID, then the file name, then the matched line:

$ git grep "go build" $(git rev-list HEAD)
f6b272b0c674c2d5022e90c3dec868af4ea26522:Makefile:      go build -ldflags "-X main.version=$$(git describe --always --dirty)"
e50f217c3e11c6ee1fb67ee720c97f4085d6c46b:Makefile:      go build

(this particular repository is pretty small right now, with just two copies of the Makefile from before and after I stuck -version support into the command).

  •  Tags:  
  • git
  • Related