git: switch branch without detaching head
Asked Answered
D

4

110

I have a repository on github with a main branch (master) and a branch for some experimental work. I made some commits and pushed to the experimental branch and everything was fine.

Now, on a different machine, I try to clone my repository (git clone repository) and then switch to the experimental branch (git checkout branchname) but every time I do this my head gets detached and I can't push my changes. What am I doing wrong? I get the feeling I'm missing a fundamental git concept someplace but reading random git man pages isn't giving me any clues.

I'm new to git so I'm sorry if I'm being an idiot but I can't find anything in the docs that will help me reattach my head.

EDIT

The concept of a tracking branch is what I was missing. Now that I grok that concept everything is clear. Personally, I find the git branch --track syntax to be much more intuitive than git checkout -b branch-name origin/branch-name.

Thanks for the help!

Dieldrin answered 22/1, 2009 at 23:37 Comment(1)
To switch branch without detaching head, with Git 2.23 (August 2019), use git switch: see my answer below.Ja
A
125
# first time: make origin/branchname locally available as localname
git checkout -b localname origin/branchname 

# othertimes 
git checkout localname 

git push origin

For convenience, you may use the same string for localname & branchname
When you checked out origin/branchname you weren't really checking out a branch. origin/branchname is a "remote" name, and you can get a list of them with

branch -a 

If you have colours enabled, local branches will be one colour, and remote another.

You have to first make a remote branch tracked locally in order to be able to switch-to and work on it.

Astatine answered 22/1, 2009 at 23:44 Comment(6)
Man, why doesn't "git checkout origin/branchname" start tracking the branch automatically if it is not tracked yet?Soap
because you still need a local name for the foreign branch.Astatine
Here's what I'm doing, and the error message: $ git checkout -b topic/fetch upstream/topic/fetch fatal: git checkout: updating paths is incompatible with switching branches. Did you intend to checkout 'upstream/topic/fetch' which can not be resolved as commit?Wigeon
Thanks for the tip about colors. To enable colors: git config --global --add color.ui trueWaxbill
@KentFredric most of the time though, the branch gets automatically tracked for me. I cloned a repo with lots of branches, and checking them without tracking worked for all of them, except for a specific branch that gave me detached state. However, this command fixed it, for which I thank youAnneal
Its worth noting that "origin/branchname" can literally be anything that resolves to a SHA1, or a SHA1 in itself =). I regularly use that to create arbitrary branches with arbitrary roots.Astatine
D
19
git clone [email protected]:abc/def.git
cd def

Now create a tracking branch:

git branch --track experimental origin/experimental
git checkout experimental

Then, after working there, simply push to github by

git push
Donative answered 23/1, 2009 at 0:38 Comment(4)
git branch -t origin/experimental # don't need to type so much :)Beadsman
The branch I want to track is called topic/fetch. When I'm trying to do $ git branch --track topic/fetch upstream/topic/fetch it says, fatal: Not a valid object name: 'upstream/topic/fetch'.Wigeon
@Dustin, that command creates a local branch 'origin/experimental' that tracks the local master. I'm guessing it's a fairly common mistake.Matroclinous
@Matroclinous % git checkout -t origin/experimental Branch experimental set up to track remote branch experimental from origin by rebasing. Switched to a new branch 'experimental'Beadsman
U
11

To expand on Kent's reply, after you do your clone the only branch you'll have (remotes don't count) is the one that was active in the repository you cloned from -- master in your case.

So, first you'll want to create a new branch to track the remote experimental branch:

$ git branch experimental origin/experimental

and then check it out:

$ git checkout experimental

However, Kent is correct -- these two commands can be combined

$ git checkout -b experimental origin/experimental
Unpremeditated answered 23/1, 2009 at 0:41 Comment(0)
J
9

With Git 2.23 (August 2019), you would use the git switch command

If you have a remote branch of the same name, it will be automatically tracked:

$ git switch new-topic
Branch 'new-topic' set up to track remote branch 'new-topic' from 'origin'
Switched to a new branch 'new-topic'
Ja answered 20/8, 2019 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.