From: Sven Verdoolaege <skimo@xxxxxxxxxx> If the submodules are not clean, then we will get an error when we actally do the checkout. Signed-off-by: Sven Verdoolaege <skimo@xxxxxxxxxx> --- unpack-trees.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 files changed, 34 insertions(+), 9 deletions(-) diff --git a/unpack-trees.c b/unpack-trees.c index 5fa637a..2f2d9b9 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -5,6 +5,7 @@ #include "cache-tree.h" #include "unpack-trees.h" #include "progress.h" +#include "refs.h" #define DBRT_DEBUG 1 @@ -426,11 +427,24 @@ static void invalidate_ce_path(struct cache_entry *ce) cache_tree_invalidate_path(active_cache_tree, ce->name); } -static int verify_clean_subdirectory(const char *path, const char *action, +/* Check that checking out ce->sha1 in subdir ce->name is not + * going to overwrite any working files. + * + * FIXME: implement this function, so we can detect problems + * early, rather than waiting until we actually try to checkout + * the submodules. + */ +static int verify_clean_submodule(struct cache_entry *ce, const char *action, + struct unpack_trees_options *o) +{ + return 0; +} + +static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, struct unpack_trees_options *o) { /* - * we are about to extract "path"; we would not want to lose + * we are about to extract "ce->name"; we would not want to lose * anything in the existing directory there. */ int namelen; @@ -438,13 +452,24 @@ static int verify_clean_subdirectory(const char *path, const char *action, struct dir_struct d; char *pathbuf; int cnt = 0; + unsigned char sha1[20]; + + if (S_ISGITLINK(ntohl(ce->ce_mode)) && + resolve_gitlink_ref(ce->name, "HEAD", sha1) == 0) { + /* If we are not going to update the submodule, then + * we don't care. + */ + if (!hashcmp(sha1, ce->sha1)) + return 0; + verify_clean_submodule(ce, action, o); + } /* * First let's make sure we do not have a local modification * in that directory. */ - namelen = strlen(path); - pos = cache_name_pos(path, namelen); + namelen = strlen(ce->name); + pos = cache_name_pos(ce->name, namelen); if (0 <= pos) return cnt; /* we have it as nondirectory */ pos = -pos - 1; @@ -452,7 +477,7 @@ static int verify_clean_subdirectory(const char *path, const char *action, struct cache_entry *ce = active_cache[i]; int len = ce_namelen(ce); if (len < namelen || - strncmp(path, ce->name, namelen) || + strncmp(ce->name, ce->name, namelen) || ce->name[namelen] != '/') break; /* @@ -470,16 +495,16 @@ static int verify_clean_subdirectory(const char *path, const char *action, * present file that is not ignored. */ pathbuf = xmalloc(namelen + 2); - memcpy(pathbuf, path, namelen); + memcpy(pathbuf, ce->name, namelen); strcpy(pathbuf+namelen, "/"); memset(&d, 0, sizeof(d)); if (o->dir) d.exclude_per_dir = o->dir->exclude_per_dir; - i = read_directory(&d, path, pathbuf, namelen+1, NULL); + i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL); if (i) die("Updating '%s' would lose untracked files in it", - path); + ce->name); free(pathbuf); return cnt; } @@ -513,7 +538,7 @@ static void verify_absent(struct cache_entry *ce, const char *action, * files that are in "foo/" we would lose * it. */ - cnt = verify_clean_subdirectory(ce->name, action, o); + cnt = verify_clean_subdirectory(ce, action, o); /* * If this removed entries from the index, -- 1.5.2.784.g5532e - 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