summaryrefslogtreecommitdiff
path: root/builtin/update-index.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/update-index.c')
-rw-r--r--builtin/update-index.c122
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) {