@@ -2936,6 +2936,134 @@ static int add_clone(int argc, const char **argv, const char *prefix)
2936
2936
return 0 ;
2937
2937
}
2938
2938
2939
+ static int config_submodule_in_gitmodules (const char * name , const char * var , const char * value )
2940
+ {
2941
+ char * key ;
2942
+ int ret ;
2943
+
2944
+ if (!is_writing_gitmodules_ok ())
2945
+ die (_ ("please make sure that the .gitmodules file is in the working tree" ));
2946
+
2947
+ key = xstrfmt ("submodule.%s.%s" , name , var );
2948
+ ret = config_set_in_gitmodules_file_gently (key , value );
2949
+ free (key );
2950
+
2951
+ return ret ;
2952
+ }
2953
+
2954
+ static void configure_added_submodule (struct add_data * add_data )
2955
+ {
2956
+ char * key ;
2957
+ char * val = NULL ;
2958
+ struct child_process add_submod = CHILD_PROCESS_INIT ;
2959
+ struct child_process add_gitmodules = CHILD_PROCESS_INIT ;
2960
+
2961
+ key = xstrfmt ("submodule.%s.url" , add_data -> sm_name );
2962
+ git_config_set_gently (key , add_data -> realrepo );
2963
+ free (key );
2964
+
2965
+ add_submod .git_cmd = 1 ;
2966
+ strvec_pushl (& add_submod .args , "add" ,
2967
+ "--no-warn-embedded-repo" , NULL );
2968
+ if (add_data -> force )
2969
+ strvec_push (& add_submod .args , "--force" );
2970
+ strvec_pushl (& add_submod .args , "--" , add_data -> sm_path , NULL );
2971
+
2972
+ if (run_command (& add_submod ))
2973
+ die (_ ("Failed to add submodule '%s'" ), add_data -> sm_path );
2974
+
2975
+ if (config_submodule_in_gitmodules (add_data -> sm_name , "path" , add_data -> sm_path ) ||
2976
+ config_submodule_in_gitmodules (add_data -> sm_name , "url" , add_data -> repo ))
2977
+ die (_ ("Failed to register submodule '%s'" ), add_data -> sm_path );
2978
+
2979
+ if (add_data -> branch ) {
2980
+ if (config_submodule_in_gitmodules (add_data -> sm_name ,
2981
+ "branch" , add_data -> branch ))
2982
+ die (_ ("Failed to register submodule '%s'" ), add_data -> sm_path );
2983
+ }
2984
+
2985
+ add_gitmodules .git_cmd = 1 ;
2986
+ strvec_pushl (& add_gitmodules .args ,
2987
+ "add" , "--force" , "--" , ".gitmodules" , NULL );
2988
+
2989
+ if (run_command (& add_gitmodules ))
2990
+ die (_ ("Failed to register submodule '%s'" ), add_data -> sm_path );
2991
+
2992
+ /*
2993
+ * NEEDSWORK: In a multi-working-tree world this needs to be
2994
+ * set in the per-worktree config.
2995
+ */
2996
+ /*
2997
+ * NEEDSWORK: In the longer run, we need to get rid of this
2998
+ * pattern of querying "submodule.active" before calling
2999
+ * is_submodule_active(), since that function needs to find
3000
+ * out the value of "submodule.active" again anyway.
3001
+ */
3002
+ if (!git_config_get_string ("submodule.active" , & val ) && val ) {
3003
+ /*
3004
+ * If the submodule being added isn't already covered by the
3005
+ * current configured pathspec, set the submodule's active flag
3006
+ */
3007
+ if (!is_submodule_active (the_repository , add_data -> sm_path )) {
3008
+ key = xstrfmt ("submodule.%s.active" , add_data -> sm_name );
3009
+ git_config_set_gently (key , "true" );
3010
+ free (key );
3011
+ }
3012
+ } else {
3013
+ key = xstrfmt ("submodule.%s.active" , add_data -> sm_name );
3014
+ git_config_set_gently (key , "true" );
3015
+ free (key );
3016
+ }
3017
+ }
3018
+
3019
+ static int add_config (int argc , const char * * argv , const char * prefix )
3020
+ {
3021
+ int force = 0 ;
3022
+ struct add_data add_data = ADD_DATA_INIT ;
3023
+
3024
+ struct option options [] = {
3025
+ OPT_STRING ('b' , "branch" , & add_data .branch ,
3026
+ N_ ("branch" ),
3027
+ N_ ("branch of repository to store in "
3028
+ "the submodule configuration" )),
3029
+ OPT_STRING (0 , "url" , & add_data .repo ,
3030
+ N_ ("string" ),
3031
+ N_ ("url to clone submodule from" )),
3032
+ OPT_STRING (0 , "resolved-url" , & add_data .realrepo ,
3033
+ N_ ("string" ),
3034
+ N_ ("url to clone the submodule from, after it has "
3035
+ "been dereferenced relative to parent's url, "
3036
+ "in the case where <url> is a relative url" )),
3037
+ OPT_STRING (0 , "path" , & add_data .sm_path ,
3038
+ N_ ("path" ),
3039
+ N_ ("where the new submodule will be cloned to" )),
3040
+ OPT_STRING (0 , "name" , & add_data .sm_name ,
3041
+ N_ ("string" ),
3042
+ N_ ("name of the new submodule" )),
3043
+ OPT__FORCE (& force , N_ ("allow adding an otherwise ignored submodule path" ),
3044
+ PARSE_OPT_NOCOMPLETE ),
3045
+ OPT_END ()
3046
+ };
3047
+
3048
+ const char * const usage [] = {
3049
+ N_ ("git submodule--helper add-config "
3050
+ "[--force|-f] [--branch|-b <branch>] "
3051
+ "--url <url> --resolved-url <resolved-url> "
3052
+ "--path <path> --name <name>" ),
3053
+ NULL
3054
+ };
3055
+
3056
+ argc = parse_options (argc , argv , prefix , options , usage , 0 );
3057
+
3058
+ if (argc )
3059
+ usage_with_options (usage , options );
3060
+
3061
+ add_data .force = !!force ;
3062
+ configure_added_submodule (& add_data );
3063
+
3064
+ return 0 ;
3065
+ }
3066
+
2939
3067
#define SUPPORT_SUPER_PREFIX (1<<0)
2940
3068
2941
3069
struct cmd_struct {
@@ -2949,6 +3077,7 @@ static struct cmd_struct commands[] = {
2949
3077
{"name" , module_name , 0 },
2950
3078
{"clone" , module_clone , 0 },
2951
3079
{"add-clone" , add_clone , 0 },
3080
+ {"add-config" , add_config , 0 },
2952
3081
{"update-module-mode" , module_update_module_mode , 0 },
2953
3082
{"update-clone" , update_clone , 0 },
2954
3083
{"ensure-core-worktree" , ensure_core_worktree , 0 },
0 commit comments