Reputation: 66478
So I've created a quick change on the GitHub repo, but it requires more work, adding unit tests, and running the build. So I have new branch created with web interface:
https://github.com/jcubic/prism/tree/patch-1
But when I use git pull
, in the terminal, I have nothing was changed. When I use git branch -a
I've got:
$ git branch -a
* master
scheme-operators
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/upstream/gh-pages
remotes/upstream/master
no branch patch-1
. I have this in .git/config:
[remote "origin"]
url = [email protected]:jcubic/prism.git
fetch = +refs/heads/master:refs/remotes/origin/master
How I can update my local repo with stuff that is on GitHub?
EDIT:
It may be a bug on the GitHub side. It was reported and I'm waiting for a reply.
Upvotes: 0
Views: 2533
Reputation: 487775
This:
[remote "origin"] url = [email protected]:jcubic/prism.git fetch = +refs/heads/master:refs/remotes/origin/master
is the problem. Note the fetch
line here; this is the result of using git clone --single-branch
or one of its several equivalents.
Having made a single-branch clone that you want to be a multi-branch clone, the recommended method is to use git remote
to update the set of branches to fetch. I personally prefer to just run git config --edit
and use my editor, but:
git remote set-branches origin "*"
will do the trick, and avoids some possible pitfalls that might occur with git config --edit
.
Your real goal here is to make these three lines read:
[remote "origin"]
url = [email protected]:jcubic/prism.git
fetch = +refs/heads/*:refs/remotes/origin/*
Note the change to the third line: we now have our (local) Git (our Git software, running on this repository) call up their Git as usual, but this time, when their Git—their software on their repository—lists out all their branches, our Git says "yes! I'll take all of those!" With just master
listed, our Git picks over their branches: Oh, hm, patch-1, that's not interesting. "feature", no, pass! "fix-23"? No way. "master": ah, that's the only one we care about: yes please!
When our Git says it doesn't want any of their branches except master
, they only send us the pieces we need to make our origin/master
—our memory of their master
—and not any of the pieces we need to make our own origin/patch-1
, for instance. So by explicitly rejecting their patch-1
, you never get an origin/patch-1
, and hence cannot create your own patch-1
from their patch-1
.
Undoing the single-branch-ness fixes all of this, and now:
git fetch origin
gets, from them, all of their branches, turning them into all your remote-tracking names, origin/*
.
git fetch --all
hreikin's answer mentions git fetch --all
(and git fetch --multiple
; there are other additional variants). These are sometimes useful when you have more than one remote.
A remote is a name-and-URL set, and you do in fact have more than one remote:
$ git branch -a * master scheme-operators remotes/origin/HEAD -> origin/master remotes/origin/master remotes/upstream/gh-pages remotes/upstream/master
This shows us that you have remotes named origin
and upstream
. These each represent different Git repositories to which you connect your Git repository.
Sometimes, you have your Git call up the Git over at origin
, to see what branches and commits they have. These go into your repository under your origin/*
names—currently, origin/master
only, because you've told your Git that all other branches are too boring for words.
Other times, you have your Git call up the Git over at upstream
, to see what branches and commits they have. These go into your repository under your upstream/*
names.
With git fetch
, you direct your Git to call up one other Git. Which one? Well, that depends: each branch, in your repository, is allowed to list one thing that Git calls an upstream. This name is a little bit unfortunate, since it's also the name of one of your remotes. But the upstream of your master
branch is typically your origin/master
: your remote-tracking name for the branch master
on the Git you call origin
.
The default, when you run git fetch
, is to call up the Git that holds the branch that your current branch is using as its remote-tracking name. So if you're on your master
, and its upstream is set to origin/master
, your Git will run git fetch origin
when you run git fetch
without naming which Git to fetch from.
If you run git fetch upstream
, though, your Git will fetch from upstream
instead of origin
. Or, you could create some other branch whose upstream is set to upstream/master
or upstream/gh-pages
:
git branch upmaster upstream/master
git checkout upmaster
git fetch
and now your Git would fetch from upstream
(the remote named upstream
), because the upstream of upmaster
is upstream/master
, which uses upstream
as its remote. (Confused yet? If not, Git has still other confusing terms to use! 😀 Seriously, these historical accidents have made quite a mess here.)
Anyway, this particular thing—where git fetch
fetches from one remote—works great when there's only one remote (usually called origin
). But once you have two or more, it's nice to be able to fetch from all of them.
That's what the --all
flag is for. It means fetch all remotes. It never means fetch all branches: the branches you get are per-remote, specified by that fetch =
line.1 But in practice, it doesn't make a lot of sense to use git fetch --all
, because there is another command:
git remote update
that means fetch all. The git remote
command has a lot more tuning options, with the idea of "group" fetches from your most-commonly-used remotes for instance. These can all be done by git fetch
but git remote
is the command that's really aimed at this kind of fine detail.
The bottom line, as it were, is:
git fetch
to fetch from the remote for this branch;git remote update
to fetch from all remotes, if you have more than one.With these as general rules, and knowledge of how upstreams and fetch =
lines work, you're now all set.
1Technically, you can have more than one line per remote. You can also override these lines using a refspec on the command line.
Upvotes: 2
Reputation: 30
You need to fetch the branches from the remote first.
git fetch --all
git fetch origin
git fetch --multiple origin upstream
git branch -a
git checkout nameofnewbranch
The documentation for 'git fetch' is available here.
Upvotes: 0
Reputation: 16338
You need to use git fetch
first.
This downloads all branches and their commit histories from GitHub (note that git pull
also runs git fetch
but also a git merge
).
After running git fetch
, you can see the remote branch with git branch -a
.
Then, you can check it out using git checkout patch-1
or git checkout -b patch-1 remotes/origin/patch-1
.
Upvotes: 0