Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

git

In trying to mirror a repo to a remote server, the server is rejecting tree object 4e8f805dd45088219b5662bd3d434eb4c5428ec0. This is not a top-level tree, by the way but a subdirectory.

How can I find out which commit(s) indirectly reference that tree object so I can avoid pushing the refs that link to those commits in order to get all the rest of my repo to push properly?

like image 591
Andrew Arnott Avatar asked Dec 11 '16 15:12

Andrew Arnott


People also ask

How do you see the commit tree?

On GitHub, you can see the commit history of a repository by: Navigating directly to the commits page of a repository. Clicking on a file, then clicking History, to get to the commit history for a specific file.

What is commit tree in git?

git-commit-tree is a low level command which commits a single tree object but does not perform any of the follow-up reference and Head work that git-commit does.

How do I see commit hash?

Looking up changes for a specific commit If you have the hash for a commit, you can use the git show command to display the changes for that single commit. The output is identical to each individual commit when using git log -p .

Which commit has this blob?

If the given object refers to a blob, it will be described as <commit-ish>:<path> , such that the blob can be found at <path> in the <commit-ish> , which itself describes the first commit in which this blob occurs in a reverse revision walk from HEAD.


1 Answers

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.

like image 69
torek Avatar answered Sep 19 '22 22:09

torek