Merge branch 'jc/lock-report-on-error'

Git 2.11 had a minor regression in "merge --ff-only" that competed
with another process that simultanously attempted to update the
index. We used to explain what went wrong with an error message,
but the new code silently failed.  The error message has been
resurrected.

* jc/lock-report-on-error:
  lockfile: LOCK_REPORT_ON_ERROR
  hold_locked_index(): align error handling with hold_lockfile_for_update()
  wt-status: implement opportunisitc index update correctly
This commit is contained in:
Junio C Hamano 2016-12-19 14:45:35 -08:00
commit 95713ff4fb
22 changed files with 49 additions and 36 deletions

View File

@ -4688,7 +4688,7 @@ static int apply_patch(struct apply_state *state,
state->index_file,
LOCK_DIE_ON_ERROR);
else
state->newfd = hold_locked_index(state->lock_file, 1);
state->newfd = hold_locked_index(state->lock_file, LOCK_DIE_ON_ERROR);
}
if (state->check_index && read_apply_cache(state) < 0) {

View File

@ -361,7 +361,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
add_new_files = !take_worktree_changes && !refresh_only;
require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
hold_locked_index(&lock_file, 1);
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
(show_only ? ADD_CACHE_PRETEND : 0) |

View File

@ -1119,7 +1119,7 @@ static void refresh_and_write_cache(void)
{
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
refresh_cache(REFRESH_QUIET);
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
die(_("unable to write index file"));
@ -1976,7 +1976,7 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
return -1;
lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
refresh_cache(REFRESH_QUIET);
@ -2016,7 +2016,7 @@ static int merge_tree(struct tree *tree)
return -1;
lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
memset(&opts, 0, sizeof(opts));
opts.head_idx = 1;

View File

@ -205,7 +205,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
if (index_opt && !state.base_dir_len && !to_tempfile) {
state.refresh_cache = 1;
state.istate = &the_index;
newfd = hold_locked_index(&lock_file, 1);
newfd = hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
}
/* Check out named files first */

View File

@ -274,7 +274,7 @@ static int checkout_paths(const struct checkout_opts *opts,
lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
if (read_cache_preload(&opts->pathspec) < 0)
return error(_("index file corrupt"));
@ -467,7 +467,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
int ret;
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
if (read_cache_preload(NULL) < 0)
return error(_("index file corrupt"));

View File

@ -711,7 +711,7 @@ static int checkout(int submodule_progress)
setup_work_tree();
lock_file = xcalloc(1, sizeof(struct lock_file));
hold_locked_index(lock_file, 1);
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
memset(&opts, 0, sizeof opts);
opts.update = 1;

View File

@ -351,7 +351,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
if (interactive) {
char *old_index_env = NULL;
hold_locked_index(&index_lock, 1);
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
refresh_cache_or_die(refresh_flags);
@ -396,7 +396,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
* (B) on failure, rollback the real index.
*/
if (all || (also && pathspec.nr)) {
hold_locked_index(&index_lock, 1);
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
add_files_to_cache(also ? prefix : NULL, &pathspec, 0);
refresh_cache_or_die(refresh_flags);
update_main_cache_tree(WRITE_TREE_SILENT);
@ -416,7 +416,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
* We still need to refresh the index here.
*/
if (!only && !pathspec.nr) {
hold_locked_index(&index_lock, 1);
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
refresh_cache_or_die(refresh_flags);
if (active_cache_changed
|| !cache_tree_fully_valid(active_cache_tree))
@ -468,7 +468,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
if (read_cache() < 0)
die(_("cannot read the index"));
hold_locked_index(&index_lock, 1);
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
add_remove_files(&partial);
refresh_cache(REFRESH_QUIET);
update_main_cache_tree(WRITE_TREE_SILENT);

View File

@ -634,7 +634,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
{
static struct lock_file lock;
hold_locked_index(&lock, 1);
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
refresh_cache(REFRESH_QUIET);
if (active_cache_changed &&
write_locked_index(&the_index, &lock, COMMIT_LOCK))
@ -671,7 +671,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
for (j = common; j; j = j->next)
commit_list_insert(j->item, &reversed);
hold_locked_index(&lock, 1);
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
clean = merge_recursive(&o, head,
remoteheads->item, reversed, &result);
if (clean < 0)
@ -781,7 +781,7 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
struct commit_list *parents, **pptr = &parents;
static struct lock_file lock;
hold_locked_index(&lock, 1);
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
refresh_cache(REFRESH_QUIET);
if (active_cache_changed &&
write_locked_index(&the_index, &lock, COMMIT_LOCK))

View File

@ -126,7 +126,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (--argc < 1)
usage_with_options(builtin_mv_usage, builtin_mv_options);
hold_locked_index(&lock_file, 1);
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
if (read_cache() < 0)
die(_("index file corrupt"));

View File

@ -150,7 +150,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
argc = parse_options(argc, argv, unused_prefix, read_tree_options,
read_tree_usage, 0);
hold_locked_index(&lock_file, 1);
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
prefix_set = opts.prefix ? 1 : 0;
if (1 < opts.merge + opts.reset + prefix_set)

View File

@ -354,7 +354,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (reset_type != SOFT) {
struct lock_file *lock = xcalloc(1, sizeof(*lock));
hold_locked_index(lock, 1);
hold_locked_index(lock, LOCK_DIE_ON_ERROR);
if (reset_type == MIXED) {
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
if (read_from_tree(&pathspec, &oid, intent_to_add))

View File

@ -292,7 +292,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (!index_only)
setup_work_tree();
hold_locked_index(&lock_file, 1);
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
if (read_cache() < 0)
die(_("index file corrupt"));

View File

@ -1012,6 +1012,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
lock_file = xcalloc(1, sizeof(struct lock_file));
/* we will diagnose later if it turns out that we need to update it */
newfd = hold_locked_index(lock_file, 0);
if (newfd < 0)
lock_error = errno;

View File

@ -174,8 +174,16 @@ int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path,
int flags, long timeout_ms)
{
int fd = lock_file_timeout(lk, path, flags, timeout_ms);
if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
unable_to_lock_die(path, errno);
if (fd < 0) {
if (flags & LOCK_DIE_ON_ERROR)
unable_to_lock_die(path, errno);
if (flags & LOCK_REPORT_ON_ERROR) {
struct strbuf buf = STRBUF_INIT;
unable_to_lock_message(path, errno, &buf);
error("%s", buf.buf);
strbuf_release(&buf);
}
}
return fd;
}

View File

@ -129,10 +129,16 @@ struct lock_file {
/*
* If a lock is already taken for the file, `die()` with an error
* message. If this flag is not specified, trying to lock a file that
* is already locked returns -1 to the caller.
* is already locked silently returns -1 to the caller, or ...
*/
#define LOCK_DIE_ON_ERROR 1
/*
* ... this flag can be passed instead to return -1 and give the usual
* error message upon an error.
*/
#define LOCK_REPORT_ON_ERROR 2
/*
* Usually symbolic links in the destination path are resolved. This
* means that (1) the lockfile is created by adding ".lock" to the

View File

@ -2133,7 +2133,7 @@ int merge_recursive_generic(struct merge_options *o,
}
}
hold_locked_index(lock, 1);
hold_locked_index(lock, LOCK_DIE_ON_ERROR);
clean = merge_recursive(o, head_commit, next_commit, ca,
result);
if (clean < 0)

View File

@ -57,7 +57,7 @@ int checkout_fast_forward(const unsigned char *head,
refresh_cache(REFRESH_QUIET);
if (hold_locked_index(lock_file, 0) < 0)
if (hold_locked_index(lock_file, LOCK_REPORT_ON_ERROR) < 0)
return -1;
memset(&trees, 0, sizeof(trees));

View File

@ -1425,12 +1425,9 @@ static int read_index_extension(struct index_state *istate,
return 0;
}
int hold_locked_index(struct lock_file *lk, int die_on_error)
int hold_locked_index(struct lock_file *lk, int lock_flags)
{
return hold_lock_file_for_update(lk, get_index_file(),
die_on_error
? LOCK_DIE_ON_ERROR
: 0);
return hold_lock_file_for_update(lk, get_index_file(), lock_flags);
}
int read_index(struct index_state *istate)

View File

@ -708,7 +708,7 @@ static void update_paths(struct string_list *update)
{
int i;
hold_locked_index(&index_lock, 1);
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
for (i = 0; i < update->nr; i++) {
struct string_list_item *item = &update->items[i];

View File

@ -323,7 +323,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
char **xopt;
static struct lock_file index_lock;
hold_locked_index(&index_lock, 1);
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
read_cache();

View File

@ -8,7 +8,7 @@ static struct lock_file index_lock;
int cmd_main(int ac, const char **av)
{
setup_git_directory();
hold_locked_index(&index_lock, 1);
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
if (read_cache() < 0)
die("unable to read index file");
active_cache_tree = NULL;

View File

@ -2258,11 +2258,12 @@ int has_uncommitted_changes(int ignore_submodules)
int require_clean_work_tree(const char *action, const char *hint, int ignore_submodules, int gently)
{
struct lock_file *lock_file = xcalloc(1, sizeof(*lock_file));
int err = 0;
int err = 0, fd;
hold_locked_index(lock_file, 0);
fd = hold_locked_index(lock_file, 0);
refresh_cache(REFRESH_QUIET);
update_index_if_able(&the_index, lock_file);
if (0 <= fd)
update_index_if_able(&the_index, lock_file);
rollback_lock_file(lock_file);
if (has_unstaged_changes(ignore_submodules)) {