]> git.ipfire.org Git - thirdparty/git.git/blobdiff - statinfo.c
Merge branch 'jc/fake-lstat'
[thirdparty/git.git] / statinfo.c
index 45156109de72e93109264198c8d370fa1e543447..3c6bc049c15d44c33c064fecbbd2236571b2dadb 100644 (file)
@@ -2,6 +2,22 @@
 #include "environment.h"
 #include "statinfo.h"
 
+/*
+ * Munge st_size into an unsigned int.
+ */
+static unsigned int munge_st_size(off_t st_size) {
+       unsigned int sd_size = st_size;
+
+       /*
+        * If the file is an exact multiple of 4 GiB, modify the value so it
+        * doesn't get marked as racily clean (zero).
+        */
+       if (!sd_size && st_size)
+               return 0x80000000;
+       else
+               return sd_size;
+}
+
 void fill_stat_data(struct stat_data *sd, struct stat *st)
 {
        sd->sd_ctime.sec = (unsigned int)st->st_ctime;
@@ -12,7 +28,7 @@ void fill_stat_data(struct stat_data *sd, struct stat *st)
        sd->sd_ino = st->st_ino;
        sd->sd_uid = st->st_uid;
        sd->sd_gid = st->st_gid;
-       sd->sd_size = st->st_size;
+       sd->sd_size = munge_st_size(st->st_size);
 }
 
 static void set_times(struct stat *st, const struct stat_data *sd)
@@ -78,7 +94,7 @@ int match_stat_data(const struct stat_data *sd, struct stat *st)
                        changed |= INODE_CHANGED;
 #endif
 
-       if (sd->sd_size != (unsigned int) st->st_size)
+       if (sd->sd_size != munge_st_size(st->st_size))
                changed |= DATA_CHANGED;
 
        return changed;