Commit Diff


commit - fd7a136d02efc789a2092aa294d1d5d7c30538e8
commit + e2b1e15228b8a9d1e237c567129f94ff53e02ca9
blob - 73f02adce16146620f98994012b197bab174c16c
blob + e82cc82d336ec34bdac10e31a51a1a32f0487a02
--- lib/worktree.c
+++ lib/worktree.c
@@ -1021,6 +1021,16 @@ get_modified_file_content_status(unsigned char *status
 	}
 
 	return err;
+}
+
+static int
+stat_info_differs(struct got_fileindex_entry *ie, struct stat *sb)
+{
+	return !(ie->ctime_sec == sb->st_ctime &&
+	    ie->ctime_nsec == sb->st_ctimensec &&
+	    ie->mtime_sec == sb->st_mtime &&
+	    ie->mtime_nsec == sb->st_mtimensec &&
+	    ie->size == (sb->st_size & 0xffffffff));
 }
 
 static const struct got_error *
@@ -1071,11 +1081,7 @@ get_file_status(unsigned char *status, struct stat *sb
 		return NULL;
 	}
 
-	if (ie->ctime_sec == sb->st_ctime &&
-	    ie->ctime_nsec == sb->st_ctimensec &&
-	    ie->mtime_sec == sb->st_mtime &&
-	    ie->mtime_nsec == sb->st_mtimensec &&
-	    ie->size == (sb->st_size & 0xffffffff))
+	if (!stat_info_differs(ie, sb))
 		return NULL;
 
 	memcpy(id.sha1, ie->blob_sha1, sizeof(id.sha1));
@@ -1131,6 +1137,21 @@ done:
 	if (f)
 		fclose(f);
 	return err;
+}
+
+/*
+ * Update timestamps in the file index if a file is unmodified and
+ * we had to run a full content comparison to find out.
+ */
+static const struct got_error *
+sync_timestamps(char *ondisk_path, unsigned char status,
+    struct got_fileindex_entry *ie, struct stat *sb)
+{
+	if (status == GOT_STATUS_NO_CHANGE && stat_info_differs(ie, sb))
+		return got_fileindex_entry_update(ie, ondisk_path,
+		    ie->blob_sha1, ie->commit_sha1, 1);
+
+	return NULL;
 }
 
 static const struct got_error *
@@ -1162,14 +1183,19 @@ update_blob(struct got_worktree *worktree,
 		if (got_fileindex_entry_has_commit(ie) &&
 		    memcmp(ie->commit_sha1, worktree->base_commit_id->sha1,
 		    SHA1_DIGEST_LENGTH) == 0) {
+			err = sync_timestamps(ondisk_path, status, ie, &sb);
+			if (err)
+				goto done;
 			err = (*progress_cb)(progress_arg, GOT_STATUS_EXISTS,
 			    path);
 			goto done;
 		}
 		if (got_fileindex_entry_has_blob(ie) &&
 		    memcmp(ie->blob_sha1, te->id->sha1,
-		    SHA1_DIGEST_LENGTH) == 0)
+		    SHA1_DIGEST_LENGTH) == 0) {
+			err = sync_timestamps(ondisk_path, status, ie, &sb);
 			goto done;
+		}
 	}
 
 	err = got_object_open_as_blob(&blob, repo, te->id, 8192);