threads / discuss / 60428

Repository cloned using SSH does not respect bare repository initial branch

Subject: Repository cloned using SSH does not respect bare repository initial branch

## tl;dr

7 messages between Oct 25, 2023 and Oct 31, 2023.

replies: 6people: 2as markdown or json

Sheik· Oct 25, 2023, 20:36 UTC · lore
Hi Maintainers,

Repository cloned using SSH does not use the branch configured in the bare repository however repository cloned using filesystem does as expected. Shouldn't they both behave the same?

Thanks Sheik

Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue)
#Create bare repository
     su - $user
     git init --bare --initial-branch=test test.git
#Clone repository
     git clone ssh://$user@$computer:/home/$user/test.git test1
     cd test1
     git remote show origin
     #Output [ORIGIN1]
     echo abc >> abc.txt && git add * && git commit -a -m test && git push
     #Output...
     #* [new branch]      master -> master
     git remote show origin
     #Output [ORIGIN2]

What did you expect to happen? (Expected behavior) Repository cloned using ssh should push to test branch just like repository cloned using filesystem does below as configured in the bare repository.

#Clone repository
     git clone home/$user/test.git test2
     git remote show origin
     #Output [ORIGIN3]
     echo abc >> abc.txt && git add * && git commit -a -m test && git push
     #Output...
     #* [new branch]      test -> test
     git remote show origin
     #Output [ORIGIN4]

What happened instead? (Actual behavior) Repository cloned using ssh pushed to master branch disregarding configuration in bare repository.

What's different between what you expected and what actually happened? For ssh cloned repository test branch should been the default branch however master was the default.

Anything else you want to add:
[ORIGIN1]
* remote origin
   HEAD branch: (unknown)
   Local branch configured for 'git pull':
     master merges with remote master
[ORIGIN2]
* remote origin
   HEAD branch: (unknown)
   Remote branch:
     master tracked
   Local branch configured for 'git pull':
     master merges with remote master
   Local ref configured for 'git push':
     master pushes to master (up to date)
[ORIGIN3]
* remote origin
   HEAD branch: (unknown)
   Local branch configured for 'git pull':
     test merges with remote test
[ORIGIN4]
* remote origin
   HEAD branch: test
   Remote branches:
     master new (next fetch will store in remotes/origin)
     test   tracked
   Local branch configured for 'git pull':
     test merges with remote test
   Local ref configured for 'git push':
     test pushes to test (up to date)

Please review the rest of the bug report below. You can delete any lines you don't wish to share.

[System Info] git version: git version 2.42.0 cpu: x86_64 no commit associated with this build sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh uname: Linux 6.5.0-2-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.5.6-1 (2023-10-07) x86_64 compiler info: gnuc: 13.2 libc info: glibc: 2.37 $SHELL (typically, interactive shell): /bin/bash

[Enabled Hooks]
Jeff King· Oct 30, 2023, 09:36 UTC · re: Sheik · lore

Re: Repository cloned using SSH does not respect bare repository initial branch

On Thu, Oct 26, 2023 at 07:36:36AM +1100, Sheik wrote:
> Repository cloned using SSH does not use the branch configured in the bare
> repository however repository cloned using filesystem does as expected.
> Shouldn't they both behave the same?
What version of Git is running on the ssh server?

Your example seems to show that the parent repository has an unborn branch (i.e., HEAD points to "refs/heads/test", but there are no commits yet). I think the server-side bits you need for that to work showed up in 59e1205d16 (ls-refs: report unborn targets of symrefs, 2021-02-05), which is in v2.31.

So even though your client seems to be v2.42 (from the output you gave), if the server is older it may not be sending sufficient information. There were also some other fixes on top of that, but I _think_ they were all client-side (so your v2.42 clone command should be doing the right thing).

-Peff
Sheik· Oct 30, 2023, 15:24 UTC · re: Jeff King · lore

Re: Repository cloned using SSH does not respect bare repository initial branch

Server version is same as client (v2.42.0) as I ran these commands all on the same machine.

Test on ssh server:
$ git -v --build-options
#Output

git version 2.42.0 cpu: x86_64 no commit associated with this build sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh

Thanks
Sheik
On 30/10/23 20:36, Jeff King wrote:
Show 20 quoted lines
> On Thu, Oct 26, 2023 at 07:36:36AM +1100, Sheik wrote:
>
>> Repository cloned using SSH does not use the branch configured in the bare
>> repository however repository cloned using filesystem does as expected.
>> Shouldn't they both behave the same?
> What version of Git is running on the ssh server?
>
> Your example seems to show that the parent repository has an unborn
> branch (i.e., HEAD points to "refs/heads/test", but there are no commits
> yet). I think the server-side bits you need for that to work showed up
> in 59e1205d16 (ls-refs: report unborn targets of symrefs, 2021-02-05),
> which is in v2.31.
>
> So even though your client seems to be v2.42 (from the output you gave),
> if the server is older it may not be sending sufficient information.
> There were also some other fixes on top of that, but I _think_ they were
> all client-side (so your v2.42 clone command should be doing the right
> thing).
>
> -Peff
Jeff King· Oct 30, 2023, 17:43 UTC · re: Sheik · lore

Re: Repository cloned using SSH does not respect bare repository initial branch

On Tue, Oct 31, 2023 at 02:24:46AM +1100, Sheik wrote:
> Server version is same as client (v2.42.0) as I ran these commands all on
> the same machine.
OK. The next thing I'd check is running both commands with:
  GIT_TRACE_PACKET=1 git clone ...

to see the protocol trace, and how it differs between the two. What I suspect you may see is that the local clone is using the "v2" protocol (a capabilities report, followed by "ls-refs", which mentions the symref value of HEAD), and the ssh one uses the older "v0" (it goes straight to the ref advertisement).

Quoting from 59e1205d16 (ls-refs: report unborn targets of symrefs, 2021-02-05), the commit I mentioned before:

    This change is only for protocol v2. A similar change for protocol
    v0 would require independent protocol design (there being no
    analogous position to signal support for "unborn") and client-side
    plumbing of the data required, so the scope of this patch set is
    limited to protocol v2.

So in v0 the server doesn't pass back sufficient information for the client to know about the name of the unborn HEAD branch.

If that's the culprit, the next question of course is why we'd do v2 locally versus v0 overssh. And that probably has to do with how we trigger the protocol upgrade. To see if the server supports v2, the client passes extra information "out of band". For git-over-http, this happens in an extra HTTP header. For local repositories, it happens in an environment variable ($GIT_PROTOCOL). For git-over-ssh it happens in that sameenvironment variable, which we instruct the ssh client to pass using "-o SendEnv". But:

  1. If your ssh client doesn't look like openssh, we don't know if it
     supports "-o" and may skip it. See the discussion in ssh.variant in
     "git help config".
  2. Some servers need to be configured to allow the client to set
     environment variables. In the case of openssh, you'd want a line
     like this in your sshd_config file:
       AcceptEnv GIT_PROTOCOL

Of the two, I'd guess that the second one is more likely to be your problem (since you're running Linux, where openssh is the norm).

-Peff
Sheik· Oct 30, 2023, 23:30 UTC · re: Jeff King · lore

Re: Repository cloned using SSH does not respect bare repository initial branch

On 31/10/23 04:43, Jeff King wrote:
Show 49 quoted lines
> On Tue, Oct 31, 2023 at 02:24:46AM +1100, Sheik wrote:
>
>> Server version is same as client (v2.42.0) as I ran these commands all on
>> the same machine.
> OK. The next thing I'd check is running both commands with:
>
>    GIT_TRACE_PACKET=1 git clone ...
>
> to see the protocol trace, and how it differs between the two. What I
> suspect you may see is that the local clone is using the "v2" protocol
> (a capabilities report, followed by "ls-refs", which mentions the symref
> value of HEAD), and the ssh one uses the older "v0" (it goes straight to
> the ref advertisement).
>
> Quoting from 59e1205d16 (ls-refs: report unborn targets of symrefs,
> 2021-02-05), the commit I mentioned before:
>
>      This change is only for protocol v2. A similar change for protocol
>      v0 would require independent protocol design (there being no
>      analogous position to signal support for "unborn") and client-side
>      plumbing of the data required, so the scope of this patch set is
>      limited to protocol v2.
>
> So in v0 the server doesn't pass back sufficient information for the
> client to know about the name of the unborn HEAD branch.
>
> If that's the culprit, the next question of course is why we'd do v2
> locally versus v0 overssh. And that probably has to do with how we
> trigger the protocol upgrade. To see if the server supports v2, the
> client passes extra information "out of band". For git-over-http, this
> happens in an extra HTTP header. For local repositories, it happens in
> an environment variable ($GIT_PROTOCOL). For git-over-ssh it happens in
> that sameenvironment variable, which we instruct the ssh client to pass
> using "-o SendEnv". But:
>
>    1. If your ssh client doesn't look like openssh, we don't know if it
>       supports "-o" and may skip it. See the discussion in ssh.variant in
>       "git help config".
>
>    2. Some servers need to be configured to allow the client to set
>       environment variables. In the case of openssh, you'd want a line
>       like this in your sshd_config file:
>
>         AcceptEnv GIT_PROTOCOL
>
> Of the two, I'd guess that the second one is more likely to be your
> problem (since you're running Linux, where openssh is the norm).
>
> -Peff

Thanks Jeff, tracing and setting the AcceptEnv indeed did the trick and workflow now works as expected.

Test steps on Debian/OpenSsh:
Server
1. Edit /etc/ssh/sshd_config
2. Add AcceptEnv GIT_PROTOCOL
3. systemctl restart sshd
Client
1. Enable ssh logging:
    export GIT_SSH_COMMAND=ssh -v
2. git clone ...
3. Output from ssh shows variable being sent (although regardless if 
AcceptEnv was set or not):
    debug1: channel 0: setting env GIT_PROTOCOL = "version=2"
    debug2: channel 0: request env confirm 0
References
1. 
https://git-scm.com/docs/git/2.42.0#Documentation/git.txt-codeGITPROTOCOLcode 
2. https://git-scm.com/docs/gitprotocol-v2#_ssh_and_file_transport
3. 
https://git-scm.com/docs/git/2.42.0#Documentation/git.txt-codeGITSSHCOMMANDcode 

Thanks Sheik

Sheik· Oct 31, 2023, 02:38 UTC · re: Sheik · lore

Re: Repository cloned using SSH does not respect bare repository initial branch

Wondering whether a link to the protocol documentation should be added in "git init --initial-branch" to make this more obvious.

 1. https://git-scm.com/docs/git-init#Documentation/git-init.txt---initial-branchltbranch-namegt
 2. https://git-scm.com/docs/gitprotocol-v2
Thanks
Sheik
Sheik· Oct 30, 2023, 15:33 UTC · re: Jeff King · lore

Re: Repository cloned using SSH does not respect bare repository initial branch

On 30/10/23 20:36, Jeff King wrote:
Show 20 quoted lines
> On Thu, Oct 26, 2023 at 07:36:36AM +1100, Sheik wrote:
>
>> Repository cloned using SSH does not use the branch configured in the bare
>> repository however repository cloned using filesystem does as expected.
>> Shouldn't they both behave the same?
> What version of Git is running on the ssh server?
>
> Your example seems to show that the parent repository has an unborn
> branch (i.e., HEAD points to "refs/heads/test", but there are no commits
> yet). I think the server-side bits you need for that to work showed up
> in 59e1205d16 (ls-refs: report unborn targets of symrefs, 2021-02-05),
> which is in v2.31.
>
> So even though your client seems to be v2.42 (from the output you gave),
> if the server is older it may not be sending sufficient information.
> There were also some other fixes on top of that, but I _think_ they were
> all client-side (so your v2.42 clone command should be doing the right
> thing).
>
> -Peff

Confirming your observation above, yes this is a purely new bare repository which has no commits yet before cloning.

Thanks
Sheik

← back to recent threads