diff options
Diffstat (limited to 'builtin/update-index.c')
-rw-r--r-- | builtin/update-index.c | 122 |
1 files changed, 66 insertions, 56 deletions
diff --git a/builtin/update-index.c b/builtin/update-index.c index 7431938fa6..9e9e04059c 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -35,6 +35,15 @@ static int mark_skip_worktree_only; #define UNMARK_FLAG 2 static struct strbuf mtime_dir = STRBUF_INIT; +/* Untracked cache mode */ +enum uc_mode { + UC_UNSPECIFIED = -1, + UC_DISABLE = 0, + UC_ENABLE, + UC_TEST, + UC_FORCE +}; + __attribute__((format (printf, 1, 2))) static void report(const char *fmt, ...) { @@ -121,7 +130,7 @@ static int test_if_untracked_cache_is_supported(void) if (!mkdtemp(mtime_dir.buf)) die_errno("Could not make temporary directory"); - fprintf(stderr, _("Testing ")); + fprintf(stderr, _("Testing mtime in '%s' "), xgetcwd()); atexit(remove_test_directory); xstat_mtime_dir(&st); fill_stat_data(&base, &st); @@ -246,7 +255,7 @@ static int process_lstat_error(const char *path, int err) { if (err == ENOENT || err == ENOTDIR) return remove_one_path(path); - return error("lstat(\"%s\"): %s", path, strerror(errno)); + return error("lstat(\"%s\"): %s", path, strerror(err)); } static int add_one_path(const struct cache_entry *old, const char *path, int len, struct stat *st) @@ -410,30 +419,18 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, return 0; } -static void chmod_path(int flip, const char *path) +static void chmod_path(char flip, const char *path) { int pos; struct cache_entry *ce; - unsigned int mode; pos = cache_name_pos(path, strlen(path)); if (pos < 0) goto fail; ce = active_cache[pos]; - mode = ce->ce_mode; - if (!S_ISREG(mode)) + if (chmod_cache_entry(ce, flip) < 0) goto fail; - switch (flip) { - case '+': - ce->ce_mode |= 0111; break; - case '-': - ce->ce_mode &= ~0111; break; - default: - goto fail; - } - cache_tree_invalidate_path(&the_index, path); - ce->ce_flags |= CE_UPDATE_IN_BASE; - active_cache_changed |= CE_ENTRY_CHANGED; + report("chmod %cx '%s'", flip, path); return; fail: @@ -468,12 +465,14 @@ static void update_one(const char *path) report("add '%s'", path); } -static void read_index_info(int line_termination) +static void read_index_info(int nul_term_line) { struct strbuf buf = STRBUF_INIT; struct strbuf uq = STRBUF_INIT; + strbuf_getline_fn getline_fn; - while (strbuf_getline(&buf, stdin, line_termination) != EOF) { + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; + while (getline_fn(&buf, stdin) != EOF) { char *ptr, *tab; char *path_name; unsigned char sha1[20]; @@ -522,7 +521,7 @@ static void read_index_info(int line_termination) goto bad_line; path_name = ptr; - if (line_termination && path_name[0] == '"') { + if (!nul_term_line && path_name[0] == '"') { strbuf_reset(&uq); if (unquote_c_style(&uq, path_name, NULL)) { die("git update-index: bad quoting of path name"); @@ -748,7 +747,7 @@ static int do_reupdate(int ac, const char **av, if (save_nr != active_nr) goto redo; } - free_pathspec(&pathspec); + clear_pathspec(&pathspec); return 0; } @@ -844,12 +843,12 @@ static int cacheinfo_callback(struct parse_opt_ctx_t *ctx, static int stdin_cacheinfo_callback(struct parse_opt_ctx_t *ctx, const struct option *opt, int unset) { - int *line_termination = opt->value; + int *nul_term_line = opt->value; if (ctx->argc != 1) return error("option '%s' must be the last argument", opt->long_name); allow_add = allow_replace = allow_remove = 1; - read_index_info(*line_termination); + read_index_info(*nul_term_line); return 0; } @@ -901,8 +900,8 @@ static int reupdate_callback(struct parse_opt_ctx_t *ctx, int cmd_update_index(int argc, const char **argv, const char *prefix) { - int newfd, entries, has_errors = 0, line_termination = '\n'; - int untracked_cache = -1; + int newfd, entries, has_errors = 0, nul_term_line = 0; + enum uc_mode untracked_cache = UC_UNSPECIFIED; int read_from_stdin = 0; int prefix_length = prefix ? strlen(prefix) : 0; int preferred_index_format = 0; @@ -912,6 +911,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) int split_index = -1; struct lock_file *lock_file; struct parse_opt_ctx_t ctx; + strbuf_getline_fn getline_fn; int parseopt_state = PARSE_OPT_UNKNOWN; struct option options[] = { OPT_BIT('q', NULL, &refresh_args.flags, @@ -963,13 +963,13 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) N_("add to index only; do not add content to object database"), 1), OPT_SET_INT(0, "force-remove", &force_remove, N_("remove named paths even if present in worktree"), 1), - OPT_SET_INT('z', NULL, &line_termination, - N_("with --stdin: input lines are terminated by null bytes"), '\0'), + OPT_BOOL('z', NULL, &nul_term_line, + N_("with --stdin: input lines are terminated by null bytes")), {OPTION_LOWLEVEL_CALLBACK, 0, "stdin", &read_from_stdin, NULL, N_("read list of paths to be updated from standard input"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, (parse_opt_cb *) stdin_callback}, - {OPTION_LOWLEVEL_CALLBACK, 0, "index-info", &line_termination, NULL, + {OPTION_LOWLEVEL_CALLBACK, 0, "index-info", &nul_term_line, NULL, N_("add entries from standard input to the index"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, (parse_opt_cb *) stdin_cacheinfo_callback}, @@ -996,8 +996,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) N_("enable or disable split index")), OPT_BOOL(0, "untracked-cache", &untracked_cache, N_("enable/disable untracked cache")), + OPT_SET_INT(0, "test-untracked-cache", &untracked_cache, + N_("test if the filesystem supports untracked cache"), UC_TEST), OPT_SET_INT(0, "force-untracked-cache", &untracked_cache, - N_("enable untracked cache without testing the filesystem"), 2), + N_("enable untracked cache without testing the filesystem"), UC_FORCE), OPT_END() }; @@ -1057,6 +1059,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) } } argc = parse_options_end(&ctx); + + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; if (preferred_index_format) { if (preferred_index_format < INDEX_FORMAT_LB || INDEX_FORMAT_UB < preferred_index_format) @@ -1070,16 +1074,17 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) } if (read_from_stdin) { - struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; setup_work_tree(); - while (strbuf_getline(&buf, stdin, line_termination) != EOF) { + while (getline_fn(&buf, stdin) != EOF) { char *p; - if (line_termination && buf.buf[0] == '"') { - strbuf_reset(&nbuf); - if (unquote_c_style(&nbuf, buf.buf, NULL)) + if (!nul_term_line && buf.buf[0] == '"') { + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) die("line is badly quoted"); - strbuf_swap(&buf, &nbuf); + strbuf_swap(&buf, &unquoted); } p = prefix_path(prefix, prefix_length, buf.buf); update_one(p); @@ -1087,7 +1092,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) chmod_path(set_executable_bit, p); free(p); } - strbuf_release(&nbuf); + strbuf_release(&unquoted); strbuf_release(&buf); } @@ -1104,27 +1109,32 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) the_index.split_index = NULL; the_index.cache_changed |= SOMETHING_CHANGED; } - if (untracked_cache > 0) { - struct untracked_cache *uc; - if (untracked_cache < 2) { - setup_work_tree(); - if (!test_if_untracked_cache_is_supported()) - return 1; - } - if (!the_index.untracked) { - uc = xcalloc(1, sizeof(*uc)); - strbuf_init(&uc->ident, 100); - uc->exclude_per_dir = ".gitignore"; - /* should be the same flags used by git-status */ - uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES; - the_index.untracked = uc; - } - add_untracked_ident(the_index.untracked); - the_index.cache_changed |= UNTRACKED_CHANGED; - } else if (!untracked_cache && the_index.untracked) { - the_index.untracked = NULL; - the_index.cache_changed |= UNTRACKED_CHANGED; + switch (untracked_cache) { + case UC_UNSPECIFIED: + break; + case UC_DISABLE: + if (git_config_get_untracked_cache() == 1) + warning("core.untrackedCache is set to true; " + "remove or change it, if you really want to " + "disable the untracked cache"); + remove_untracked_cache(&the_index); + report(_("Untracked cache disabled")); + break; + case UC_TEST: + setup_work_tree(); + return !test_if_untracked_cache_is_supported(); + case UC_ENABLE: + case UC_FORCE: + if (git_config_get_untracked_cache() == 0) + warning("core.untrackedCache is set to false; " + "remove or change it, if you really want to " + "enable the untracked cache"); + add_untracked_cache(&the_index); + report(_("Untracked cache enabled for '%s'"), get_git_work_tree()); + break; + default: + die("BUG: bad untracked_cache value: %d", untracked_cache); } if (active_cache_changed) { |