1717#include "oid.h"
1818#include "oidmap.h"
1919#include "zstream.h"
20+ #include "object.h"
2021
2122extern git_mutex git__mwindow_mutex ;
2223
@@ -33,7 +34,8 @@ struct git_indexer {
3334 unsigned int parsed_header :1 ,
3435 pack_committed :1 ,
3536 have_stream :1 ,
36- have_delta :1 ;
37+ have_delta :1 ,
38+ do_fsync :1 ;
3739 struct git_pack_header hdr ;
3840 struct git_pack_file * pack ;
3941 unsigned int mode ;
@@ -123,6 +125,9 @@ int git_indexer_new(
123125 git_hash_ctx_init (& idx -> hash_ctx );
124126 git_hash_ctx_init (& idx -> trailer );
125127
128+ if (git_object__synchronous_writing )
129+ idx -> do_fsync = 1 ;
130+
126131 error = git_buf_joinpath (& path , prefix , suff );
127132 if (error < 0 )
128133 goto cleanup ;
@@ -161,6 +166,11 @@ int git_indexer_new(
161166 return -1 ;
162167}
163168
169+ void git_indexer__set_fsync (git_indexer * idx , int do_fsync )
170+ {
171+ idx -> do_fsync = !!do_fsync ;
172+ }
173+
164174/* Try to store the delta so we can try to resolve it later */
165175static int store_delta (git_indexer * idx )
166176{
@@ -989,7 +999,9 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
989999 return -1 ;
9901000
9911001 if (git_filebuf_open (& index_file , filename .ptr ,
992- GIT_FILEBUF_HASH_CONTENTS , idx -> mode ) < 0 )
1002+ GIT_FILEBUF_HASH_CONTENTS |
1003+ (idx -> do_fsync ? GIT_FILEBUF_FSYNC : 0 ),
1004+ idx -> mode ) < 0 )
9931005 goto on_error ;
9941006
9951007 /* Write out the header */
@@ -1066,6 +1078,11 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
10661078 return -1 ;
10671079 }
10681080
1081+ if (idx -> do_fsync && p_fsync (idx -> pack -> mwf .fd ) < 0 ) {
1082+ giterr_set (GITERR_OS , "failed to fsync packfile" );
1083+ goto on_error ;
1084+ }
1085+
10691086 /* We need to close the descriptor here so Windows doesn't choke on commit_at */
10701087 if (p_close (idx -> pack -> mwf .fd ) < 0 ) {
10711088 giterr_set (GITERR_OS , "failed to close packfile" );
@@ -1078,7 +1095,14 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
10781095 goto on_error ;
10791096
10801097 /* And don't forget to rename the packfile to its new place. */
1081- p_rename (idx -> pack -> pack_name , git_buf_cstr (& filename ));
1098+ if (p_rename (idx -> pack -> pack_name , git_buf_cstr (& filename )) < 0 )
1099+ goto on_error ;
1100+
1101+ /* And fsync the parent directory if we're asked to. */
1102+ if (idx -> do_fsync &&
1103+ git_futils_fsync_parent (git_buf_cstr (& filename )) < 0 )
1104+ goto on_error ;
1105+
10821106 idx -> pack_committed = 1 ;
10831107
10841108 git_buf_free (& filename );
0 commit comments