Skip to content

Commit 29cb775

Browse files
authored
Merge pull request #1643 from cruessler/add-gix-log
Add gix log
2 parents df5cead + 162887e commit 29cb775

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

gitoxide-core/src/repository/log.rs

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use anyhow::bail;
2+
use gix::bstr::{BString, ByteSlice};
3+
4+
pub 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+
14+
fn 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+
28+
fn 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+
32+
fn 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+
}

gitoxide-core/src/repository/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub mod commitgraph;
4646
mod fsck;
4747
pub use fsck::function as fsck;
4848
pub mod index;
49+
pub mod log;
4950
pub mod mailmap;
5051
mod merge_base;
5152
pub use merge_base::merge_base;

src/plumbing/main.rs

+9
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,15 @@ pub fn main() -> Result<()> {
269269
},
270270
),
271271
},
272+
Subcommands::Log(crate::plumbing::options::log::Platform { pathspec }) => prepare_and_run(
273+
"log",
274+
trace,
275+
verbose,
276+
progress,
277+
progress_keep_open,
278+
None,
279+
move |_progress, out, _err| core::repository::log::log(repository(Mode::Lenient)?, out, pathspec),
280+
),
272281
Subcommands::Worktree(crate::plumbing::options::worktree::Platform { cmd }) => match cmd {
273282
crate::plumbing::options::worktree::SubCommands::List => prepare_and_run(
274283
"worktree-list",

src/plumbing/options/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ pub enum Subcommands {
146146
MergeBase(merge_base::Command),
147147
Merge(merge::Platform),
148148
Diff(diff::Platform),
149+
Log(log::Platform),
149150
Worktree(worktree::Platform),
150151
/// Subcommands that need no git repository to run.
151152
#[clap(subcommand)]
@@ -499,6 +500,18 @@ pub mod diff {
499500
}
500501
}
501502

503+
pub mod log {
504+
use gix::bstr::BString;
505+
506+
/// List all commits in a repository, optionally limited to those that change a given path
507+
#[derive(Debug, clap::Parser)]
508+
pub struct Platform {
509+
/// The git path specification to show a log for.
510+
#[clap(value_parser = crate::shared::AsBString)]
511+
pub pathspec: Option<BString>,
512+
}
513+
}
514+
502515
pub mod config {
503516
use gix::bstr::BString;
504517

0 commit comments

Comments
 (0)