summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-10-29 21:12:37 +0100
committerCarlos Martín Nieto <cmn@dwim.me>2015-10-30 19:49:35 +0100
commiteb5977991a75f8d1630348a529805ba40765a616 (patch)
treebcfe5564a27a4c10a065de0afe7dac761d0d68c4 /src/fileops.c
parenta2f96479abfe17357f666a80d9d0163dd8014fa1 (diff)
downloadlibgit2-eb5977991a75f8d1630348a529805ba40765a616.tar.gz
filebuf: use a checksum to detect file changes
Instead of relying on the size and timestamp, which can hide changes performed in the same second, hash the file content's when we care about detecting changes.
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 57d2ce9c3..9bef02847 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -153,11 +153,12 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
}
int git_futils_readbuffer_updated(
- git_buf *buf, const char *path, time_t *mtime, size_t *size, int *updated)
+ git_buf *buf, const char *path, git_oid *checksum, int *updated)
{
+ int error;
git_file fd;
struct stat st;
- bool changed = false;
+ git_oid checksum_new;
assert(buf && path && *path);
@@ -178,26 +179,6 @@ int git_futils_readbuffer_updated(
return -1;
}
- /*
- * If we were given a time and/or a size, we only want to read the file
- * if it has been modified.
- */
- if (size && *size != (size_t)st.st_size)
- changed = true;
- if (mtime && *mtime != (time_t)st.st_mtime)
- changed = true;
- if (!size && !mtime)
- changed = true;
-
- if (!changed) {
- return 0;
- }
-
- if (mtime != NULL)
- *mtime = st.st_mtime;
- if (size != NULL)
- *size = (size_t)st.st_size;
-
if ((fd = git_futils_open_ro(path)) < 0)
return fd;
@@ -208,6 +189,28 @@ int git_futils_readbuffer_updated(
p_close(fd);
+ if ((error = git_hash_buf(&checksum_new, buf->ptr, buf->size)) < 0) {
+ git_buf_free(buf);
+ return error;
+ }
+
+ /*
+ * If we were given a checksum, we only want to use it if it's different
+ */
+ if (checksum && !git_oid__cmp(checksum, &checksum_new)) {
+ git_buf_free(buf);
+ if (updated)
+ *updated = 0;
+
+ return 0;
+ }
+
+ /*
+ * If we're here, the file did change, or the user didn't have an old version
+ */
+ if (checksum)
+ git_oid_cpy(checksum, &checksum_new);
+
if (updated != NULL)
*updated = 1;
@@ -216,7 +219,7 @@ int git_futils_readbuffer_updated(
int git_futils_readbuffer(git_buf *buf, const char *path)
{
- return git_futils_readbuffer_updated(buf, path, NULL, NULL, NULL);
+ return git_futils_readbuffer_updated(buf, path, NULL, NULL);
}
int git_futils_writebuffer(