MvG
MvG

Reputation: 60868

Auto-update submodule

I'd like to automatically update a git submodule as part of our build system whenever it is out of sync, i.e. if the checked-out version is not the same as the version recorded in the tree.

Currently I do git submodule status ‹path› and check whether the first character of the resulting output is a space (in sync) or something else (- for not initialized, + for out-of-sync commit, or U for merge conflicts).

Is there some cheaper (in terms of execution time) command to obtain this information? Can I perhaps compare timestamps of two suitably chosen files to determine whether the submodule is in need of an update?

Upvotes: 2

Views: 1287

Answers (2)

MvG
MvG

Reputation: 60868

The git submodule command is implemented as a shell script, although it does request some help from git submodule--helper. The relevant line for the issue at hand is this:

git diff-files --ignore-submodules=dirty --quiet -- "$sm_path"

This distinguishes a matching commit (space in git submodule status) from a differing one (+ in status). There are other pieces of code which come before and serve to detect U conflicts (with the help of git submodule--helper) or - uninitialized submodules.

In my experiments, the case of conflicts (i.e. a merge in the parent repo had conflicting inputs on what commit to use for the submodule) led to a non-zero exit status for the diff-files command as well. An uninitialized repository was not reported, though. So I'd suggest the following commands to check whether a submodule is up to date:

test -f "$sm_path/.git" -o -d "$sm_path/.git" && \
git diff-files --ignore-submodules=dirty --quiet -- "$sm_path"

Upvotes: 2

pathfinderelite
pathfinderelite

Reputation: 3137

I'm not sure this answers your question(s), but it might serve to obtain your ultimate goal:

git submodule update --checkout [<submodule>]

This will checkout the submodule version which is stored in the tree, unless the already checked-out submodule has modifications which conflict, in which case it will abort.

You could add this as a post-checkout hook to do it automatically.

And if you like living dangerously, you could use the following to reset the submodule(s) prior to checkout, so as to avoid conflicts when checking-out the new version.

git submodule foreach git reset --hard HEAD
git submodule foreach git clean -f

Of course, that will wipe any changes you have in your submodules, so use with caution.

Upvotes: 1

Related Questions