push and pull add delete

This commit is contained in:
fyears 2024-06-16 19:48:40 +08:00
parent 94350873a9
commit 9b1a8f6068
7 changed files with 153 additions and 37 deletions

View File

@ -52,7 +52,7 @@ Bidirectional:
| local deleted | (04) delete remote | (05) pull | (01) clean history | (03) pull |
| local created | (??) conflict | (??) conflict | (06) push | (11/12/13/14/15) conflict |
Incremental push only:
Incremental push:
| local\remote | remote unchanged | remote modified | remote deleted | remote created |
| --------------- | ---------------------------- | ---------------------------- | ---------------------- | ---------------------------- |
@ -61,7 +61,7 @@ Incremental push only:
| local deleted | **(29) conflict do nothing** | **(30) conflict do nothing** | (01) clean history | **(28) conflict do nothing** |
| local created | (??) conflict | (??) conflict | (06) push | **(23) conflict push** |
Incremental pull only:
Incremental pull:
| local\remote | remote unchanged | remote modified | remote deleted | remote created |
| --------------- | ---------------------- | ---------------------- | ---------------------------- | ---------------------- |
@ -69,3 +69,21 @@ Incremental pull only:
| local modified | **(27) conflict pull** | **(24) conflict pull** | **(34) conflict do nothing** | (??) conflict |
| local deleted | **(35) conflict pull** | (05) pull | (01) clean history | (03) pull |
| local created | (??) conflict | (??) conflict | **(31) conflict do nothing** | **(22) conflict pull** |
Incremental push and delete (diff decisionBranch: 38):
| local\remote | remote unchanged | remote modified | remote deleted | remote created |
| --------------- | ---------------------------- | ---------------------------- | ---------------------- | ---------------------------- |
| local unchanged | (02/21) do nothing | **(26) conflict push** | **(32) conflict push** | (??) conflict |
| local modified | (10) push | **(25) conflict push** | (08) push | (??) conflict |
| local deleted | **(38) delete remote** | **(30) conflict do nothing** | (01) clean history | **(28) conflict do nothing** |
| local created | (??) conflict | (??) conflict | (06) push | **(23) conflict push** |
Incremental pull and delete (diff decisionBranch: 39):
| local\remote | remote unchanged | remote modified | remote deleted | remote created |
| --------------- | ---------------------- | ---------------------- | ---------------------------- | ---------------------- |
| local unchanged | (02/21) do nothing | (09) pull | **(39) delete local** | (??) conflict |
| local modified | **(27) conflict pull** | **(24) conflict pull** | **(34) conflict do nothing** | (??) conflict |
| local deleted | **(35) conflict pull** | (05) pull | (01) clean history | (03) pull |
| local created | (??) conflict | (??) conflict | **(31) conflict do nothing** | **(22) conflict pull** |

View File

@ -335,7 +335,10 @@ const getSyncPlanInplace = async (
mixedEntry.decision = "folder_existed_both_then_do_nothing";
mixedEntry.change = false;
} else if (local !== undefined && remote === undefined) {
if (syncDirection === "incremental_pull_only") {
if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 107;
mixedEntry.decision = "folder_to_skip";
mixedEntry.change = false;
@ -346,7 +349,10 @@ const getSyncPlanInplace = async (
mixedEntry.change = true;
}
} else if (local === undefined && remote !== undefined) {
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 108;
mixedEntry.decision = "folder_to_skip";
mixedEntry.change = false;
@ -373,7 +379,10 @@ const getSyncPlanInplace = async (
} else if (local !== undefined && remote === undefined) {
if (prevSync !== undefined) {
// then the folder is deleted on remote
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 122;
mixedEntry.decision = "folder_to_skip";
keptFolder.add(getParentFolder(key));
@ -383,6 +392,10 @@ const getSyncPlanInplace = async (
mixedEntry.decision = "folder_to_skip";
mixedEntry.change = false;
keptFolder.add(getParentFolder(key));
} else if (syncDirection === "incremental_pull_and_delete_only") {
mixedEntry.decisionBranch = 135;
mixedEntry.decision = "folder_to_be_deleted_on_local";
mixedEntry.change = true;
} else {
// bidirectional
mixedEntry.decisionBranch = 124;
@ -392,13 +405,19 @@ const getSyncPlanInplace = async (
} else {
// then the folder is created on local
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 125;
mixedEntry.decision =
"folder_existed_local_then_also_create_remote";
mixedEntry.change = true;
keptFolder.add(getParentFolder(key));
} else if (syncDirection === "incremental_pull_only") {
} else if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 126;
mixedEntry.decision = "folder_to_skip";
mixedEntry.change = false;
@ -420,7 +439,14 @@ const getSyncPlanInplace = async (
mixedEntry.decision = "folder_to_skip";
mixedEntry.change = false;
keptFolder.add(getParentFolder(key));
} else if (syncDirection === "incremental_pull_only") {
} else if (syncDirection === "incremental_push_and_delete_only") {
mixedEntry.decisionBranch = 136;
mixedEntry.decision = "folder_to_be_deleted_on_remote";
mixedEntry.change = true;
} else if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 129;
mixedEntry.decision = "folder_to_skip";
mixedEntry.change = false;
@ -433,12 +459,18 @@ const getSyncPlanInplace = async (
}
} else {
// then the folder is created on remote
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 131;
mixedEntry.decision = "folder_to_skip";
mixedEntry.change = false;
keptFolder.add(getParentFolder(key));
} else if (syncDirection === "incremental_pull_only") {
} else if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 132;
mixedEntry.decision =
"folder_existed_remote_then_also_create_local";
@ -497,7 +529,10 @@ const getSyncPlanInplace = async (
skipSizeLargerThan <= 0 ||
remote.sizeEnc! <= skipSizeLargerThan
) {
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 26;
mixedEntry.decision = "conflict_modified_then_keep_local";
mixedEntry.change = true;
@ -521,7 +556,10 @@ const getSyncPlanInplace = async (
skipSizeLargerThan <= 0 ||
local.sizeEnc! <= skipSizeLargerThan
) {
if (syncDirection === "incremental_pull_only") {
if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 27;
mixedEntry.decision = "conflict_modified_then_keep_remote";
mixedEntry.change = true;
@ -578,12 +616,18 @@ const getSyncPlanInplace = async (
mixedEntry.change = true;
keptFolder.add(getParentFolder(key));
}
} else if (syncDirection === "incremental_pull_only") {
} else if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 22;
mixedEntry.decision = "conflict_created_then_keep_remote";
mixedEntry.change = true;
keptFolder.add(getParentFolder(key));
} else if (syncDirection === "incremental_push_only") {
} else if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 23;
mixedEntry.decision = "conflict_created_then_keep_local";
mixedEntry.change = true;
@ -630,12 +674,18 @@ const getSyncPlanInplace = async (
mixedEntry.change = true;
keptFolder.add(getParentFolder(key));
}
} else if (syncDirection === "incremental_pull_only") {
} else if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 24;
mixedEntry.decision = "conflict_modified_then_keep_remote";
mixedEntry.change = true;
keptFolder.add(getParentFolder(key));
} else if (syncDirection === "incremental_push_only") {
} else if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 25;
mixedEntry.decision = "conflict_modified_then_keep_local";
mixedEntry.change = true;
@ -664,7 +714,10 @@ const getSyncPlanInplace = async (
skipSizeLargerThan <= 0 ||
remote.sizeEnc! <= skipSizeLargerThan
) {
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 28;
mixedEntry.decision = "conflict_created_then_do_nothing";
mixedEntry.change = false;
@ -692,7 +745,14 @@ const getSyncPlanInplace = async (
mixedEntry.decision = "conflict_created_then_do_nothing";
mixedEntry.change = false;
keptFolder.add(getParentFolder(key));
} else if (syncDirection === "incremental_pull_only") {
} else if (syncDirection === "incremental_push_and_delete_only") {
mixedEntry.decisionBranch = 38;
mixedEntry.decision = "local_is_deleted_thus_also_delete_remote";
mixedEntry.change = true;
} else if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 35;
mixedEntry.decision = "conflict_created_then_keep_remote";
mixedEntry.change = true;
@ -708,7 +768,10 @@ const getSyncPlanInplace = async (
skipSizeLargerThan <= 0 ||
remote.sizeEnc! <= skipSizeLargerThan
) {
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 30;
mixedEntry.decision = "conflict_created_then_do_nothing";
mixedEntry.change = false;
@ -733,7 +796,10 @@ const getSyncPlanInplace = async (
if (prevSync === undefined) {
// if A is not in the previous list, A is new
if (skipSizeLargerThan <= 0 || local.sizeEnc! <= skipSizeLargerThan) {
if (syncDirection === "incremental_pull_only") {
if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 31;
mixedEntry.decision = "conflict_created_then_do_nothing";
mixedEntry.change = false;
@ -756,7 +822,10 @@ const getSyncPlanInplace = async (
prevSync.sizeEnc === local.sizeEnc
) {
// if A is in the previous list and UNMODIFIED, A has been deleted by B
if (syncDirection === "incremental_push_only") {
if (
syncDirection === "incremental_push_only" ||
syncDirection === "incremental_push_and_delete_only"
) {
mixedEntry.decisionBranch = 32;
mixedEntry.decision = "conflict_created_then_keep_local";
mixedEntry.change = true;
@ -764,6 +833,10 @@ const getSyncPlanInplace = async (
mixedEntry.decisionBranch = 33;
mixedEntry.decision = "conflict_created_then_do_nothing";
mixedEntry.change = false;
} else if (syncDirection === "incremental_pull_and_delete_only") {
mixedEntry.decisionBranch = 39;
mixedEntry.decision = "remote_is_deleted_thus_also_delete_local";
mixedEntry.change = true;
} else {
mixedEntry.decisionBranch = 7;
mixedEntry.decision = "remote_is_deleted_thus_also_delete_local";
@ -772,7 +845,10 @@ const getSyncPlanInplace = async (
} else {
// if A is in the previous list and MODIFIED, A has been deleted by B but modified by A
if (skipSizeLargerThan <= 0 || local.sizeEnc! <= skipSizeLargerThan) {
if (syncDirection === "incremental_pull_only") {
if (
syncDirection === "incremental_pull_only" ||
syncDirection === "incremental_pull_and_delete_only"
) {
mixedEntry.decisionBranch = 34;
mixedEntry.decision = "conflict_created_then_do_nothing";
mixedEntry.change = false;
@ -826,7 +902,7 @@ const getSyncPlanInplace = async (
mixedEntityMappings["/$@meta"] = {
key: "/$@meta", // don't mess up with the types
sideNotes: {
version: "20240525 fs version",
version: "20240616 fs version",
generateTime: currTime,
generateTimeFmt: currTimeFmt,
service: settings.serviceType,

View File

@ -120,7 +120,9 @@ export interface WebdisConfig {
export type SyncDirectionType =
| "bidirectional"
| "incremental_pull_only"
| "incremental_push_only";
| "incremental_push_only"
| "incremental_pull_and_delete_only"
| "incremental_push_and_delete_only";
export type CipherMethodType = "rclone-base64" | "openssl-base64" | "unknown";

View File

@ -292,11 +292,15 @@
"settings_protectmodifypercentage_custom_desc": "custom",
"settings_protectmodifypercentage_customfield": "Custom Abort Sync If Modification Above Percentage",
"settings_protectmodifypercentage_customfield_desc": "You need to enter a number between 0 (inclusive) and 100 (inclusive). Float number is also allowed.",
"setting_syncdirection": "Sync Direction",
"setting_syncdirection_desc": "Which direction should the plugin sync to? Please be aware that only CHANGED files (based on time and size) are synced regardless any option.",
"setting_syncdirection": "Sync Direction (experimental)",
"setting_syncdirection_desc": "<p>Which direction should the plugin sync to? Please be aware that only CHANGED files (based on time and size) are synced regardless any option.</p><ol><li>Bidirectional: Changes on both side are synced to the other side.</li><li>Incremental Push: Locally created or modifed files are copied to remote.</li><li>Incremental Pull: Remotely created or modifed files are copied to local.</li><li>Incremental Push And Delete: Locally created or modifed files are copied to remote, <strong>and local deletion operations are run on remote too.</strong></li><li>Incremental Pull And Delete: Remotely created or modifed files are copied to local, <strong>and remote deletion operations are run on local too.</strong></li></ol>",
"setting_syncdirection_bidirectional_desc": "Bidirectional (default)",
"setting_syncdirection_incremental_push_only_desc": "Incremental Push Only (aka backup mode)",
"setting_syncdirection_incremental_pull_only_desc": "Incremental Pull Only",
"setting_syncdirection_incremental_push_only_desc": "Incremental Push (aka backup mode)",
"setting_syncdirection_incremental_pull_only_desc": "Incremental Pull",
"setting_syncdirection_incremental_push_and_delete_only_desc": "Incremental Push And Delete",
"setting_syncdirection_incremental_pull_and_delete_only_desc": "Incremental Pull And Delete",
"settings_enablemobilestatusbar": "Mobile Status Bar (experimental)",
"settings_enablemobilestatusbar_desc": "By default Obsidian mobile hides status bar. But some users want to show it up. So here is a hack.",
"settings_importexport": "Import and Export Partial Settings",

View File

@ -291,11 +291,15 @@
"settings_protectmodifypercentage_custom_desc": "自定义",
"settings_protectmodifypercentage_customfield": "如果修改超过自定义百分比则中止同步",
"settings_protectmodifypercentage_customfield_desc": "您需要输入 0~ 100的数字。小数也是可以的。",
"setting_syncdirection": "同步方向",
"setting_syncdirection_desc": "插件应该向哪里同步?注意每个选项都是只有修改了的文件(基于修改时间和大小判断)才会触发同步动作。",
"setting_syncdirection": "同步方向(实验性质)",
"setting_syncdirection_desc": "<p>W插件应该向哪里同步注意每个选项都是只有修改了的文件基于修改时间和大小判断才会触发同步动作。</p><ol><li>双向同步:一边的变动会同步到另一边。</li><li>增量推送:本地创建或修改的文件会复制到远端。</li><li>增量拉取:远端创建或修改的文件会复制到本地。</li><li>增量推送带删除:本地创建或修改的文件会复制到远端,<strong>本地的删除也会在远端运行。</strong></li><li>增量拉取带删除:远端创建或修改的文件会复制到本地,<strong>远端的删除也会在本地运行。</strong></li></ol>",
"setting_syncdirection_bidirectional_desc": "双向同步(默认)",
"setting_syncdirection_incremental_push_only_desc": "只增量推送(也即:备份模式)",
"setting_syncdirection_incremental_pull_only_desc": "只增量拉取",
"setting_syncdirection_incremental_push_only_desc": "增量推送(也即:备份模式)",
"setting_syncdirection_incremental_pull_only_desc": "增量拉取",
"setting_syncdirection_incremental_push_and_delete_only_desc": "增量推送带删除",
"setting_syncdirection_incremental_pull_and_delete_only_desc": "增量拉取带删除",
"settings_enablemobilestatusbar": "手机的状态栏(实验性质)",
"settings_enablemobilestatusbar_desc": "Obsidian 手机版默认隐藏了状态栏。有些用户希望展示它。这里提供了设置选项。",
"settings_importexport": "导入导出部分设置",

View File

@ -290,11 +290,15 @@
"settings_protectmodifypercentage_custom_desc": "自定義",
"settings_protectmodifypercentage_customfield": "如果修改超過自定義百分比則中止同步",
"settings_protectmodifypercentage_customfield_desc": "您需要輸入 0~ 100的數字。小數也是可以的。",
"setting_syncdirection": "同步方向",
"setting_syncdirection_desc": "外掛應該向哪裡同步?注意每個選項都是隻有修改了的檔案(基於修改時間和大小判斷)才會觸發同步動作。",
"setting_syncdirection": "同步方向(實驗性質)",
"setting_syncdirection_desc": "<p>W外掛應該向哪裡同步注意每個選項都是隻有修改了的檔案基於修改時間和大小判斷才會觸發同步動作。</p><ol><li>雙向同步:一邊的變動會同步到另一邊。</li><li>增量推送:本地建立或修改的檔案會複製到遠端。</li><li>增量拉取:遠端建立或修改的檔案會複製到本地。</li><li>增量推送帶刪除:本地建立或修改的檔案會複製到遠端,<strong>本地的刪除也會在遠端執行。</strong></li><li>增量拉取帶刪除:遠端建立或修改的檔案會複製到本地,<strong>遠端的刪除也會在本地執行。</strong></li></ol>",
"setting_syncdirection_bidirectional_desc": "雙向同步(預設)",
"setting_syncdirection_incremental_push_only_desc": "只增量推送(也即:備份模式)",
"setting_syncdirection_incremental_pull_only_desc": "只增量拉取",
"setting_syncdirection_incremental_push_only_desc": "增量推送(也即:備份模式)",
"setting_syncdirection_incremental_pull_only_desc": "增量拉取",
"setting_syncdirection_incremental_push_and_delete_only_desc": "增量推送帶刪除",
"setting_syncdirection_incremental_pull_and_delete_only_desc": "增量拉取帶刪除",
"settings_enablemobilestatusbar": "手機的狀態列(實驗性質)",
"settings_enablemobilestatusbar_desc": "Obsidian 手機版預設隱藏了狀態列。有些使用者希望展示它。這裡提供了設定選項。",
"settings_importexport": "匯入匯出部分設定",

View File

@ -2369,7 +2369,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
new Setting(advDiv)
.setName(t("setting_syncdirection"))
.setDesc(t("setting_syncdirection_desc"))
.setDesc(stringToFragment(t("setting_syncdirection_desc")))
.addDropdown((dropdown) => {
dropdown.addOption(
"bidirectional",
@ -2383,6 +2383,14 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
"incremental_pull_only",
t("setting_syncdirection_incremental_pull_only_desc")
);
dropdown.addOption(
"incremental_push_and_delete_only",
t("setting_syncdirection_incremental_push_and_delete_only_desc")
);
dropdown.addOption(
"incremental_pull_and_delete_only",
t("setting_syncdirection_incremental_pull_and_delete_only_desc")
);
dropdown
.setValue(this.plugin.settings.syncDirection ?? "bidirectional")