Merge branch 'ma/lockfile-fixes'
An earlier update made it possible to use an on-stack in-core lockfile structure (as opposed to having to deliberately leak an on-heap one). Many codepaths have been updated to take advantage of this new facility. * ma/lockfile-fixes: read_cache: roll back lock in `update_index_if_able()` read-cache: leave lock in right state in `write_locked_index()` read-cache: drop explicit `CLOSE_LOCK`-flag cache.h: document `write_locked_index()` apply: remove `newfd` from `struct apply_state` apply: move lockfile into `apply_state` cache-tree: simplify locking logic checkout-index: simplify locking logic tempfile: fix documentation on `delete_tempfile()` lockfile: fix documentation on `close_lock_file_gently()` treewide: prefer lockfiles on the stack sha1_file: do not leak `lock_file`
This commit is contained in:
commit
0b646bcac9
25
apply.c
25
apply.c
@ -75,13 +75,10 @@ static int parse_ignorewhitespace_option(struct apply_state *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int init_apply_state(struct apply_state *state,
|
int init_apply_state(struct apply_state *state,
|
||||||
const char *prefix,
|
const char *prefix)
|
||||||
struct lock_file *lock_file)
|
|
||||||
{
|
{
|
||||||
memset(state, 0, sizeof(*state));
|
memset(state, 0, sizeof(*state));
|
||||||
state->prefix = prefix;
|
state->prefix = prefix;
|
||||||
state->lock_file = lock_file;
|
|
||||||
state->newfd = -1;
|
|
||||||
state->apply = 1;
|
state->apply = 1;
|
||||||
state->line_termination = '\n';
|
state->line_termination = '\n';
|
||||||
state->p_value = 1;
|
state->p_value = 1;
|
||||||
@ -146,8 +143,6 @@ int check_apply_state(struct apply_state *state, int force_apply)
|
|||||||
}
|
}
|
||||||
if (state->check_index)
|
if (state->check_index)
|
||||||
state->unsafe_paths = 0;
|
state->unsafe_paths = 0;
|
||||||
if (!state->lock_file)
|
|
||||||
return error("BUG: state->lock_file should not be NULL");
|
|
||||||
|
|
||||||
if (state->apply_verbosity <= verbosity_silent) {
|
if (state->apply_verbosity <= verbosity_silent) {
|
||||||
state->saved_error_routine = get_error_routine();
|
state->saved_error_routine = get_error_routine();
|
||||||
@ -4709,13 +4704,13 @@ static int apply_patch(struct apply_state *state,
|
|||||||
state->apply = 0;
|
state->apply = 0;
|
||||||
|
|
||||||
state->update_index = state->check_index && state->apply;
|
state->update_index = state->check_index && state->apply;
|
||||||
if (state->update_index && state->newfd < 0) {
|
if (state->update_index && !is_lock_file_locked(&state->lock_file)) {
|
||||||
if (state->index_file)
|
if (state->index_file)
|
||||||
state->newfd = hold_lock_file_for_update(state->lock_file,
|
hold_lock_file_for_update(&state->lock_file,
|
||||||
state->index_file,
|
state->index_file,
|
||||||
LOCK_DIE_ON_ERROR);
|
LOCK_DIE_ON_ERROR);
|
||||||
else
|
else
|
||||||
state->newfd = hold_locked_index(state->lock_file, LOCK_DIE_ON_ERROR);
|
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) {
|
||||||
@ -4911,22 +4906,18 @@ int apply_all_patches(struct apply_state *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state->update_index) {
|
if (state->update_index) {
|
||||||
res = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);
|
res = write_locked_index(&the_index, &state->lock_file, COMMIT_LOCK);
|
||||||
if (res) {
|
if (res) {
|
||||||
error(_("Unable to write new index file"));
|
error(_("Unable to write new index file"));
|
||||||
res = -128;
|
res = -128;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
state->newfd = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = !!errs;
|
res = !!errs;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (state->newfd >= 0) {
|
rollback_lock_file(&state->lock_file);
|
||||||
rollback_lock_file(state->lock_file);
|
|
||||||
state->newfd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->apply_verbosity <= verbosity_silent) {
|
if (state->apply_verbosity <= verbosity_silent) {
|
||||||
set_error_routine(state->saved_error_routine);
|
set_error_routine(state->saved_error_routine);
|
||||||
|
8
apply.h
8
apply.h
@ -36,9 +36,8 @@ enum apply_verbosity {
|
|||||||
struct apply_state {
|
struct apply_state {
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
|
|
||||||
/* These are lock_file related */
|
/* Lock file */
|
||||||
struct lock_file *lock_file;
|
struct lock_file lock_file;
|
||||||
int newfd;
|
|
||||||
|
|
||||||
/* These control what gets looked at and modified */
|
/* These control what gets looked at and modified */
|
||||||
int apply; /* this is not a dry-run */
|
int apply; /* this is not a dry-run */
|
||||||
@ -116,8 +115,7 @@ extern int apply_parse_options(int argc, const char **argv,
|
|||||||
int *force_apply, int *options,
|
int *force_apply, int *options,
|
||||||
const char * const *apply_usage);
|
const char * const *apply_usage);
|
||||||
extern int init_apply_state(struct apply_state *state,
|
extern int init_apply_state(struct apply_state *state,
|
||||||
const char *prefix,
|
const char *prefix);
|
||||||
struct lock_file *lock_file);
|
|
||||||
extern void clear_apply_state(struct apply_state *state);
|
extern void clear_apply_state(struct apply_state *state);
|
||||||
extern int check_apply_state(struct apply_state *state, int force_apply);
|
extern int check_apply_state(struct apply_state *state, int force_apply);
|
||||||
|
|
||||||
|
27
builtin/am.c
27
builtin/am.c
@ -1134,11 +1134,11 @@ static const char *msgnum(const struct am_state *state)
|
|||||||
*/
|
*/
|
||||||
static void refresh_and_write_cache(void)
|
static void refresh_and_write_cache(void)
|
||||||
{
|
{
|
||||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
|
|
||||||
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
|
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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1488,11 +1488,10 @@ static int run_apply(const struct am_state *state, const char *index_file)
|
|||||||
struct argv_array apply_opts = ARGV_ARRAY_INIT;
|
struct argv_array apply_opts = ARGV_ARRAY_INIT;
|
||||||
struct apply_state apply_state;
|
struct apply_state apply_state;
|
||||||
int res, opts_left;
|
int res, opts_left;
|
||||||
static struct lock_file lock_file;
|
|
||||||
int force_apply = 0;
|
int force_apply = 0;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
|
|
||||||
if (init_apply_state(&apply_state, NULL, &lock_file))
|
if (init_apply_state(&apply_state, NULL))
|
||||||
die("BUG: init_apply_state() failed");
|
die("BUG: init_apply_state() failed");
|
||||||
|
|
||||||
argv_array_push(&apply_opts, "apply");
|
argv_array_push(&apply_opts, "apply");
|
||||||
@ -1946,15 +1945,14 @@ next:
|
|||||||
*/
|
*/
|
||||||
static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
|
static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
|
||||||
{
|
{
|
||||||
struct lock_file *lock_file;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
struct unpack_trees_options opts;
|
struct unpack_trees_options opts;
|
||||||
struct tree_desc t[2];
|
struct tree_desc t[2];
|
||||||
|
|
||||||
if (parse_tree(head) || parse_tree(remote))
|
if (parse_tree(head) || parse_tree(remote))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(struct lock_file));
|
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||||
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
|
|
||||||
|
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
|
|
||||||
@ -1970,11 +1968,11 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
|
|||||||
init_tree_desc(&t[1], remote->buffer, remote->size);
|
init_tree_desc(&t[1], remote->buffer, remote->size);
|
||||||
|
|
||||||
if (unpack_trees(2, t, &opts)) {
|
if (unpack_trees(2, t, &opts)) {
|
||||||
rollback_lock_file(lock_file);
|
rollback_lock_file(&lock_file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
|
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||||
die(_("unable to write new index file"));
|
die(_("unable to write new index file"));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1986,15 +1984,14 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
|
|||||||
*/
|
*/
|
||||||
static int merge_tree(struct tree *tree)
|
static int merge_tree(struct tree *tree)
|
||||||
{
|
{
|
||||||
struct lock_file *lock_file;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
struct unpack_trees_options opts;
|
struct unpack_trees_options opts;
|
||||||
struct tree_desc t[1];
|
struct tree_desc t[1];
|
||||||
|
|
||||||
if (parse_tree(tree))
|
if (parse_tree(tree))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(struct lock_file));
|
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||||
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;
|
||||||
@ -2005,11 +2002,11 @@ static int merge_tree(struct tree *tree)
|
|||||||
init_tree_desc(&t[0], tree->buffer, tree->size);
|
init_tree_desc(&t[0], tree->buffer, tree->size);
|
||||||
|
|
||||||
if (unpack_trees(1, t, &opts)) {
|
if (unpack_trees(1, t, &opts)) {
|
||||||
rollback_lock_file(lock_file);
|
rollback_lock_file(&lock_file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
|
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||||
die(_("unable to write new index file"));
|
die(_("unable to write new index file"));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -9,8 +9,6 @@ static const char * const apply_usage[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct lock_file lock_file;
|
|
||||||
|
|
||||||
int cmd_apply(int argc, const char **argv, const char *prefix)
|
int cmd_apply(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int force_apply = 0;
|
int force_apply = 0;
|
||||||
@ -18,7 +16,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)
|
|||||||
int ret;
|
int ret;
|
||||||
struct apply_state state;
|
struct apply_state state;
|
||||||
|
|
||||||
if (init_apply_state(&state, prefix, &lock_file))
|
if (init_apply_state(&state, prefix))
|
||||||
exit(128);
|
exit(128);
|
||||||
|
|
||||||
argc = apply_parse_options(argc, argv,
|
argc = apply_parse_options(argc, argv,
|
||||||
|
@ -129,8 +129,6 @@ static const char * const builtin_checkout_index_usage[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct lock_file lock_file;
|
|
||||||
|
|
||||||
static int option_parse_stage(const struct option *opt,
|
static int option_parse_stage(const struct option *opt,
|
||||||
const char *arg, int unset)
|
const char *arg, int unset)
|
||||||
{
|
{
|
||||||
@ -150,7 +148,7 @@ static int option_parse_stage(const struct option *opt,
|
|||||||
int cmd_checkout_index(int argc, const char **argv, const char *prefix)
|
int cmd_checkout_index(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int newfd = -1;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
int all = 0;
|
int all = 0;
|
||||||
int read_from_stdin = 0;
|
int read_from_stdin = 0;
|
||||||
int prefix_length;
|
int prefix_length;
|
||||||
@ -206,7 +204,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, LOCK_DIE_ON_ERROR);
|
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check out named files first */
|
/* Check out named files first */
|
||||||
@ -251,7 +249,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
|
|||||||
if (all)
|
if (all)
|
||||||
checkout_all(prefix, prefix_length);
|
checkout_all(prefix, prefix_length);
|
||||||
|
|
||||||
if (0 <= newfd &&
|
if (is_lock_file_locked(&lock_file) &&
|
||||||
write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||||
die("Unable to write new index file");
|
die("Unable to write new index file");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -247,7 +247,7 @@ static int checkout_paths(const struct checkout_opts *opts,
|
|||||||
struct object_id rev;
|
struct object_id rev;
|
||||||
struct commit *head;
|
struct commit *head;
|
||||||
int errs = 0;
|
int errs = 0;
|
||||||
struct lock_file *lock_file;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
|
|
||||||
if (opts->track != BRANCH_TRACK_UNSPECIFIED)
|
if (opts->track != BRANCH_TRACK_UNSPECIFIED)
|
||||||
die(_("'%s' cannot be used with updating paths"), "--track");
|
die(_("'%s' cannot be used with updating paths"), "--track");
|
||||||
@ -275,9 +275,7 @@ static int checkout_paths(const struct checkout_opts *opts,
|
|||||||
return run_add_interactive(revision, "--patch=checkout",
|
return run_add_interactive(revision, "--patch=checkout",
|
||||||
&opts->pathspec);
|
&opts->pathspec);
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(struct lock_file));
|
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||||
|
|
||||||
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"));
|
||||||
|
|
||||||
@ -376,7 +374,7 @@ static int checkout_paths(const struct checkout_opts *opts,
|
|||||||
}
|
}
|
||||||
errs |= finish_delayed_checkout(&state);
|
errs |= finish_delayed_checkout(&state);
|
||||||
|
|
||||||
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
|
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||||
die(_("unable to write new index file"));
|
die(_("unable to write new index file"));
|
||||||
|
|
||||||
read_ref_full("HEAD", 0, rev.hash, NULL);
|
read_ref_full("HEAD", 0, rev.hash, NULL);
|
||||||
@ -472,9 +470,9 @@ static int merge_working_tree(const struct checkout_opts *opts,
|
|||||||
int *writeout_error)
|
int *writeout_error)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
|
|
||||||
hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
|
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"));
|
||||||
|
|
||||||
@ -591,7 +589,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
|
|||||||
if (!cache_tree_fully_valid(active_cache_tree))
|
if (!cache_tree_fully_valid(active_cache_tree))
|
||||||
cache_tree_update(&the_index, WRITE_TREE_SILENT | WRITE_TREE_REPAIR);
|
cache_tree_update(&the_index, WRITE_TREE_SILENT | WRITE_TREE_REPAIR);
|
||||||
|
|
||||||
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
|
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||||
die(_("unable to write new index file"));
|
die(_("unable to write new index file"));
|
||||||
|
|
||||||
if (!opts->force && !opts->quiet)
|
if (!opts->force && !opts->quiet)
|
||||||
|
@ -706,7 +706,7 @@ static int checkout(int submodule_progress)
|
|||||||
{
|
{
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
char *head;
|
char *head;
|
||||||
struct lock_file *lock_file;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
struct unpack_trees_options opts;
|
struct unpack_trees_options opts;
|
||||||
struct tree *tree;
|
struct tree *tree;
|
||||||
struct tree_desc t;
|
struct tree_desc t;
|
||||||
@ -733,8 +733,7 @@ static int checkout(int submodule_progress)
|
|||||||
/* We need to be in the new work tree for the checkout */
|
/* We need to be in the new work tree for the checkout */
|
||||||
setup_work_tree();
|
setup_work_tree();
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(struct lock_file));
|
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||||
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;
|
||||||
@ -750,7 +749,7 @@ static int checkout(int submodule_progress)
|
|||||||
if (unpack_trees(1, &t, &opts) < 0)
|
if (unpack_trees(1, &t, &opts) < 0)
|
||||||
die(_("unable to checkout working tree"));
|
die(_("unable to checkout working tree"));
|
||||||
|
|
||||||
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
|
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||||
die(_("unable to write new index file"));
|
die(_("unable to write new index file"));
|
||||||
|
|
||||||
err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1),
|
err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1),
|
||||||
|
@ -355,7 +355,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||||||
|
|
||||||
refresh_cache_or_die(refresh_flags);
|
refresh_cache_or_die(refresh_flags);
|
||||||
|
|
||||||
if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK))
|
if (write_locked_index(&the_index, &index_lock, 0))
|
||||||
die(_("unable to create temporary index"));
|
die(_("unable to create temporary index"));
|
||||||
|
|
||||||
old_index_env = getenv(INDEX_ENVIRONMENT);
|
old_index_env = getenv(INDEX_ENVIRONMENT);
|
||||||
@ -374,7 +374,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||||||
if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) {
|
if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) {
|
||||||
if (reopen_lock_file(&index_lock) < 0)
|
if (reopen_lock_file(&index_lock) < 0)
|
||||||
die(_("unable to write index file"));
|
die(_("unable to write index file"));
|
||||||
if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK))
|
if (write_locked_index(&the_index, &index_lock, 0))
|
||||||
die(_("unable to update temporary index"));
|
die(_("unable to update temporary index"));
|
||||||
} else
|
} else
|
||||||
warning(_("Failed to update main cache tree"));
|
warning(_("Failed to update main cache tree"));
|
||||||
@ -401,7 +401,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||||||
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);
|
||||||
if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK))
|
if (write_locked_index(&the_index, &index_lock, 0))
|
||||||
die(_("unable to write new_index file"));
|
die(_("unable to write new_index file"));
|
||||||
commit_style = COMMIT_NORMAL;
|
commit_style = COMMIT_NORMAL;
|
||||||
ret = get_lock_file_path(&index_lock);
|
ret = get_lock_file_path(&index_lock);
|
||||||
@ -474,7 +474,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||||||
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);
|
||||||
if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK))
|
if (write_locked_index(&the_index, &index_lock, 0))
|
||||||
die(_("unable to write new_index file"));
|
die(_("unable to write new_index file"));
|
||||||
|
|
||||||
hold_lock_file_for_update(&false_lock,
|
hold_lock_file_for_update(&false_lock,
|
||||||
@ -486,7 +486,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||||||
add_remove_files(&partial);
|
add_remove_files(&partial);
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
|
|
||||||
if (write_locked_index(&the_index, &false_lock, CLOSE_LOCK))
|
if (write_locked_index(&the_index, &false_lock, 0))
|
||||||
die(_("unable to write temporary index file"));
|
die(_("unable to write temporary index file"));
|
||||||
|
|
||||||
discard_cache();
|
discard_cache();
|
||||||
|
@ -203,17 +203,16 @@ static int builtin_diff_combined(struct rev_info *revs,
|
|||||||
|
|
||||||
static void refresh_index_quietly(void)
|
static void refresh_index_quietly(void)
|
||||||
{
|
{
|
||||||
struct lock_file *lock_file;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
lock_file = xcalloc(1, sizeof(struct lock_file));
|
fd = hold_locked_index(&lock_file, 0);
|
||||||
fd = hold_locked_index(lock_file, 0);
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return;
|
return;
|
||||||
discard_cache();
|
discard_cache();
|
||||||
read_cache();
|
read_cache();
|
||||||
refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED);
|
refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED);
|
||||||
update_index_if_able(&the_index, lock_file);
|
update_index_if_able(&the_index, &lock_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv)
|
static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv)
|
||||||
|
@ -616,7 +616,6 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||||||
if (hold_lock_file_for_update(&lock, buf.buf, 0) < 0 ||
|
if (hold_lock_file_for_update(&lock, buf.buf, 0) < 0 ||
|
||||||
write_locked_index(&wtindex, &lock, COMMIT_LOCK)) {
|
write_locked_index(&wtindex, &lock, COMMIT_LOCK)) {
|
||||||
ret = error("could not write %s", buf.buf);
|
ret = error("could not write %s", buf.buf);
|
||||||
rollback_lock_file(&lock);
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
changed_files(&wt_modified, buf.buf, workdir);
|
changed_files(&wt_modified, buf.buf, workdir);
|
||||||
|
12
cache-tree.c
12
cache-tree.c
@ -602,11 +602,11 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat
|
|||||||
|
|
||||||
int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
|
int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
|
||||||
{
|
{
|
||||||
int entries, was_valid, newfd;
|
int entries, was_valid;
|
||||||
struct lock_file lock_file = LOCK_INIT;
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
newfd = hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
|
hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
|
||||||
|
|
||||||
entries = read_index_from(index_state, index_path);
|
entries = read_index_from(index_state, index_path);
|
||||||
if (entries < 0) {
|
if (entries < 0) {
|
||||||
@ -625,10 +625,7 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
|
|||||||
ret = WRITE_TREE_UNMERGED_INDEX;
|
ret = WRITE_TREE_UNMERGED_INDEX;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (0 <= newfd) {
|
write_locked_index(index_state, &lock_file, COMMIT_LOCK);
|
||||||
if (!write_locked_index(index_state, &lock_file, COMMIT_LOCK))
|
|
||||||
newfd = -1;
|
|
||||||
}
|
|
||||||
/* Not being able to write is fine -- we are only interested
|
/* Not being able to write is fine -- we are only interested
|
||||||
* in updating the cache-tree part, and if the next caller
|
* in updating the cache-tree part, and if the next caller
|
||||||
* ends up using the old index with unupdated cache-tree part
|
* ends up using the old index with unupdated cache-tree part
|
||||||
@ -650,8 +647,7 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
|
|||||||
hashcpy(sha1, index_state->cache_tree->oid.hash);
|
hashcpy(sha1, index_state->cache_tree->oid.hash);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (0 <= newfd)
|
rollback_lock_file(&lock_file);
|
||||||
rollback_lock_file(&lock_file);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
cache.h
25
cache.h
@ -602,9 +602,28 @@ extern int do_read_index(struct index_state *istate, const char *path,
|
|||||||
extern int read_index_from(struct index_state *, const char *path);
|
extern int read_index_from(struct index_state *, const char *path);
|
||||||
extern int is_index_unborn(struct index_state *);
|
extern int is_index_unborn(struct index_state *);
|
||||||
extern int read_index_unmerged(struct index_state *);
|
extern int read_index_unmerged(struct index_state *);
|
||||||
|
|
||||||
|
/* For use with `write_locked_index()`. */
|
||||||
#define COMMIT_LOCK (1 << 0)
|
#define COMMIT_LOCK (1 << 0)
|
||||||
#define CLOSE_LOCK (1 << 1)
|
|
||||||
|
/*
|
||||||
|
* Write the index while holding an already-taken lock. Close the lock,
|
||||||
|
* and if `COMMIT_LOCK` is given, commit it.
|
||||||
|
*
|
||||||
|
* Unless a split index is in use, write the index into the lockfile.
|
||||||
|
*
|
||||||
|
* With a split index, write the shared index to a temporary file,
|
||||||
|
* adjust its permissions and rename it into place, then write the
|
||||||
|
* split index to the lockfile. If the temporary file for the shared
|
||||||
|
* index cannot be created, fall back to the behavior described in
|
||||||
|
* the previous paragraph.
|
||||||
|
*
|
||||||
|
* With `COMMIT_LOCK`, the lock is always committed or rolled back.
|
||||||
|
* Without it, the lock is closed, but neither committed nor rolled
|
||||||
|
* back.
|
||||||
|
*/
|
||||||
extern int write_locked_index(struct index_state *, struct lock_file *lock, unsigned flags);
|
extern int write_locked_index(struct index_state *, struct lock_file *lock, unsigned flags);
|
||||||
|
|
||||||
extern int discard_index(struct index_state *);
|
extern int discard_index(struct index_state *);
|
||||||
extern void move_index_extensions(struct index_state *dst, struct index_state *src);
|
extern void move_index_extensions(struct index_state *dst, struct index_state *src);
|
||||||
extern int unmerged_index(const struct index_state *);
|
extern int unmerged_index(const struct index_state *);
|
||||||
@ -716,6 +735,10 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
|
|||||||
extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
|
extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
|
||||||
extern struct cache_entry *refresh_cache_entry(struct cache_entry *, unsigned int);
|
extern struct cache_entry *refresh_cache_entry(struct cache_entry *, unsigned int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opportunistically update the index but do not complain if we can't.
|
||||||
|
* The lockfile is always committed or rolled back.
|
||||||
|
*/
|
||||||
extern void update_index_if_able(struct index_state *, struct lock_file *);
|
extern void update_index_if_able(struct index_state *, struct lock_file *);
|
||||||
|
|
||||||
extern int hold_locked_index(struct lock_file *, int);
|
extern int hold_locked_index(struct lock_file *, int);
|
||||||
|
21
config.c
21
config.c
@ -2751,7 +2751,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
{
|
{
|
||||||
int ret = 0, remove = 0;
|
int ret = 0, remove = 0;
|
||||||
char *filename_buf = NULL;
|
char *filename_buf = NULL;
|
||||||
struct lock_file *lock;
|
struct lock_file lock = LOCK_INIT;
|
||||||
int out_fd;
|
int out_fd;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
FILE *config_file = NULL;
|
FILE *config_file = NULL;
|
||||||
@ -2766,8 +2766,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
if (!config_filename)
|
if (!config_filename)
|
||||||
config_filename = filename_buf = git_pathdup("config");
|
config_filename = filename_buf = git_pathdup("config");
|
||||||
|
|
||||||
lock = xcalloc(1, sizeof(struct lock_file));
|
out_fd = hold_lock_file_for_update(&lock, config_filename, 0);
|
||||||
out_fd = hold_lock_file_for_update(lock, config_filename, 0);
|
|
||||||
if (out_fd < 0) {
|
if (out_fd < 0) {
|
||||||
ret = error("could not lock config file %s", config_filename);
|
ret = error("could not lock config file %s", config_filename);
|
||||||
goto out;
|
goto out;
|
||||||
@ -2786,9 +2785,9 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) {
|
if (chmod(get_lock_file_path(&lock), st.st_mode & 07777) < 0) {
|
||||||
ret = error_errno("chmod on %s failed",
|
ret = error_errno("chmod on %s failed",
|
||||||
get_lock_file_path(lock));
|
get_lock_file_path(&lock));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2812,7 +2811,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
*/
|
*/
|
||||||
if (copystr.len > 0) {
|
if (copystr.len > 0) {
|
||||||
if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) {
|
if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) {
|
||||||
ret = write_error(get_lock_file_path(lock));
|
ret = write_error(get_lock_file_path(&lock));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
strbuf_reset(©str);
|
strbuf_reset(©str);
|
||||||
@ -2828,7 +2827,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
store.baselen = strlen(new_name);
|
store.baselen = strlen(new_name);
|
||||||
if (!copy) {
|
if (!copy) {
|
||||||
if (write_section(out_fd, new_name) < 0) {
|
if (write_section(out_fd, new_name) < 0) {
|
||||||
ret = write_error(get_lock_file_path(lock));
|
ret = write_error(get_lock_file_path(&lock));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -2862,7 +2861,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (write_in_full(out_fd, output, length) < 0) {
|
if (write_in_full(out_fd, output, length) < 0) {
|
||||||
ret = write_error(get_lock_file_path(lock));
|
ret = write_error(get_lock_file_path(&lock));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2874,7 +2873,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
*/
|
*/
|
||||||
if (copystr.len > 0) {
|
if (copystr.len > 0) {
|
||||||
if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) {
|
if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) {
|
||||||
ret = write_error(get_lock_file_path(lock));
|
ret = write_error(get_lock_file_path(&lock));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
strbuf_reset(©str);
|
strbuf_reset(©str);
|
||||||
@ -2883,13 +2882,13 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
|
|||||||
fclose(config_file);
|
fclose(config_file);
|
||||||
config_file = NULL;
|
config_file = NULL;
|
||||||
commit_and_out:
|
commit_and_out:
|
||||||
if (commit_lock_file(lock) < 0)
|
if (commit_lock_file(&lock) < 0)
|
||||||
ret = error_errno("could not write config file %s",
|
ret = error_errno("could not write config file %s",
|
||||||
config_filename);
|
config_filename);
|
||||||
out:
|
out:
|
||||||
if (config_file)
|
if (config_file)
|
||||||
fclose(config_file);
|
fclose(config_file);
|
||||||
rollback_lock_file(lock);
|
rollback_lock_file(&lock);
|
||||||
out_no_rollback:
|
out_no_rollback:
|
||||||
free(filename_buf);
|
free(filename_buf);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -240,8 +240,8 @@ extern char *get_locked_file_path(struct lock_file *lk);
|
|||||||
* If the lockfile is still open, close it (and the file pointer if it
|
* If the lockfile is still open, close it (and the file pointer if it
|
||||||
* has been opened using `fdopen_lock_file()`) without renaming the
|
* has been opened using `fdopen_lock_file()`) without renaming the
|
||||||
* lockfile over the file being locked. Return 0 upon success. On
|
* lockfile over the file being locked. Return 0 upon success. On
|
||||||
* failure to `close(2)`, return a negative value and roll back the
|
* failure to `close(2)`, return a negative value (the lockfile is not
|
||||||
* lock file. Usually `commit_lock_file()`, `commit_lock_file_to()`,
|
* rolled back). Usually `commit_lock_file()`, `commit_lock_file_to()`,
|
||||||
* or `rollback_lock_file()` should eventually be called.
|
* or `rollback_lock_file()` should eventually be called.
|
||||||
*/
|
*/
|
||||||
static inline int close_lock_file_gently(struct lock_file *lk)
|
static inline int close_lock_file_gently(struct lock_file *lk)
|
||||||
|
@ -2162,7 +2162,7 @@ int merge_recursive_generic(struct merge_options *o,
|
|||||||
struct commit **result)
|
struct commit **result)
|
||||||
{
|
{
|
||||||
int clean;
|
int clean;
|
||||||
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
|
struct lock_file lock = LOCK_INIT;
|
||||||
struct commit *head_commit = get_ref(head, o->branch1);
|
struct commit *head_commit = get_ref(head, o->branch1);
|
||||||
struct commit *next_commit = get_ref(merge, o->branch2);
|
struct commit *next_commit = get_ref(merge, o->branch2);
|
||||||
struct commit_list *ca = NULL;
|
struct commit_list *ca = NULL;
|
||||||
@ -2178,14 +2178,14 @@ int merge_recursive_generic(struct merge_options *o,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hold_locked_index(lock, LOCK_DIE_ON_ERROR);
|
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)
|
||||||
return clean;
|
return clean;
|
||||||
|
|
||||||
if (active_cache_changed &&
|
if (active_cache_changed &&
|
||||||
write_locked_index(&the_index, lock, COMMIT_LOCK))
|
write_locked_index(&the_index, &lock, COMMIT_LOCK))
|
||||||
return err(o, _("Unable to write index."));
|
return err(o, _("Unable to write index."));
|
||||||
|
|
||||||
return clean ? 0 : 1;
|
return clean ? 0 : 1;
|
||||||
|
8
merge.c
8
merge.c
@ -53,11 +53,11 @@ int checkout_fast_forward(const struct object_id *head,
|
|||||||
struct tree_desc t[MAX_UNPACK_TREES];
|
struct tree_desc t[MAX_UNPACK_TREES];
|
||||||
int i, nr_trees = 0;
|
int i, nr_trees = 0;
|
||||||
struct dir_struct dir;
|
struct dir_struct dir;
|
||||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
struct lock_file lock_file = LOCK_INIT;
|
||||||
|
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
|
|
||||||
if (hold_locked_index(lock_file, LOCK_REPORT_ON_ERROR) < 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));
|
||||||
@ -91,9 +91,7 @@ int checkout_fast_forward(const struct object_id *head,
|
|||||||
}
|
}
|
||||||
if (unpack_trees(nr_trees, t, &opts))
|
if (unpack_trees(nr_trees, t, &opts))
|
||||||
return -1;
|
return -1;
|
||||||
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK)) {
|
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||||
rollback_lock_file(lock_file);
|
|
||||||
return error(_("unable to write new index file"));
|
return error(_("unable to write new index file"));
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
31
read-cache.c
31
read-cache.c
@ -2176,17 +2176,22 @@ static int has_racy_timestamp(struct index_state *istate)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Opportunistically update the index but do not complain if we can't
|
|
||||||
*/
|
|
||||||
void update_index_if_able(struct index_state *istate, struct lock_file *lockfile)
|
void update_index_if_able(struct index_state *istate, struct lock_file *lockfile)
|
||||||
{
|
{
|
||||||
if ((istate->cache_changed || has_racy_timestamp(istate)) &&
|
if ((istate->cache_changed || has_racy_timestamp(istate)) &&
|
||||||
verify_index(istate) &&
|
verify_index(istate))
|
||||||
write_locked_index(istate, lockfile, COMMIT_LOCK))
|
write_locked_index(istate, lockfile, COMMIT_LOCK);
|
||||||
|
else
|
||||||
rollback_lock_file(lockfile);
|
rollback_lock_file(lockfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On success, `tempfile` is closed. If it is the temporary file
|
||||||
|
* of a `struct lock_file`, we will therefore effectively perform
|
||||||
|
* a 'close_lock_file_gently()`. Since that is an implementation
|
||||||
|
* detail of lockfiles, callers of `do_write_index()` should not
|
||||||
|
* rely on it.
|
||||||
|
*/
|
||||||
static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
|
static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
|
||||||
int strip_extensions)
|
int strip_extensions)
|
||||||
{
|
{
|
||||||
@ -2314,7 +2319,6 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
|
|||||||
return -1;
|
return -1;
|
||||||
if (close_tempfile_gently(tempfile)) {
|
if (close_tempfile_gently(tempfile)) {
|
||||||
error(_("could not close '%s'"), tempfile->filename.buf);
|
error(_("could not close '%s'"), tempfile->filename.buf);
|
||||||
delete_tempfile(&tempfile);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (stat(tempfile->filename.buf, &st))
|
if (stat(tempfile->filename.buf, &st))
|
||||||
@ -2343,14 +2347,9 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
|
|||||||
int ret = do_write_index(istate, lock->tempfile, 0);
|
int ret = do_write_index(istate, lock->tempfile, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
assert((flags & (COMMIT_LOCK | CLOSE_LOCK)) !=
|
|
||||||
(COMMIT_LOCK | CLOSE_LOCK));
|
|
||||||
if (flags & COMMIT_LOCK)
|
if (flags & COMMIT_LOCK)
|
||||||
return commit_locked_index(lock);
|
return commit_locked_index(lock);
|
||||||
else if (flags & CLOSE_LOCK)
|
return close_lock_file_gently(lock);
|
||||||
return close_lock_file_gently(lock);
|
|
||||||
else
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_split_index(struct index_state *istate,
|
static int write_split_index(struct index_state *istate,
|
||||||
@ -2499,7 +2498,8 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
|
|||||||
(istate->cache_changed & ~EXTMASK)) {
|
(istate->cache_changed & ~EXTMASK)) {
|
||||||
if (si)
|
if (si)
|
||||||
hashclr(si->base_sha1);
|
hashclr(si->base_sha1);
|
||||||
return do_write_locked_index(istate, lock, flags);
|
ret = do_write_locked_index(istate, lock, flags);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getenv("GIT_TEST_SPLIT_INDEX")) {
|
if (getenv("GIT_TEST_SPLIT_INDEX")) {
|
||||||
@ -2515,7 +2515,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
|
|||||||
if (new_shared_index) {
|
if (new_shared_index) {
|
||||||
ret = write_shared_index(istate, lock, flags);
|
ret = write_shared_index(istate, lock, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = write_split_index(istate, lock, flags);
|
ret = write_split_index(istate, lock, flags);
|
||||||
@ -2524,6 +2524,9 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
|
|||||||
if (!ret && !new_shared_index)
|
if (!ret && !new_shared_index)
|
||||||
freshen_shared_index(sha1_to_hex(si->base_sha1), 1);
|
freshen_shared_index(sha1_to_hex(si->base_sha1), 1);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (flags & COMMIT_LOCK)
|
||||||
|
rollback_lock_file(lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,7 +1184,6 @@ static int read_and_refresh_cache(struct replay_opts *opts)
|
|||||||
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL);
|
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL);
|
||||||
if (the_index.cache_changed && index_fd >= 0) {
|
if (the_index.cache_changed && index_fd >= 0) {
|
||||||
if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK)) {
|
if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK)) {
|
||||||
rollback_lock_file(&index_lock);
|
|
||||||
return error(_("git %s: failed to refresh the index"),
|
return error(_("git %s: failed to refresh the index"),
|
||||||
_(action_name(opts)));
|
_(action_name(opts)));
|
||||||
}
|
}
|
||||||
|
19
sha1_file.c
19
sha1_file.c
@ -456,19 +456,19 @@ struct alternate_object_database *alloc_alt_odb(const char *dir)
|
|||||||
|
|
||||||
void add_to_alternates_file(const char *reference)
|
void add_to_alternates_file(const char *reference)
|
||||||
{
|
{
|
||||||
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
|
struct lock_file lock = LOCK_INIT;
|
||||||
char *alts = git_pathdup("objects/info/alternates");
|
char *alts = git_pathdup("objects/info/alternates");
|
||||||
FILE *in, *out;
|
FILE *in, *out;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
hold_lock_file_for_update(lock, alts, LOCK_DIE_ON_ERROR);
|
hold_lock_file_for_update(&lock, alts, LOCK_DIE_ON_ERROR);
|
||||||
out = fdopen_lock_file(lock, "w");
|
out = fdopen_lock_file(&lock, "w");
|
||||||
if (!out)
|
if (!out)
|
||||||
die_errno("unable to fdopen alternates lockfile");
|
die_errno("unable to fdopen alternates lockfile");
|
||||||
|
|
||||||
in = fopen(alts, "r");
|
in = fopen(alts, "r");
|
||||||
if (in) {
|
if (in) {
|
||||||
struct strbuf line = STRBUF_INIT;
|
struct strbuf line = STRBUF_INIT;
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
while (strbuf_getline(&line, in) != EOF) {
|
while (strbuf_getline(&line, in) != EOF) {
|
||||||
if (!strcmp(reference, line.buf)) {
|
if (!strcmp(reference, line.buf)) {
|
||||||
@ -480,18 +480,15 @@ void add_to_alternates_file(const char *reference)
|
|||||||
|
|
||||||
strbuf_release(&line);
|
strbuf_release(&line);
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
if (found) {
|
|
||||||
rollback_lock_file(lock);
|
|
||||||
lock = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (errno != ENOENT)
|
else if (errno != ENOENT)
|
||||||
die_errno("unable to read alternates file");
|
die_errno("unable to read alternates file");
|
||||||
|
|
||||||
if (lock) {
|
if (found) {
|
||||||
|
rollback_lock_file(&lock);
|
||||||
|
} else {
|
||||||
fprintf_or_die(out, "%s\n", reference);
|
fprintf_or_die(out, "%s\n", reference);
|
||||||
if (commit_lock_file(lock))
|
if (commit_lock_file(&lock))
|
||||||
die_errno("unable to move new alternates file into place");
|
die_errno("unable to move new alternates file into place");
|
||||||
if (alt_odb_tail)
|
if (alt_odb_tail)
|
||||||
link_alt_odb_entries(reference, '\n', NULL, 0);
|
link_alt_odb_entries(reference, '\n', NULL, 0);
|
||||||
|
@ -68,10 +68,10 @@
|
|||||||
* `create_tempfile()` returns an allocated tempfile on success or NULL
|
* `create_tempfile()` returns an allocated tempfile on success or NULL
|
||||||
* on failure. On errors, `errno` describes the reason for failure.
|
* on failure. On errors, `errno` describes the reason for failure.
|
||||||
*
|
*
|
||||||
* `delete_tempfile()`, `rename_tempfile()`, and `close_tempfile_gently()`
|
* `rename_tempfile()` and `close_tempfile_gently()` return 0 on success.
|
||||||
* return 0 on success. On failure they set `errno` appropriately and return
|
* On failure they set `errno` appropriately and return -1.
|
||||||
* -1. `delete` and `rename` (but not `close`) do their best to delete the
|
* `delete_tempfile()` and `rename` (but not `close`) do their best to
|
||||||
* temporary file before returning.
|
* delete the temporary file before returning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct tempfile {
|
struct tempfile {
|
||||||
|
@ -2297,14 +2297,14 @@ 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 = LOCK_INIT;
|
||||||
int err = 0, fd;
|
int err = 0, fd;
|
||||||
|
|
||||||
fd = hold_locked_index(lock_file, 0);
|
fd = hold_locked_index(&lock_file, 0);
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
if (0 <= fd)
|
if (0 <= fd)
|
||||||
update_index_if_able(&the_index, lock_file);
|
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)) {
|
||||||
/* TRANSLATORS: the action is e.g. "pull with rebase" */
|
/* TRANSLATORS: the action is e.g. "pull with rebase" */
|
||||||
|
Loading…
Reference in New Issue
Block a user