When the .gitmodules file is not available in the working directory, try
using HEAD:.gitmodules from the index. This covers the case when the
file is part of the repository but for some reason it is not checked
out, for example because of a sparse checkout.
This makes it possible to use at least the 'git submodule' commands
which *read* the gitmodules configuration file without fully populating
the work dir.
Writing to .gitmodules wills still require that the file is checked out,
so check for that in config_gitmodules_set.
Signed-off-by: Antonio Ospite
---
I am doing the is_gitmodules_hidden() check in the open for now, I am not sure
whether it is approprate to do that inside stage_updated_gitmodules.
builtin/mv.c| 2 ++
builtin/rm.c| 7 +--
builtin/submodule--helper.c | 21 -
cache.h | 1 +
config.c| 15 +--
submodule.c | 15 +++
submodule.h | 1 +
7 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/builtin/mv.c b/builtin/mv.c
index 7a63667d6..41fd9b7be 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -83,6 +83,8 @@ static void prepare_move_submodule(const char *src, int first,
die(_("Directory %s is in index and no submodule?"), src);
if (!is_staging_gitmodules_ok(&the_index))
die(_("Please stage your changes to .gitmodules or stash them
to proceed"));
+ if (is_gitmodules_hidden(&the_index))
+ die(_("cannot work with hidden submodule config"));
strbuf_addf(&submodule_dotgit, "%s/.git", src);
*submodule_gitfile = read_gitfile(submodule_dotgit.buf);
if (*submodule_gitfile)
diff --git a/builtin/rm.c b/builtin/rm.c
index 5b6fc7ee8..e3526a342 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -284,9 +284,12 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
list.entry[list.nr].name = xstrdup(ce->name);
list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);
- if (list.entry[list.nr++].is_submodule &&
- !is_staging_gitmodules_ok(&the_index))
+ if (list.entry[list.nr++].is_submodule) {
+ if (!is_staging_gitmodules_ok(&the_index))
die (_("Please stage your changes to .gitmodules or
stash them to proceed"));
+ if (is_gitmodules_hidden(&the_index))
+ die(_("cannot work with hidden submodule config"));
+ }
}
if (pathspec.nr) {
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index de5caa776..b3bdb4b66 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1873,6 +1873,9 @@ static int module_config(int argc, const char **argv,
const char *prefix)
if (read_cache() < 0)
die(_("index file corrupt"));
+ if (is_gitmodules_hidden(&the_index))
+ die(_("cannot stage changes to hidden submodule
config"));
+
stage_updated_gitmodules(&the_index);
if (write_locked_index(&the_index, &lock_file,
@@ -1897,8 +1900,24 @@ static int module_config(int argc, const char **argv,
const char *prefix)
}
/* Equivalent to ACTION_SET in builtin/config.c */
- if (argc == 3)
+ if (argc == 3) {
+ struct object_id oid;
+
+ /*
+* If the .gitmodules file is not in the work tree but it is
+* in the index, stop, as writing new values and staging them
+* would blindly overwrite ALL the old content.
+*
+* Do not use is_gitmodules_hidden() here, to gracefully
+* handle the case when .gitmodules is neither in the work
+* tree nor in the index, i.e.: a new GITMODULES_FILE is going
+* to be created.
+*/
+ if (!file_exists(GITMODULES_FILE) && get_oid(GITMODULES_BLOB,
&oid) >= 0)
+ die(_("cannot change unchecked out .gitmodules, check
it out first"));
+
return config_gitmodules_set(argv[1], argv[2]);
+ }
return 0;
}
diff --git a/cache.h b/cache.h
index 0c1fb9fbc..6d45b0cbb 100644
--- a/cache.h
+++ b/cache.h
@@ -417,6 +417,7 @@ static inline enum object_type object_type(unsigned int
mode)
#define INFOATTRIBUTES_FILE "info/attributes"
#define ATTRIBUTE_MACRO_PREFIX "[attr]"
#define GITMODULES_FILE ".gitmodules"
+#define GITMODULES_BLOB "HEAD:.gitmodules"
#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF"
#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"
#define GIT_NOTES_DISPLAY_REF_ENVIRONMENT "GIT_NOTES_DISPLAY_REF"
diff --git a/config.c b/config.c
index 8ffe29330..7d9744622 100644
--- a/config.c
+++ b/co