In this case, based on your own comment, it appears that the answer was to create a remote first:
It worked after making the following change: Instead of "origin" I was actually using the url to the repo. Setting up the git remote origin, and trying it again actually using "origin" in the command, worked.
It's worth mentioning why this is the way to work with Git.
Git is really, mainly, about commits. Each commit has a unique hash ID, and when two different Git repositories share commits, they share them by those unique hash IDs. (Hence all Git repositories use the same hash IDs for the same commits. To see if you have commit H, for some hash ID H, Git just checks whether you have that hash ID.)
Note that we connect a pair of Gits using git fetch
(get stuff from another Git) and git push
(give stuff to another Git). The git pull
command just means: run git fetch
(to get stuff), then run a second Git command (to incorporate the stuff just obtained). The "stuff" that your Git will get, or give, here is some set of Git internal objects, starting with commit objects (and/or tag objects) and going on to include any other stuff required to make those commit objects complete. (These internal objects also have hash IDs. All of these hash IDs are big and ugly, and look totally random.)
But for many reasons, including the fact that humans are bad at remembering raw hash IDs, we—and Git—use a name to remember the last hash ID of some branch. That name is a branch name like master
or 12.0
or whatever. When you connect two Gits, one Git gets to see the other's branch names—but that's all, we just see them. So, whether you run git fetch
, or run git pull
to have Git run git fetch
for you, your Git will call up some other Git—by some URL—and see all its branch names. Your Git can then get commits, using the hash IDs attached to their branch names.
Hence, you can run:
git fetch <url> <branch-name>
which will call up their Git, and obtain some set of commits if necessary and appropriate, stuffing those commits into your own repository. In your repository, each such commit will have the same hash ID as in their repository. If you pass those commits on to another Git repository, they will continue to have the same hash IDs. But your Git doesn't save their branch names—well, not anywhere permanent and useful—at this point. Those branch names are their names, not your names.
Back in the bad old days before the idea of a remote like origin
, this is all you had. Your Git would call up their Git by URL, get their commits, and drop them into your repository. Your Git wouldn't save their branch names permanently—but your Git would scribble some information down into a file named .git/FETCH_HEAD
. This file would list their branch names and the hash IDs, which would last until the next git fetch
.
Someone noticed that it would be really useful if your Git did save their Git's branch names. But: where can we save them? We can't overwrite our branches. How do we save "branch B of url U"? Also, why do we have to type in scheme://some.long.host.name/some/long/path/to/repo.git
all the itme? Wouldn't it be handy if we had a short name for the URL?
And lo! the remote was invented
If we:
- create a short name like
origin
to hold the URL, and
- take all of their branch names, like
master
and develop
and maybe 12.0
and so on, and stick that short name in front of their branch names
then we can just type in:
git fetch origin
and have our Git:
- call up their Git by the stored URL;
- get their commits;
- remember their branch names and hash IDs as
origin/master
and origin/develop
and origin/12.0
and so on.
Now we have an easy and convenient way to talk about their master
: our origin/master
is a remote-tracking name1 that remembers origin
's master
. Our origin/develop
is a remote-tracking name that remembers origin
's develop
, and our origin/12.0
is a remote-tracking name that remembers origin
's 12.0
.
Now that we have these convenient remote-tracking names, we can—and the Git folks did—augment git checkout
so that it can create a local branch from the remote-tracking name. So now you can just do:
git checkout 12.0
and your Git will say to itself: *Hmm, I don't have a branch named 12.0
. But I do have an origin/12.0
, that looks good! Let me create 12.0
based off the commit I'm remembering via origin/12.0
now, and then switch to that branch!*
And that's what remote-tracking names are good for. They remember your other (peer) Git's branch names, and they make it easy for you to create your own branch names that mirror theirs. They also let your Git figure out things like ahead 1
or behind 3
if your branch name and your remote-tracking name—your copy of their branch name—drift apart.
Note that you must run git fetch
now and then to get your Git to call up their Git and update your Git's copy of their Git's branch names. You can either run git fetch
yourself, or let git pull
run it.2
1Git documentation calls this a remote-tracking branch name, but I've found that leaving out the word branch here seems to work better. It helps avoid confusion between these things and regular (real, local) branch names. You can decide for yourself whether to call it a remote-tracking branch name every time, or use the slightly shorter phrase remote-tracking name.
2I prefer to run git fetch
myself, for many reasons. I won't go into most of them, such as the scars I still have from git pull
destroying days of work back in the bad old days.
This also explains origin master
vs origin/master
Remember that git pull
just:
- runs
git fetch
, then
- runs a second Git command, usually
git merge
.
The git fetch
command needs to know: fetch from where? This can be a URL, or—better, for the reasons we just saw—the name of a remote like origin
. So this is going to turn into git fetch origin
, for instance.
But when we do a git fetch origin
, we'll call up the Git over at origin
(or its URL) and get a list of its branches. Which branches would we like to fetch?
The default is to get all branches automatically.3 That's usually the best thing to do, but if you are in a hurry and some upstream repository tends to have a lot of commits on a lot of branch names, you can restrict this git fetch
to only update one remote-tracking name, via:
git fetch origin <name>
The name
you use here is their branch name! So if you want to restrict your git fetch
to only pick up any new commits from their develop
, and only update your origin/develop
, you would run git fetch origin develop
.
This is the syntax you use with git pull
because for the most part, git pull
just passes your arguments on to git fetch
. So, git pull --all
passes --all
to git fetch
. In git fetch
, --all
means fetch from all remotes. It does not have anything to do with which branches are to be fetched. The default is all branches anyway. Never use git pull --all
.4
Some git pull
arguments are used to change which second command to use (merge vs rebase), and a few get passed on to that second command (e.g., a -m
message for git merge
). But the remote name, if you use one, and the branch name, if you use one, are given to git fetch
.
The second command—the git merge
or git rebase
—always operates on the current branch. So this leads to the last thing to remember: git fetch
is always safe as it does not modify your current branch; git merge
or git rebase
works on your current branch; and git pull
runs both, so it works on your current branch. You can run git fetch
any time, from any branch, but you must be on the right branch when you run git pull
. You can be on any branch, or even no branch, if you run git fetch
.
If you do run git fetch
, then want to merge or rebase, you will use names like origin/master
here:
git fetch
git rebase origin/master
Note that you can rebase a branch named feature
onto origin/master
this way, even if git pull
would merge or rebase feature
with origin/feature
. You get a lot more control if you use a separate fetch, and the names make more sense (to me anyway) because they are the remote-tracking names that have the origin/
in front afterward. It's only the combination command—git pull
—that needs the other Git's branch name.
3Actually, the default is stored under the name origin
. The default default is all branches, but using git clone --single-branch
or git remote add
, you can tell Git that some particular remote should default to only one branch. Using git remote
, you can edit the list of branches and tell Git that the default is to get two specific branches, or three, or whatever. Or you can use git config --edit
and see the raw refspec settings under remote.origin.fetch
, but we won't go into all the gory details here.
4"What, never?" Well, hardly ever? Seriously, people always think it means all branches. It doesn't. Don't use it or you'll fall into this trap. It's not a terrible trap, as fetching from all remotes is not actually harmful, it's just silly, like the start of this footnote. But it also won't override the single-branch-ness of a single-branch clone or remote.