diff options
author | Derrick Stolee <dstolee@microsoft.com> | 2019-11-21 22:04:48 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-11-22 16:11:45 +0900 |
commit | fb10ca5b54362e6f860e1e9049e03924fcf5f05b (patch) | |
tree | c5a23ed39b39ab869387abc34e61f52445eeb2d9 /builtin/sparse-checkout.c | |
parent | sparse-checkout: use in-process update for disable subcommand (diff) | |
download | tgif-fb10ca5b54362e6f860e1e9049e03924fcf5f05b.tar.xz |
sparse-checkout: write using lockfile
If two 'git sparse-checkout set' subcommands are launched at the
same time, the behavior can be unexpected as they compete to write
the sparse-checkout file and update the working directory.
Take a lockfile around the writes to the sparse-checkout file. In
addition, acquire this lock around the working directory update
to avoid two commands updating the working directory in different
ways.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/sparse-checkout.c')
-rw-r--r-- | builtin/sparse-checkout.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index a11ea65599..9a620ff014 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -170,25 +170,32 @@ static int write_patterns_and_update(struct pattern_list *pl) { char *sparse_filename; FILE *fp; + int fd; + struct lock_file lk = LOCK_INIT; int result; - result = update_working_directory(pl); + sparse_filename = get_sparse_checkout_filename(); + fd = hold_lock_file_for_update(&lk, sparse_filename, + LOCK_DIE_ON_ERROR); + result = update_working_directory(pl); if (result) { + rollback_lock_file(&lk); + free(sparse_filename); clear_pattern_list(pl); update_working_directory(NULL); return result; } - sparse_filename = get_sparse_checkout_filename(); - fp = fopen(sparse_filename, "w"); + fp = xfdopen(fd, "w"); if (core_sparse_checkout_cone) write_cone_to_file(fp, pl); else write_patterns_to_file(fp, pl); - fclose(fp); + fflush(fp); + commit_lock_file(&lk); free(sparse_filename); clear_pattern_list(pl); |