Reputation: 59365
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:
REPO_URL
person.json
file./people/person.json
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
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
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