diff --git a/src-tauri/src/app.rs b/src-tauri/src/app.rs index bfd3c3489..4c3c6a381 100644 --- a/src-tauri/src/app.rs +++ b/src-tauri/src/app.rs @@ -352,8 +352,35 @@ impl App { &diff::Options { context_lines }, ) .context("failed to diff")?; + let diff = Self::diff_hunks_to_string(diff); + Ok(diff) + } + pub fn git_commit_diff( + &self, + project_id: &str, + commit_id: &str, + ) -> Result> { + let project = self.gb_project(project_id)?; + let project_repository = project_repository::Repository::open(&project) + .context("failed to open project repository")?; - let diff = diff + let commit = project_repository + .git_repository + .find_commit(git2::Oid::from_str(commit_id).unwrap())?; + + let parent = commit.parent(0).context("failed to get parent commit")?; + let commit_tree = commit.tree().context("failed to get commit tree")?; + let parent_tree = parent.tree().context("failed to get parent tree")?; + let diff = diff::trees(&project_repository, &parent_tree, &commit_tree)?; + + let diff = Self::diff_hunks_to_string(diff); + Ok(diff) + } + + fn diff_hunks_to_string( + diff: HashMap>, + ) -> HashMap { + return diff .into_iter() .map(|(file_path, hunks)| { ( @@ -366,8 +393,6 @@ impl App { ) }) .collect::>(); - - Ok(diff) } pub fn git_match_paths(&self, project_id: &str, pattern: &str) -> Result> { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index e617e519a..a7922fce7 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -288,6 +288,25 @@ async fn git_wd_diff( Ok(diff) } +#[tauri::command(async)] +#[instrument(name = "git_commit_diff", skip(handle))] +async fn git_commit_diff( + handle: tauri::AppHandle, + project_id: &str, + commit_id: &str, +) -> Result, Error> { + let app = handle.state::(); + let diff = app + .git_commit_diff(project_id, commit_id) + .with_context(|| { + format!( + "failed to get git diff for project {} and commit {}", + project_id, commit_id + ) + })?; + Ok(diff) +} + #[tauri::command(async)] #[instrument(name = "git_match_paths", skip(handle))] async fn git_match_paths( @@ -708,6 +727,7 @@ async fn main() { git_stage, git_unstage, git_wd_diff, + git_commit_diff, delete_all_data, get_logs_archive_path, get_project_archive_path, diff --git a/src/lib/api/git/diffs.ts b/src/lib/api/git/diffs.ts index ca8f605c2..07d8d9ccc 100644 --- a/src/lib/api/git/diffs.ts +++ b/src/lib/api/git/diffs.ts @@ -11,6 +11,10 @@ const list = (params: { projectId: string; contextLines?: number }) => const stores: Record>> = {}; +export function getCommitDiff(params: { projectId: string; commitId: string }) { + return invoke>('git_commit_diff', params); +} + export function getDiffsStore(params: { projectId: string }) { if (stores[params.projectId]) return stores[params.projectId]; const store = asyncWritable([], () => list(params)); diff --git a/src/routes/repo/[projectId]/BaseBranchPeek.svelte b/src/routes/repo/[projectId]/BaseBranchPeek.svelte index 90234cdd7..90399d9c7 100644 --- a/src/routes/repo/[projectId]/BaseBranchPeek.svelte +++ b/src/routes/repo/[projectId]/BaseBranchPeek.svelte @@ -5,6 +5,7 @@ import type { BranchController } from '$lib/vbranches/branchController'; import Scrollbar from '$lib/components/Scrollbar.svelte'; import { projectMergeUpstreamWarningDismissed } from '$lib/config/config'; + // import { getCommitDiff } from '$lib/api/git/diffs'; export let base: BaseBranch; export let branchController: BranchController; @@ -72,6 +73,16 @@
{#each base.recentCommits as commit} + {/each}