diff --git a/fix-conflicts.ts b/fix-conflicts.ts index 38293d8..c22c346 100644 --- a/fix-conflicts.ts +++ b/fix-conflicts.ts @@ -4,7 +4,7 @@ import { join } from "https://deno.land/std@0.173.0/path/mod.ts"; const mainDir = '/home/ben/Nextcloud'; const backupDir = '/home/ben/Nextcloud.bak'; - const DRY_RUN = true; + const DRY_RUN = Deno.env.get('MOIST_RUN') === '1' ? false : true; const BATCH_SIZE = 16; const ENCRYPTED_CONTENT_STRING = 'HBEGIN:oc_encryption_module:OC_DEFAULT_MODULE:cipher'; const CONFLICTED_COPY_REGEX = /.*( \(conflicted copy \d{4}-\d{2}-\d{2} \d+\))(\.[^\.]*)?/; @@ -43,9 +43,13 @@ import { join } from "https://deno.land/std@0.173.0/path/mod.ts"; if (!normalFile) { if (!DRY_RUN) { // Only the conflicted file exists, just move it to the non-conflict filename - await Deno.rename(conflictedFileName, nonConflictedFileName); + try { + await Deno.copyFile(conflictedFileName, nonConflictedFileName); + } catch (err) { + console.error(err); + } } - return `[${conflictedFileName}] only conflicted exists. Move to non-conflict filename`; + return `[${conflictedFileName}] only conflicted exists. Copy to non-conflict filename`; } const normalFileInfo = await Deno.fstat(normalFile.rid); conflictedFile.close(); @@ -66,9 +70,9 @@ import { join } from "https://deno.land/std@0.173.0/path/mod.ts"; if (normalSha === conflictedSha) { if (!DRY_RUN) { // They're the same, remove the conflicted file - await Deno.remove(conflictedFileName); + // await Deno.remove(conflictedFileName); } - return `[${conflictedFileName}] conflict and non-conflict have the same contents, remove the conflict`; + return `[${conflictedFileName}] conflict and non-conflict have the same contents, do nothing`; } const headP = Deno.run({ @@ -91,42 +95,52 @@ import { join } from "https://deno.land/std@0.173.0/path/mod.ts"; console.error(nonConflictedFileName, conflictedFileName); if (!DRY_RUN) { // Whatever, deleted the conflicted one - await Deno.remove(conflictedFileName); + // await Deno.remove(conflictedFileName); } - return `[${conflictedFileName}] both are encrypted but with different contents. We'll remove the conflict`; + return `[${conflictedFileName}] both are encrypted but with different contents. Do nothing`; } if (normalEncrypted) { if (!DRY_RUN) { - // delete normal - await Deno.remove(nonConflictedFileName); - await Deno.rename(conflictedFileName, nonConflictedFileName); + const ddP = Deno.run({ + cmd: ['dd', `if=${conflictedFileName}`, `of=${nonConflictedFileName}`], + }); + const status = await ddP.status(); + if (status.code !== 0) { + console.error(`Could not replace contents of file! ${conflictedFileName} > ${nonConflictedFileName}`); + } + ddP.close(); } - return `[${conflictedFileName}] the non-conflict is encrypted. Remove it and move the conflicted file in its place`; + return `[${conflictedFileName}] the non-conflict is encrypted. Replace its contents with the non-encrypted stuff`; } if (conflictedEncrypted) { if (!DRY_RUN) { // delete conflicted - await Deno.remove(conflictedFileName); + // await Deno.remove(conflictedFileName); } - return `[${conflictedFileName}] the conflict is encrypted. Remove it and keep the normal file`; + return `[${conflictedFileName}] the conflict is encrypted. Do nothing`; } if (normalFileInfo.mtime > conflictedFileInfo.mtime) { if (!DRY_RUN) { // delete conflicted - await Deno.remove(conflictedFileName); + // await Deno.remove(conflictedFileName); } - return `[${conflictedFileName}] conflict is older than the non-conflict. Remove the conflict`; + return `[${conflictedFileName}] conflict is older than the non-conflict. Do nothing`; } if (!DRY_RUN) { - // delete normal - await Deno.remove(nonConflictedFileName); - await Deno.rename(conflictedFileName, nonConflictedFileName); + const ddP = Deno.run({ + cmd: ['dd', `if=${conflictedFileName}`, `of=${nonConflictedFileName}`], + }); + const status = await ddP.status(); + if (status.code !== 0) { + console.error(`Could not replace contents of file! ${conflictedFileName} > ${nonConflictedFileName}`); + } + ddP.close(); } - return `[${conflictedFileName}] non-conflict is older than the conflict. Remove the non-conflict`; + return `[${conflictedFileName}] non-conflict is older than the conflict. Replace its contents with the newer stuff`; }).map(p => p.then((msg) => { filesSuccess++; console.log(`[${filesSuccess}/${totalFiles}] ${msg}`);