|
2 | 2 | #define DISABLE_SIGN_COMPARE_WARNINGS
|
3 | 3 |
|
4 | 4 | #include "builtin.h"
|
| 5 | +#include "abspath.h" |
5 | 6 | #include "config.h"
|
6 | 7 | #include "dir.h"
|
7 | 8 | #include "environment.h"
|
|
23 | 24 | static const char *empty_base = "";
|
24 | 25 |
|
25 | 26 | static char const * const builtin_sparse_checkout_usage[] = {
|
26 |
| - N_("git sparse-checkout (init | list | set | add | reapply | disable | check-rules) [<options>]"), |
| 27 | + N_("git sparse-checkout (init | list | set | add | reapply | disable | check-rules | clean) [<options>]"), |
27 | 28 | NULL
|
28 | 29 | };
|
29 | 30 |
|
@@ -924,6 +925,66 @@ static int sparse_checkout_reapply(int argc, const char **argv,
|
924 | 925 | return update_working_directory(repo, NULL);
|
925 | 926 | }
|
926 | 927 |
|
| 928 | +static char const * const builtin_sparse_checkout_clean_usage[] = { |
| 929 | + "git sparse-checkout clean [-n|--dry-run]", |
| 930 | + NULL |
| 931 | +}; |
| 932 | + |
| 933 | +static const char *msg_remove = N_("Removing %s\n"); |
| 934 | + |
| 935 | +static int sparse_checkout_clean(int argc, const char **argv, |
| 936 | + const char *prefix, |
| 937 | + struct repository *repo) |
| 938 | +{ |
| 939 | + struct strbuf full_path = STRBUF_INIT; |
| 940 | + const char *msg = msg_remove; |
| 941 | + size_t worktree_len; |
| 942 | + |
| 943 | + struct option builtin_sparse_checkout_clean_options[] = { |
| 944 | + OPT_END(), |
| 945 | + }; |
| 946 | + |
| 947 | + setup_work_tree(); |
| 948 | + if (!repo->settings.sparse_checkout) |
| 949 | + die(_("must be in a sparse-checkout to clean directories")); |
| 950 | + if (!repo->settings.sparse_checkout_cone) |
| 951 | + die(_("must be in a cone-mode sparse-checkout to clean directories")); |
| 952 | + |
| 953 | + argc = parse_options(argc, argv, prefix, |
| 954 | + builtin_sparse_checkout_clean_options, |
| 955 | + builtin_sparse_checkout_clean_usage, 0); |
| 956 | + |
| 957 | + if (repo_read_index(repo) < 0) |
| 958 | + die(_("failed to read index")); |
| 959 | + |
| 960 | + if (convert_to_sparse(repo->index, SPARSE_INDEX_MEMORY_ONLY) || |
| 961 | + repo->index->sparse_index == INDEX_EXPANDED) |
| 962 | + die(_("failed to convert index to a sparse index; resolve merge conflicts and try again")); |
| 963 | + |
| 964 | + strbuf_addstr(&full_path, repo->worktree); |
| 965 | + strbuf_addch(&full_path, '/'); |
| 966 | + worktree_len = full_path.len; |
| 967 | + |
| 968 | + for (size_t i = 0; i < repo->index->cache_nr; i++) { |
| 969 | + struct cache_entry *ce = repo->index->cache[i]; |
| 970 | + if (!S_ISSPARSEDIR(ce->ce_mode)) |
| 971 | + continue; |
| 972 | + strbuf_setlen(&full_path, worktree_len); |
| 973 | + strbuf_add(&full_path, ce->name, ce->ce_namelen); |
| 974 | + |
| 975 | + if (!is_directory(full_path.buf)) |
| 976 | + continue; |
| 977 | + |
| 978 | + printf(msg, ce->name); |
| 979 | + |
| 980 | + if (remove_dir_recursively(&full_path, 0)) |
| 981 | + warning_errno(_("failed to remove '%s'"), ce->name); |
| 982 | + } |
| 983 | + |
| 984 | + strbuf_release(&full_path); |
| 985 | + return 0; |
| 986 | +} |
| 987 | + |
927 | 988 | static char const * const builtin_sparse_checkout_disable_usage[] = {
|
928 | 989 | "git sparse-checkout disable",
|
929 | 990 | NULL
|
@@ -1079,6 +1140,7 @@ int cmd_sparse_checkout(int argc,
|
1079 | 1140 | OPT_SUBCOMMAND("set", &fn, sparse_checkout_set),
|
1080 | 1141 | OPT_SUBCOMMAND("add", &fn, sparse_checkout_add),
|
1081 | 1142 | OPT_SUBCOMMAND("reapply", &fn, sparse_checkout_reapply),
|
| 1143 | + OPT_SUBCOMMAND("clean", &fn, sparse_checkout_clean), |
1082 | 1144 | OPT_SUBCOMMAND("disable", &fn, sparse_checkout_disable),
|
1083 | 1145 | OPT_SUBCOMMAND("check-rules", &fn, sparse_checkout_check_rules),
|
1084 | 1146 | OPT_END(),
|
|
0 commit comments