Verification of submodules initialization [Git]
Asked Answered
S

3

10

Recently I started using git submodules in my project. One of my scripts creates a repo with submodules. I would like to create a function which checks if the submodules were initialized successfully.

What are good indications to verify?

I guess, we first should check if there is a .git directory in the main repo. Then I should check each submodule, but for what?

Hope my question is understandable, if not, I would glad to specify more.

Spiros answered 17/6, 2018 at 15:15 Comment(0)
T
3

The git submodule status command outputs a parseable line for each submodule:

status [--cached] [--recursive] [--] [<path>...]
    Show the status of the submodules. This will print the SHA-1 of the currently checked out commit for each
    submodule, along with the submodule path and the output of git describe for the SHA-1. Each SHA-1 will
    possibly be prefixed with - if the submodule is not initialized, + if the currently checked out submodule
    commit does not match the SHA-1 found in the index of the containing repository and U if the submodule has
    merge conflicts.

If you just want to know that each submodule is initialized, it would suffice to do:

if git submodule status | grep --quiet '^-'; then
    echo "A git submodule is not initialized."
fi
Torture answered 15/11, 2022 at 22:11 Comment(0)
K
1

I would do e.g.

git submodule foreach status and git submodule summary

and double check the .gitmodules file in the parent repository.

Karoline answered 17/6, 2018 at 20:9 Comment(0)
U
0

To better parse git submodule summary, use Git 2.21 (Feb. 2019): The "git submodule summary" subcommand showed shortened commit object names by mechanically truncating them at 7-hexdigit, which has been improved to let "rev-parse --short" scale the length of the abbreviation with the size of the repository.

See commit 0586a43 (03 Feb 2019) by Sven van Haastregt (svenvh).
(Merged by Junio C Hamano -- gitster -- in commit 257507a, 07 Feb 2019)

git-submodule.sh: shorten submodule SHA-1s using rev-parse

Until now, git submodule summary was always emitting 7-character SHA-1s that have a higher chance of being ambiguous for larger repositories.
Use git rev-parse --short instead, which will determine suitable short SHA-1 lengths.

When a submodule hasn't been initialized with "submodule init" or not cloned, git rev-parse would not work in it yet; as a fallback, use the original method of cutting at 7 hexdigits.


Note that With Git 2.29 (Q4 2020), git submodule summary from "git submodule"(man) is getting rewritten in C.

It is no longer part of git-submodule.sh.

See commit e83e333 (13 Aug 2020) by Prathamesh Chavan (pratham-pc).
See commit ede8a5b, commit 180b154, commit 6414c3d (13 Aug 2020) by Shourya Shukla (periperidip).
(Merged by Junio C Hamano -- gitster -- in commit bbdba3d, 09 Sep 2020)

submodule: port submodule subcommand 'summary' from shell to C

Mentored-by: Christian Couder
Mentored-by: Stefan Beller
Mentored-by: Kaartic Sivaraam
Helped-by: Johannes Schindelin
Signed-off-by: Prathamesh Chavan
Signed-off-by: Shourya Shukla

Convert submodule subcommand 'summary' to a builtin and call it via 'git-submodule.sh'.

The shell version had to call $diff_cmd twice, once to find the modified modules cared by the user and then again, with that list of modules to do various operations for computing the summary of those modules.

On the other hand, the C version does not need a second call to $diff_cmd since it reuses the module list from the first call to do the aforementioned tasks.

In the C version, we use the combination of setting a child process' working directory to the submodule path and then calling 'prepare_submodule_repo_env()' which also sets the 'GIT_DIR' to '.git', so that we can be certain that those spawned processes will not access the superproject's ODB by mistake.

A behavioural difference between the C and the shell version is that the shell version outputs two line feeds after the 'git log(man)' output when run outside of the tests while the C version outputs one line feed in any case.
The reason for this is that the shell version calls log with '--pretty=format:<fmt>' whose output is followed by two echo calls; 'format' does not have "terminator" semantics like its 'tformat' counterpart.
So, the log output is terminated by a newline only when invoked by the user and not when invoked from the scripts.

This results in the one & two line feed differences in the shell version.

On the other hand, the C version calls log with '--pretty=<fmt>' which is equivalent to '--pretty:tformat:<fmt>' which is then followed by a 'printf("\n")'.
Due to its "terminator" semantics the log output is always terminated by newline and hence one line feed in any case.

Also, when we try to pass an option-like argument after a non-option argument, for instance:

git submodule summary HEAD --foo-bar  

(or)  

git submodule summary HEAD --cached  

That argument would be treated like a path to the submodule for which the user is requesting a summary.
So, the option ends up having no effect.
Though, passing '--quiet' is an exception to this:

git submodule summary HEAD --quiet  

While 'summary' doesn't support '--quiet', we don't get an output for the above command as '--quiet' is treated as a path which means we get an output only if a submodule whose path is '--quiet' exists.

The error message in case of computing a summary for non-existent submodules in the C version is different from that of the shell version.

Undercroft answered 9/3, 2019 at 23:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.