20
static const char *empty_base = "";
21
22
static char const * const builtin_sparse_checkout_usage[] = {
23
- N_("git sparse-checkout (init | list | set | add | reapply | disable) [<options>]"),
23
+ N_("git sparse-checkout (init | list | set | add | reapply | disable | check-rules) [<options>]"),
24
NULL
25
};
26
382
return 0;
383
}
384
385
-static int update_modes(int *cone_mode, int *sparse_index)
386
-{
387
- int mode, record_mode;
388
-
389
- /* Determine if we need to record the mode; ensure sparse checkout on */
390
- record_mode = (*cone_mode != -1) || !core_apply_sparse_checkout;
391
-
385
+static enum sparse_checkout_mode update_cone_mode(int *cone_mode) {
386
/* If not specified, use previous definition of cone mode */
387
if (*cone_mode == -1 && core_apply_sparse_checkout)
388
*cone_mode = core_sparse_checkout_cone;
390
/* Set cone/non-cone mode appropriately */
391
core_apply_sparse_checkout = 1;
392
if (*cone_mode == 1 || *cone_mode == -1) {
399
- mode = MODE_CONE_PATTERNS;
393
core_sparse_checkout_cone = 1;
401
- } else {
402
- mode = MODE_ALL_PATTERNS;
403
- core_sparse_checkout_cone = 0;
394
+ return MODE_CONE_PATTERNS;
395
}
396
+ core_sparse_checkout_cone = 0;
397
+ return MODE_ALL_PATTERNS;
398
+}
399
+
400
+static int update_modes(int *cone_mode, int *sparse_index)
401
+{
402
+ int mode, record_mode;
403
+
404
+ /* Determine if we need to record the mode; ensure sparse checkout on */
405
+ record_mode = (*cone_mode != -1) || !core_apply_sparse_checkout;
406
+
407
+ mode = update_cone_mode(cone_mode);
408
if (record_mode && set_config(mode))
409
return 1;
410
548
549
static void add_patterns_from_input(struct pattern_list *pl,
550
int argc, const char **argv,
548
- int use_stdin)
551
+ FILE *file)
552
{
553
int i;
554
if (core_sparse_checkout_cone) {
558
hashmap_init(&pl->parent_hashmap, pl_hashmap_cmp, NULL, 0);
559
pl->use_cone_patterns = 1;
560
558
- if (use_stdin) {
561
+ if (file) {
562
struct strbuf unquoted = STRBUF_INIT;
560
- while (!strbuf_getline(&line, stdin)) {
563
+ while (!strbuf_getline(&line, file)) {
564
if (line.buf[0] == '"') {
565
strbuf_reset(&unquoted);
566
if (unquote_c_style(&unquoted, line.buf, NULL))
582
}
583
}
584
} else {
582
- if (use_stdin) {
585
+ if (file) {
586
struct strbuf line = STRBUF_INIT;
587
585
- while (!strbuf_getline(&line, stdin)) {
588
+ while (!strbuf_getline(&line, file)) {
589
size_t len;
590
char *buf = strbuf_detach(&line, &len);
591
add_pattern(buf, empty_base, 0, pl, 0);
612
struct pattern_list existing;
613
char *sparse_filename = get_sparse_checkout_filename();
614
612
- add_patterns_from_input(pl, argc, argv, use_stdin);
615
+ add_patterns_from_input(pl, argc, argv,
616
+ use_stdin ? stdin : NULL);
617
618
memset(&existing, 0, sizeof(existing));
619
existing.use_cone_patterns = core_sparse_checkout_cone;
650
pl, NULL, 0))
651
die(_("unable to load existing sparse-checkout patterns"));
652
free(sparse_filename);
649
- add_patterns_from_input(pl, argc, argv, use_stdin);
653
+ add_patterns_from_input(pl, argc, argv, use_stdin ? stdin : NULL);
654
}
655
656
static int modify_pattern_list(int argc, const char **argv, int use_stdin,
669
break;
670
671
case REPLACE:
668
- add_patterns_from_input(pl, argc, argv, use_stdin);
672
+ add_patterns_from_input(pl, argc, argv,
673
+ use_stdin ? stdin : NULL);
674
break;
675
}
676
932
return set_config(MODE_NO_PATTERNS);
933
}
934
935
+static char const * const builtin_sparse_checkout_check_rules_usage[] = {
936
+ N_("git sparse-checkout check-rules [-z] [--skip-checks]"
937
+ "[--[no-]cone] [--rules-file <file>]"),
938
+ NULL
939
+};
940
+
941
+static struct sparse_checkout_check_rules_opts {
942
+ int cone_mode;
943
+ int null_termination;
944
+ char *rules_file;
945
+} check_rules_opts;
946
+
947
+static int check_rules(struct pattern_list *pl, int null_terminated) {
948
+ struct strbuf line = STRBUF_INIT;
949
+ struct strbuf unquoted = STRBUF_INIT;
950
+ char *path;
951
+ int line_terminator = null_terminated ? 0 : '\n';
952
+ strbuf_getline_fn getline_fn = null_terminated ? strbuf_getline_nul
953
+ : strbuf_getline;
954
+ the_repository->index->sparse_checkout_patterns = pl;
955
+ while (!getline_fn(&line, stdin)) {
956
+ path = line.buf;
957
+ if (!null_terminated && line.buf[0] == '"') {
958
+ strbuf_reset(&unquoted);
959
+ if (unquote_c_style(&unquoted, line.buf, NULL))
960
+ die(_("unable to unquote C-style string '%s'"),
961
+ line.buf);
962
+
963
+ path = unquoted.buf;
964
+ }
965
+
966
+ if (path_in_sparse_checkout(path, the_repository->index))
967
+ write_name_quoted(path, stdout, line_terminator);
968
+ }
969
+ strbuf_release(&line);
970
+ strbuf_release(&unquoted);
971
+
972
+ return 0;
973
+}
974
+
975
+static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix)
976
+{
977
+ static struct option builtin_sparse_checkout_check_rules_options[] = {
978
+ OPT_BOOL('z', NULL, &check_rules_opts.null_termination,
979
+ N_("terminate input and output files by a NUL character")),
980
+ OPT_BOOL(0, "cone", &check_rules_opts.cone_mode,
981
+ N_("when used with --rules-file interpret patterns as cone mode patterns")),
982
+ OPT_FILENAME(0, "rules-file", &check_rules_opts.rules_file,
983
+ N_("use patterns in <file> instead of the current ones.")),
984
+ OPT_END(),
985
+ };
986
+
987
+ FILE *fp;
988
+ int ret;
989
+ struct pattern_list pl = {0};
990
+ char *sparse_filename;
991
+ check_rules_opts.cone_mode = -1;
992
+
993
+ argc = parse_options(argc, argv, prefix,
994
+ builtin_sparse_checkout_check_rules_options,
995
+ builtin_sparse_checkout_check_rules_usage,
996
+ PARSE_OPT_KEEP_UNKNOWN_OPT);
997
+
998
+ if (check_rules_opts.rules_file && check_rules_opts.cone_mode < 0)
999
+ check_rules_opts.cone_mode = 1;
1000
+
1001
+ update_cone_mode(&check_rules_opts.cone_mode);
1002
+ pl.use_cone_patterns = core_sparse_checkout_cone;
1003
+ if (check_rules_opts.rules_file) {
1004
+ fp = xfopen(check_rules_opts.rules_file, "r");
1005
+ add_patterns_from_input(&pl, argc, argv, fp);
1006
+ fclose(fp);
1007
+ } else {
1008
+ sparse_filename = get_sparse_checkout_filename();
1009
+ if (add_patterns_from_file_to_list(sparse_filename, "", 0, &pl,
1010
+ NULL, 0))
1011
+ die(_("unable to load existing sparse-checkout patterns"));
1012
+ free(sparse_filename);
1013
+ }
1014
+
1015
+ ret = check_rules(&pl, check_rules_opts.null_termination);
1016
+ clear_pattern_list(&pl);
1017
+ return ret;
1018
+}
1019
+
1020
int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
1021
{
1022
parse_opt_subcommand_fn *fn = NULL;
1027
OPT_SUBCOMMAND("add", &fn, sparse_checkout_add),
1028
OPT_SUBCOMMAND("reapply", &fn, sparse_checkout_reapply),
1029
OPT_SUBCOMMAND("disable", &fn, sparse_checkout_disable),
1030
+ OPT_SUBCOMMAND("check-rules", &fn, sparse_checkout_check_rules),
1031
OPT_END(),
1032
};
1033