43

Git allows to fetch from any given remote and reference, for example

git fetch <remote-url> <reference>

So that those given commits are available without having to add remotes or creating branches.

This however only works for references, like branch names or tags, but not for specific hashes and thus commits that are not referenced directly anywhere.

Is there a way to fetch a specific commit from a remote?

Maic López Sáenz
  • 10,385
  • 4
  • 44
  • 57

4 Answers4

49

As today I tried:

git fetch origin <commit-hash>

And it works like a charm! (git version 2.20.1)

Just be sure the <commit-hash> is the full length reference

crgarridos
  • 8,758
  • 3
  • 49
  • 61
  • a question, does it also update the branch references when we fetch with hash? – Jay Joshi Aug 01 '23 at 23:08
  • 1
    No, it just brings the commit to your local. Then you can operate on it. (e.g., you can `git checkout` it, `git cherry-pick- it`, or `git show` it) See: https://stackoverflow.com/a/70381400/1797950 – crgarridos Aug 02 '23 at 09:33
  • What if one has only the short commit hash? https://stackoverflow.com/questions/70256063/retrieve-the-full-commit-hash-from-the-remote-using-a-short-hash indicates it would need to have been fetched already but that's a catch-22. – Noel Yap Aug 04 '23 at 16:55
18

See "Pull a specific commit from a remote git repository":
With Git 2.5 (July 2015), you will be able to do:

git fetch --depth=1 <a/remote/repo.git> <full-lenght SHA1>
git cat-file commit $SHA1

If the SHA1 is "reachable" from one of the branch tips of the remote repo, then you can fetch it.

Caveats:

  • you need a Git 2.5 remote repo server though, which will handle the uploadpack.allowReachableSHA1InWant config (and you need that config to be set to true, in order to allow a single commit fetch).
  • And, as illustrated in crgarridos's answer, you need the full SHA1, and you cannot use git rev-parse, since you don't have all the commits, as noted by Jim Hurne in the comments.
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Just like in the other answer here, make sure the $SHA1 is the full length reference. – mkurz May 14 '21 at 08:16
  • 1
    @mkurz Yes, I have edited my answer to include the use of `git rev-parse`, thereby insuring I will *always* use the full-length SHA1 – VonC May 14 '21 at 08:25
  • Unfortunately, `git rev-parse` only works reliably if you have already fetched all of the remote's commits, which of course you do not have if all you want to fetch is a single commit. – Jim Hurne May 21 '21 at 20:37
  • @JimHurne Good point, than you. I have edited the answer accordingly. – VonC May 21 '21 at 21:22
9

No. According to the manual, git fetch wants a refspec, the simplest form of which is a ref, and a bare SHA-1 isn't a ref. I.e., the commit has to have a name (branch, tag) on the remote for you to be able to fetch it.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
1

git fetch [remote] [sha] && git checkout FETCH_HEAD will allow you to checkout a commit that is on the remote; even if that sha is not yet merged (like in a Gerrit environment).

or... git fetch [remote] [sha] && git cherry-pick FETCH_HEAD if you wish to cherry-pick it instead.

Examples:

  • git fetch origin d8a9a9395bb0532a0498f800e38ef5e60dfb173f && git checkout FETCH_HEAD
  • git fetch origin d8a9a9395bb0532a0498f800e38ef5e60dfb173f && git cherry-pick FETCH_HEAD
joanis
  • 10,635
  • 14
  • 30
  • 40
Jacob Moldrup
  • 99
  • 1
  • 1
  • 4