dav/sync.c

changeset 649
0f4c59ac8c74
parent 648
fefe4b6f1048
child 650
14e7101d7604
--- 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;

mercurial