summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2014-03-14 23:47:06 -0400
committerJunio C Hamano <gitster@pobox.com>2014-03-17 15:03:32 -0700
commit7839632167bc6ceef20f28bd046f7001493b070f (patch)
treea61644530405b976da4af5eed725a9d9930788ea
parent0179c945fce361c56b465e8a3f0fdf0962a816a1 (diff)
downloadgit-jk/shallow-update-fix.tar.gz
shallow: verify shallow file after taking lockjk/shallow-update-fix
Before writing the shallow file, we stat() the existing file to make sure it has not been updated since our operation began. However, we do not do so under a lock, so there is a possible race: 1. Process A takes the lock. 2. Process B calls check_shallow_file_for_update and finds no update. 3. Process A commits the lockfile. 4. Process B takes the lock, then overwrite's process A's changes. We can fix this by doing our check while we hold the lock. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--shallow.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/shallow.c b/shallow.c
index c7602ce3a2..0b267b6411 100644
--- a/shallow.c
+++ b/shallow.c
@@ -263,9 +263,9 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
struct strbuf sb = STRBUF_INIT;
int fd;
- check_shallow_file_for_update();
fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
LOCK_DIE_ON_ERROR);
+ check_shallow_file_for_update();
if (write_shallow_commits(&sb, 0, extra)) {
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
die_errno("failed to write to %s",
@@ -310,9 +310,9 @@ void prune_shallow(int show_only)
strbuf_release(&sb);
return;
}
- check_shallow_file_for_update();
fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
LOCK_DIE_ON_ERROR);
+ check_shallow_file_for_update();
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
die_errno("failed to write to %s",