diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-10-29 21:12:37 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-10-30 19:49:35 +0100 |
commit | eb5977991a75f8d1630348a529805ba40765a616 (patch) | |
tree | bcfe5564a27a4c10a065de0afe7dac761d0d68c4 /src/fileops.c | |
parent | a2f96479abfe17357f666a80d9d0163dd8014fa1 (diff) | |
download | libgit2-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.c | 49 |
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( |