Avleen
Avleen

Reputation: 252

Auto-committing git submodule hash in super-project

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?

Upvotes: 10

Views: 2917

Answers (2)

Daniel Zhang
Daniel Zhang

Reputation: 5858

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"

Upvotes: 3

Adam Dymitruk
Adam Dymitruk

Reputation: 129594

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.

Upvotes: 6

Related Questions