@@ -14,6 +14,7 @@ static const char *const builtin_config_usage[] = {
14
14
15
15
static char * key ;
16
16
static regex_t * key_regexp ;
17
+ static const char * value_pattern ;
17
18
static regex_t * regexp ;
18
19
static int show_keys ;
19
20
static int omit_values ;
@@ -34,6 +35,7 @@ static int respect_includes_opt = -1;
34
35
static struct config_options config_options ;
35
36
static int show_origin ;
36
37
static int show_scope ;
38
+ static int fixed_value ;
37
39
38
40
#define ACTION_GET (1<<0)
39
41
#define ACTION_GET_ALL (1<<1)
@@ -133,17 +135,18 @@ static struct option builtin_config_options[] = {
133
135
OPT_STRING ('f' , "file" , & given_config_source .file , N_ ("file" ), N_ ("use given config file" )),
134
136
OPT_STRING (0 , "blob" , & given_config_source .blob , N_ ("blob-id" ), N_ ("read config from given blob object" )),
135
137
OPT_GROUP (N_ ("Action" )),
136
- OPT_BIT (0 , "get" , & actions , N_ ("get value: name [value-regex ]" ), ACTION_GET ),
137
- OPT_BIT (0 , "get-all" , & actions , N_ ("get all values: key [value-regex ]" ), ACTION_GET_ALL ),
138
- OPT_BIT (0 , "get-regexp" , & actions , N_ ("get values for regexp: name-regex [value-regex ]" ), ACTION_GET_REGEXP ),
138
+ OPT_BIT (0 , "get" , & actions , N_ ("get value: name [value-pattern ]" ), ACTION_GET ),
139
+ OPT_BIT (0 , "get-all" , & actions , N_ ("get all values: key [value-pattern ]" ), ACTION_GET_ALL ),
140
+ OPT_BIT (0 , "get-regexp" , & actions , N_ ("get values for regexp: name-regex [value-pattern ]" ), ACTION_GET_REGEXP ),
139
141
OPT_BIT (0 , "get-urlmatch" , & actions , N_ ("get value specific for the URL: section[.var] URL" ), ACTION_GET_URLMATCH ),
140
- OPT_BIT (0 , "replace-all" , & actions , N_ ("replace all matching variables: name value [value_regex ]" ), ACTION_REPLACE_ALL ),
142
+ OPT_BIT (0 , "replace-all" , & actions , N_ ("replace all matching variables: name value [value-pattern ]" ), ACTION_REPLACE_ALL ),
141
143
OPT_BIT (0 , "add" , & actions , N_ ("add a new variable: name value" ), ACTION_ADD ),
142
- OPT_BIT (0 , "unset" , & actions , N_ ("remove a variable: name [value-regex ]" ), ACTION_UNSET ),
143
- OPT_BIT (0 , "unset-all" , & actions , N_ ("remove all matches: name [value-regex ]" ), ACTION_UNSET_ALL ),
144
+ OPT_BIT (0 , "unset" , & actions , N_ ("remove a variable: name [value-pattern ]" ), ACTION_UNSET ),
145
+ OPT_BIT (0 , "unset-all" , & actions , N_ ("remove all matches: name [value-pattern ]" ), ACTION_UNSET_ALL ),
144
146
OPT_BIT (0 , "rename-section" , & actions , N_ ("rename section: old-name new-name" ), ACTION_RENAME_SECTION ),
145
147
OPT_BIT (0 , "remove-section" , & actions , N_ ("remove a section: name" ), ACTION_REMOVE_SECTION ),
146
148
OPT_BIT ('l' , "list" , & actions , N_ ("list all" ), ACTION_LIST ),
149
+ OPT_BOOL (0 , "fixed-value" , & fixed_value , N_ ("use string equality when comparing values to 'value-pattern'" )),
147
150
OPT_BIT ('e' , "edit" , & actions , N_ ("open an editor" ), ACTION_EDIT ),
148
151
OPT_BIT (0 , "get-color" , & actions , N_ ("find the color configured: slot [default]" ), ACTION_GET_COLOR ),
149
152
OPT_BIT (0 , "get-colorbool" , & actions , N_ ("find the color setting: slot [stdout-is-tty]" ), ACTION_GET_COLORBOOL ),
@@ -296,6 +299,8 @@ static int collect_config(const char *key_, const char *value_, void *cb)
296
299
return 0 ;
297
300
if (use_key_regexp && regexec (key_regexp , key_ , 0 , NULL , 0 ))
298
301
return 0 ;
302
+ if (fixed_value && strcmp (value_pattern , (value_ ?value_ :"" )))
303
+ return 0 ;
299
304
if (regexp != NULL &&
300
305
(do_not_match ^ !!regexec (regexp , (value_ ?value_ :"" ), 0 , NULL , 0 )))
301
306
return 0 ;
@@ -306,7 +311,7 @@ static int collect_config(const char *key_, const char *value_, void *cb)
306
311
return format_config (& values -> items [values -> nr ++ ], key_ , value_ );
307
312
}
308
313
309
- static int get_value (const char * key_ , const char * regex_ )
314
+ static int get_value (const char * key_ , const char * regex_ , unsigned flags )
310
315
{
311
316
int ret = CONFIG_GENERIC_ERROR ;
312
317
struct strbuf_list values = {NULL };
@@ -343,7 +348,9 @@ static int get_value(const char *key_, const char *regex_)
343
348
}
344
349
}
345
350
346
- if (regex_ ) {
351
+ if (regex_ && (flags & CONFIG_FLAGS_FIXED_VALUE ))
352
+ value_pattern = regex_ ;
353
+ else if (regex_ ) {
347
354
if (regex_ [0 ] == '!' ) {
348
355
do_not_match = 1 ;
349
356
regex_ ++ ;
@@ -631,6 +638,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
631
638
{
632
639
int nongit = !startup_info -> have_repository ;
633
640
char * value ;
641
+ int flags = 0 ;
634
642
635
643
given_config_source .file = xstrdup_or_null (getenv (CONFIG_ENVIRONMENT ));
636
644
@@ -766,6 +774,42 @@ int cmd_config(int argc, const char **argv, const char *prefix)
766
774
usage_builtin_config ();
767
775
}
768
776
777
+ /* check usage of --fixed-value */
778
+ if (fixed_value ) {
779
+ int allowed_usage = 0 ;
780
+
781
+ switch (actions ) {
782
+ /* git config --get <name> <value-pattern> */
783
+ case ACTION_GET :
784
+ /* git config --get-all <name> <value-pattern> */
785
+ case ACTION_GET_ALL :
786
+ /* git config --get-regexp <name-pattern> <value-pattern> */
787
+ case ACTION_GET_REGEXP :
788
+ /* git config --unset <name> <value-pattern> */
789
+ case ACTION_UNSET :
790
+ /* git config --unset-all <name> <value-pattern> */
791
+ case ACTION_UNSET_ALL :
792
+ allowed_usage = argc > 1 && !!argv [1 ];
793
+ break ;
794
+
795
+ /* git config <name> <value> <value-pattern> */
796
+ case ACTION_SET_ALL :
797
+ /* git config --replace-all <name> <value> <value-pattern> */
798
+ case ACTION_REPLACE_ALL :
799
+ allowed_usage = argc > 2 && !!argv [2 ];
800
+ break ;
801
+
802
+ /* other options don't allow --fixed-value */
803
+ }
804
+
805
+ if (!allowed_usage ) {
806
+ error (_ ("--fixed-value only applies with 'value-pattern'" ));
807
+ usage_builtin_config ();
808
+ }
809
+
810
+ flags |= CONFIG_FLAGS_FIXED_VALUE ;
811
+ }
812
+
769
813
if (actions & PAGING_ACTIONS )
770
814
setup_auto_pager ("config" , 1 );
771
815
@@ -827,7 +871,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
827
871
value = normalize_value (argv [0 ], argv [1 ]);
828
872
UNLEAK (value );
829
873
return git_config_set_multivar_in_file_gently (given_config_source .file ,
830
- argv [0 ], value , argv [2 ], 0 );
874
+ argv [0 ], value , argv [2 ],
875
+ flags );
831
876
}
832
877
else if (actions == ACTION_ADD ) {
833
878
check_write ();
@@ -836,31 +881,33 @@ int cmd_config(int argc, const char **argv, const char *prefix)
836
881
UNLEAK (value );
837
882
return git_config_set_multivar_in_file_gently (given_config_source .file ,
838
883
argv [0 ], value ,
839
- CONFIG_REGEX_NONE , 0 );
884
+ CONFIG_REGEX_NONE ,
885
+ flags );
840
886
}
841
887
else if (actions == ACTION_REPLACE_ALL ) {
842
888
check_write ();
843
889
check_argc (argc , 2 , 3 );
844
890
value = normalize_value (argv [0 ], argv [1 ]);
845
891
UNLEAK (value );
846
892
return git_config_set_multivar_in_file_gently (given_config_source .file ,
847
- argv [0 ], value , argv [2 ], 1 );
893
+ argv [0 ], value , argv [2 ],
894
+ flags | CONFIG_FLAGS_MULTI_REPLACE );
848
895
}
849
896
else if (actions == ACTION_GET ) {
850
897
check_argc (argc , 1 , 2 );
851
- return get_value (argv [0 ], argv [1 ]);
898
+ return get_value (argv [0 ], argv [1 ], flags );
852
899
}
853
900
else if (actions == ACTION_GET_ALL ) {
854
901
do_all = 1 ;
855
902
check_argc (argc , 1 , 2 );
856
- return get_value (argv [0 ], argv [1 ]);
903
+ return get_value (argv [0 ], argv [1 ], flags );
857
904
}
858
905
else if (actions == ACTION_GET_REGEXP ) {
859
906
show_keys = 1 ;
860
907
use_key_regexp = 1 ;
861
908
do_all = 1 ;
862
909
check_argc (argc , 1 , 2 );
863
- return get_value (argv [0 ], argv [1 ]);
910
+ return get_value (argv [0 ], argv [1 ], flags );
864
911
}
865
912
else if (actions == ACTION_GET_URLMATCH ) {
866
913
check_argc (argc , 2 , 2 );
@@ -871,7 +918,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
871
918
check_argc (argc , 1 , 2 );
872
919
if (argc == 2 )
873
920
return git_config_set_multivar_in_file_gently (given_config_source .file ,
874
- argv [0 ], NULL , argv [1 ], 0 );
921
+ argv [0 ], NULL , argv [1 ],
922
+ flags );
875
923
else
876
924
return git_config_set_in_file_gently (given_config_source .file ,
877
925
argv [0 ], NULL );
@@ -880,7 +928,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
880
928
check_write ();
881
929
check_argc (argc , 1 , 2 );
882
930
return git_config_set_multivar_in_file_gently (given_config_source .file ,
883
- argv [0 ], NULL , argv [1 ], 1 );
931
+ argv [0 ], NULL , argv [1 ],
932
+ flags | CONFIG_FLAGS_MULTI_REPLACE );
884
933
}
885
934
else if (actions == ACTION_RENAME_SECTION ) {
886
935
int ret ;
0 commit comments