# Revision ref '@{push}' not resolved as documented

3 messages from 2023-04-02 to 2023-04-03. Participants: Alexandre Garnier, Felipe Contreras, Junio C Hamano.
Thread: https://gitlist.dev/t/59524

## Alexandre Garnier, 2023-04-02 15:16

Subject: Revision ref '@{push}' not resolved as documented
Message-ID: <CAFFOgCUs9d6wJDf3p-+8UkzXRSymCgBctGt+rP+k0CzZPp2LJw@mail.gmail.com>
URL: https://gitlist.dev/e/CAFFOgCUs9d6wJDf3p-%2B8UkzXRSymCgBctGt%2BrP%2Bk0CzZPp2LJw%40mail.gmail.com

```
Hi!

I followed the example of ref '@{push}' in the documentation of
'rev-parse' (https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt-emltbranchnamegtpushemegemmasterpushemempushem)
and it doesn't work as documented.
Here is a way to reproduce:

# Setup
$ git init --bare origin.git
$ git clone --bare origin.git myfork.git
$ git clone origin.git local
$ cd local/
$ git commit --allow-empty -m init
$ git push origin
$ git remote add myfork ../myfork.git

# Check for
$ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/main
$ git rev-parse --symbolic-full-name @{push}
refs/remotes/origin/main

# Follow doc's example
$ git config push.default current
$ git config remote.pushdefault myfork
$ git switch -c mybranch origin/main
$ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/main
$ git rev-parse --symbolic-full-name @{push}  # should be
refs/remotes/myfork/mybranch
@{push}
fatal: ambiguous argument '@{push}': unknown revision or path not in
the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

# Push is done with the expected remote, and only then the ref can be resolved
$ git push
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To ../myfork.git
* [new branch] mybranch -> mybranch
$ git rev-parse --symbolic-full-name @{push}
refs/remotes/myfork/mybranch

So it means the branch has to exist in the remote to resolve '@{push}'
as a symbolic ref?
I think I remember that a few years ago the example was working as-is
without the need to push.

If this is the expected behavior (not the best IMHO as it was a way to
check where it is going to be pushed before doing it), documentation
of the ref needs to be updated I think.

Regards,
-- 
Alex Garnier

```

## Felipe Contreras, 2023-04-02 18:41

Subject: Re: Revision ref '@{push}' not resolved as documented
Message-ID: <CAMP44s0ujDcosdU2yDz-o7G8aCswEkpTP=Bfnjgt+5p=D4iHJw@mail.gmail.com>
URL: https://gitlist.dev/e/CAMP44s0ujDcosdU2yDz-o7G8aCswEkpTP%3DBfnjgt%2B5p%3DD4iHJw%40mail.gmail.com
In-Reply-To: <CAFFOgCUs9d6wJDf3p-+8UkzXRSymCgBctGt+rP+k0CzZPp2LJw@mail.gmail.com>

```
On Sun, Apr 2, 2023 at 10:41 AM Alexandre Garnier <zigarn@gmail.com> wrote:

> # Push is done with the expected remote, and only then the ref can be resolved
> $ git push
> Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
> To ../myfork.git
> * [new branch] mybranch -> mybranch
> $ git rev-parse --symbolic-full-name @{push}
> refs/remotes/myfork/mybranch
>
> So it means the branch has to exist in the remote to resolve '@{push}'
> as a symbolic ref?

It has to exist as a ref.

This is not just for @{push}, same with @{upstream}:

% git config branch.master.merge refs/heads/foobar

Now `master@{upstream}` doesn't work.

> I think I remember that a few years ago the example was working as-is
> without the need to push.

You don't need to push, you can fetch, but the remote ref has to
exist, and I think it has always been that way.

Cheers.

-- 
Felipe Contreras

```

## Junio C Hamano, 2023-04-03 16:51

Subject: Re: Revision ref '@{push}' not resolved as documented
Message-ID: <xmqqh6tw7vtu.fsf@gitster.g>
URL: https://gitlist.dev/e/xmqqh6tw7vtu.fsf%40gitster.g
In-Reply-To: <CAFFOgCUs9d6wJDf3p-+8UkzXRSymCgBctGt+rP+k0CzZPp2LJw@mail.gmail.com>

```
Alexandre Garnier <zigarn@gmail.com> writes:

> # Push is done with the expected remote, and only then the ref can be resolved
> $ git push
> Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
> To ../myfork.git
> * [new branch] mybranch -> mybranch
> $ git rev-parse --symbolic-full-name @{push}
> refs/remotes/myfork/mybranch

This one is expected.

I think the root cause of this confusion is that the "rev-parse"
command, even with "--symbolic" or "--symbolic-full-name", is still
about answering a question about an existing object name.  If
"rev-parse X" fails because X does not spell a valid object name,
"rev-parse --symbolic-full-name X" is designed to fail the same way.

I am not sure how involved the implementation to change the above
design to be offhand.  The general flow of rev-parse is to feed an
end-user supplied string to the object-name layer and ask it to be
turned into an object name, and "--symbolic-full" must be stopping
that flow after the original string is canonicalized (e.g. 'master'
is turned into 'refs/heads/master') but before it is turned into an
object name, in order to be able to return 'refs/heads/master'.  I
would not be surprised if it wasn't to hard to special case the
"--symbolic" request to yield an unborn branch name like you
expected, but it would change the semantics and breaks backward
compatibility, so care must be taken if anybody wants to pursue
this.

Thanks.



```
