WIP: List the most recent change to each top-level entry in a git tree

fix: correctly handle repositories with only one commit

Signed-off-by: tjh <x@tjh.dev>
Change-Id: I6a6a69649d9e92d08262bf8f19babba0661e05b9

tjh.dev 315666bf f7dfe9f1

verified
+15 -7
+15 -7
src/main.rs
··· 3 use gix::ObjectId; 4 use gix::Repository; 5 use gix::bstr::BStr; 6 use gix::date::Time; 7 use gix::object::tree::EntryRef; 8 use gix::objs::decode::Error as DecodeError; ··· 42 rev_walk = rev_walk.with_boundary([stop_commit.id]); 43 } 44 45 for revision in rev_walk.all()? { 46 if interested.is_empty() { 47 break; ··· 49 50 let revision = revision?; 51 let Some(&parent_id) = revision.parent_ids.first() else { 52 break; 53 }; 54 ··· 62 let mut scanner = EntryScanner::new(current_tree.iter(), parent_tree.iter())?; 63 while let Some(change) = scanner.next_change()? { 64 if interested.remove(change.filename()) { 65 - let id = revision.id; 66 - println!( 67 - "{:<name_pad$}\t{id}\t{}\t{}", 68 - change.filename().to_string(), 69 - format_ts(&current_commit.time()?, arguments.utc)?, 70 - current_commit.message()?.summary(), 71 - ); 72 } 73 } 74
··· 3 use gix::ObjectId; 4 use gix::Repository; 5 use gix::bstr::BStr; 6 + use gix::bstr::ByteSlice; 7 use gix::date::Time; 8 use gix::object::tree::EntryRef; 9 use gix::objs::decode::Error as DecodeError; ··· 43 rev_walk = rev_walk.with_boundary([stop_commit.id]); 44 } 45 46 + let output = |filename: &BStr, commit: &Commit| -> anyhow::Result<()> { 47 + let id = commit.id; 48 + let ts = format_ts(&commit.time()?, arguments.utc)?; 49 + let message = commit.message()?.summary(); 50 + println!("{filename:<name_pad$}\t{id}\t{ts}\t{message}",); 51 + Ok(()) 52 + }; 53 + 54 for revision in rev_walk.all()? { 55 if interested.is_empty() { 56 break; ··· 58 59 let revision = revision?; 60 let Some(&parent_id) = revision.parent_ids.first() else { 61 + // The revision has no parents. Assume any remaining entries belong 62 + // to this commit. 63 + for entry in interested.drain() { 64 + output(entry.as_bstr(), &current_commit)?; 65 + } 66 break; 67 }; 68 ··· 76 let mut scanner = EntryScanner::new(current_tree.iter(), parent_tree.iter())?; 77 while let Some(change) = scanner.next_change()? { 78 if interested.remove(change.filename()) { 79 + output(change.filename(), &current_commit)?; 80 } 81 } 82