gitoxide_core/repository/revision/
resolve.rs1use crate::OutputFormat;
2
3pub struct Options {
4 pub format: OutputFormat,
5 pub explain: bool,
6 pub cat_file: bool,
7 pub tree_mode: TreeMode,
8 pub blob_format: BlobFormat,
9 pub show_reference: bool,
10}
11
12pub enum TreeMode {
13 Raw,
14 Pretty,
15}
16
17#[derive(Copy, Clone)]
18pub enum BlobFormat {
19 Git,
20 Worktree,
21 Diff,
22 DiffOrGit,
23}
24
25pub(crate) mod function {
26 use std::ffi::OsString;
27
28 use super::Options;
29 use crate::{
30 repository::{cat::display_object, revision, revision::resolve::BlobFormat},
31 OutputFormat,
32 };
33
34 pub fn resolve(
35 mut repo: gix::Repository,
36 specs: Vec<OsString>,
37 mut out: impl std::io::Write,
38 Options {
39 format,
40 explain,
41 cat_file,
42 tree_mode,
43 blob_format,
44 show_reference,
45 }: Options,
46 ) -> anyhow::Result<()> {
47 repo.object_cache_size_if_unset(1024 * 1024);
48 let mut cache = (!matches!(blob_format, BlobFormat::Git))
49 .then(|| {
50 repo.diff_resource_cache(
51 match blob_format {
52 BlobFormat::Git => {
53 unreachable!("checked before")
54 }
55 BlobFormat::Worktree | BlobFormat::Diff => {
56 gix::diff::blob::pipeline::Mode::ToWorktreeAndBinaryToText
57 }
58 BlobFormat::DiffOrGit => gix::diff::blob::pipeline::Mode::ToGitUnlessBinaryToTextIsPresent,
59 },
60 Default::default(),
61 )
62 })
63 .transpose()?;
64
65 match format {
66 OutputFormat::Human => {
67 for spec in specs {
68 if explain {
69 return revision::explain(spec, out);
70 }
71 let spec = gix::path::os_str_into_bstr(&spec)?;
72 let spec = repo.rev_parse(spec)?;
73 if cat_file {
74 return display_object(&repo, spec, tree_mode, cache.as_mut().map(|c| (blob_format, c)), out);
75 }
76 if let Some(r) = spec.first_reference().filter(|_| show_reference) {
77 writeln!(out, "{}", r.name)?;
78 }
79 if let Some(r) = spec.second_reference().filter(|_| show_reference) {
80 writeln!(out, "{}", r.name)?;
81 }
82 writeln!(out, "{spec}", spec = spec.detach())?;
83 }
84 }
85 #[cfg(feature = "serde")]
86 OutputFormat::Json => {
87 if explain {
88 anyhow::bail!("Explanations are only for human consumption")
89 }
90 serde_json::to_writer_pretty(
91 &mut out,
92 &specs
93 .into_iter()
94 .map(|spec| {
95 gix::path::os_str_into_bstr(&spec)
96 .map_err(anyhow::Error::from)
97 .and_then(|spec| repo.rev_parse(spec).map_err(Into::into))
98 .map(gix::revision::Spec::detach)
99 })
100 .collect::<Result<Vec<_>, _>>()?,
101 )?;
102 }
103 }
104 Ok(())
105 }
106}