aboutsummaryrefslogtreecommitdiff
path: root/fast-import.c
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2007-03-07 18:05:38 -0500
committerShawn O. Pearce <spearce@spearce.org>2007-03-07 18:05:38 -0500
commit60b9004cdb106ce56589cbe587b6b5e7d6ad3cf9 (patch)
tree8d335936637646866e3728bc4cab28d8c4db2661 /fast-import.c
parent93e72d8d8fbfbbf28abee82c3e769337d7b940ec (diff)
downloadgit-60b9004cdb106ce56589cbe587b6b5e7d6ad3cf9.tar.gz
git-60b9004cdb106ce56589cbe587b6b5e7d6ad3cf9.tar.xz
Use atomic updates to the fast-import mark file
When we allow fast-import frontends to reload a mark file from a prior session we want to let them use the same file as they exported the marks to. This makes it very simple for the frontend to save state across incremental imports. But we don't want to lose the old marks table if anything goes wrong while writing our current marks table. So instead of truncating and overwriting the path specified to --export-marks we use the standard lockfile code to write the current marks out to a temporary file, then rename it over the old marks table. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'fast-import.c')
-rw-r--r--fast-import.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/fast-import.c b/fast-import.c
index 28f5e7c3b..a09221242 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1375,16 +1375,33 @@ static void dump_marks_helper(FILE *f,
static void dump_marks(void)
{
- if (mark_file)
- {
- FILE *f = fopen(mark_file, "w");
- if (f) {
- dump_marks_helper(f, 0, marks);
- fclose(f);
- } else
- failure |= error("Unable to write marks file %s: %s",
- mark_file, strerror(errno));
+ static struct lock_file mark_lock;
+ int mark_fd;
+ FILE *f;
+
+ if (!mark_file)
+ return;
+
+ mark_fd = hold_lock_file_for_update(&mark_lock, mark_file, 0);
+ if (mark_fd < 0) {
+ failure |= error("Unable to write marks file %s: %s",
+ mark_file, strerror(errno));
+ return;
}
+
+ f = fdopen(mark_fd, "w");
+ if (!f) {
+ rollback_lock_file(&mark_lock);
+ failure |= error("Unable to write marks file %s: %s",
+ mark_file, strerror(errno));
+ return;
+ }
+
+ dump_marks_helper(f, 0, marks);
+ fclose(f);
+ if (commit_lock_file(&mark_lock))
+ failure |= error("Unable to write marks file %s: %s",
+ mark_file, strerror(errno));
}
static void read_next_command(void)