diff options
-rw-r--r-- | builtin/submodule--helper.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 85aafe46a4..6ee962207c 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1105,6 +1105,50 @@ static int resolve_remote_submodule_branch(int argc, const char **argv, return 0; } +static int push_check(int argc, const char **argv, const char *prefix) +{ + struct remote *remote; + + if (argc < 2) + die("submodule--helper push-check requires at least 1 argument"); + + /* + * The remote must be configured. + * This is to avoid pushing to the exact same URL as the parent. + */ + remote = pushremote_get(argv[1]); + if (!remote || remote->origin == REMOTE_UNCONFIGURED) + die("remote '%s' not configured", argv[1]); + + /* Check the refspec */ + if (argc > 2) { + int i, refspec_nr = argc - 2; + struct ref *local_refs = get_local_heads(); + struct refspec *refspec = parse_push_refspec(refspec_nr, + argv + 2); + + for (i = 0; i < refspec_nr; i++) { + struct refspec *rs = refspec + i; + + if (rs->pattern || rs->matching) + continue; + + /* + * LHS must match a single ref + * NEEDSWORK: add logic to special case 'HEAD' once + * working with submodules in a detached head state + * ceases to be the norm. + */ + if (count_refspec_match(rs->src, local_refs, NULL) != 1) + die("src refspec '%s' must name a ref", + rs->src); + } + free_refspec(refspec_nr, refspec); + } + + return 0; +} + static int absorb_git_dirs(int argc, const char **argv, const char *prefix) { int i; @@ -1170,6 +1214,7 @@ static struct cmd_struct commands[] = { {"resolve-relative-url-test", resolve_relative_url_test, 0}, {"init", module_init, SUPPORT_SUPER_PREFIX}, {"remote-branch", resolve_remote_submodule_branch, 0}, + {"push-check", push_check, 0}, {"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX}, {"is-active", is_active, 0}, }; |