From: Sven Verdoolaege <skimo@xxxxxxxxxx> --- entry.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 56 insertions(+), 2 deletions(-) diff --git a/entry.c b/entry.c index 8c70a47..24bf161 100644 --- a/entry.c +++ b/entry.c @@ -104,10 +104,63 @@ static int checkout_submodule(struct cache_entry *ce, const char *path, const st return 0; } +static const char *relativize_path(const char *path, const char *dest) +{ + static char relative_path[PATH_MAX]; + int slashes; + const char *cp; + char *rp; + + if (path[0] == '/') + return path; + + for (slashes = 0, cp = strchr(dest, '/'); cp; cp = strchr(cp, '/')) { + ++slashes; + while (*cp == '/') + ++cp; + } + if (3 * slashes + strlen(path) + 1 > sizeof(relative_path)) + die("path too long"); + + rp = relative_path; + while (slashes--) { + memcpy(rp, "../", 3); + rp += 3; + } + strcpy(rp, path); + + return relative_path; +} + +static int write_submodule(struct cache_entry *ce, char *path, const struct checkout *state) +{ + struct stat st; + const char *submodule_dir, *dest; + + if (mkdir(path, 0777) < 0) + return error("git-checkout-index: cannot create subproject directory %s", path); + + if (!state->submodules) + return 0; + + submodule_dir = git_path("submodules/%s/.git", ce->name); + if (lstat(submodule_dir, &st)) + return error("submodule '%s' unavailable", ce->name); + + dest = mkpath("%s/.git", ce->name); + submodule_dir = relativize_path(submodule_dir, dest); + + if (symlink(submodule_dir, dest)) + return -1; + + return checkout_submodule(ce, path, state); +} + static int write_entry(struct cache_entry *ce, char *path, const struct checkout *state, int to_tempfile) { int fd; long wrote; + int err; switch (ntohl(ce->ce_mode) & S_IFMT) { char *buf, *new; @@ -177,8 +230,9 @@ 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) - return error("git-checkout-index: cannot create subproject directory %s", path); + err = write_submodule(ce, path, state); + if (err) + return err; break; default: return error("git-checkout-index: unknown file mode for %s", path); -- 1.5.2.rc3.815.g8fc2 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html