Reputation: 99418
I was under master branch, and run git branch -ra
which shows a branch
remotes/origin/deals
The branch isn't shown in the output of git branch
.
I guess that it is a remote-tracking branch, correct?
I wanted to switch to that branch, but I accidentally ran
$ git branch remotes/origin/deals
$ git branch
* master
remotes/origin/deals
Is it correct that i should have ran git branch -b remotes/origin/deals
instead?
Did I create a new branch whose name is also remotes/origin/deals
, and are there now two branches whose names are both remotes/origin/deals
and how is that possible?
If I created a new branch remotes/origin/deals
, is it a local branch? how can I remove it?
Thanks.
Upvotes: -1
Views: 270
Reputation: 488103
The answers you have gotten so far are all correct, but are not pointing out a key distinction. As you saw in another question, Git declares that there are two "kinds" of branches, regular (local) branches and remote-tracking branches.
Under the hood, however, Git actually unifies these—and tags, too—by lumping them all together under the general category of references. So this brings up a good question: How does Git decide that B is a local branch and R is a remote-tracking branch?
The obvious answer is actually the wrong answer!
The git branch
command, when run with no flags or with -l
, shows local branches:
$ git branch
master
test
Or, when run with -r
, it shows remote-tracking branches:
$ git branch -r
origin/master
origin/test
You might say to yourself: Aha, origin
means "remote-tracking". But this isn't true, and in fact, when you run git branch -a
to see both local and remote-tracking branches, the output changes:
$ git branch -a
master
test
remotes/origin/master
remotes/origin/test
Now it's a bit more mysterious. Maybe remotes/origin
means remote-tracking? Well, that's closer, but still not right.
In fact, git branch
is lying to you, with a good excuse: it's trying to shorten things. The full name of each reference starts with refs/
. If git branch
did not do this shortening, you would see:
refs/heads/master
refs/heads/test
refs/remotes/origin/master
refs/remotes/origin/test
Now the obvious answer is the correct answer: A local branch starts with refs/heads/
and a remote-tracking branch starts with refs/remotes/
. (For completeness, let's also note that a tag starts with refs/tags/
.) The git branch
command shortens these, with the idea that you know what kind of branch you're looking for because you either asked for local branches or for remote-tracking branches.
The git branch
command applies the same rules to branch creation. If you use -l
or no flag at all, it creates a regular (local) branch: it puts refs/heads/
in front of whatever you typed in. If you use -r
, it creates a remote-tracking branch: it puts refs/remotes/
in front. Then, as usual, it strips those off again when it shows them to you.
What this means is that git branch remotes/origin/deals
creates refs/heads/remotes/origin/deals
: a local branch, not a remote-tracking branch. It then shows up as remotes/origin/deals
after stripping off refs/heads/
. It's sometimes impossible to tell this apart from an actual remote-tracking branch refs/remotes/origin/deals
, so if you actually had both the name would be somewhat ambiguous.1 Since you don't, though, it's not ambiguous: it's just a local branch, with a very misleading name.
The "plumbing" command git for-each-ref
will, as its default action, print every reference—branches, remote-tracking branches, tags, "notes", the "stash": in short, everything under refs/
—by full name. If you're in this ambiguous-reference situation, you can get a full dump of everything using git for-each-ref
.
For a nicer (higher level) view, git branch
with appropriate flags, and/or with various color options set, will split up the names. If git branch -l
(or git branch
with no flags) shows a branch name, it's local, even if it starts with origin/
or remotes/origin/
. If git branch -r
shows a branch name, it's a remote-tracking branch. With color mode turned on, local branches default to plain, except for the current branch which is printed in green; and remote-tracking branches are printed in red. Adding multiple v
flags (e.g., git branch -avv
), you get additional information, with "upstream" names printed in blue. (Upstreams are most often remote-tracking branches, since these are the ones Git creates automatically, but you can set one local branch as the upstream for another local branch.)
1Git deals with this by choosing one according to Git's internal rules. These rules are described in the gitrevisions
documentation, but there is an important caveat: the git checkout
command uses its own, different, rules. So git diff
or git log
will show one thing, while git checkout
will do another, in some ambiguous-name cases. It's best just to avoid the situation entirely.
Upvotes: 1
Reputation: 295373
When you ran
$ git branch remotes/origin/deals
...you created a new file:
# file describing local branch created by the above command
.git/logs/refs/heads/remotes/origin/deals
...which, indeed, you should probably delete (either by hand, or with git branch -d remotes/origin/deals
).
This is as opposed to the file pointing to the remote branch head:
# file created by fetching from the remote branch
.git/logs/refs/remotes/origin/deals
To check out a remote branch, you should use:
$ git checkout remotes/origin/deals
...or, to create and checkout a local branch which tracks that remote branch:
$ git checkout -b deals --track origin/deals
Upvotes: 1
Reputation: 181
If you want switch on a remote branch you need : git checkout branchname .
Now you has created a branch with same name of remote branch . A simple solution could be to clone your project on a different local folder . After this you can run : git checkout remotes/origin/deals .
Upvotes: 1
Reputation: 746
git branch remotes/origin/deals
creates a new branch called remotes/origin/deals
git checkout -b remotes/origin/deals
creates a new branch called remotes/origin/deals and points to that branch
git checkout remotes/origin/deals
points to an existing branch called remotes/origin/deals
git branch -d remotes/origin/deals
safely deletes the branch making sure there is no uncommitted work
git branch -D remotes/origin/deals
forcefully deletes the branch
git push origin --delete {the_remote_branch}
deletes the remote branch
Upvotes: 1