1

The following commands fail to check out this commit:

$ git clone git@github.com:DefinitelyTyped/DefinitelyTyped.git
$ cd DefinitelyTyped
$ git checkout e90424c424ef9087d0589234e9e9cd0140bab0d7
fatal: reference is not a tree: e90424c424ef9087d0589234e9e9cd0140bab0d7

Attempting to follow the advice given here results in the following:

$ git fetch origin e90424c424ef9087d0589234e9e9cd0140bab0d7
$ echo $?
1

Is this failure something specific to GitHub / large repos on GitHub? My git version is 2.10.1.

** edit **

$ git fetch origin e90424c424ef9087d0589234e9e9cd0140bab0d7:refs/remotes/origin‌​/foo-commit
$ echo $?
1
$ git cat-file -p e90424c424ef9087d0589234e9e9cd0140bab0d7
fatal: Not a valid object name e90424c424ef9087d0589234e9e9cd0140bab0d7
$ git branch -a --contains e90424c424ef9087d0589234e9e9cd0140bab0d7 
error: no such commit e90424c424ef9087d0589234e9e9cd0140bab0d7
$ git reset e90424c424ef9087d0589234e9e9cd0140bab0d7
fatal: Could not parse object 'e90424c424ef9087d0589234e9e9cd0140bab0d7'.
Community
  • 1
  • 1
AJP
  • 26,547
  • 23
  • 88
  • 127
  • It looks like that commit is a merge commit, and if I recall correctly, you can't really checkout a merge commit. Try to checkout a parent or child commit. – Jeff Huijsmans Mar 29 '17 at 12:27
  • @JeffHuijsmans you can definitely checkout a merge commit. But just incase I tried the same commands with one of its parents `2a09e3d7da0b3234c1814b3e2b859e6fe6725c40` and got the same error. Thanks for the input and idea though. – AJP Mar 29 '17 at 12:32
  • Did you cd into the cloned repository? (I am asking this, since your `git checkout` command is shown to be executed immediately after the `git clone` command). – Leon Mar 29 '17 at 12:39
  • @AJP I see, sorry for the misinformation! I'm stumped now, as well :-). Hope someone comes along that knows the deep parts of `git`, haha. @Leon I reproduced the error, even with the `cd`! – Jeff Huijsmans Mar 29 '17 at 12:44
  • @JeffHuijsmans What is the output of `git cat-file -p e90424c424ef9087d0589234e9e9cd0140bab0d7`? – Leon Mar 29 '17 at 12:46
  • `fatal: Not a valid object name e90424c424ef9087d0589234e9e9cd0140bab0d7` – Jeff Huijsmans Mar 29 '17 at 12:51
  • It seems that the said commit doesn't belong to any current branch, that's why it isn't included in the clone. – Leon Mar 29 '17 at 13:04
  • Can you try to fetch it exactly as in the linked answer: `git fetch origin e90424c424ef9087d0589234e9e9cd0140bab0d7:refs/remotes/origin/foo-commit` – Leon Mar 29 '17 at 13:06
  • @Leon I have updated question: that command returns with status code 1 unfortunately (also updated question to remove `cd` ambiguity). – AJP Mar 29 '17 at 13:46

3 Answers3

2

The behavior you are seeing can happen if a repository is rebased. You can replicate this yourself by pushing a commit to a remote repository, then updating it with git commit --amend and (force) pushing the updated repository.

The old commit id will continue to exist in the remote repository until some sort of garbage collection runs, but because it is unreachable from any existing reference it will not be included in a git clone operation.

larsks
  • 277,717
  • 41
  • 399
  • 399
2

I suspect that the commit is not reachable from any ref (branch or tag) so the server isn't including it in the pack file it sends you.

In my tests, fetching a specific commit by SHA1 only seems to work if the commit is already in your local repo (which isn't too useful as far as I can tell; it does update FETCH_HEAD I guess)... I didn't even know it would work in that case.

Without direct access to the remote repo, I don't know a procedure to recover. (I'm not counting the idea of manually fetching each object individually and reconstructing the commit - and any missing history - locally; even if it can be done in theory, it's totally impractical.)

A little research suggests trying this command:

git archive -o repo.tar --remote=git@github.com:DefinitelyTyped/DefinitelyTyped.git e90424c424ef9087d0589234e9e9cd0140bab0d7

I'm not in a position to test this with any protocol but https, and it won't work with that protocol; but you might give it a shot.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
0

You can check whether e90424c424ef9087d0589234e9e9cd0140bab0d7 commit is the part of current branch or not.

git branch -a --contains e90424c424ef9087d0589234e9e9cd0140bab0d7 

With this, you can see list of all branches which contains this hash commit.

Also with "checkout" option works with branch names not with hash commit. Using hash commit with checkout either results in "detached head state" or "fatal: reference is not a tree."

If you want to navigate to specific commit in your current branch use git reset with soft/hard options.

git reset e90424c424ef9087d0589234e9e9cd0140bab0d7
git reset --hard e90424c424ef9087d0589234e9e9cd0140bab0d7

This will update your HEAD pointer to specific commit.

Ninja
  • 2,050
  • 1
  • 23
  • 27
  • There is nothing wrong with `checkout` to a specific SHA1 value. In many cases, you *want* to go to detached head state rather than move the current branch ref with a `reset`. – Mark Adelsberger Mar 29 '17 at 14:30