From c39140851aee635aaf2af727d6e2bd64c8e7a8f6 Mon Sep 17 00:00:00 2001 From: garak95 <267723355+garak95@users.noreply.github.com> Date: Tue, 31 Mar 2026 02:19:51 +0100 Subject: [PATCH] Add support to view diff changes in the revert dialog --- src/git.ts | 6 ++++++ src/i18n.ts | 3 +++ src/main.ts | 14 ++++++++++++-- src/modals.ts | 34 +++++++++++++++++++++++++++++++--- styles.css | 5 +++++ 5 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/git.ts b/src/git.ts index ea829c5..06eee44 100644 --- a/src/git.ts +++ b/src/git.ts @@ -177,6 +177,12 @@ export async function getChangedFiles(cwd: string, gitPath: string): Promise { + const stdout = await runGit({ cwd, gitPath, args: ["diff", "--", filePath] }); + if (!stdout) return ""; + return stdout; +} + export async function commitAll(cwd: string, gitPath: string, message: string): Promise { await runGit({ cwd, gitPath, args: ["add", "-A"] }); diff --git a/src/i18n.ts b/src/i18n.ts index 246f6ad..44a0027 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -60,6 +60,7 @@ type Translations = { revertConfirmDesc: string; revertConfirmButton: string; revertCancelButton: string; + revertViewChanges: string, revertNoChanges: string; revertFileMenu: string; noticeFileReverted: string; @@ -199,6 +200,7 @@ const en: Translations = { revertConfirmDesc: "The following files will be reverted:", revertConfirmButton: "Revert", revertCancelButton: "Cancel", + revertViewChanges: "(view changes)", revertNoChanges: "No changes to revert.", revertFileMenu: "Revert file changes", noticeFileReverted: "GitAutoCommit: File reverted.", @@ -333,6 +335,7 @@ const zhCN: Translations = { revertConfirmDesc: "以下文件将被还原:", revertConfirmButton: "还原", revertCancelButton: "取消", + revertViewChanges: "(view changes)", revertNoChanges: "没有可还原的修改。", revertFileMenu: "还原文件修改", noticeFileReverted: "GitAutoCommit: 文件已还原。", diff --git a/src/main.ts b/src/main.ts index 2987586..af92809 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,9 @@ import { EventRef, Menu, Notice, Platform, Plugin, TAbstractFile, TFile, FileSystemAdapter } from "obsidian"; import { AutoGitSettings, AutoGitSettingTab, DEFAULT_SETTINGS } from "./settings"; -import { getChangedFiles, commitAll, push, pull, getConflictFiles, markConflictsResolved, revertAll, revertFile, getChangedFilesSync, commitSyncAndPushDetached, setGitDebug } from "./git"; +import { getChangedFiles, commitAll, push, pull, getConflictFiles, markConflictsResolved, revertAll, revertFile, getChangedFilesSync, commitSyncAndPushDetached, setGitDebug, getChangedFileDiff } from "./git"; import { renderTemplate } from "./template"; import { t } from "./i18n"; -import { RevertConfirmModal } from "./modals"; +import { RevertConfirmModal, ViewDiffModal } from "./modals"; import { GitStatusBadgeManager } from "./statusBadges"; import { ProgressNotice } from "./notice"; @@ -362,6 +362,11 @@ export default class AutoGitPlugin extends Plugin { new Notice(t().noticeRevertFailed((e as Error).message)); } })(); + }, (filePath: string) => { + void (async () => { + const diff = await getChangedFileDiff(cwd, this.settings.gitPath, filePath); + new ViewDiffModal(this.app, filePath, diff).open(); + })(); }).open(); } catch (e) { new Notice(t().noticeRevertFailed((e as Error).message)); @@ -394,6 +399,11 @@ export default class AutoGitPlugin extends Plugin { new Notice(t().noticeFileRevertFailed((e as Error).message)); } })(); + }, (filePath: string) => { + void (async () => { + const diff = await getChangedFileDiff(this.getVaultPath(), this.settings.gitPath, filePath); + new ViewDiffModal(this.app, filePath, diff).open(); + })(); }).open(); }); }); diff --git a/src/modals.ts b/src/modals.ts index 451b48a..a839998 100644 --- a/src/modals.ts +++ b/src/modals.ts @@ -4,23 +4,27 @@ import { t } from "./i18n"; export class RevertConfirmModal extends Modal { private files: string[]; private onConfirm: () => void; + private onDiffRequest: (filePath: string) => void; - constructor(app: App, files: string[], onConfirm: () => void) { + constructor(app: App, files: string[], onConfirm: () => void, onDiffRequest: (filePath: string) => void) { super(app); this.files = files; this.onConfirm = onConfirm; + this.onDiffRequest = onDiffRequest; } onOpen() { const i18n = t(); const { contentEl } = this; - contentEl.createEl("h2", { text: i18n.revertConfirmTitle }); + this.setTitle(i18n.revertConfirmTitle); contentEl.createEl("p", { text: i18n.revertConfirmDesc }); const listEl = contentEl.createEl("ul", { cls: "revert-file-list" }); this.files.forEach((file) => { - listEl.createEl("li", { text: file }); + listEl.createEl("li", { text: file + " " }) + .createEl("a", { href: "#", text: i18n.revertViewChanges }) + .addEventListener("click", () => this.onDiffRequest(file)); }); const buttonContainer = contentEl.createDiv({ cls: "modal-button-container" }); @@ -43,3 +47,27 @@ export class RevertConfirmModal extends Modal { this.contentEl.empty(); } } + +export class ViewDiffModal extends Modal { + private title: string; + private diff: string; + + constructor(app: App, title: string, diff: string) { + super(app); + this.title = title; + this.diff = diff; + } + + onOpen() { + this.setTitle(this.title); + const preview = this.contentEl.createEl("div", { cls: "diff-preview-modal" }); + preview.createEl("pre").setText(this.diff); + // MarkdownRenderer + // .render(this.app, "```diff\n" + this.diff + "\n```", preview, "", new MarkdownRenderChild(preview)); + } + + onClose() { + this.contentEl.empty(); + } +} + diff --git a/styles.css b/styles.css index eb1d283..259b308 100644 --- a/styles.css +++ b/styles.css @@ -31,3 +31,8 @@ .git-status-badge[data-status="U"] { color: #ff0000; } + +.diff-preview-modal { + font-size: var(--font-ui-small); + overflow: scroll; +} \ No newline at end of file