Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't do a checkout with multiple remotes

Tags:

I have two remotes set up in my local git repo. One is the repo of an open-source project I'm contributing to, and the other is my fork of that repo.

It seems that I'm only able to check out stuff that I pull down from the origin remote. My normal method of grabbing a branch from a remote consists of

$ git fetch <remote> <branch> $ git checkout <branch> 

But this doesn't seem to work in my current situation.

$ git fetch my-remote my-branch remote: Counting objects: 2297, done. remote: Compressing objects: 100% (1951/1951), done. remote: Total 2297 (delta 1044), reused 0 (delta 0), pack-reused 50 Receiving objects: 100% (2297/2297), 2.10 MiB | 1.59 MiB/s, done. Resolving deltas: 100% (1045/1045), done. From https://github.com/me/my-repo  * branch            my-branch -> FETCH_HEAD  * [new branch]      my-branch -> origin/my-branch $ git checkout my-branch error: pathspec 'my-branch' did not match any file(s) known to git. 

Furthermore, the branch does not appear when I do git branch.

What's going on here?

like image 781
limp_chimp Avatar asked Jun 01 '15 13:06

limp_chimp


People also ask

Can a repository have multiple remotes?

You can add multiple remotes by using git remote or git config commands or editing the config file. As git can group multiple remotes, you can follow any of the following ways to configure multiple remotes to push simultaneously(no need all). You can set multiple remote URLs to a single remote using git remote.

How do I force checkout to another branch?

Force a Checkout You can pass the -f or --force option with the git checkout command to force Git to switch branches, even if you have un-staged changes (in other words, the index of the working tree differs from HEAD ). Basically, it can be used to throw away local changes.

What does it mean to checkout a remote branch?

Git checkout remote branch is a way for a programmer to access the work of a colleague or collaborator for the purpose of review and collaboration. There is no actual command called “git checkout remote branch.” It's just a way of referring to the action of checking out a remote branch.


2 Answers

When you have only a single remote (let's call it origin) then when you type

git checkout foo

when foo doesn't exist but origin/foo does exist git will behave as though you typed the following

git checkout -b foo origin/foo

If you have multiple remotes, and foo does not exist locally but exists in 2 or more remotes then this behavior is suppressed.

You will need to explicitly create foo and instruct git what remote/branch you want it to track.

git checkout -b foo <remote>/foo

like image 98
Andrew C Avatar answered Oct 01 '22 22:10

Andrew C


Git 2.19 will help, since "git checkout" and "git worktree add" learned to honor checkout.defaultRemote when auto-vivifying a local branch out of a remote tracking branch in a repository with multiple remotes that have tracking branches that share the same names.

See commit 8d7b558, commit ad8d510, commit 1c55055, commit 3c87aa9, commit e4d2d55, commit e417151, commit 17b44ae, commit c8cbf20 (05 Jun 2018) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit 50858ed, 02 Aug 2018)

Note: DWIM is "do what I mean", when a computer systems attempt to anticipate what users intend to do, correcting trivial errors automatically rather than blindly executing users' explicit but potentially incorrect inputs.
I have seen in with Git 2.16 remote format, and Git 2.13 checkout completion.

checkout & worktree: introduce checkout.defaultRemote

Introduce a checkout.defaultRemote setting which can be used to designate a remote to prefer (via checkout.defaultRemote=origin) when running e.g. "git checkout master" to mean origin/master, even though there's other remotes that have the "master" branch.

I want this because it's very handy to use this workflow to checkout a repository and create a topic branch, then get back to a "master" as retrieved from upstream:

(    cd /tmp &&    rm -rf tbdiff &&    git clone [email protected]:trast/tbdiff.git &&    cd tbdiff &&    git branch -m topic &&    git checkout master 

)

That will output:

Branch 'master' set up to track remote branch 'master' from 'origin'. Switched to a new branch 'master' 

But as soon as a new remote is added (e.g. just to inspect something from someone else) the DWIMery goes away:

(    cd /tmp &&    rm -rf tbdiff &&    git clone [email protected]:trast/tbdiff.git &&    cd tbdiff &&    git branch -m topic &&    git remote add avar [email protected]:avar/tbdiff.git &&    git fetch avar &&    git checkout master 

)

Will output (without the advice output added earlier in this series):

error: pathspec 'master' did not match any file(s) known to git. 

The new checkout.defaultRemote config allows me to say that whenever that ambiguity comes up I'd like to prefer "origin", and it'll still work as though the only remote I had was "origin".

CodeManX does point out in the comments how to set that new option:

git config --add checkout.defaultRemote origin  

(add --global if you want to set it globally)

like image 45
VonC Avatar answered Oct 01 '22 21:10

VonC