threads / discuss / 53091

Checking Out Branches Containing Submodules With update=none and submodule.recurse=true Fails With fatal:not a git repository

Subject: Checking Out Branches Containing Submodules With update=none and submodule.recurse=true Fails With fatal:not a git repository

## tl;dr

2 messages between Mar 25, 2020 and Oct 7, 2020.

replies: 1people: 2as markdown or json

daniel mclean· Mar 25, 2020, 04:19 UTC · lore
Hello git developers,
Firstly thanks for a great tool!
I have run into an issue that it would be good to get your advice on.

I have a git repository with multiple submodules. A few of these submodules are configured with update=none so that they point to a specific commit but so that clone operations and submodule update operations don't retrieve their contents.

When working with this repository and trying to change branches, git is reporting a fatal error when changing branches. This can be worked around by deinit'ing the submodules before switching branches but that doesn't seem like it should be necessary.

The reproduction steps are to:
- Clone the repo
- Checkout a branch containing submodules that are set with
update=none (git checkout branch-name)
- Update and init submodules (git submodule update --init)
- Attempt to switch to a different branch (git checkout other-branch)

At this point git will report an error at the first submodule with update=none: fatal: not a git repository: ../.git/modules/no-update-submodule fatal: could not reset submodule index

After doing some sleuthing it seems that this is because when update=none the submodule repository is not cloned to .git/module/<module name>, however when attempting to change branches using a checkout, git then stumbles since it expects the repository to be there.

This seems obvious when run with GIT_TRACE=1, git fails when it attempts to run the read-tree command:

19:20:18.129343 run-command.c:663 trace: run_command: cd no-update-submodule; unset GIT_PREFIX; GIT_DIR=.git git --super-prefix= no-update-submodule/ read-tree -u --reset 4b825dc642cb6eb9a060e54bf8d69288fbee4904 fatal: not a git repository: ../.git/modules/no-update-submodule fatal: could not reset submodule index

If my understanding of how update=none for a submodule and git is correct, then it seems like it shouldn't be trying to do this since it should know that the repository isn't there (update=none after all). This behaviour occurs when I have submodule.recurse set to true, however interestingly when I set it to false I don't run into this issue. So it seems like these two directives are providing mixed messages in a sense, one says don't clone the submodule repo and the other says look into the submodule repo and try to find more submodules.

I've tried the 2.20 version of git that comes prepackaged with my OS and built git 2.26 from source with the same outcome. I'm running on Debian stretch on x64 in case that matters.

I'm happy to pursue trying to suggest a fix for this, but am new to the git codebase and so would appreciate some feedback on whether this is in fact an issue and some advice on how to best approach a solution.

Thanks Daniel

Philippe Blain· Oct 7, 2020, 21:29 UTC · re: daniel mclean · lore

Re: Checking Out Branches Containing Submodules With update=none and submodule.recurse=true Fails With fatal:not a git repository

Hi Daniel, 
Show 28 quoted lines
> Le 25 mars 2020 à 00:19, daniel mclean <maczor@gmail.com> a écrit :
> 
> Hello git developers,
> 
> Firstly thanks for a great tool!
> 
> I have run into an issue that it would be good to get your advice on.
> 
> I have a git repository with multiple submodules.  A few of these
> submodules are configured with update=none so that they point to a
> specific commit but so that clone operations and submodule update
> operations don't retrieve their contents.
> 
> When working with this repository and trying to change branches, git
> is reporting a fatal error when changing branches.  This can be worked
> around by deinit'ing the submodules before switching branches but that
> doesn't seem like it should be necessary.
> 
> The reproduction steps are to:
> - Clone the repo
> - Checkout a branch containing submodules that are set with
> update=none (git checkout branch-name)
> - Update and init submodules (git submodule update --init)
> - Attempt to switch to a different branch (git checkout other-branch)
> 
> At this point git will report an error at the first submodule with update=none:
> fatal: not a git repository: ../.git/modules/no-update-submodule
> fatal: could not reset submodule index
I tried reproducing this with the following script, but it does not fail for me:

``` !/bin/bash

set -x

create_repo () { name=$1 rm -rf $name git init $name cd $name date>>file git add file git commit -m "add file" cd ../ }

create_repo super create_repo sub1 create_repo sub2

cd super git submodule add ../sub1 git submodule add ../sub2 git config -f .gitmodules submodule.sub1.update none git add .gitmodules git commit -m "add sub1 and sub2" git co -b other-branch date>>file git add file git commit -m "update file" git checkout master cd ../

rm -rf clone git clone super clone cd clone git submodule update --init git config submodule.recurse true git checkout other-branch # no error ! ls -R ```

If you could try to come up with a similar reproducer, it would help to better diagnose this failure. I was not sure by reading your message if both branches involved had the same number of submodules, or the same 'update' settings for each submodules, so maybe that's where your use case differs from my script.

> After doing some sleuthing it seems that this is because when
> update=none the submodule repository is not cloned to
> .git/module/<module name>,
I gather that's the expected behaviour, no ?
> however when attempting to change branches
> using a checkout, git then stumbles since it expects the repository to
> be there.

I've seen that happen when going from a commit where the submodule does not exist to a commit where it does exist, (see [1], [2]), but your situation is a little different.

Show 9 quoted lines
> If my understanding of how update=none for a submodule and git is
> correct, then it seems like it shouldn't be trying to do this since it
> should know that the repository isn't there (update=none after all).
> This behaviour occurs when I have submodule.recurse set to true,
> however interestingly when I set it to false I don't run into this
> issue.
> So it seems like these two directives are providing mixed messages in
> a sense, one says don't clone the submodule repo and the other says
> look into the submodule repo and try to find more submodules.

From reading the documentation of `submodule.<name>.update` [3], it seems that `git checkout` should not care about this config setting, but in my script above, it seems it does (at least for the value "none"), or else it would crash as you describe... I've not looked at the code in depth, but I might if you can come up with a reproducer.

Cheers,
Philippe.

[1] https://lore.kernel.org/git/CAE5ih78zCR0ZdHAjoxguUb3Y6KFkZcoxJjhS7rkbtZpr+d1n=g@mail.gmail.com/ [2] https://lore.kernel.org/git/20200501005432.h62dnpkx7feb7rto@glandium.org/T/#u [3] https://git-scm.com/docs/git-config#Documentation/git-config.txt-submoduleltnamegtupdate

← back to recent threads