diff --git a/crates/radicle-types/src/traits/repo.rs b/crates/radicle-types/src/traits/repo.rs index fc13ed3e3..a8f68ccbf 100644 --- a/crates/radicle-types/src/traits/repo.rs +++ b/crates/radicle-types/src/traits/repo.rs @@ -781,18 +781,20 @@ pub trait Repo: Profile { let profile = self.profile(); let repo = profile.storage.repository(rid)?; - let repo = surf::Repository::open(repo.path())?; - let history = repo.history(&head)?; + // Hide `base` from the walk rather than stopping at the first commit + // that equals it. A merge commit reaches `base` through one of its + // parents, so truncating there drops every commit the other parent + // contributes and leaves the revision looking like a single commit. + let mut walk = repo.backend.revwalk()?; + walk.set_sorting(git2::Sort::TOPOLOGICAL | git2::Sort::TIME)?; + walk.push(git::raw::Oid::from_str(&head)?)?; + walk.hide(git::raw::Oid::from_str(&base)?)?; - let commits = history - .take_while(|c| { - if let Ok(c) = c { - c.id.to_string() != base - } else { - false - } - }) - .filter_map(|c| c.map(Into::into).ok()) + let surf_repo = surf::Repository::open(repo.path())?; + let commits = walk + .filter_map(|oid| oid.ok()) + .filter_map(|oid| surf_repo.commit(git::Oid::from(oid)).ok()) + .map(Into::into) .collect(); Ok(commits) diff --git a/src/components/Changes.svelte b/src/components/Changes.svelte index 31220fe08..e3b18c7cd 100644 --- a/src/components/Changes.svelte +++ b/src/components/Changes.svelte @@ -345,13 +345,16 @@ }); // A single-commit revision has nothing to choose between, so select that - // commit automatically to surface its message. + // commit automatically to surface its message. The diff stays the + // revision's own range: a merge commit's first parent is the side it merged + // into, not the revision base, so narrowing to the commit diff there would + // show the other branch's changes instead of the patch's. $effect(() => { if (commitList.length === 1 && !selectedCommit) { const only = commitList[0]; selectRevision({ - headId: only.id, - baseId: only.parents[0], + headId: revision.head, + baseId: revision.base, commitId: only.id, commit: only, });