Re: [PATCH] revisions: add @{default} shorthand for default branch
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Jan 31, 2026, 19:16 UTC
- Message-ID
- <xmqqv7gh4mpw.fsf@gitster.g>
- In-Reply-To
- <xmqq4io3831o.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
Show 19 quoted lines
> For those who follow the naming the upstream decided to use in
> cloned repositories, init.defaultBranch is probably the last thing
> you want to take as a hint, as these people decided to _ignore_ the
> preference of their own and instead to follow what upstream uses.
> For that, refs/remotes/origin/HEAD would be a lot more stronger
> hint. If they call their primary branch 'trunk', these people would
> want to call theirs 'trunk'. And for that, these people would not
> do anything with init.defaultBranch.
>
>> git checkout $(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')
>>
>> That's uneccessary overhead, that could now be replaced with:
>>
>> git checkout @{default}
>
> That mirrors what I wrote in the previous paragraph. Those who
> follow the naming the upstream uses, refs/remotes/$remote/HEAD
> (here, "origin" may not be the default remote) would be a better
> hint than init.defaultBranch so calling it @{default} is misleading.Thinking about this more, while I can see how using the remote-tracking branch that is pointed by refs/remotes/origin/HEAD may make sense, I see no sensible reason why mapping that to a local branch name by simply stripping refs/remotes/origin/ makes sense.
Stepping back a bit, the workflow that may be helped by being able to learn the value of "refs/remotes/origin/HEAD", in addition to @{upstream} and @{push} would be laid out like the following:
* The project uses 'main' as its primary integration branch. After you clone it, refs/remotes/origin/HEAD points at their 'main' (i.e., you have refs/remotes/origin/main keeping track of it), "git fetch" updates refs/remotes/origin/HEAD when they change their naming if you are using a recent enough version of Git.
* The project uses topic based workflow. The idea is each topic gets its own topic branch, e.g., 'feature', and participants join forces to bring it to perfection, after which 'main' merges the completed 'feature'.
* You, as a participant of this project, fork your own 'feature' local branch from the remote-tracking branch 'origin/feature'. You publish the result into a separate repository of your own, different from where you cloned from. If you fetch from there, a remote-tracking branch 'refs/remotes/publish/feature' may be created in your local clone as well (assuming your publishing repository is called 'publish').
Now, you have @{upstream} that is their 'feature' (that is kept track of with refs/remotes/origin/feature remote-tracking branch in your local clone), @{push} that is refs/remotes/publish/feature. Comparing your local progress against these two are useful to see where you are, how far you came, and how much others you see in @{upstream} may have diverged.
In addition, the overall "progress" of the project is how far @{upstream} has come relative to refs/remotes/origin/main, which is the ultimate target that you and your fellow project participants want to see @{upstream} gets merged, is a useful thing to keep track of.
So in that sense, I do understand why somebody may find it useful if there is a handy short-hand for refs/remotes/origin/main (or whichever branch is pointed at by refs/remotes/origin/HEAD) in the above picture. And refs/remotes/origin/HEAD already does have a handy short-hand, which is 'origin' ;-).
But step back and notice that there is no mention of local 'main' in the above layout?
As Kristoffer said in another message [*1*], I would too expect that people would not work on their 'main' (or have their 'main' track the upstream's 'main'). So the utility of the piping to sed we saw above is dubious, unless we are talking about quite different workflow, but I do not think of what that other workflow would look like that makes a neutral synonym for 'main' useful.
So, enough about refs/remotes/origin/HEAD. Back to your original idea of using init.defaultBranch.
In one of your other messages [*2*], you reported that you were having trouble with repositories without init.defaultBranch configuration variable cofigured.
Doesn't repo_default_branch_name() do the right thing without being noisy at all even in a repository without that configured, as the function will fall back to the built-in default? While I do not think of a workflow in which a handy access to the value the function gives would be so useful that it deserves a short-hand, it would be a reasonable candidate of what to be called "@{default}", if it proves useful, I would think.
Show 11 quoted lines
> I am not good at naming things, so instead of calling it @{primary}
> let's call it @{dumbo}. With the realization that what branch
> refs/remotes/$remote/HEAD points at is a good source of hint, I
> actually think $branch@{dumbo} does make sense, and @{dumbo} should
> be a short-hand for $branch@{dumbo} where the name of the current
> branch is substituted for $branch (i.e. similar to @{push}, I
> suppose). As you may be interacting with two sets of branches that
> go to two different remotes.
>
> In any case, it is very different from what you implemented as the
> @{default} in your patch.[References]
*1* https://lore.kernel.org/git/7b62316f-a30a-4895-808d-baa20be0f3af@app.fastmail.com/
*2* https://lore.kernel.org/git/20260131000923.70152-1-haraldnordgren@gmail.com/