How to find the commit(s) that point to a git tree object?

As you noted, you just need to find the commit(s) with the desired tree. If it could be a top level tree you would need one extra test, but since it's not, you don't.

You want:

  • for some set of commits (all those reachable from a given branch name, for instance)
  • if that commit has, as a sub-tree, the target tree hash: print the commit ID

which is trivial with two Git "plumbing" commands plus grep:

#! /bin/sh
#
#  set these:
searchfor=4e8f805dd45088219b5662bd3d434eb4c5428ec0

startpoints="master"  # branch names or HEAD or whatever
# you can use rev-list limiters too, e.g., origin/master..master

git rev-list $startpoints |
    while read commithash; do
        if git ls-tree -d -r --full-tree $commithash | grep $searchfor; then
            echo " -- found at $commithash"
        fi
    done

To check top-level trees you would git cat-file -p $commithash as well and see if it has the hash in it.

Note that this same code will find blobs (assuming you take out the -d option from git ls-tree). However, no tree can have the ID of a blob, or vice versa. The grep will print the matching line so you'll see, e.g.:

040000 tree a3a6276bba360af74985afa8d79cfb4dfc33e337    perl/Git/SVN/Memoize
 -- found at 3ab228137f980ff72dbdf5064a877d07bec76df9

To clean this up for general use, you might want to use git cat-file -t on the search-for blob-or-tree to get its type.

Tags:

Git