summaryrefslogtreecommitdiff
path: root/builtin/sparse-checkout.c
diff options
context:
space:
mode:
authorDerrick Stolee <dstolee@microsoft.com>2019-11-21 22:04:48 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-11-22 07:11:45 (GMT)
commitfb10ca5b54362e6f860e1e9049e03924fcf5f05b (patch)
treec5a23ed39b39ab869387abc34e61f52445eeb2d9 /builtin/sparse-checkout.c
parent99dfa6f9702ee81c44ef9382933e4e391ec5d6ee (diff)
downloadgit-fb10ca5b54362e6f860e1e9049e03924fcf5f05b.zip
git-fb10ca5b54362e6f860e1e9049e03924fcf5f05b.tar.gz
git-fb10ca5b54362e6f860e1e9049e03924fcf5f05b.tar.bz2
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.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index a11ea65..9a620ff 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);