Code

Add config option to enable 'fsync()' of object files
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Jun 2008 22:18:44 +0000 (15:18 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 18 Jun 2008 23:50:35 +0000 (16:50 -0700)
As explained in the documentation[*] this is totally useless on
filesystems that do ordered/journalled data writes, but it can be a
useful safety feature on filesystems like HFS+ that only journal the
metadata, not the actual file contents.

It defaults to off, although we could presumably in theory some day
auto-enable it on a per-filesystem basis.

[*] Yes, I updated the docs for the thing.  Hell really _has_ frozen
    over, and the four horsemen are probably just beyond the horizon.
    EVERYBODY PANIC!

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
cache.h
config.c
environment.c
sha1_file.c

index 5331b450ea051334d53ce3f1e727e33def2ea2cf..2466ecfc6b2be075e88c1b1a48e814c726e228f5 100644 (file)
@@ -372,6 +372,14 @@ core.whitespace::
   does not trigger if the character before such a carriage-return
   is not a whitespace (not enabled by default).
 
+core.fsyncobjectfiles::
+       This boolean will enable 'fsync()' when writing object files.
++
+This is a total waste of time and effort on a filesystem that orders
+data writes properly, but can be useful for filesystems that do not use
+journalling (traditional UNIX filesystems) or that only journal metadata
+and not file contents (OS X's HFS+, or Linux ext3 with "data=writeback").
+
 alias.*::
        Command aliases for the linkgit:git[1] command wrapper - e.g.
        after defining "alias.last = cat-file commit HEAD", the invocation
diff --git a/cache.h b/cache.h
index 81b7e17de26ae33249c60b101f5718cb5c5e5699..01c8502afb3afe19b59ea2dad8cf64e154aa3612 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -435,6 +435,7 @@ extern size_t packed_git_window_size;
 extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
 extern int auto_crlf;
+extern int fsync_object_files;
 
 enum safe_crlf {
        SAFE_CRLF_FALSE = 0,
index 9d14a74f8261f4b658372f21b54a5ea21b31bb8a..b2d5b4e4e35b467147ddb9374ef13d0523b4b58d 100644 (file)
--- a/config.c
+++ b/config.c
@@ -460,6 +460,11 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.fsyncobjectfiles")) {
+               fsync_object_files = git_config_bool(var, value);
+               return 0;
+       }
+
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
 }
index 73feb2d03a917d1fbdc8d9397b42fd90e5916bca..d5c3e29e9766d8d1b58c9d4ec6a059926cefce46 100644 (file)
@@ -29,6 +29,7 @@ const char *apply_default_whitespace;
 int zlib_compression_level = Z_BEST_SPEED;
 int core_compression_level;
 int core_compression_seen;
+int fsync_object_files;
 size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
 size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
 size_t delta_base_cache_limit = 16 * 1024 * 1024;
index 191f814e09ee6067edf7b0acc73a04751e73a6da..fe4ee3ece57ae8627572554c1e9af9f292c67ac6 100644 (file)
@@ -2083,7 +2083,8 @@ int hash_sha1_file(const void *buf, unsigned long len, const char *type,
 /* Finalize a file on disk, and close it. */
 static void close_sha1_file(int fd)
 {
-       /* For safe-mode, we could fsync_or_die(fd, "sha1 file") here */
+       if (fsync_object_files)
+               fsync_or_die(fd, "sha1 file");
        fchmod(fd, 0444);
        if (close(fd) != 0)
                die("unable to write sha1 file");