Re: git switch has fatal dependency on default fetch config
- From
- Jeremiah Steele (Jerry) <jeremiah@dubsado.com>
- Date
- Dec 7, 2023, 02:20 UTC
- Message-ID
- <94F78A2F-8AAA-49FE-A0A0-D63F1DAE3D31@dubsado.com>
- In-Reply-To
- <20231206191148.GA103708@coredump.intra.peff.net>
For me, the main convenience of upstream tracking is for "git status" ahead/behind info, which requires you to have already fetched changes from the remote. For my "normal" work, I have a small set of branches set as default fetch refs. When I need to work on a branch not in that set, I fetch that specific branch. (I'm not interested in downloading and creating hundreds of branches when I only need one.)
The requirement to reverse-engineer from the *default* fetch refspec seems like an odd implementation choice and a major shortcoming for storing tracking configuration. The vast majority of the time, origin/branch will map to refs/heads/branch on the remote anyhow. When I have a command that sets up tracking configuration, I would expect to be able to specify the remote refspec somehow, rather than having a hard dependency on a configuration value for default behavior. I feel like the following sequence should work as expected (with a limited default fetch spec), but there are several things that go wrong:
% git fetch origin feature # should fetch to refs/remotes/origin/feature % git switch feature # should find origin/feature, create a local branch with the same name, and set up tracking
Oh well.
Thanks for the response and the explanation.
Show 58 quoted lines
> On Dec 6, 2023, at 11:11 AM, Jeff King <peff@peff.net> wrote:
>
> On Tue, Dec 05, 2023 at 07:41:28PM -0800, Jeremiah Steele (Jerry) wrote:
>
>> Changing the default fetch refspec for a remote breaks git switch:
>>
>> % git branch -r
>> origin/HEAD -> origin/master
>> origin/feature
>> origin/master
>> % git remote set-branches origin master
>> % git switch -c feature --track origin/feature
>> fatal: cannot set up tracking information; starting point 'origin/feature' is not a branch
>> % git remote set-branches --add origin feature
>> % git switch -c feature --track origin/feature
>> branch 'feature' set up to track 'origin/feature'.
>> Switched to a new branch 'feature'
>>
>> It seems like I should be able to fetch a remote branch and track it
>> without having to monkey around with my default fetch config. Is there
>> a reason git switch has a hard dependency on the default remote fetch
>> refspec configuration?
>
> I think it's required by the form of the tracking config, which is
> defined by a named remote and a remote branch, like:
>
> [branch "foo"]
> remote = origin
> merge = refs/heads/foo
>
> You explicitly asked to track "origin/feature", which means that Git has
> to be able to turn that into config as above. It can handle two cases:
>
> 1. It's a local branch in refs/heads/, in which case the remote is "."
> and the "merge" field is the name of the branch.
>
> 2. It's a ref that can be found by reversing a fetch refspec. With the
> default remote.origin.fetch refspec of refs/heads/*:refs/remotes/origin/*,
> we know that "refs/remotes/origin/feature" comes from "refs/heads/feature"
> on the "origin" remote.
>
> But since you used "remote set-branches" to limit that refspec, we
> can't do that same reversal. And "origin/feature", while we do
> still have it as a ref, does not correspond to any remote ref we'd
> fetch. So we don't know how to set up the tracking config.
>
> The notion of "tracking" really came about as defining what "git pull"
> does. And without a remote that fetches, "git pull" does not really make
> much sense.
>
> I'd guess that you are more interested in being able to just use
> @{upstream}, especially as the default for things like rebase, etc. And
> that could work without being able to actually fetch the ref. But those
> two things are intertwined in Git. You obviously can still base a branch
> off of "origin/feature", but you'll have to specify it manually when
> doing rebase, etc.
>
> -Peff