Search code examples
gitwindows-subsystem-for-linuxgit-submodules

Prevent Submodule Recursion on Initial "git pull"


Every day in WSL, the first time I run git pull in a repository with submodules, it does a bunch of extra stuff by recursing into the submodules. When doing this, it inevitably fails. Then I have to run a second git pull, which results in only updating the root repository. How can I configure git so the recursion doesn't happen on the first (or any other) call?

This is the output generated the first time I call git pull:

user@computer:/path/repo$ git pull
remote: Enumerating objects: 5254, done.
remote: Counting objects: 100% (2042/2042), done.
remote: Compressing objects: 100% (741/741), done.
remote: Total 1276 (delta 737), reused 893 (delta 483), pack-reused 0 (from 0)
Receiving objects: 100% (1276/1276), 2.45 MiB | 4.85 MiB/s, done.
Resolving deltas: 100% (737/737), completed with 361 local objects.
From url:repo
   [update list]
Fetching submodule [submodule name]
fatal: git upload-pack: not our ref [commit hash]
fatal: remote error: upload-pack: not our ref [commit hash]
Errors during submodule fetch:
        [submodule name]

I have confirmed that the output of git config -l does NOT include an entry for submodule.recurse or fetch.recursesubmodules. My git version is 2.34.1, WSL OS version is Ubuntu 22.04.

My .gitmodules submodule configuration file in the root repository looks like the following:

[submodule "name1"]
        path = submod1
        url = ../submod1.git
        branch = dev
[submodule "name2"]
        path = submod2
        url = ../submod2.git
        branch = dev
[submodule "name3"]
        path = submod3
        url = ../submod3-different-name.git
        branch = dev

Solution

  • Fetching submodule [submodule name]
    fatal: git upload-pack: not our ref [commit hash]
    fatal: remote error: upload-pack: not our ref [commit hash]
    Errors during submodule fetch:
           [submodule name]
    

    This error can happen if in one of the fetched superproject commits, the submodule is recorded at a commit that does not exist on the configured submodule remote.

    Either (most likely) this submodule commit was never pushed to the submodule remote, or (less likely) it was pushed but is not reachable from any ref anymore and thus was garbage-collected. I say "less likely" because most big Git hosting providers run garbage-collection very rarely, if ever.

    As mentioned in the comments, git fetch defaults to --recurse-submodules=on-demand, so to completely disable submodule fetches you should explicitely set it to off. Note that in this case you must ensure to update submodules after your git pull: git submodule update --init --recursive. But a better option would be to not push superproject commits that reference a submodule commit that is not pushed, if that is the root cause of the problem.