@@ -601,9 +601,10 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
601601 idx -> inbuf_len += size - to_expell ;
602602}
603603
604+ #if defined(NO_MMAP ) || !defined(GIT_WIN32 )
605+
604606static int write_at (git_indexer * idx , const void * data , off64_t offset , size_t size )
605607{
606- #ifdef NO_MMAP
607608 size_t remaining_size = size ;
608609 const char * ptr = (const char * )data ;
609610
@@ -619,7 +620,31 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
619620 offset += nb ;
620621 remaining_size -= nb ;
621622 }
623+
624+ return 0 ;
625+ }
626+
627+ static int append_to_pack (git_indexer * idx , const void * data , size_t size )
628+ {
629+ if (write_at (idx , data , idx -> pack -> mwf .size , size ) < 0 ) {
630+ git_error_set (GIT_ERROR_OS , "cannot extend packfile '%s'" , idx -> pack -> pack_name );
631+ return -1 ;
632+ }
633+
634+ return 0 ;
635+ }
636+
622637#else
638+
639+ /*
640+ * Windows may keep different views to a networked file for the mmap- and
641+ * open-accessed versions of a file, so any writes done through
642+ * `write(2)`/`pwrite(2)` may not be reflected on the data that `mmap(2)` is
643+ * able to read.
644+ */
645+
646+ static int write_at (git_indexer * idx , const void * data , off64_t offset , size_t size )
647+ {
623648 git_file fd = idx -> pack -> mwf .fd ;
624649 size_t mmap_alignment ;
625650 size_t page_offset ;
@@ -644,7 +669,6 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
644669 map_data = (unsigned char * )map .data ;
645670 memcpy (map_data + page_offset , data , size );
646671 p_munmap (& map );
647- #endif
648672
649673 return 0 ;
650674}
@@ -680,6 +704,8 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
680704 return write_at (idx , data , idx -> pack -> mwf .size , size );
681705}
682706
707+ #endif
708+
683709static int read_stream_object (git_indexer * idx , git_indexer_progress * stats )
684710{
685711 git_packfile_stream * stream = & idx -> stream ;
@@ -1279,11 +1305,19 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
12791305 if (git_mwindow_free_all (& idx -> pack -> mwf ) < 0 )
12801306 goto on_error ;
12811307
1282- /* Truncate file to undo rounding up to next page_size in append_to_pack */
1308+ #if !defined(NO_MMAP ) && defined(GIT_WIN32 )
1309+ /*
1310+ * Some non-Windows remote filesystems fail when truncating files if the
1311+ * file permissions change after opening the file (done by p_mkstemp).
1312+ *
1313+ * Truncation is only needed when mmap is used to undo rounding up to next
1314+ * page_size in append_to_pack.
1315+ */
12831316 if (p_ftruncate (idx -> pack -> mwf .fd , idx -> pack -> mwf .size ) < 0 ) {
12841317 git_error_set (GIT_ERROR_OS , "failed to truncate pack file '%s'" , idx -> pack -> pack_name );
12851318 return -1 ;
12861319 }
1320+ #endif
12871321
12881322 if (idx -> do_fsync && p_fsync (idx -> pack -> mwf .fd ) < 0 ) {
12891323 git_error_set (GIT_ERROR_OS , "failed to fsync packfile" );
0 commit comments