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