From: Andy Parkins <andyparkins@gmail.com>
To: git@vger.kernel.org
Subject: [RFC/PATCH] Implement poor-man's submodule support using commit hooks
Date: Wed, 20 Dec 2006 13:09:01 +0000 [thread overview]
Message-ID: <200612201309.02119.andyparkins@gmail.com> (raw)
Make a file called .gitmodules. In it, list the paths containing a
submodule. Add that file to the index.
This patch adds a check to the pre-commit hook finds that file and pulls
the HEAD hash out of each of the listed submodule repositories. That
hash is then listed to the .gitmodules file along with the submodule
name and .gitmodules is added back to the repository.
You've now got poor-man's submodule support. Any commits to the
submodule will change the hash and hence the .gitmodules file will be
different and therefore will show up as "modified" to git.
It's not got any nice UI for checking out (obviously) or merging; but it
does at least record the state of a project. With a bit of manual work you
can easily check out the right commit in the submodule. If there were a
post-checkout hook script, this could probably be automated.
To prevent git-prune in the submodule from removing references that the
supermodule refers to the post-commit hook reads the .gitmodules file
and creates a file in submodule/.git/refs/superrefs/ that refers to the
hash we've references. git-prune in the submodule will find that
reference and hence won't remove it from under us.
Problems:
- git-prune in the supermodule doesn't clean the supermodule refs in
the submodule
- no checkout support
- no reset support
- no merge support (other than what git provides for the .gitmodule
file)
- no check for dirty submodule before commit
Signed-off-by: Andy Parkins <andyparkins@gmail.com>
---
This is in replacement of the previous patch.
I've used the --show-cdup option of git-rev-parse to make it work even in
subdirectories. I've also added git-prune protection by adding a post-commit
script to reference the hash in the submodule.
What'd you reckon? Might be useful until real submodule support arrives.
If there is no .gitmodules file in the root, then git behaves as it always did.
I suppose if this were actually found to be really useful, it should go in
git-commit.sh itself, rather than the hooks.
templates/hooks--post-commit | 29 +++++++++++++++++++++++++-
templates/hooks--pre-commit | 47 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/templates/hooks--post-commit b/templates/hooks--post-commit
index 8be6f34..551d928 100644
--- a/templates/hooks--post-commit
+++ b/templates/hooks--post-commit
@@ -5,4 +5,31 @@
#
# To enable this hook, make this file executable.
-: Nothing
+# Poor-man's Submodules
+# ---------------------
+# If we're here, then a commit has succeeded. If submodule support is enabled
+# then we need a way of telling the submodule that we now reference a hash
+# owned by it, so that it is not pruned.
+WORKINGTOP=$(git-rev-parse --show-cdup)
+GITMODULES="${WORKINGTOP}.gitmodules"
+if [ -f "$GITMODULES" ]; then
+ cat "$GITMODULES" |
+ while read subdir hash
+ do
+ SUBMODULEPATH="$WORKINGTOP$subdir/.git/refs/superrefs"
+
+ # XXX: check if the line is a comment
+
+ # check if the subdir is a repository
+ if [ ! -d "$WORKINGTOP$subdir/.git" ]; then
+ continue;
+ fi
+
+ # Write the hash to a file of the same name - this means that if we get
+ # multiple commits that refer to the submodule, we only get one file in
+ # the submodule, as the submodule hash is constant across supermodule
+ # commits
+ mkdir -p "$SUBMODULEPATH"
+ echo $hash > "$SUBMODULEPATH/$hash"
+ done
+fi
diff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit
index 723a9ef..7718369 100644
--- a/templates/hooks--pre-commit
+++ b/templates/hooks--pre-commit
@@ -67,5 +67,50 @@ perl -e '
}
}
exit($found_bad);
-'
+' || exit 1
+
+# Poor-man's Submodules
+# ---------------------
+# Enable poor-man's submodule support when .gitmodules is present
+# Simply create a .gitmodules file listing the paths in your repository
+# that contain other git repositories; each line will be replaced with the
+# path followed by the hash of the current HEAD of the submodule.
+# When the submodule changes hash this file will be different from the
+# version in the repository and a change will be noted - voila, submodules.
+# Of course there is no checkout support, but at least the current state
+# will be accurately recorded
+WORKINGTOP=$(git-rev-parse --show-cdup)
+GITMODULES="${WORKINGTOP}.gitmodules"
+if [ -f "$GITMODULES" ]; then
+ cat "$GITMODULES" |
+ while read subdir hash
+ do
+ # check if the line is a comment and output it anyway
+ if (expr "x$subdir" : "x#" >/dev/null) then
+ echo "$subdir $hash"
+ continue;
+ fi
+
+ # check if the subdir is a repository
+ if [ ! -d "$WORKINGTOP$subdir/.git" ]; then
+ echo "$subdir is not a git repository, so it can't be a submodule"
+ exit 1;
+ fi
+
+ # XXX: really need a check here and quit if the submodule is
+ # dirty
+
+ echo "$subdir $(GIT_DIR=$WORKINGTOP$subdir/.git git-rev-parse HEAD)"
+ done > newgitmodules
+ # Update
+ mv newgitmodules "$GITMODULES"
+
+ # This relies on the .gitmodules file having already been added to
+ # the repository - perhaps this should be automated?
+ git-update-index "$GITMODULES" ||
+ (
+ echo "FATAL: Submodule tracker file, $GITMODULES, is not tracked in this repository." >&2
+ exit 1
+ )
+fi
--
1.4.4.2.g0d2a
next reply other threads:[~2006-12-20 13:09 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-20 13:09 Andy Parkins [this message]
2006-12-20 13:29 ` [RFC/PATCH] Implement poor-man's submodule support using commit hooks Johannes Sixt
2006-12-20 13:47 ` Andy Parkins
2006-12-20 14:07 ` Jakub Narebski
2006-12-20 14:20 ` Andy Parkins
2006-12-20 14:33 ` Rogan Dawes
2006-12-20 14:40 ` Andy Parkins
2006-12-20 15:42 ` Randal L. Schwartz
2006-12-20 16:09 ` Johannes Schindelin
2006-12-20 13:36 ` Martin Waitz
2006-12-20 13:48 ` Andy Parkins
2006-12-20 14:35 ` Andy Parkins
2006-12-20 15:44 ` Martin Waitz
2006-12-20 14:18 ` Johannes Sixt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200612201309.02119.andyparkins@gmail.com \
--to=andyparkins@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).