How to create a branch in git basing it on a remote branch
This question already has an answer here:
You can just type:
git fetch <remote>
to fetch all refs from your remote,
git checkout <remote>/<branch>
lets you checkout your remotes branch to an "anonymous" branch,
git checkout -b <new_local_branch>
creates a local branch based on the remote one you checked out.
You can also set the remote branch as upstream:
git branch --set-upstream-to=<remote/branch> <new_local_branch>
TL;DR version
git fetch remote; git checkout branch
History
The git designers seem to have made this deliberately confusing, but actually the confusion is due to the evolutionary path git took.
In the very old days (before git version 1.5) you just grabbed the branch directly off the other repository, typing in the full URL for the repository each time. As you can probably imagine, typing in long repository paths all the time grew old fast. There were a bunch of intermediate solutions, then someone came up with the idea of a remote: a short name like origin
you could use to store everything you might like to know about the other git repository.
Along with the remote came remote-tracking branches. The idea here was that if your git calls up another git over the Internet-phone and spends some time chatting with it and retrieves a whole bunch of new stuff, it might be nice to tuck away, in your own repository, a memory of every branch they offered you and which commits those were. These are your remote-tracking branches: origin/master
, origin/develop
, and so on.
Whenever you run git fetch origin
your git phones up their git, picks up any new commits they offer, and squirrels away all their branches as origin/branch
. If you did not have them before, you do now.
Checking out a remote-tracking branch
Now, you can check out a remote-tracking branch, but you can't get on a remote-tracking branch:
$ git checkout origin/develop
is exactly like finding the commit ID of origin/develop
:
$ git rev-parse origin/develop
39d22b9678b8c571aab6902620c95907d5bef2db
and then handing that to git checkout
:
$ git checkout 39d22b9678b8c571aab6902620c95907d5bef2db
Note: checking out '39d22b9678b8c571aab6902620c95907d5bef2db'.
You are in 'detached HEAD' state. ...
(The only difference is that git can use the name origin/develop
if you hand that to git checkout
—you still get that 'detached HEAD' message.)
Creating a local branch
git checkout -b branch
will create and put you on a new local branch, starting from the current commit. Which is fine, but this means you have to check out the remote-tracking branch first. Or, you can tell git checkout -b
where to start the new branch. But then you should also set it up to track (as git puts it) the other branch, which brings us to:
Creating a local branch from a remote-tracking branch
Now, the tricky bit is that once you have origin/develop
(or some other origin/
-qualified branch name), you can git checkout
a regular, ordinary, local branch using that same name, even if you don't have one yet. Git will notice that develop
is not (yet) a branch name, so it will scan through all your remote-tracking branches and discover that there's exactly one matching name— origin/develop
in this case—and assume you meant "please create a new develop
and make it track origin/develop
so that it initially starts with the same commit that origin/develop
points to right now".
(This is such a common thing to need that the git folks added it way back in git version 1.6.6.)
Wait, a local branch tracks a remote-tracking branch?
Yes.
But then why isn't it a local-tracking branch?
There are way too many occurrences of the words "local", "remote", and "tracking" already, not to mention the multiple meanings of the word "branch". You want a local-tracking branch to track a remote-tracking branch? What happens if your local branch tracks another local branch? :-) (Yes, git can do that.)
Seriously, the terminology is a little weird. It just grew like that.
A few other things
The git branch
command has --set-upstream-to
and --unset-upstream
. These operate on the current branch by default, or a local branch if you specify one, and set the name of the other branch that the local branch is to track (for --set-upstream-to
), or stop the local branch from tracking whatever it is set to track (for --unset-upstream
). These use the word "upstream" instead of the phrase remote-tracking branch, which is reasonable since you can set the upstream to another local branch. That's how you track the other branch (whether or not it's a remote-tracking branch).
What good is having a local branch track some other branch? Why bother at all?
It lets git rebase
and git merge
know what to rebase-on or merge-with so that you don't have to type that in again; and it lets git status
count commits that you have on the local branch that the other branch doesn't ( ahead 3
, for instance) and/or that they have that you don't (eg, behind 12
). In other words, it's just for convenience. It is pretty convenient though. It tastes good and it's good for you!
I found a way. This one command does it:
git fetch remote branch_name:branch_name
链接地址: http://www.djcxy.com/p/89684.html
下一篇: 如何在基于远程分支的git中创建分支