diff -r fefe4b6f1048 -r 0f4c59ac8c74 dav/sync.c --- a/dav/sync.c Sun Sep 29 12:57:13 2019 +0200 +++ b/dav/sync.c Thu Oct 03 12:00:25 2019 +0200 @@ -965,6 +965,7 @@ fprintf(stderr, "Error: resource %s has no etag\n", res->path); return REMOTE_NO_CHANGE; } + char *hash = sync_get_content_hash(res); DavBool issplit = dav_get_property(res, "idav:split") ? TRUE : FALSE; if(issplit) { @@ -1004,15 +1005,9 @@ } } else if(local) { DavBool nochange = FALSE; - char *content_hash = sync_get_content_hash(res); - if(SYNC_SYMLINK(dir) && nullstrcmp(link, local->link_target)) { ret = REMOTE_CHANGE_LINK; nochange = TRUE; - } else if(content_hash && local->hash) { - if(!strcmp(content_hash, local->hash)) { - nochange = TRUE; - } } else if(local->etag) { sstr_t e = sstr(etag); if(sstrprefix(e, S("W/"))) { @@ -1041,7 +1036,28 @@ } else { ret = REMOTE_CHANGE_NEW; } - + + // if hashing is enabled we can compare the hash of the remote file + // with the local file to test if a file is really modified + if (!iscollection && + !link && + (ret == REMOTE_CHANGE_MODIFIED || ret == REMOTE_CHANGE_CONFLICT_LOCAL_MODIFIED) && + exists && + hash && + !dir->pull_skip_hashing) + { + // because rehashing a file is slow, there is a config element for + // disabling this (pull-skip-hashing) + char *local_hash = util_file_hash(local_path); + if(local_hash) { + if(!strcmp(hash, local_hash)) { + ret = REMOTE_NO_CHANGE; + } + } + free(local_hash); + } + + // if a file is not modified, check if the metadata has changed while(ret == REMOTE_NO_CHANGE && local) { // check if tags have changed if(dir->tagconfig) { @@ -2909,7 +2925,7 @@ char *hash = sync_get_content_hash(remote); if(hash && res->hash && equal) { - // if requested, check if the local and remote are equal + // if requested, check if the local and remote res are equal if(!strcmp(hash, res->hash)) { *equal = TRUE; return 0;