Subject: Re: [BUG] fetching all remote branches results in failed multiple updates

From: Alexander Huynh <[email-masked]>
Date: Wed, 13 Mar 2019 23:45:24 +0000

Hi all,

I appreciate the help offered in identifying what I was doing incorrectly.

Upon further investigation, I remembered why I added the original
`origin.fetch` parameter: I was compensating for shallow clones not fetching
all remote refs.

Here's the use case that I have:

    [root@chabuduo ~]# useradd -m git-test -s /bin/bash
    [root@chabuduo ~]# sudo --preserve-env=SSH_AUTH_SOCK -u git-test -i
    [git-test@chabuduo ~]$ git clone --depth=1 [email-masked]:git/git.git
    Cloning into 'git'...
    The authenticity of host 'github.com (192.30.255.112)' can't be established.
    RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'github.com,192.30.255.112' (RSA) to the list of known hosts.
    remote: Enumerating objects: 3664, done.
    remote: Counting objects: 100% (3664/3664), done.
    remote: Compressing objects: 100% (3282/3282), done.
    remote: Total 3664 (delta 276), reused 1921 (delta 232), pack-reused 0
    Receiving objects: 100% (3664/3664), 8.31 MiB | 9.61 MiB/s, done.
    Resolving deltas: 100% (276/276), done.
    [git-test@chabuduo ~]$ cd git/
    [git-test@chabuduo git]$ git branch -a
    * master
      remotes/origin/HEAD -> origin/master
      remotes/origin/master

Running a shallow clone results in only the remote `HEAD` ref being fetched,
as observed by the last `git branch -a`.

No additional refs are fetched, even when promoting the shallow repository to
a full one:

    [git-test@chabuduo git]$ git pull --unshallow
    remote: Enumerating objects: 255783, done.
    remote: Counting objects: 100% (255777/255777), done.
    remote: Compressing objects: 100% (62079/62079), done.
    remote: Total 253423 (delta 193725), reused 249056 (delta 189413), pack-reused 0
    Receiving objects: 100% (253423/253423), 94.28 MiB | 33.96 MiB/s, done.
    Resolving deltas: 100% (193725/193725), completed with 2155 local objects.
    remote: Enumerating objects: 709, done.
    remote: Total 709 (delta 0), reused 0 (delta 0), pack-reused 709
    Receiving objects: 100% (709/709), 363.70 KiB | 12.12 MiB/s, done.
    From github.com:git/git
     * [new tag]             gitgui-0.10.0    -> gitgui-0.10.0
     * [new tag]             gitgui-0.10.1    -> gitgui-0.10.1
    ...
    Already up to date.
    [git-test@chabuduo git]$ git branch -a
    * master
      remotes/origin/HEAD -> origin/master
      remotes/origin/master

How I've managed to work around the issue is by force fetching all refs, as
explained in the example at https://git-scm.com/docs/git-fetch#CRTB:

    [git-test@chabuduo git]$ git fetch origin '+refs/heads/*:refs/remotes/origin/*'
    remote: Enumerating objects: 1218, done.
    remote: Counting objects: 100% (1218/1218), done.
    remote: Total 7699 (delta 1218), reused 1218 (delta 1218), pack-reused 6481
    Receiving objects: 100% (7699/7699), 4.31 MiB | 17.22 MiB/s, done.
    Resolving deltas: 100% (4881/4881), completed with 435 local objects.
    From github.com:git/git
     * [new branch]            maint      -> origin/maint
     * [new branch]            next       -> origin/next
     * [new branch]            pu         -> origin/pu
     * [new branch]            todo       -> origin/todo

This populates the missing references from a shallow clone:

    [git-test@chabuduo git]$ git branch -a
    * master
      remotes/origin/HEAD -> origin/master
      remotes/origin/maint
      remotes/origin/master
      remotes/origin/next
      remotes/origin/pu
      remotes/origin/todo

I've created an alias that allows for filling out refs for future shallow
clones:

    % git config --global alias.fetcha '!f() { remote="${1:-origin}"; git fetch "$remote" "+refs/heads/*:refs/remotes/$remote/*"; }; f'

I'm also interested in more efficient ways to obtain all refs from shallow
clones, if anyone has better ideas.

Thanks for taking the time to help me understand,
Alex