[PATCH] simple submodule checkout support
From: Martin Waitz <hidden>
Date: 2016-06-15 22:43:08
Subsystem:
kernel build + files below scripts/ (unless maintained elsewhere), the rest · Maintainers:
Nathan Chancellor, Nicolas Schier, Linus Torvalds
Add the ability to move a submodule to a commit which is referenced by a new supermodule version. This is not yet a full submodule checkout support -- you can't checkout any commit which is not yet available in the submodule object database. This means you can't create new submodules yet. Signed-off-by: Martin Waitz <redacted> --- .gitignore | 1 + Makefile | 2 +- entry.c | 16 +++++++++++----- git-dirlink-checkout.sh | 27 +++++++++++++++++++++++++++ t/t3041-subprojects-checkout.sh | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 git-dirlink-checkout.sh create mode 100755 t/t3041-subprojects-checkout.sh
diff --git a/.gitignore b/.gitignore
index 4dc0c39..8436a83 100644
--- a/.gitignore
+++ b/.gitignore@@ -37,6 +37,7 @@ git-diff git-diff-files git-diff-index git-diff-tree +git-dirlink-checkout git-describe git-fast-import git-fetch
diff --git a/Makefile b/Makefile
index 2fea115..fcd0125 100644
--- a/Makefile
+++ b/Makefile@@ -196,7 +196,7 @@ SCRIPT_SH = \ git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \ git-pull.sh git-rebase.sh \ git-repack.sh git-request-pull.sh git-reset.sh \ - git-sh-setup.sh \ + git-sh-setup.sh git-dirlink-checkout.sh \ git-tag.sh git-verify-tag.sh \ git-applymbox.sh git-applypatch.sh git-am.sh \ git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
diff --git a/entry.c b/entry.c
index 82bf725..6e85e81 100644
--- a/entry.c
+++ b/entry.c@@ -1,5 +1,6 @@ #include "cache.h" #include "blob.h" +#include "run-command.h" static void create_directories(const char *path, const struct checkout *state) {
@@ -79,6 +80,13 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout { int fd; long wrote; + const char *dirlink_checkout[] = { + "dirlink-checkout", path, sha1_to_hex(ce->sha1), NULL + }; + struct child_process cmd = { + .argv = dirlink_checkout, + .git_cmd = 1 + }; switch (ntohl(ce->ce_mode) & S_IFMT) { char *buf, *new;
@@ -148,7 +156,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout case S_IFDIRLNK: if (to_tempfile) return error("git-checkout-index: cannot create temporary subproject %s", path); - if (mkdir(path, 0777) < 0) + if (run_command(&cmd) != 0) return error("git-checkout-index: cannot create subproject directory %s", path); break; default:
@@ -192,10 +200,8 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t * just do the right thing) */ unlink(path); - if (S_ISDIR(st.st_mode)) { - /* If it is a gitlink, leave it alone! */ - if (S_ISDIRLNK(ntohl(ce->ce_mode))) - return 0; + if (S_ISDIR(st.st_mode) && + access(mkpath("%s/.git/HEAD", path), R_OK)!=0) { if (!state->force) return error("%s is a directory", path); remove_subtree(path);
diff --git a/git-dirlink-checkout.sh b/git-dirlink-checkout.sh
new file mode 100644
index 0000000..2e63970
--- /dev/null
+++ b/git-dirlink-checkout.sh@@ -0,0 +1,27 @@ +#!/bin/sh -e + +USAGE="<dirlink-path> <new-ref>" + +path="$1" +sha1="$2" + +test -n "$sha1" || usage +unset GIT_DIR + +if test ! -d "$path/.git"; then + mkdir "$path" + cd "$path" + # FIXME talk about what the user can do here + echo "This git submodule has not been populated yet." > README.git + exit 0 +fi + +cd "$path" +. git-sh-setup + +if git rev-parse --verify "$sha1" >/dev/null 2>&1; then + git checkout "$sha1" +else + # FIXME try to fetch it + echo >&2 "Cannot checkout $sha1 for $path." +fi
diff --git a/t/t3041-subprojects-checkout.sh b/t/t3041-subprojects-checkout.sh
new file mode 100755
index 0000000..4b3cea9
--- /dev/null
+++ b/t/t3041-subprojects-checkout.sh@@ -0,0 +1,39 @@ +#!/bin/sh + +test_description='submodule checkout' +. ./test-lib.sh + +test_expect_success 'submodule creation' \ + '(mkdir A && cd A && + git init && + echo 1 > a && + git add a && + git commit -m "create submodule" || exit $? )' + +test_expect_success 'Super module creation' \ + 'git add A && + git commit -m "supermodule creation" && + git branch one' + +test_expect_success 'submodule change' \ + '(cd A && + echo 2 > a && + git add a && + git commit -m "create submodule" || exit $? )' + +test_expect_success 'supermodule change' \ + 'git add A && + git commit -m "supermodule creation"' + +test_expect_success 'supermodule switching branch' \ + 'git checkout one && + echo 1 > expected && + git diff expected A/a' + +test_expect_success 'supermodule reset' \ + 'git reset --hard master && + echo 2 > expected && + git diff expected A/a' + + +test_done
--
1.5.1.2.247.gaef5a
--
Martin Waitz