fix: escape rewrite replacement, diagnostic no-op commit, doc + askpass hardening

- Use function replacer in rewriteBody to prevent $& / $$ / $` / $' pattern
  corruption when alt text or siteUrl contains dollar-sign sequences
- Detect empty staged index after `git add -A` and throw a clear
  "No changes to publish" error instead of a cryptic git failure
- Correct README flat-slug description: single image → <slug>.<ext>,
  multiple → <slug>-1.<ext>, <slug>-2.<ext> (original filename discarded)
- Harden askpass dir resolution: show a Notice and return early if
  getFullPath is absent (desktop-only guard), rather than passing a bad path

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-19 02:32:02 +00:00
parent ee56f8c9a2
commit c6f28474e4
6 changed files with 45 additions and 5 deletions

View File

@@ -50,3 +50,22 @@ test("second sync resets cleanly (fetch+reset path)", async () => {
execFileSync("git", ["clone", bare, verify]);
expect(readFileSync(join(verify, "_posts/second.md"), "utf8")).toBe("x");
});
test("commitAndPush rejects with diagnostic error when nothing is staged", async () => {
// Use a fresh base dir so we get a clean clone
const base2 = join(root, "work2");
mkdirSync(base2, { recursive: true });
const client = new ChildProcessGitClient({ baseDir: base2 });
// Clone and write a file, then commit it
await client.syncClone({ url: bare, branch: "main" });
await client.writeFiles([{ repoPath: "_posts/no-change.md", data: "same content" }]);
await client.commitAndPush({ message: "initial no-change", branch: "main", authorName: "t", authorEmail: "t@t" });
// Now sync again — tree now matches origin, re-writing the same content stages nothing
const client2 = new ChildProcessGitClient({ baseDir: base2 });
await client2.syncClone({ url: bare, branch: "main" });
await client2.writeFiles([{ repoPath: "_posts/no-change.md", data: "same content" }]);
await expect(
client2.commitAndPush({ message: "noop", branch: "main", authorName: "t", authorEmail: "t@t" })
).rejects.toThrow(/no changes to publish/i);
});