18
static const char *empty_base = "";
19
20
static char const * const builtin_sparse_checkout_usage[] = {
21
- N_("git sparse-checkout (init|list|set|disable) <options>"),
21
+ N_("git sparse-checkout (init|list|set|add|disable) <options>"),
22
NULL
23
};
24
404
}
405
406
static char const * const builtin_sparse_checkout_set_usage[] = {
407
- N_("git sparse-checkout set (--stdin | <patterns>)"),
407
+ N_("git sparse-checkout (set|add) (--stdin | <patterns>)"),
408
NULL
409
};
410
464
465
enum modify_type {
466
REPLACE,
467
+ ADD,
468
};
469
470
+static void add_patterns_cone_mode(int argc, const char **argv,
471
+ struct pattern_list *pl)
472
+{
473
+ struct strbuf buffer = STRBUF_INIT;
474
+ struct pattern_entry *pe;
475
+ struct hashmap_iter iter;
476
+ struct pattern_list existing;
477
+ char *sparse_filename = get_sparse_checkout_filename();
478
+
479
+ add_patterns_from_input(pl, argc, argv);
480
+
481
+ memset(&existing, 0, sizeof(existing));
482
+ existing.use_cone_patterns = core_sparse_checkout_cone;
483
+
484
+ if (add_patterns_from_file_to_list(sparse_filename, "", 0,
485
+ &existing, NULL))
486
+ die(_("unable to load existing sparse-checkout patterns"));
487
+ free(sparse_filename);
488
+
489
+ hashmap_for_each_entry(&existing.recursive_hashmap, &iter, pe, ent) {
490
+ if (!hashmap_contains_parent(&pl->recursive_hashmap,
491
+ pe->pattern, &buffer) ||
492
+ !hashmap_contains_parent(&pl->parent_hashmap,
493
+ pe->pattern, &buffer)) {
494
+ strbuf_reset(&buffer);
495
+ strbuf_addstr(&buffer, pe->pattern);
496
+ insert_recursive_pattern(pl, &buffer);
497
+ }
498
+ }
499
+
500
+ clear_pattern_list(&existing);
501
+ strbuf_release(&buffer);
502
+}
503
+
504
+static void add_patterns_literal(int argc, const char **argv,
505
+ struct pattern_list *pl)
506
+{
507
+ char *sparse_filename = get_sparse_checkout_filename();
508
+ if (add_patterns_from_file_to_list(sparse_filename, "", 0,
509
+ pl, NULL))
510
+ die(_("unable to load existing sparse-checkout patterns"));
511
+ free(sparse_filename);
512
+ add_patterns_from_input(pl, argc, argv);
513
+}
514
+
515
static int modify_pattern_list(int argc, const char **argv, enum modify_type m)
516
{
517
int result;
519
struct pattern_list pl;
520
memset(&pl, 0, sizeof(pl));
521
476
- add_patterns_from_input(&pl, argc, argv);
522
+ switch (m) {
523
+ case ADD:
524
+ if (core_sparse_checkout_cone)
525
+ add_patterns_cone_mode(argc, argv, &pl);
526
+ else
527
+ add_patterns_literal(argc, argv, &pl);
528
+ break;
529
+
530
+ case REPLACE:
531
+ add_patterns_from_input(&pl, argc, argv);
532
+ break;
533
+ }
534
535
if (!core_apply_sparse_checkout) {
536
set_config(MODE_ALL_PATTERNS);
547
return result;
548
}
549
493
-static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
550
+static int sparse_checkout_set(int argc, const char **argv, const char *prefix,
551
+ enum modify_type m)
552
{
553
static struct option builtin_sparse_checkout_set_options[] = {
554
OPT_BOOL(0, "stdin", &set_opts.use_stdin,
565
builtin_sparse_checkout_set_usage,
566
PARSE_OPT_KEEP_UNKNOWN);
567
510
- return modify_pattern_list(argc, argv, REPLACE);
568
+ return modify_pattern_list(argc, argv, m);
569
}
570
571
static int sparse_checkout_disable(int argc, const char **argv)
616
if (!strcmp(argv[0], "init"))
617
return sparse_checkout_init(argc, argv);
618
if (!strcmp(argv[0], "set"))
561
- return sparse_checkout_set(argc, argv, prefix);
619
+ return sparse_checkout_set(argc, argv, prefix, REPLACE);
620
+ if (!strcmp(argv[0], "add"))
621
+ return sparse_checkout_set(argc, argv, prefix, ADD);
622
if (!strcmp(argv[0], "disable"))
623
return sparse_checkout_disable(argc, argv);
624
}