Add a --stage option to the 'submodule--helper config' command so that
the .gitmodules file can be staged without referring to it explicitly by
file path.

In practice the config will still be written to .gitmoudules, there are
no plans to change the file path, but having this level of indirection
makes it possible to perform possible additional checks before staging
the file.

Signed-off-by: Antonio Ospite <a...@ao2.it>
---
 builtin/submodule--helper.c | 44 +++++++++++++++++++++++++++++++++++--
 t/t7411-submodule-config.sh | 35 +++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b32110e3b..de5caa776 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -5,6 +5,7 @@
 #include "parse-options.h"
 #include "quote.h"
 #include "pathspec.h"
+#include "lockfile.h"
 #include "dir.h"
 #include "submodule.h"
 #include "submodule-config.h"
@@ -1837,10 +1838,49 @@ static int config_print_callback(const char *key_, 
const char *value_, void *cb_
 
 static int module_config(int argc, const char **argv, const char *prefix)
 {
+       int stage_gitmodules = 0;
        int ret;
 
-       if (argc < 2 || argc > 3)
-               die("submodule--helper config takes 1 or 2 arguments: name 
[value]");
+       struct option module_config_options[] = {
+               OPT_BOOL(0, "stage", &stage_gitmodules,
+                           N_("stage the .gitmodules file content")),
+               OPT_END()
+       };
+       const char *const git_submodule_helper_usage[] = {
+               N_("git submodule--helper config name [value]"),
+               N_("git submodule--helper config --stage"),
+               NULL
+       };
+
+       argc = parse_options(argc, argv, prefix, module_config_options,
+                            git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0);
+
+       if ((stage_gitmodules && argc > 1) ||
+           (!stage_gitmodules && (argc < 2 || argc > 3)))
+               usage_with_options(git_submodule_helper_usage, 
module_config_options);
+
+       /*
+        * Equivalent to "git add --force .gitmodules".
+        *
+        * Silently override already staged changes, to support consecutive
+        * invocations of "git submodule add".
+        */
+       if (stage_gitmodules) {
+               static struct lock_file lock_file;
+
+               hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
+
+               if (read_cache() < 0)
+                       die(_("index file corrupt"));
+
+               stage_updated_gitmodules(&the_index);
+
+               if (write_locked_index(&the_index, &lock_file,
+                                      COMMIT_LOCK | SKIP_IF_UNCHANGED))
+                       die(_("Unable to write new index file"));
+
+               return 0;
+       }
 
        /* Equivalent to ACTION_GET in builtin/config.c */
        if (argc == 2) {
diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh
index dfe019f05..a0b2f7cd6 100755
--- a/t/t7411-submodule-config.sh
+++ b/t/t7411-submodule-config.sh
@@ -165,4 +165,39 @@ test_expect_success 'overwriting unstaged submodules 
config with "submodule--hel
        )
 '
 
+test_expect_success 'staging submodules config with "submodule--helper 
config"' '
+       (cd super &&
+               : >expected &&
+               git diff --name-only --cached >actual &&
+               test_cmp expected actual &&
+               git submodule--helper config --stage &&
+               echo ".gitmodules" >expected &&
+               git diff --name-only --cached >actual &&
+               test_cmp expected actual
+       )
+'
+
+test_expect_success 'overwriting staged submodules config with 
"submodule--helper config"' '
+       (cd super &&
+               echo "even_newer_url" >expected &&
+               git submodule--helper config submodule.submodule.url 
"even_newer_url" &&
+               git submodule--helper config submodule.submodule.url >actual &&
+               test_cmp expected actual
+       )
+'
+
+test_expect_success 're-staging overridden submodule config with 
"submodule--helper config"' '
+       (cd super &&
+               echo ".gitmodules" >expected &&
+               git diff --name-only --cached >actual &&
+               test_cmp expected actual &&
+               echo "bogus config" >.gitmodules &&
+               git submodule--helper config --stage &&
+               git diff --name-only --cached >actual &&
+               test_cmp expected actual &&
+               git reset HEAD .gitmodules &&
+               git checkout .gitmodules
+       )
+'
+
 test_done
-- 
2.17.0

Reply via email to