mkit_cli/commands/
rev_list.rs1use std::collections::HashSet;
7use std::io::Write;
8
9use clap::Parser;
10use mkit_core::store::ObjectStore;
11
12use crate::clap_shim;
13use crate::exit;
14use crate::format;
15
16#[derive(Debug, Parser)]
17#[command(
18 name = "mkit rev-list",
19 about = "List commit objects reachable from a revision."
20)]
21struct RevListOpts {
22 #[arg(long)]
24 count: bool,
25 rev: String,
27}
28
29#[must_use]
30pub fn run(args: &[String]) -> u8 {
31 let opts = match clap_shim::parse::<RevListOpts>("mkit rev-list", args) {
32 Ok(o) => o,
33 Err(code) => return code,
34 };
35 let cwd = match std::env::current_dir() {
36 Ok(p) => p,
37 Err(e) => return emit_err(&format!("cwd: {e}"), exit::NOINPUT),
38 };
39 let layout = match super::resolve_layout(&cwd) {
40 Ok(layout) => layout,
41 Err(code) => return code,
42 };
43 let store = match ObjectStore::open(&layout) {
44 Ok(s) => s,
45 Err(e) => return emit_err(&format!("not a mkit repo: {e}"), exit::GENERAL_ERROR),
46 };
47 let tip = match super::revspec::resolve_revision(&store, &layout, &opts.rev) {
48 Ok(h) => super::log::peel_tags(&store, h),
51 Err(e) => {
52 return emit_err(
53 &format!("bad revision '{}': {e}", opts.rev),
54 exit::GENERAL_ERROR,
55 );
56 }
57 };
58 let commits = match super::log::ordered_commits(&store, &[tip], &HashSet::new()) {
59 Ok(c) => c,
60 Err(code) => return code,
61 };
62 let mut stdout = std::io::stdout().lock();
63 if opts.count {
64 let _ = writeln!(stdout, "{}", commits.len());
65 } else {
66 for (h, _) in &commits {
67 let _ = writeln!(stdout, "{}", format::hex_hash(h));
68 }
69 }
70 exit::OK
71}
72
73use super::error as emit_err;