gitoxide_core/repository/
log.rs1use anyhow::bail;
2use gix::bstr::{BString, ByteSlice};
3
4pub fn log(mut repo: gix::Repository, out: &mut dyn std::io::Write, path: Option<BString>) -> anyhow::Result<()> {
5 repo.object_cache_size_if_unset(repo.compute_object_cache_size_for_tree_diffs(&**repo.index_or_empty()?));
6
7 if let Some(path) = path {
8 log_file(repo, out, path)
9 } else {
10 log_all(repo, out)
11 }
12}
13
14fn log_all(repo: gix::Repository, out: &mut dyn std::io::Write) -> Result<(), anyhow::Error> {
15 let head = repo.head()?.peel_to_commit_in_place()?;
16 let topo = gix::traverse::commit::topo::Builder::from_iters(&repo.objects, [head.id], None::<Vec<gix::ObjectId>>)
17 .build()?;
18
19 for info in topo {
20 let info = info?;
21
22 write_info(&repo, &mut *out, &info)?;
23 }
24
25 Ok(())
26}
27
28fn log_file(_repo: gix::Repository, _out: &mut dyn std::io::Write, _path: BString) -> anyhow::Result<()> {
29 bail!("File-based lookup isn't yet implemented in a way that is competitively fast");
30}
31
32fn write_info(
33 repo: &gix::Repository,
34 mut out: impl std::io::Write,
35 info: &gix::traverse::commit::Info,
36) -> Result<(), std::io::Error> {
37 let commit = repo.find_commit(info.id).unwrap();
38
39 let message = commit.message_raw_sloppy();
40 let title = message.lines().next();
41
42 writeln!(
43 out,
44 "{} {}",
45 info.id.to_hex_with_len(8),
46 title.map_or_else(|| "<no message>".into(), BString::from)
47 )?;
48
49 Ok(())
50}