mirror of
https://github.com/git/git.git
synced 2024-11-24 02:17:02 +08:00
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:
commit
95713ff4fb
2
apply.c
2
apply.c
@ -4688,7 +4688,7 @@ static int apply_patch(struct apply_state *state,
|
|||||||
state->index_file,
|
state->index_file,
|
||||||
LOCK_DIE_ON_ERROR);
|
LOCK_DIE_ON_ERROR);
|
||||||
else
|
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) {
|
if (state->check_index && read_apply_cache(state) < 0) {
|
||||||
|
@ -361,7 +361,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||||||
add_new_files = !take_worktree_changes && !refresh_only;
|
add_new_files = !take_worktree_changes && !refresh_only;
|
||||||
require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
|
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) |
|
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
|
||||||
(show_only ? ADD_CACHE_PRETEND : 0) |
|
(show_only ? ADD_CACHE_PRETEND : 0) |
|
||||||
|
@ -1119,7 +1119,7 @@ static void refresh_and_write_cache(void)
|
|||||||
{
|
{
|
||||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
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);
|
refresh_cache(REFRESH_QUIET);
|
||||||
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
|
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
|
||||||
die(_("unable to write index file"));
|
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;
|
return -1;
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(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);
|
refresh_cache(REFRESH_QUIET);
|
||||||
|
|
||||||
@ -2016,7 +2016,7 @@ static int merge_tree(struct tree *tree)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(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);
|
||||||
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
memset(&opts, 0, sizeof(opts));
|
||||||
opts.head_idx = 1;
|
opts.head_idx = 1;
|
||||||
|
@ -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) {
|
if (index_opt && !state.base_dir_len && !to_tempfile) {
|
||||||
state.refresh_cache = 1;
|
state.refresh_cache = 1;
|
||||||
state.istate = &the_index;
|
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 */
|
/* Check out named files first */
|
||||||
|
@ -274,7 +274,7 @@ static int checkout_paths(const struct checkout_opts *opts,
|
|||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(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(&opts->pathspec) < 0)
|
if (read_cache_preload(&opts->pathspec) < 0)
|
||||||
return error(_("index file corrupt"));
|
return error(_("index file corrupt"));
|
||||||
|
|
||||||
@ -467,7 +467,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
|
|||||||
int ret;
|
int ret;
|
||||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
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)
|
if (read_cache_preload(NULL) < 0)
|
||||||
return error(_("index file corrupt"));
|
return error(_("index file corrupt"));
|
||||||
|
|
||||||
|
@ -711,7 +711,7 @@ static int checkout(int submodule_progress)
|
|||||||
setup_work_tree();
|
setup_work_tree();
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(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);
|
||||||
|
|
||||||
memset(&opts, 0, sizeof opts);
|
memset(&opts, 0, sizeof opts);
|
||||||
opts.update = 1;
|
opts.update = 1;
|
||||||
|
@ -351,7 +351,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||||||
|
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
char *old_index_env = NULL;
|
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);
|
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.
|
* (B) on failure, rollback the real index.
|
||||||
*/
|
*/
|
||||||
if (all || (also && pathspec.nr)) {
|
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);
|
add_files_to_cache(also ? prefix : NULL, &pathspec, 0);
|
||||||
refresh_cache_or_die(refresh_flags);
|
refresh_cache_or_die(refresh_flags);
|
||||||
update_main_cache_tree(WRITE_TREE_SILENT);
|
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.
|
* We still need to refresh the index here.
|
||||||
*/
|
*/
|
||||||
if (!only && !pathspec.nr) {
|
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);
|
refresh_cache_or_die(refresh_flags);
|
||||||
if (active_cache_changed
|
if (active_cache_changed
|
||||||
|| !cache_tree_fully_valid(active_cache_tree))
|
|| !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)
|
if (read_cache() < 0)
|
||||||
die(_("cannot read the index"));
|
die(_("cannot read the index"));
|
||||||
|
|
||||||
hold_locked_index(&index_lock, 1);
|
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||||
add_remove_files(&partial);
|
add_remove_files(&partial);
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
update_main_cache_tree(WRITE_TREE_SILENT);
|
update_main_cache_tree(WRITE_TREE_SILENT);
|
||||||
|
@ -634,7 +634,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
|
|||||||
{
|
{
|
||||||
static struct lock_file lock;
|
static struct lock_file lock;
|
||||||
|
|
||||||
hold_locked_index(&lock, 1);
|
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
if (active_cache_changed &&
|
if (active_cache_changed &&
|
||||||
write_locked_index(&the_index, &lock, COMMIT_LOCK))
|
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)
|
for (j = common; j; j = j->next)
|
||||||
commit_list_insert(j->item, &reversed);
|
commit_list_insert(j->item, &reversed);
|
||||||
|
|
||||||
hold_locked_index(&lock, 1);
|
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
|
||||||
clean = merge_recursive(&o, head,
|
clean = merge_recursive(&o, head,
|
||||||
remoteheads->item, reversed, &result);
|
remoteheads->item, reversed, &result);
|
||||||
if (clean < 0)
|
if (clean < 0)
|
||||||
@ -781,7 +781,7 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
|
|||||||
struct commit_list *parents, **pptr = &parents;
|
struct commit_list *parents, **pptr = &parents;
|
||||||
static struct lock_file lock;
|
static struct lock_file lock;
|
||||||
|
|
||||||
hold_locked_index(&lock, 1);
|
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
if (active_cache_changed &&
|
if (active_cache_changed &&
|
||||||
write_locked_index(&the_index, &lock, COMMIT_LOCK))
|
write_locked_index(&the_index, &lock, COMMIT_LOCK))
|
||||||
|
@ -126,7 +126,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
|
|||||||
if (--argc < 1)
|
if (--argc < 1)
|
||||||
usage_with_options(builtin_mv_usage, builtin_mv_options);
|
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)
|
if (read_cache() < 0)
|
||||||
die(_("index file corrupt"));
|
die(_("index file corrupt"));
|
||||||
|
|
||||||
|
@ -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,
|
argc = parse_options(argc, argv, unused_prefix, read_tree_options,
|
||||||
read_tree_usage, 0);
|
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;
|
prefix_set = opts.prefix ? 1 : 0;
|
||||||
if (1 < opts.merge + opts.reset + prefix_set)
|
if (1 < opts.merge + opts.reset + prefix_set)
|
||||||
|
@ -354,7 +354,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
if (reset_type != SOFT) {
|
if (reset_type != SOFT) {
|
||||||
struct lock_file *lock = xcalloc(1, sizeof(*lock));
|
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) {
|
if (reset_type == MIXED) {
|
||||||
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
|
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
|
||||||
if (read_from_tree(&pathspec, &oid, intent_to_add))
|
if (read_from_tree(&pathspec, &oid, intent_to_add))
|
||||||
|
@ -292,7 +292,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
|||||||
if (!index_only)
|
if (!index_only)
|
||||||
setup_work_tree();
|
setup_work_tree();
|
||||||
|
|
||||||
hold_locked_index(&lock_file, 1);
|
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||||
|
|
||||||
if (read_cache() < 0)
|
if (read_cache() < 0)
|
||||||
die(_("index file corrupt"));
|
die(_("index file corrupt"));
|
||||||
|
@ -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() */
|
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
|
||||||
lock_file = xcalloc(1, sizeof(struct lock_file));
|
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);
|
newfd = hold_locked_index(lock_file, 0);
|
||||||
if (newfd < 0)
|
if (newfd < 0)
|
||||||
lock_error = errno;
|
lock_error = errno;
|
||||||
|
12
lockfile.c
12
lockfile.c
@ -174,8 +174,16 @@ int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path,
|
|||||||
int flags, long timeout_ms)
|
int flags, long timeout_ms)
|
||||||
{
|
{
|
||||||
int fd = lock_file_timeout(lk, path, flags, timeout_ms);
|
int fd = lock_file_timeout(lk, path, flags, timeout_ms);
|
||||||
if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
|
if (fd < 0) {
|
||||||
unable_to_lock_die(path, errno);
|
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;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,10 +129,16 @@ struct lock_file {
|
|||||||
/*
|
/*
|
||||||
* If a lock is already taken for the file, `die()` with an error
|
* 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
|
* 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
|
#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
|
* Usually symbolic links in the destination path are resolved. This
|
||||||
* means that (1) the lockfile is created by adding ".lock" to the
|
* means that (1) the lockfile is created by adding ".lock" to the
|
||||||
|
@ -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,
|
clean = merge_recursive(o, head_commit, next_commit, ca,
|
||||||
result);
|
result);
|
||||||
if (clean < 0)
|
if (clean < 0)
|
||||||
|
2
merge.c
2
merge.c
@ -57,7 +57,7 @@ int checkout_fast_forward(const unsigned char *head,
|
|||||||
|
|
||||||
refresh_cache(REFRESH_QUIET);
|
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;
|
return -1;
|
||||||
|
|
||||||
memset(&trees, 0, sizeof(trees));
|
memset(&trees, 0, sizeof(trees));
|
||||||
|
@ -1425,12 +1425,9 @@ static int read_index_extension(struct index_state *istate,
|
|||||||
return 0;
|
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(),
|
return hold_lock_file_for_update(lk, get_index_file(), lock_flags);
|
||||||
die_on_error
|
|
||||||
? LOCK_DIE_ON_ERROR
|
|
||||||
: 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_index(struct index_state *istate)
|
int read_index(struct index_state *istate)
|
||||||
|
2
rerere.c
2
rerere.c
@ -708,7 +708,7 @@ static void update_paths(struct string_list *update)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
hold_locked_index(&index_lock, 1);
|
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||||
|
|
||||||
for (i = 0; i < update->nr; i++) {
|
for (i = 0; i < update->nr; i++) {
|
||||||
struct string_list_item *item = &update->items[i];
|
struct string_list_item *item = &update->items[i];
|
||||||
|
@ -323,7 +323,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
|
|||||||
char **xopt;
|
char **xopt;
|
||||||
static struct lock_file index_lock;
|
static struct lock_file index_lock;
|
||||||
|
|
||||||
hold_locked_index(&index_lock, 1);
|
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||||
|
|
||||||
read_cache();
|
read_cache();
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ static struct lock_file index_lock;
|
|||||||
int cmd_main(int ac, const char **av)
|
int cmd_main(int ac, const char **av)
|
||||||
{
|
{
|
||||||
setup_git_directory();
|
setup_git_directory();
|
||||||
hold_locked_index(&index_lock, 1);
|
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||||
if (read_cache() < 0)
|
if (read_cache() < 0)
|
||||||
die("unable to read index file");
|
die("unable to read index file");
|
||||||
active_cache_tree = NULL;
|
active_cache_tree = NULL;
|
||||||
|
@ -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)
|
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));
|
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);
|
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);
|
rollback_lock_file(lock_file);
|
||||||
|
|
||||||
if (has_unstaged_changes(ignore_submodules)) {
|
if (has_unstaged_changes(ignore_submodules)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user