10

When you commit in a git submodule, you need to go up to the super-project to do a second commit, which is the new hash of the submodule.

This is incredibly annoying, easy to forget and can cause all manner of problems if you don't do it.

What I want to do is:

  1. Commit the changes in my submodule
  2. Have the hash committed automatically in the super-project
  3. Have both the submodule and the super-project pushed to their remote-origin ('git push')

What's the best way to figure out if you're in a submodule, where the super-project is, etc and automate this?

Maybe some kind of post-commit hook in the submodule?

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
Avleen
  • 252
  • 2
  • 7

2 Answers2

6

Have you tried git-slave? This is exactly what it's designed to do.

You can also script that yourself. Be aware that there are 2 options on the git command itself that can help greatily: --work-tree and --git-dir. Using these you can act on any repo without leaving the current directory.

Then there is also git submodule foreach --recursive git push.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • strange, zero upvotes? +1, at least. I don't know about any of these commands ;) – Dan Rosenstark Apr 08 '13 at 23:53
  • The command-line options did not seem to work, for me, when attempting to operate on a superproject. This may be due to the way the Git environment is handled when in a submodule. – Daniel Zhang Feb 28 '20 at 04:04
3

While submodules may not be optimized for this usage, having a submodule of submodules can be a solution to maintaining a single point of access to multiple independent projects.

This has served needs such as those that arise when implementing a monorepo. Automating a superproject commit on every submodule update can alleviate a mostly administrative step when adopting such a setup.

I have pieced together a post-commit hook that is fairly straightforward for automatically updating the superproject on every commit in a submodule.

#!/bin/bash
#
# Update a superproject when a commit is made to a submodule.
# Intended for .git/**modules/{THE_SUBMODULE}/hooks/post-commit
# where the double-star indicates variadic path elements.
#
# Depends on Git >= 2.13.

# Clean the Git environment before crossing repository boundaries.
# From https://stackoverflow.com/questions/36196548/cannot-trigger-post-commit-git-hook-on-git-submodule
while read variable; do
    unset $variable
done < <(env | grep "^GIT_" | sed 's/=.*//g')

COMMIT_MSG="submodule update"
GIT="git"
SUPERPROJECT_WORKING_TREE=`git rev-parse --show-superproject-working-tree`
echo " Committing to $SUPERPROJECT_WORKING_TREE."
cd $SUPERPROJECT_WORKING_TREE
$GIT add .
$GIT commit -m "$COMMIT_MSG"
Daniel Zhang
  • 5,778
  • 2
  • 23
  • 28