105

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!

Dana Robinson
  • 4,105
  • 8
  • 29
  • 40
  • To switch branch without detaching head, with Git 2.23 (August 2019), use **`git switch`**: see [my answer below](https://stackoverflow.com/a/57578521/6309). – VonC Aug 20 '19 at 17:07

4 Answers4

118
# 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.

Kent Fredric
  • 54,014
  • 14
  • 101
  • 148
  • 9
    Man, why doesn't "git checkout origin/branchname" start tracking the branch automatically if it is not tracked yet? – Martin Konicek Dec 22 '10 at 18:02
  • 4
    because you still need a local name for the foreign branch. – Kent Fredric Dec 23 '10 at 11:12
  • 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? – ulu Jan 24 '12 at 13:27
  • 2
    Thanks for the tip about colors. To enable colors: `git config --global --add color.ui true` – PonyEars Sep 25 '13 at 19:13
  • @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 you – Fermin Silva Jun 16 '16 at 17:45
  • 1
    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. – Kent Fredric Jun 19 '16 at 06:57
17
git clone git@github.com: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
Christoph Rüegg
  • 4,416
  • 1
  • 18
  • 32
  • 3
    git branch -t origin/experimental # don't need to type so much :) – Dustin Jan 23 '09 at 00:51
  • 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'. – ulu Jan 24 '12 at 13:24
  • 1
    @Dustin, that command creates a local branch 'origin/experimental' that tracks the local master. I'm guessing it's a fairly common mistake. – PDug Aug 07 '13 at 21:58
  • 1
    @PDug % git checkout -t origin/experimental Branch experimental set up to track remote branch experimental from origin by rebasing. Switched to a new branch 'experimental' – Dustin Aug 12 '13 at 16:56
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
Pat Notz
  • 186,044
  • 29
  • 86
  • 92
4

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'
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283