Skip to content

Instantly share code, notes, and snippets.

@gvaughn
Forked from chrismo/copr.md
Created July 18, 2014 16:15
Show Gist options
  • Save gvaughn/2a24abb3d2d54f5dca82 to your computer and use it in GitHub Desktop.
Save gvaughn/2a24abb3d2d54f5dca82 to your computer and use it in GitHub Desktop.

Greg Vaughn posted this cool alias the other day:

copr = "!f() { git fetch -fu origin refs/pull/$1/head:pr-$1; git checkout pr-$1; } ; f"

Preferring to be a stock-tools person, I wanted to deconstruct this to see how I'd use it off-the-shelf without the alias.

git fetch     -- I'm already familiar with this command
-fu           -- these two flags I'm not sure are necessary, esp. -u since the help says, 
                 "unless you are implementing your own Porcelain you are not supposed to use 
                 it." - and since I don't know what Porcelain is, I presume I'm in the general camp. 
origin        -- I also know this is the repo (the remote name from `git remote`)

Now to some new stuff for my brain:

refs/pull/$1/head:pr-$1

I know the $1 is just a variable for the PR number. This whole thing is the refspec according to git help fetch:

   <refspec>
       The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>, 
       followed by a colon :, followed by the destination ref <dst>.

       The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref 
       that matches it is fast-forwarded using <src>. If the optional plus + is used, the local ref is 
       updated even if it does not result in a fast-forward update.

Since I have a git completion script installed, I realize I can see the list of available refspecs with:

git fetch origin [<tab><tab>]

[chrismo@momac foo (master)]$ git fetch origin
HEAD:HEAD                                         refs/pull/2/merge:refs/pull/2/merge
master:master                                     refs/pull/3/head:refs/pull/3/head
refs/pull/2/head:refs/pull/2/head                 refs/pull/3/merge:refs/pull/3/merge

These can be explicitly listed (without auto-completion magic) with git ls-remote origin

[chrismo@momac foo (master)]$ git ls-remote origin
f2720fe21c9e6b92ede4f9f99598f60d3251b0b1	HEAD
f2720fe21c9e6b92ede4f9f99598f60d3251b0b1	refs/heads/master
594fe52884ca771c26a70a45402f9cfedf58c3ae	refs/pull/2/head
3dd41b7ac6db8160e61ee89d920894ab20ea0b28	refs/pull/2/merge
00d5916224d47fa99cf76ceb5e2b81ca76cd1f62	refs/pull/3/head
07f43e1ce5ae8abc3afb2d27b5a845de67819029	refs/pull/3/merge

Back to the refspec help from the fetch command, I see that refs/pull/2/head is the src and whatever is on the right side of the colon is the dst. So ...

git fetch origin refs/pull/2/head:pr-2

... simply means, fetch the contents of pull request 2 and put it into a new local branch called pr-2 -- the destination local branch could be named whatever I want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment