ThomasReggi
ThomasReggi

Reputation: 59365

Get all commit hashes for when a file exactly matches in repo

I have a git repository with about a thousand commits, and I have a JSON file and I know the path of that file in the repository.

This is the bare file I have let's call it person.json.

{
  "name": "Thomas",
  "age": 30
}

I know at some point in the git history this file existed / exists in a git repo. Its relative path was ./people/person.json and never changes.

Given these three things:

My goal is to output all the commit hashes where the file person.json exactly appears / matches in the repo.

The obvious manual solution is to loop over all commits in a repo, and do a checksum match between the file I have and where the file should be. This possible but would take a long time for many files.

Are there ways of doing this native to git?

Upvotes: 1

Views: 224

Answers (2)

chipfall
chipfall

Reputation: 360

I know you asked for the native git solution, but I came here looking for any answer and found it's faster to follow the log where a file changed and do an external checksum but this is given smaller files less frequently changed:

 cs=$( sha1sum path/file | cut -d' ' -f 1 )
 git log --format="%H" --follow -- path/file | while read a; do
     echo -n "$a "; git --no-pager show $a:path/file | sha1sum
 done | grep -B 1 $cs

Among others, git log sha1..sha1 is a way to view the result(s).

Upvotes: 0

eftshift0
eftshift0

Reputation: 30212

That is a plain local operation that would take a pretty small time on your repo on a decent box (not sure about windows)... so, get the hash for the file.... like this:

git ls-tree -r HEAD | grep the-file

In my case:

$ git ls-tree -r HEAD | grep pom.xml
100755 blob some-hash-id    pom.xml

You take some-hash-id, and then do this:

git log --all --pretty=%h | while read revision; do 
    lines=$( git ls-tree -r $revision | grep some-hash-id | wc -l )
    if [ $lines -gt 0 ]; then
        echo The file is present in $revision
        git ls-tree -r $revision | grep some-hash-id
        echo
    fi
done

And that's it.

Upvotes: 2

Related Questions