23
23
static const char * empty_base = "" ;
24
24
25
25
static char const * const builtin_sparse_checkout_usage [] = {
26
- N_ ("git sparse-checkout (init | list | set | add | reapply | disable) [<options>]" ),
26
+ N_ ("git sparse-checkout (init | list | set | add | reapply | disable | check-rules ) [<options>]" ),
27
27
NULL
28
28
};
29
29
@@ -60,6 +60,7 @@ static int sparse_checkout_list(int argc, const char **argv, const char *prefix)
60
60
char * sparse_filename ;
61
61
int res ;
62
62
63
+ setup_work_tree ();
63
64
if (!core_apply_sparse_checkout )
64
65
die (_ ("this worktree is not sparse" ));
65
66
@@ -384,26 +385,29 @@ static int set_config(enum sparse_checkout_mode mode)
384
385
return 0 ;
385
386
}
386
387
387
- static int update_modes (int * cone_mode , int * sparse_index )
388
- {
389
- int mode , record_mode ;
390
-
391
- /* Determine if we need to record the mode; ensure sparse checkout on */
392
- record_mode = (* cone_mode != -1 ) || !core_apply_sparse_checkout ;
393
-
388
+ static enum sparse_checkout_mode update_cone_mode (int * cone_mode ) {
394
389
/* If not specified, use previous definition of cone mode */
395
390
if (* cone_mode == -1 && core_apply_sparse_checkout )
396
391
* cone_mode = core_sparse_checkout_cone ;
397
392
398
393
/* Set cone/non-cone mode appropriately */
399
394
core_apply_sparse_checkout = 1 ;
400
395
if (* cone_mode == 1 || * cone_mode == -1 ) {
401
- mode = MODE_CONE_PATTERNS ;
402
396
core_sparse_checkout_cone = 1 ;
403
- } else {
404
- mode = MODE_ALL_PATTERNS ;
405
- core_sparse_checkout_cone = 0 ;
397
+ return MODE_CONE_PATTERNS ;
406
398
}
399
+ core_sparse_checkout_cone = 0 ;
400
+ return MODE_ALL_PATTERNS ;
401
+ }
402
+
403
+ static int update_modes (int * cone_mode , int * sparse_index )
404
+ {
405
+ int mode , record_mode ;
406
+
407
+ /* Determine if we need to record the mode; ensure sparse checkout on */
408
+ record_mode = (* cone_mode != -1 ) || !core_apply_sparse_checkout ;
409
+
410
+ mode = update_cone_mode (cone_mode );
407
411
if (record_mode && set_config (mode ))
408
412
return 1 ;
409
413
@@ -449,6 +453,7 @@ static int sparse_checkout_init(int argc, const char **argv, const char *prefix)
449
453
OPT_END (),
450
454
};
451
455
456
+ setup_work_tree ();
452
457
repo_read_index (the_repository );
453
458
454
459
init_opts .cone_mode = -1 ;
@@ -546,7 +551,7 @@ static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)
546
551
547
552
static void add_patterns_from_input (struct pattern_list * pl ,
548
553
int argc , const char * * argv ,
549
- int use_stdin )
554
+ FILE * file )
550
555
{
551
556
int i ;
552
557
if (core_sparse_checkout_cone ) {
@@ -556,9 +561,9 @@ static void add_patterns_from_input(struct pattern_list *pl,
556
561
hashmap_init (& pl -> parent_hashmap , pl_hashmap_cmp , NULL , 0 );
557
562
pl -> use_cone_patterns = 1 ;
558
563
559
- if (use_stdin ) {
564
+ if (file ) {
560
565
struct strbuf unquoted = STRBUF_INIT ;
561
- while (!strbuf_getline (& line , stdin )) {
566
+ while (!strbuf_getline (& line , file )) {
562
567
if (line .buf [0 ] == '"' ) {
563
568
strbuf_reset (& unquoted );
564
569
if (unquote_c_style (& unquoted , line .buf , NULL ))
@@ -580,10 +585,10 @@ static void add_patterns_from_input(struct pattern_list *pl,
580
585
}
581
586
}
582
587
} else {
583
- if (use_stdin ) {
588
+ if (file ) {
584
589
struct strbuf line = STRBUF_INIT ;
585
590
586
- while (!strbuf_getline (& line , stdin )) {
591
+ while (!strbuf_getline (& line , file )) {
587
592
size_t len ;
588
593
char * buf = strbuf_detach (& line , & len );
589
594
add_pattern (buf , empty_base , 0 , pl , 0 );
@@ -610,7 +615,8 @@ static void add_patterns_cone_mode(int argc, const char **argv,
610
615
struct pattern_list existing ;
611
616
char * sparse_filename = get_sparse_checkout_filename ();
612
617
613
- add_patterns_from_input (pl , argc , argv , use_stdin );
618
+ add_patterns_from_input (pl , argc , argv ,
619
+ use_stdin ? stdin : NULL );
614
620
615
621
memset (& existing , 0 , sizeof (existing ));
616
622
existing .use_cone_patterns = core_sparse_checkout_cone ;
@@ -647,7 +653,7 @@ static void add_patterns_literal(int argc, const char **argv,
647
653
pl , NULL , 0 ))
648
654
die (_ ("unable to load existing sparse-checkout patterns" ));
649
655
free (sparse_filename );
650
- add_patterns_from_input (pl , argc , argv , use_stdin );
656
+ add_patterns_from_input (pl , argc , argv , use_stdin ? stdin : NULL );
651
657
}
652
658
653
659
static int modify_pattern_list (int argc , const char * * argv , int use_stdin ,
@@ -666,7 +672,8 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,
666
672
break ;
667
673
668
674
case REPLACE :
669
- add_patterns_from_input (pl , argc , argv , use_stdin );
675
+ add_patterns_from_input (pl , argc , argv ,
676
+ use_stdin ? stdin : NULL );
670
677
break ;
671
678
}
672
679
@@ -761,6 +768,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
761
768
OPT_END (),
762
769
};
763
770
771
+ setup_work_tree ();
764
772
if (!core_apply_sparse_checkout )
765
773
die (_ ("no sparse-checkout to add to" ));
766
774
@@ -807,6 +815,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
807
815
OPT_END (),
808
816
};
809
817
818
+ setup_work_tree ();
810
819
repo_read_index (the_repository );
811
820
812
821
set_opts .cone_mode = -1 ;
@@ -856,6 +865,7 @@ static int sparse_checkout_reapply(int argc, const char **argv,
856
865
OPT_END (),
857
866
};
858
867
868
+ setup_work_tree ();
859
869
if (!core_apply_sparse_checkout )
860
870
die (_ ("must be in a sparse-checkout to reapply sparsity patterns" ));
861
871
@@ -899,6 +909,7 @@ static int sparse_checkout_disable(int argc, const char **argv,
899
909
* forcibly return to a dense checkout regardless of initial state.
900
910
*/
901
911
912
+ setup_work_tree ();
902
913
argc = parse_options (argc , argv , prefix ,
903
914
builtin_sparse_checkout_disable_options ,
904
915
builtin_sparse_checkout_disable_usage , 0 );
@@ -924,6 +935,91 @@ static int sparse_checkout_disable(int argc, const char **argv,
924
935
return set_config (MODE_NO_PATTERNS );
925
936
}
926
937
938
+ static char const * const builtin_sparse_checkout_check_rules_usage [] = {
939
+ N_ ("git sparse-checkout check-rules [-z] [--skip-checks]"
940
+ "[--[no-]cone] [--rules-file <file>]" ),
941
+ NULL
942
+ };
943
+
944
+ static struct sparse_checkout_check_rules_opts {
945
+ int cone_mode ;
946
+ int null_termination ;
947
+ char * rules_file ;
948
+ } check_rules_opts ;
949
+
950
+ static int check_rules (struct pattern_list * pl , int null_terminated ) {
951
+ struct strbuf line = STRBUF_INIT ;
952
+ struct strbuf unquoted = STRBUF_INIT ;
953
+ char * path ;
954
+ int line_terminator = null_terminated ? 0 : '\n' ;
955
+ strbuf_getline_fn getline_fn = null_terminated ? strbuf_getline_nul
956
+ : strbuf_getline ;
957
+ the_repository -> index -> sparse_checkout_patterns = pl ;
958
+ while (!getline_fn (& line , stdin )) {
959
+ path = line .buf ;
960
+ if (!null_terminated && line .buf [0 ] == '"' ) {
961
+ strbuf_reset (& unquoted );
962
+ if (unquote_c_style (& unquoted , line .buf , NULL ))
963
+ die (_ ("unable to unquote C-style string '%s'" ),
964
+ line .buf );
965
+
966
+ path = unquoted .buf ;
967
+ }
968
+
969
+ if (path_in_sparse_checkout (path , the_repository -> index ))
970
+ write_name_quoted (path , stdout , line_terminator );
971
+ }
972
+ strbuf_release (& line );
973
+ strbuf_release (& unquoted );
974
+
975
+ return 0 ;
976
+ }
977
+
978
+ static int sparse_checkout_check_rules (int argc , const char * * argv , const char * prefix )
979
+ {
980
+ static struct option builtin_sparse_checkout_check_rules_options [] = {
981
+ OPT_BOOL ('z' , NULL , & check_rules_opts .null_termination ,
982
+ N_ ("terminate input and output files by a NUL character" )),
983
+ OPT_BOOL (0 , "cone" , & check_rules_opts .cone_mode ,
984
+ N_ ("when used with --rules-file interpret patterns as cone mode patterns" )),
985
+ OPT_FILENAME (0 , "rules-file" , & check_rules_opts .rules_file ,
986
+ N_ ("use patterns in <file> instead of the current ones." )),
987
+ OPT_END (),
988
+ };
989
+
990
+ FILE * fp ;
991
+ int ret ;
992
+ struct pattern_list pl = {0 };
993
+ char * sparse_filename ;
994
+ check_rules_opts .cone_mode = -1 ;
995
+
996
+ argc = parse_options (argc , argv , prefix ,
997
+ builtin_sparse_checkout_check_rules_options ,
998
+ builtin_sparse_checkout_check_rules_usage ,
999
+ PARSE_OPT_KEEP_UNKNOWN_OPT );
1000
+
1001
+ if (check_rules_opts .rules_file && check_rules_opts .cone_mode < 0 )
1002
+ check_rules_opts .cone_mode = 1 ;
1003
+
1004
+ update_cone_mode (& check_rules_opts .cone_mode );
1005
+ pl .use_cone_patterns = core_sparse_checkout_cone ;
1006
+ if (check_rules_opts .rules_file ) {
1007
+ fp = xfopen (check_rules_opts .rules_file , "r" );
1008
+ add_patterns_from_input (& pl , argc , argv , fp );
1009
+ fclose (fp );
1010
+ } else {
1011
+ sparse_filename = get_sparse_checkout_filename ();
1012
+ if (add_patterns_from_file_to_list (sparse_filename , "" , 0 , & pl ,
1013
+ NULL , 0 ))
1014
+ die (_ ("unable to load existing sparse-checkout patterns" ));
1015
+ free (sparse_filename );
1016
+ }
1017
+
1018
+ ret = check_rules (& pl , check_rules_opts .null_termination );
1019
+ clear_pattern_list (& pl );
1020
+ return ret ;
1021
+ }
1022
+
927
1023
int cmd_sparse_checkout (int argc , const char * * argv , const char * prefix )
928
1024
{
929
1025
parse_opt_subcommand_fn * fn = NULL ;
@@ -934,6 +1030,7 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
934
1030
OPT_SUBCOMMAND ("add" , & fn , sparse_checkout_add ),
935
1031
OPT_SUBCOMMAND ("reapply" , & fn , sparse_checkout_reapply ),
936
1032
OPT_SUBCOMMAND ("disable" , & fn , sparse_checkout_disable ),
1033
+ OPT_SUBCOMMAND ("check-rules" , & fn , sparse_checkout_check_rules ),
937
1034
OPT_END (),
938
1035
};
939
1036
0 commit comments