ディレクトリのsyncのために定期的にcronで実行して便利に使わせていただいていたのですが、ファイルの更新を「サイズが違う」あるいは「タイムスタンプが違う」のどちらかで判定しているので、古いファイルに同期してしまう問題があります。
普段は古いファイルをダウンロード(sync)される前に手動でpushして対応していたのですが、先ほど油断した隙に1時間の作業を全部ロールバックされてしまったので、さすがに何とかすることにしました。
1114 sub has_change ($$) { 1115 my ($local_path, $content) = @_; 1116 1117 my $remote_epoch = $strp->parse_datetime($content->{client_modified})->epoch; 1118 my $local_epoch = $local_path->stat->mtime; 1119 my $remote_size = $content->{size}; 1120 my $local_size = $local_path->stat->size; 1121 1122 if ($debug) { 1123 printf "remote: %10s %10s %s\n", $remote_epoch, $remote_size, $content->{path_display}; 1124 printf "local: %10s %10s %s\n", $local_epoch, $local_size, decode('locale_fs', $local_path); 1125 } 1126 1127 if (($remote_size != $local_size) || ($remote_epoch != $local_epoch)) { 1128 return 1; 1129 } 1130 1131 return; 1132 }
問題の部分はここ。
1114 sub has_change ($$$) { ... 1127 # if (($remote_size != $local_size) || ($remote_epoch != $local_epoch)) { 1128 if ($remote_size != $local_size){ 1129 if($is_upload){ 1130 return 1 if $remote_epoch < $local_epoch; 1131 } 1132 else{ # download 1133 return 1 if $remote_epoch > $local_epoch; 1134 } 1135 } 1136 return; 1137 }
has_changedはダウンロードとアップロードの2箇所呼ばれるので、「ファイルが新しい場合に更新」を実現させようとすると不等号の向きが逆になります。のでフラグを追加。
$ grep -nE "has_change|^sub sync_upload|sub sync_download" /usr/local/bin/dropbox-api 720:sub sync_download { 764: if ((!-f $local_path) || has_change($local_path, $content, 0)) { 872:sub sync_download_file { 884: if ((!-f $local_path) || has_change($local_path, $content, 0)) { 927:sub sync_upload { 976: if (has_change($local_path, $content, 1)) { 1050:sub sync_upload_file { 1091: if (has_change($local_path, $content, 1)) {