diff --git a/src/main/frontend/fs/diff_merge.cljs b/src/main/frontend/fs/diff_merge.cljs index 9b9108dd0..0db8b17ea 100644 --- a/src/main/frontend/fs/diff_merge.cljs +++ b/src/main/frontend/fs/diff_merge.cljs @@ -107,7 +107,6 @@ (filter seq) (string/join "\n")))) - (defn three-way-merge [base income current format] (let [->ast (fn [text] (if (= format :org) diff --git a/src/main/frontend/fs/sync.cljs b/src/main/frontend/fs/sync.cljs index 4f1804487..024248d5b 100644 --- a/src/main/frontend/fs/sync.cljs +++ b/src/main/frontend/fs/sync.cljs @@ -957,7 +957,7 @@ :filePaths filepaths' :token token}))))))) (c (fs/read-file repo-dir rpath)))] + content (c (-> (fs/file-exists? repo-dir rpath) + (p/then (fn [exists?] + (when exists? + (fs/read-file repo-dir rpath)))))))] (and (seq origin-db-content) (or (nil? content) (some :removed (diff/diff origin-db-content content)))))))) @@ -1562,6 +1565,41 @@ delete-filetxns)] (set (concat update-file-items rename-file-items delete-file-items)))) +(defn- c (p/all (->> relative-paths + (map (fn [rpath] + (prn ::handle-remote-deletion rpath) + (p/let [base-file (path/path-join "logseq/version-files/base" rpath) + current-change-file rpath + format (gp-util/get-format current-change-file) + repo (state/get-current-repo) + repo-dir (config/get-repo-dir repo) + base-exists? (fs/file-exists? repo-dir base-file)] + (if base-exists? + (p/let [base-content (fs/read-file repo-dir base-file) + current-content (-> (fs/read-file repo-dir current-change-file) + (p/catch (fn [_] nil)))] + (if (= base-content current-content) + ;; base-content == current-content, delete current-change-file + (p/do! + ( (fs/read-file repo-dir current-change-file) + (p/catch (fn [_] nil)))] (if (= base-content current-content) (do (prn "base=current, write directly") @@ -1588,11 +1628,14 @@ (path/path-join repo-dir incoming-file) (path/path-join repo-dir current-change-file)) (fs/copy! repo - (path/path-join repo-dir incoming-file) - (path/path-join repo-dir base-file)))) + (path/path-join repo-dir incoming-file) + (path/path-join repo-dir base-file)))) (do (prn "base!=current, should do a 3-way merge") - (p/let [incoming-content (fs/read-file repo-dir incoming-file) + (prn ::cur + current-content) + (p/let [current-content (or current-content "") + incoming-content (fs/read-file repo-dir incoming-file) merged-content (diff-merge/three-way-merge base-content incoming-content current-content format)] (prn ::merged-content merged-content) (when (seq merged-content) @@ -1608,16 +1651,27 @@ :else (do - (prn "no base, use legacy buggy mode") - (prn ::copy incoming-file current-change-file) - (fs/copy! repo - (path/path-join repo-dir incoming-file) - (path/path-join repo-dir current-change-file)) - (fs/copy! repo - (path/path-join repo-dir incoming-file) - (path/path-join repo-dir base-file))))))))))))) - + (prn "no base, use empty content as base, avoid loosing data") + (p/let [current-content (-> (fs/read-file repo-dir current-change-file) + (p/catch (fn [_] nil))) + current-content (or current-content "") + incoming-content (fs/read-file repo-dir incoming-file) + merged-content (diff-merge/three-way-merge "" current-content incoming-content format)] + (if (= incoming-content merged-content) + (p/do! + (fs/copy! repo + (path/path-join repo-dir incoming-file) + (path/path-join repo-dir current-change-file)) + (fs/copy! repo + (path/path-join repo-dir incoming-file) + (path/path-join repo-dir base-file))) + ;; else + (p/do! + (fs/write-file! repo repo-dir current-change-file merged-content {:skip-compare? true}) + (file-handler/alter-file repo current-change-file merged-content {:re-render-root? true + :from-disk? true + :fs/event :fs/remote-file-change}))))))))))))))) (defn- apply-filetxns [*sync-state graph-uuid base-path filetxns *paused] @@ -1672,7 +1726,7 @@ (if (