2760
return !!ret;
2761
}
2762
2763
+struct add_data {
2764
+ const char *prefix;
2765
+ const char *branch;
2766
+ const char *reference_path;
2767
+ const char *sm_path;
2768
+ const char *sm_name;
2769
+ const char *repo;
2770
+ const char *realrepo;
2771
+ int depth;
2772
+ unsigned int force: 1;
2773
+ unsigned int quiet: 1;
2774
+ unsigned int progress: 1;
2775
+ unsigned int dissociate: 1;
2776
+};
2777
+#define ADD_DATA_INIT { .depth = -1 }
2778
+
2779
+static void show_fetch_remotes(FILE *output, const char *sm_name, const char *git_dir_path)
2780
+{
2781
+ struct child_process cp_remote = CHILD_PROCESS_INIT;
2782
+ struct strbuf sb_remote_out = STRBUF_INIT;
2783
+
2784
+ cp_remote.git_cmd = 1;
2785
+ strvec_pushf(&cp_remote.env_array,
2786
+ "GIT_DIR=%s", git_dir_path);
2787
+ strvec_push(&cp_remote.env_array, "GIT_WORK_TREE=.");
2788
+ strvec_pushl(&cp_remote.args, "remote", "-v", NULL);
2789
+ if (!capture_command(&cp_remote, &sb_remote_out, 0)) {
2790
+ char *next_line;
2791
+ char *line = sb_remote_out.buf;
2792
+ while ((next_line = strchr(line, '\n')) != NULL) {
2793
+ size_t len = next_line - line;
2794
+ if (strip_suffix_mem(line, &len, " (fetch)"))
2795
+ fprintf(output, " %.*s\n", (int)len, line);
2796
+ line = next_line + 1;
2797
+ }
2798
+ }
2799
+
2800
+ strbuf_release(&sb_remote_out);
2801
+}
2802
+
2803
+static int add_submodule(const struct add_data *add_data)
2804
+{
2805
+ char *submod_gitdir_path;
2806
+ struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
2807
+
2808
+ /* perhaps the path already exists and is already a git repo, else clone it */
2809
+ if (is_directory(add_data->sm_path)) {
2810
+ struct strbuf sm_path = STRBUF_INIT;
2811
+ strbuf_addstr(&sm_path, add_data->sm_path);
2812
+ submod_gitdir_path = xstrfmt("%s/.git", add_data->sm_path);
2813
+ if (is_nonbare_repository_dir(&sm_path))
2814
+ printf(_("Adding existing repo at '%s' to the index\n"),
2815
+ add_data->sm_path);
2816
+ else
2817
+ die(_("'%s' already exists and is not a valid git repo"),
2818
+ add_data->sm_path);
2819
+ strbuf_release(&sm_path);
2820
+ free(submod_gitdir_path);
2821
+ } else {
2822
+ struct child_process cp = CHILD_PROCESS_INIT;
2823
+ submod_gitdir_path = xstrfmt(".git/modules/%s", add_data->sm_name);
2824
+
2825
+ if (is_directory(submod_gitdir_path)) {
2826
+ if (!add_data->force) {
2827
+ fprintf(stderr, _("A git directory for '%s' is found "
2828
+ "locally with remote(s):"),
2829
+ add_data->sm_name);
2830
+ show_fetch_remotes(stderr, add_data->sm_name,
2831
+ submod_gitdir_path);
2832
+ free(submod_gitdir_path);
2833
+ die(_("If you want to reuse this local git "
2834
+ "directory instead of cloning again from\n"
2835
+ " %s\n"
2836
+ "use the '--force' option. If the local git "
2837
+ "directory is not the correct repo\n"
2838
+ "or if you are unsure what this means, choose "
2839
+ "another name with the '--name' option.\n"),
2840
+ add_data->realrepo);
2841
+ } else {
2842
+ printf(_("Reactivating local git directory for "
2843
+ "submodule '%s'\n"), add_data->sm_name);
2844
+ }
2845
+ }
2846
+ free(submod_gitdir_path);
2847
+
2848
+ clone_data.prefix = add_data->prefix;
2849
+ clone_data.path = add_data->sm_path;
2850
+ clone_data.name = add_data->sm_name;
2851
+ clone_data.url = add_data->realrepo;
2852
+ clone_data.quiet = add_data->quiet;
2853
+ clone_data.progress = add_data->progress;
2854
+ if (add_data->reference_path)
2855
+ string_list_append(&clone_data.reference,
2856
+ xstrdup(add_data->reference_path));
2857
+ clone_data.dissociate = add_data->dissociate;
2858
+ if (add_data->depth >= 0)
2859
+ clone_data.depth = xstrfmt("%d", add_data->depth);
2860
+
2861
+ if (clone_submodule(&clone_data))
2862
+ return -1;
2863
+
2864
+ prepare_submodule_repo_env(&cp.env_array);
2865
+ cp.git_cmd = 1;
2866
+ cp.dir = add_data->sm_path;
2867
+ strvec_pushl(&cp.args, "checkout", "-f", "-q", NULL);
2868
+
2869
+ if (add_data->branch) {
2870
+ strvec_pushl(&cp.args, "-B", add_data->branch, NULL);
2871
+ strvec_pushf(&cp.args, "origin/%s", add_data->branch);
2872
+ }
2873
+
2874
+ if (run_command(&cp))
2875
+ die(_("unable to checkout submodule '%s'"), add_data->sm_path);
2876
+ }
2877
+ return 0;
2878
+}
2879
+
2880
+static int add_clone(int argc, const char **argv, const char *prefix)
2881
+{
2882
+ int force = 0, quiet = 0, dissociate = 0, progress = 0;
2883
+ struct add_data add_data = ADD_DATA_INIT;
2884
+
2885
+ struct option options[] = {
2886
+ OPT_STRING('b', "branch", &add_data.branch,
2887
+ N_("branch"),
2888
+ N_("branch of repository to checkout on cloning")),
2889
+ OPT_STRING(0, "prefix", &prefix,
2890
+ N_("path"),
2891
+ N_("alternative anchor for relative paths")),
2892
+ OPT_STRING(0, "path", &add_data.sm_path,
2893
+ N_("path"),
2894
+ N_("where the new submodule will be cloned to")),
2895
+ OPT_STRING(0, "name", &add_data.sm_name,
2896
+ N_("string"),
2897
+ N_("name of the new submodule")),
2898
+ OPT_STRING(0, "url", &add_data.realrepo,
2899
+ N_("string"),
2900
+ N_("url where to clone the submodule from")),
2901
+ OPT_STRING(0, "reference", &add_data.reference_path,
2902
+ N_("repo"),
2903
+ N_("reference repository")),
2904
+ OPT_BOOL(0, "dissociate", &dissociate,
2905
+ N_("use --reference only while cloning")),
2906
+ OPT_INTEGER(0, "depth", &add_data.depth,
2907
+ N_("depth for shallow clones")),
2908
+ OPT_BOOL(0, "progress", &progress,
2909
+ N_("force cloning progress")),
2910
+ OPT__FORCE(&force, N_("allow adding an otherwise ignored submodule path"),
2911
+ PARSE_OPT_NOCOMPLETE),
2912
+ OPT__QUIET(&quiet, "suppress output for cloning a submodule"),
2913
+ OPT_END()
2914
+ };
2915
+
2916
+ const char *const usage[] = {
2917
+ N_("git submodule--helper add-clone [<options>...] "
2918
+ "--url <url> --path <path> --name <name>"),
2919
+ NULL
2920
+ };
2921
+
2922
+ argc = parse_options(argc, argv, prefix, options, usage, 0);
2923
+
2924
+ if (argc != 0)
2925
+ usage_with_options(usage, options);
2926
+
2927
+ add_data.prefix = prefix;
2928
+ add_data.progress = !!progress;
2929
+ add_data.dissociate = !!dissociate;
2930
+ add_data.force = !!force;
2931
+ add_data.quiet = !!quiet;
2932
+
2933
+ if (add_submodule(&add_data))
2934
+ return 1;
2935
+
2936
+ return 0;
2937
+}
2938
+
2939
#define SUPPORT_SUPER_PREFIX (1<<0)
2940
2941
struct cmd_struct {
2948
{"list", module_list, 0},
2949
{"name", module_name, 0},
2950
{"clone", module_clone, 0},
2951
+ {"add-clone", add_clone, 0},
2952
{"update-module-mode", module_update_module_mode, 0},
2953
{"update-clone", update_clone, 0},
2954
{"ensure-core-worktree", ensure_core_worktree, 0},