Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does git branch -t fail with "Not tracking: ambiguous information"?

Tags:

git

branch

When I try to create a new branch tracking a remote branch, I get this:

$ git branch -t test origin/foo
error: Not tracking: ambiguous information for ref refs/remotes/origin/foo

The source seems to somehow search for branches to track and throws me out because it finds less more than one, but I don't exactly get what it's looking for since I already told it what to track on the command line.

Can anybody tell me what's going on and how to fix it?

like image 610
che Avatar asked Sep 08 '09 16:09

che


3 Answers

I saw this also when I had two remote repo's with the same (default) fetch pattern (fetch = +refs/heads/*:refs/remotes/origin/*) and the same branches.

The original mistake was in creating two remotes with the same fetch configuration. The new remote has a different name, and therefore the name of its folder should have been changed as well. Here is an example of a proper multiple-remote configuration:

[remote "origin"]
    url = <primary-source>
    fetch = +refs/heads/*:refs/remotes/origin/*
[remote "alt"]
    url = <alternate-source>
    fetch = +refs/heads/*:refs/remotes/alt/*

In place of alt put any name of your choosing.

Explanation:

The meaning of refs/heads/*:refs/remotes/origin/* is: take all the remote reference in refs/heads on the remote side, and put the to refs/heads/origin on our side. refs/heads is the path where branches are stored, so if you have branch foo on the remote, it will be fetched to origin/foo in your local repo. The + on the beginning means that the destination branches should be always overwritten (w/o that there are some additional checks).

Alternatively:

You can also manually add the info to the project's .git/config, e.g.:

[branch "mybranch"]
    remote = origin
    merge = refs/heads/mybranch
like image 161
Matthew Phillips Avatar answered Nov 18 '22 06:11

Matthew Phillips


because it finds less than one

Nope: because it finds more than one matching remote branch, which means the function remote_find_tracking() returns more than one tracking branch for a given local branch ref.

Is some_remote_branch not already tracked by one of your local branches?
(a git config -l would allow you to check what you have currently have set up).
(a git branch -r can also help to list your current remote-tracking branches. )

See also "copy a branch from one to another repo" for more details with Git 2.36 (Q2 2022).


remote branches, which I thought are something different that remote-tracking branches.

Wrong, as illustrated by this thread:

remote-branches are the "real" remote-tracking-branches. You don't commit to them locally, they are essentially read-only copies of exactly what is happening in a remote repository.
If you try to 'git-checkout' a remote-tracking branch, you will get a detached HEAD.

Local branch:
A branch to which you may commit changes. Optionally, the branch can be configured to "follow" one of your remote-tracking branches. This means that a 'git-pull' without arguments (when your local branch is checked out), will automatically 'git-fetch' and then 'git-merge' the remote-tracking branch.

Now:

it's the job of git-fetch to update remote-tracking branches with any changes found in the remote repository.
Git-pull runs git-fetch and then runs a git-merge to update the currently-checked-out branch.

The problem is, for git-merge:

When this happens, git-merge must decide which remote-tracking-branch to merge into the currently checked out local branch.
You can set which remote-tracking-branch will be selected in this situation with the --track option.

--track sets up a local following branch to refer to a remote's branch, not to the tracking branch

Consider that remote_find_tracking() takes a single remote and a refspec with src filled, and returns the given refspec after filling its dst, if an appropriate tracking was configured for the remote, meaning git.

/*
 * For the given remote, reads the refspec's src and sets the other fields.
 */
int remote_find_tracking(struct remote *remote, struct refspec *refspec);

May be it considers it already has a local following branch matching some_remote_branch. Do you have any local branch with that exact same name?
Or, the other way around: your current branch has a remote branch with a similar name, which makes it a natural candidate for any git-merge: trying to make it track another remote branch would make the git-merge unable to choose which local branch to update/merge with changes of a remote.

like image 28
VonC Avatar answered Nov 18 '22 04:11

VonC


Got it! The problem was that I have previously set up a remote with --mirror, for the purpose of having a backup / public copy of my repository.

If you run

git remote add --mirror <name> <url>

it does not only flag the remote as mirror (which is what I wanted for pushes), but also configures remote.<mirror>.fetch option for the mirror to +refs/*:refs/*, which means that all of your branches suddenly "track" your mirror repository and any attempt to create a tracking branch is going to fail.

(As an added bonus, running git fetch <mirror> is going to overwrite all your refs with old ones from your backup repo.)

The solution that seems to fix this issue is setting remote.<mirror>.fetch to : (which, I hope, means "never fetch anything"). This apparently fixes the tracking issue and eliminates the deadly fetch.

like image 13
che Avatar answered Nov 18 '22 04:11

che