From 2ea6acb69726d67e242116ab049815b33c0153c0 Mon Sep 17 00:00:00 2001 From: Peer Sommerlund Date: Sat, 27 Jun 2026 08:36:16 +0200 Subject: [PATCH] Change walk order from ByCommitTime to topological order This is preparation for a graph implementation. If sorted by commit time, a graph may have to draw a parent before its child. This is confusing to the user and require extra memory for the graph render algorithm. --- CHANGELOG.md | 1 + asyncgit/src/sync/logwalker.rs | 44 +++++++--------------------------- 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68c2158509..a587bc1dd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * open the external editor from the status diff view [[@WaterWhisperer](https://github.com/WaterWhisperer)] ([#2805](https://github.com/gitui-org/gitui/issues/2805)) * automatically convert spaces to dashes when creating or renaming a branch [[@pbouillon]](https//pbouillon.github.io)] ([#2916](https://github.com/gitui-org/gitui/pull/2916)) * support rewording non-HEAD commits when `commit.gpgsign` is enabled (gpg format only) [[@guerinoni](https://github.com/guerinoni)] ([#2959](https://github.com/gitui-org/gitui/pull/2959)) +* change commit order from commit time to topology order ### Fixes * crash when opening submodule ([#2895](https://github.com/gitui-org/gitui/issues/2895)) diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index 81a6fd321e..a92711b89d 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -2,36 +2,11 @@ use super::{CommitId, SharedCommitFilterFn}; use crate::error::Result; use git2::{Commit, Oid, Repository}; use gix::revision::Walk; -use std::{ - cmp::Ordering, - collections::{BinaryHeap, HashSet}, -}; - -struct TimeOrderedCommit<'a>(Commit<'a>); - -impl Eq for TimeOrderedCommit<'_> {} - -impl PartialEq for TimeOrderedCommit<'_> { - fn eq(&self, other: &Self) -> bool { - self.0.time().eq(&other.0.time()) - } -} - -impl PartialOrd for TimeOrderedCommit<'_> { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for TimeOrderedCommit<'_> { - fn cmp(&self, other: &Self) -> Ordering { - self.0.time().cmp(&other.0.time()) - } -} +use std::collections::HashSet; /// pub struct LogWalker<'a> { - commits: BinaryHeap>, + commits: Vec>, visited: HashSet, limit: usize, repo: &'a Repository, @@ -43,8 +18,8 @@ impl<'a> LogWalker<'a> { pub fn new(repo: &'a Repository, limit: usize) -> Result { let c = repo.head()?.peel_to_commit()?; - let mut commits = BinaryHeap::with_capacity(10); - commits.push(TimeOrderedCommit(c)); + let mut commits = Vec::with_capacity(10); + commits.push(c); Ok(Self { commits, @@ -74,11 +49,11 @@ impl<'a> LogWalker<'a> { let mut count = 0_usize; while let Some(c) = self.commits.pop() { - for p in c.0.parents() { + for p in c.parents() { self.visit(p); } - let id: CommitId = c.0.id().into(); + let id: CommitId = c.id().into(); let commit_should_be_included = if let Some(ref filter) = self.filter { filter(self.repo, &id)? @@ -102,7 +77,7 @@ impl<'a> LogWalker<'a> { // fn visit(&mut self, c: Commit<'a>) { if self.visited.insert(c.id()) { - self.commits.push(TimeOrderedCommit(c)); + self.commits.push(c); } } } @@ -137,10 +112,7 @@ impl<'a> LogWalkerWithoutFilter<'a> { let tips = [commit.id]; - let platform = repo - .rev_walk(tips) - .sorting(gix::revision::walk::Sorting::ByCommitTime(gix::traverse::commit::simple::CommitTimeOrder::NewestFirst)) - .use_commit_graph(false); + let platform = repo.rev_walk(tips); let walk = platform.all()?;