threads / discuss / 60517

Feature request: git status --branch-only

Subject: Feature request: git status --branch-only

## tl;dr

7 messages between Nov 14, 2023 and Nov 16, 2023.

replies: 6people: 3as markdown or json

Ondra Medek· Nov 14, 2023, 10:16 UTC · lore

Hello, I am working on a tol which should fetch changes from a remote repository on a user click. I want to limit fetch on the current remote tracking branch (something like "origin/master"), but surprisingly, it's hard to get it for all corner cases like a fresh clone of an empty repository or detached head, etc. E.g see this SO thread https://stackoverflow.com/questions/171550/find-out-which-remote-branch-a-local-branch-is-tracking/52896538

The most reliable way for me is to call
git status -b --no-ahead-behind --porcelain=v2

and parse the "# branch.upstream" line output. However, it is a bit slow on large repos and yields unused output for me. So, I propose a new switch "git status --branch-only" which would output branch status only.

Note: workaround is to specify some non-existing directory, like
git status -b --no-ahead-behind --porcelain=v2 .this-dir-does-not-exists

Thanks Ondra Medek

Phillip Wood· Nov 14, 2023, 12:28 UTC · re: Ondra Medek · lore

Re: Feature request: git status --branch-only

Hi Ondra
On 14/11/2023 10:16, Ondra Medek wrote:
Show 7 quoted lines
> Hello,
> I am working on a tol which should fetch changes from a remote
> repository on a user click. I want to limit fetch on the current
> remote tracking branch (something like "origin/master"), but
> surprisingly, it's hard to get it for all corner cases like a fresh
> clone of an empty repository or detached head, etc. E.g see this SO
> thread https://stackoverflow.com/questions/171550/find-out-which-remote-branch-a-local-branch-is-tracking/52896538
I think you can do this by calling
	git symbolic-ref --quiet HEAD

to get the full refname of the current branch. If HEAD is detached it will print nothing and exit with exit code 1. Then you can call

	git for-each-ref --format="%(upstream:short)" $refname
to get the upstream branch
Best Wishes
Phillip
Ondra Medek· Nov 14, 2023, 12:40 UTC · re: Phillip Wood · lore

Re: Feature request: git status --branch-only

Hi Phillip,
it does not work for a fresh clone of an empty repository
    git for-each-ref --format="%(upstream:short)" refs/heads/master
outputs nothing, while
    git status -b --no-ahead-behind --porcelain=v2
outputs

# branch.oid (initial) # branch.head master # branch.upstream origin/master

I.e. it outputs a proper upstream branch.

Best regards Ondra

Ondra Medek
On Tue, 14 Nov 2023 at 13:28, Phillip Wood <phillip.wood123@gmail.com> wrote:
Show 26 quoted lines
>
> Hi Ondra
>
> On 14/11/2023 10:16, Ondra Medek wrote:
> > Hello,
> > I am working on a tol which should fetch changes from a remote
> > repository on a user click. I want to limit fetch on the current
> > remote tracking branch (something like "origin/master"), but
> > surprisingly, it's hard to get it for all corner cases like a fresh
> > clone of an empty repository or detached head, etc. E.g see this SO
> > thread https://stackoverflow.com/questions/171550/find-out-which-remote-branch-a-local-branch-is-tracking/52896538
>
> I think you can do this by calling
>
>         git symbolic-ref --quiet HEAD
>
> to get the full refname of the current branch. If HEAD is detached it
> will print nothing and exit with exit code 1. Then you can call
>
>         git for-each-ref --format="%(upstream:short)" $refname
>
> to get the upstream branch
>
> Best Wishes
>
> Phillip
Phillip Wood· Nov 14, 2023, 15:02 UTC · re: Ondra Medek · lore

Re: Feature request: git status --branch-only

Hi Ondra
On 14/11/2023 12:40, Ondra Medek wrote:
Show 7 quoted lines
> Hi Phillip,
> 
> it does not work for a fresh clone of an empty repository
> 
>      git for-each-ref --format="%(upstream:short)" refs/heads/master
> 
> outputs nothing, while

Oh dear, that's a shame. I wonder if it is a bug because the documentation says that

	--format="%(upstream:track)"

should print "[gone]" whenever an unknown upstream ref is encountered but trying that on a clone of an empty repository gives no output.

Best Wishes
Phillip
Show 44 quoted lines
>      git status -b --no-ahead-behind --porcelain=v2
> 
> outputs
> 
> # branch.oid (initial)
> # branch.head master
> # branch.upstream origin/master
> 
> I.e. it outputs a proper upstream branch.
> 
> Best regards
> Ondra
> 
> Ondra Medek
> 
> 
> On Tue, 14 Nov 2023 at 13:28, Phillip Wood <phillip.wood123@gmail.com> wrote:
>>
>> Hi Ondra
>>
>> On 14/11/2023 10:16, Ondra Medek wrote:
>>> Hello,
>>> I am working on a tol which should fetch changes from a remote
>>> repository on a user click. I want to limit fetch on the current
>>> remote tracking branch (something like "origin/master"), but
>>> surprisingly, it's hard to get it for all corner cases like a fresh
>>> clone of an empty repository or detached head, etc. E.g see this SO
>>> thread https://stackoverflow.com/questions/171550/find-out-which-remote-branch-a-local-branch-is-tracking/52896538
>>
>> I think you can do this by calling
>>
>>          git symbolic-ref --quiet HEAD
>>
>> to get the full refname of the current branch. If HEAD is detached it
>> will print nothing and exit with exit code 1. Then you can call
>>
>>          git for-each-ref --format="%(upstream:short)" $refname
>>
>> to get the upstream branch
>>
>> Best Wishes
>>
>> Phillip
> 
Ondra Medek· Nov 14, 2023, 19:44 UTC · re: Phillip Wood · lore

Re: Feature request: git status --branch-only

Hi Phillip,

even "[gone]" would not be much of help for me. I would need something like "origin/master [gone]" i.e. what "git status -b --porcelain" prints. (Note, I've written about "git status -b --porcelain=v2" before because v2 is better documented and parseable.)

Regards Ondra Medek

On Tue, 14 Nov 2023 at 16:02, Phillip Wood <phillip.wood123@gmail.com> wrote:
Show 69 quoted lines
>
> Hi Ondra
>
> On 14/11/2023 12:40, Ondra Medek wrote:
> > Hi Phillip,
> >
> > it does not work for a fresh clone of an empty repository
> >
> >      git for-each-ref --format="%(upstream:short)" refs/heads/master
> >
> > outputs nothing, while
>
> Oh dear, that's a shame. I wonder if it is a bug because the
> documentation says that
>
>         --format="%(upstream:track)"
>
> should print "[gone]" whenever an unknown upstream ref is encountered
> but trying that on a clone of an empty repository gives no output.
>
> Best Wishes
>
> Phillip
>
>
> >      git status -b --no-ahead-behind --porcelain=v2
> >
> > outputs
> >
> > # branch.oid (initial)
> > # branch.head master
> > # branch.upstream origin/master
> >
> > I.e. it outputs a proper upstream branch.
> >
> > Best regards
> > Ondra
> >
> > Ondra Medek
> >
> >
> > On Tue, 14 Nov 2023 at 13:28, Phillip Wood <phillip.wood123@gmail.com> wrote:
> >>
> >> Hi Ondra
> >>
> >> On 14/11/2023 10:16, Ondra Medek wrote:
> >>> Hello,
> >>> I am working on a tol which should fetch changes from a remote
> >>> repository on a user click. I want to limit fetch on the current
> >>> remote tracking branch (something like "origin/master"), but
> >>> surprisingly, it's hard to get it for all corner cases like a fresh
> >>> clone of an empty repository or detached head, etc. E.g see this SO
> >>> thread https://stackoverflow.com/questions/171550/find-out-which-remote-branch-a-local-branch-is-tracking/52896538
> >>
> >> I think you can do this by calling
> >>
> >>          git symbolic-ref --quiet HEAD
> >>
> >> to get the full refname of the current branch. If HEAD is detached it
> >> will print nothing and exit with exit code 1. Then you can call
> >>
> >>          git for-each-ref --format="%(upstream:short)" $refname
> >>
> >> to get the upstream branch
> >>
> >> Best Wishes
> >>
> >> Phillip
> >
Jeff King· Nov 14, 2023, 20:18 UTC · re: Phillip Wood · lore

Re: Feature request: git status --branch-only

On Tue, Nov 14, 2023 at 03:02:04PM +0000, Phillip Wood wrote:
Show 18 quoted lines
> Hi Ondra
> 
> On 14/11/2023 12:40, Ondra Medek wrote:
> > Hi Phillip,
> > 
> > it does not work for a fresh clone of an empty repository
> > 
> >      git for-each-ref --format="%(upstream:short)" refs/heads/master
> > 
> > outputs nothing, while
> 
> Oh dear, that's a shame. I wonder if it is a bug because the documentation
> says that
> 
> 	--format="%(upstream:track)"
> 
> should print "[gone]" whenever an unknown upstream ref is encountered but
> trying that on a clone of an empty repository gives no output.

I think it would print "gone" if the upstream branch went missing. But in this case the actual local branch is missing. And for-each-ref will not show an entry at all for a ref that does not exist. The "refs/heads/master" on your command line is not a ref, but a pattern, and that pattern does not match anything. So it's working as intended.

I think a more direct tool would be:
  git rev-parse --symbolic-full-name master@{upstream}

That convinces branch_get_upstream() to return the value we want, but sadly it seems to get lost somewhere in the resolution process, and we spit out an error. Arguably that is a bug (with --symbolic or --symbolic-full-name, I think it would be OK to resolve names even if they don't point to something, but it's possible that would have other unexpected side effects).

-Peff
phillip.wood123@gmail.com· Nov 16, 2023, 16:09 UTC · re: Jeff King · lore

Re: Feature request: git status --branch-only

Hi Peff
On 14/11/2023 20:18, Jeff King wrote:
Show 26 quoted lines
> On Tue, Nov 14, 2023 at 03:02:04PM +0000, Phillip Wood wrote:
> 
>> Hi Ondra
>>
>> On 14/11/2023 12:40, Ondra Medek wrote:
>>> Hi Phillip,
>>>
>>> it does not work for a fresh clone of an empty repository
>>>
>>>       git for-each-ref --format="%(upstream:short)" refs/heads/master
>>>
>>> outputs nothing, while
>>
>> Oh dear, that's a shame. I wonder if it is a bug because the documentation
>> says that
>>
>> 	--format="%(upstream:track)"
>>
>> should print "[gone]" whenever an unknown upstream ref is encountered but
>> trying that on a clone of an empty repository gives no output.
> 
> I think it would print "gone" if the upstream branch went missing. But
> in this case the actual local branch is missing. And for-each-ref will
> not show an entry at all for a ref that does not exist. The
> "refs/heads/master" on your command line is not a ref, but a pattern,
> and that pattern does not match anything. So it's working as intended.

Oh of course, I'd somehow forgotten that "refs/heads/master" did not exist so it makes sense that for-each-ref does not print anything.

Show 10 quoted lines
> I think a more direct tool would be:
> 
>    git rev-parse --symbolic-full-name master@{upstream}
> 
> That convinces branch_get_upstream() to return the value we want, but
> sadly it seems to get lost somewhere in the resolution process, and we
> spit out an error. Arguably that is a bug (with --symbolic or
> --symbolic-full-name, I think it would be OK to resolve names even if
> they don't point to something, but it's possible that would have other
> unexpected side effects).

Yeah, maybe we should look at fixing that - I didn't suggest it because I knew it did not work on an unborn branch but as you say there is no obvious reason why it shouldn't

Best Wishes
Phillip
> -Peff

← back to recent threads