Reputation: 13974
I have arbitrary file foo
, not committed to git.
I also have a file whose entire history has been kept in git, bar
.
How can I determine if foo
is identical to any version of bar
that has ever existed?
Upvotes: 3
Views: 490
Reputation: 488183
It's easy to tell if the contents of file foo
appear somewhere in the repo:
file=foo # or argument to script, etc
sha1=$(git hash-object -t blob $file)
repotype=$(git cat-file -t $sha1 2>/dev/null) || {
echo "file \"$file\" is not in the repo"
exit 1
}
[ $repotype = blob ] || {
echo "uh oh: file \"$file\" matches non-file ($repotype) object"
exit 1
}
However, just because foo
appears in the repo as a blob, does not mean it appears under the name bar
(or maybe not even at all, it could have been git add
ed but never checked in under a commit). So now look at every (reasonable?) commit, extracting the blob-ID for your target path, skipping the commit if it's not in there:
target_path=bar
git rev-list --branches | # or --all, or HEAD, or (etc)
while read id; do
file_id=$(git rev-parse -q --verify $id:$target_path) || continue
[ $file_id = $sha1 ] || continue
echo "found \"$file\" as \"$target_path\" in $id"
# do more here if you like, e.g., git show $id
done
If you want to find it under any name, rather than some particular explicit name, you can git ls-tree -r
each commit to find all blob
s and check their IDs.
(note: untested except piecemeal, and an occasional bit may have been retyped or altered along the way, beware of typos or silly errors)
Upvotes: 4
Reputation: 2591
Using a combination of md5sum
, git log
and grep
would work:
for SHA in `git log --pretty=format:"%h" bar`; do
git show $SHA:bar | md5sum
done | grep `md5sum foo| cut -d' ' -f1`
The above command git log --pretty=format:"%h" bar
get the list of all commits for bar
file then we do md5sum on each one of them (git show
to show the file in that commit). At the end we grep the md5sum of foo
file
Upvotes: 2