Skip to content

Add gix log #1643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions gitoxide-core/src/repository/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use anyhow::bail;
use gix::bstr::{BString, ByteSlice};

pub fn log(mut repo: gix::Repository, out: &mut dyn std::io::Write, path: Option<BString>) -> anyhow::Result<()> {
repo.object_cache_size_if_unset(repo.compute_object_cache_size_for_tree_diffs(&**repo.index_or_empty()?));

if let Some(path) = path {
log_file(repo, out, path)
} else {
log_all(repo, out)
}
}

fn log_all(repo: gix::Repository, out: &mut dyn std::io::Write) -> Result<(), anyhow::Error> {
let head = repo.head()?.peel_to_commit_in_place()?;
let topo = gix::traverse::commit::topo::Builder::from_iters(&repo.objects, [head.id], None::<Vec<gix::ObjectId>>)
.build()?;

for info in topo {
let info = info?;

write_info(&repo, &mut *out, &info)?;
}

Ok(())
}

fn log_file(_repo: gix::Repository, _out: &mut dyn std::io::Write, _path: BString) -> anyhow::Result<()> {
bail!("File-based lookup isn't yet implemented in a way that is competitively fast");
}

fn write_info(
repo: &gix::Repository,
mut out: impl std::io::Write,
info: &gix::traverse::commit::Info,
) -> Result<(), std::io::Error> {
let commit = repo.find_commit(info.id).unwrap();

let message = commit.message_raw_sloppy();
let title = message.lines().next();

writeln!(
out,
"{} {}",
info.id.to_hex_with_len(8),
title.map_or_else(|| "<no message>".into(), BString::from)
)?;

Ok(())
}
1 change: 1 addition & 0 deletions gitoxide-core/src/repository/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub mod commitgraph;
mod fsck;
pub use fsck::function as fsck;
pub mod index;
pub mod log;
pub mod mailmap;
mod merge_base;
pub use merge_base::merge_base;
Expand Down
9 changes: 9 additions & 0 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,15 @@ pub fn main() -> Result<()> {
},
),
},
Subcommands::Log(crate::plumbing::options::log::Platform { pathspec }) => prepare_and_run(
"log",
trace,
verbose,
progress,
progress_keep_open,
None,
move |_progress, out, _err| core::repository::log::log(repository(Mode::Lenient)?, out, pathspec),
),
Subcommands::Worktree(crate::plumbing::options::worktree::Platform { cmd }) => match cmd {
crate::plumbing::options::worktree::SubCommands::List => prepare_and_run(
"worktree-list",
Expand Down
13 changes: 13 additions & 0 deletions src/plumbing/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ pub enum Subcommands {
MergeBase(merge_base::Command),
Merge(merge::Platform),
Diff(diff::Platform),
Log(log::Platform),
Worktree(worktree::Platform),
/// Subcommands that need no git repository to run.
#[clap(subcommand)]
Expand Down Expand Up @@ -499,6 +500,18 @@ pub mod diff {
}
}

pub mod log {
use gix::bstr::BString;

/// List all commits in a repository, optionally limited to those that change a given path
#[derive(Debug, clap::Parser)]
pub struct Platform {
/// The git path specification to show a log for.
#[clap(value_parser = crate::shared::AsBString)]
pub pathspec: Option<BString>,
}
}

pub mod config {
use gix::bstr::BString;

Expand Down
Loading