0

Github has magic refs called pull/NN/head, pull/NN/merge.

I want to understand what's keeping something like this from working:

$ git clone https://github.com/cben/sandbox --branch pull/7/merge
Cloning into 'sandbox'...
fatal: Remote branch pull/7/merge not found in upstream origin

This is probably because these refs are neither under refs/branches nor refs/tags (git clone --branch docs say it can also take a tag):

$ git ls-remote https://github.com/cben/sandbox
71bea916dee6a03221443cc15c254edc97ff8d42    HEAD
e2f53347112b66ceba2986339c66244cd4458209    refs/heads/branch-to-remain-unmerged
71bea916dee6a03221443cc15c254edc97ff8d42    refs/heads/gh-pages
a34f5181eb779bb6728725f0b21fd9bc78c0d0a8    refs/heads/master
6a23126f508a59c006163aa7fee2dbb7b12d871e    refs/heads/prefixed-header
8ce1ef94fa1e8bf0456aac5368edf0ccdf2c2f3a    refs/heads/test-push-from-c9
6a23126f508a59c006163aa7fee2dbb7b12d871e    refs/pull/6/head
e2f53347112b66ceba2986339c66244cd4458209    refs/pull/7/head
a18487b006434d4f83a6738c1031a80d845bb303    refs/pull/7/merge
71bea916dee6a03221443cc15c254edc97ff8d42    refs/tags/a-tag

Is another way to make git clone checkout an arbitrary ref (preferably in --single-branch / --depth 1 mode)?

  • I know I could clone another branch/tag, fetch this ref and checkout FETCH_HEAD. I can even use empty git repo technique from https://stackoverflow.com/a/4146786/239657 to avoid downloading anything else:

    $ git init
    $ git remote add origin https://github.com/cben/sandbox
    $ git fetch origin pull/7/merge --depth 1
    $ git checkout --detach FETCH_HEAD
    

    but my motivation is not just achieving the clone — it's figuring out if I can coax tools like npm and Bundler that accept git url branch into using a pull/NN/merge ref directly.

    • UPDATE: bundler accepts :ref => "refs/pull/232/merge"! It has special handling if ref starts with ref/ — an extra git fetch and later in same file reset --hard to the desired revision.
Beni Cherniavsky-Paskin
  • 9,483
  • 2
  • 50
  • 58
  • If spelling out the reference (`git clone -b refs/pull/7/merge`) doesn't work—and I suspect it doesn't—you'll have to either build `git clone` out of its primitives (clone = mkdir + git init + git remote add + git fetch + git checkout, more or less), or clone first, then fetch the specific ref, then check it out as a detached HEAD. – torek Feb 26 '18 at 18:19
  • https://stackoverflow.com/a/43759576/239657 shows that git clone does support an arbitrary refspec! Combined with https://gist.github.com/piscisaureus/3342247, I tried `git clone --config remote.origin.fetch=refs/pull/7/merge:pr-7 https://github.com/cben/sandbox` — close, but I still need to `git fetch` to actually get it fetched, unless I use `--mirror` but that implies bare, nothing is checked out. Plus I can only add refspecs, so all branches are downloaded? – Beni Cherniavsky-Paskin Feb 26 '18 at 18:32
  • `-b refs/pull/7/merge` doesn't work. `git clone -vv` is helpful to see what heads it requests. https://git.seveas.net/the-meaning-of-refs-and-refspecs.html is excellent tour of refs and refspecs but didn't help much here. – Beni Cherniavsky-Paskin Feb 26 '18 at 18:37
  • Yes, so it looks like you'll need to have some sort of wrapper around / instead-of a direct `git clone`. – torek Feb 26 '18 at 18:45

0 Answers0