History

[commitgraph] Add `Graph::at` constructor.

This constructor tries to accept as many commit-graph-looking paths as possible, such as `.git/objects/info`, `.git/objects/info/commit-graph`, or `.git/objects/info/commit-graphs`.

Conor Davis committed 6 years ago

Commit a7830521 parent 1b738ac2 files · +44 −16Browse files

Showing the changes to git-commitgraph/src/graph (1 of 2 files). Show all

Unified · Split

git-commitgraph/src/graph/init.rs+42−15
@@ -4,6 +4,7 @@ use crate::{ · 3 unmodified lines
44 };
55 use git_object::HashKind;
66 use std::{
7+ convert::TryFrom,
78 io::{BufRead, BufReader},
89 path::{Path, PathBuf},
910 };
@@ -23,7 +24,9 @@ pub enum Error { · 13 unmodified lines
2324 path2: PathBuf,
2425 hash2: HashKind,
2526 },
26− #[error("Could not open commit-graph file at '{}'", path.display())]
27+ #[error("Did not find any files that look like commit graphs at '{}'", .0.display())]
28+ InvalidPath(PathBuf),
29+ #[error("Could not open commit-graph file at '{}'", .path.display())]
2730 Io {
2831 #[source]
2932 err: std::io::Error,
@@ -38,22 +41,12 @@ pub enum Error { · 8 unmodified lines
3841
3942 /// Instantiate a `Graph` from various sources
4043 impl Graph {
41− pub fn from_info_dir(info_dir: impl AsRef<Path>) -> Result<Self, Error> {
42− Self::from_single_file(info_dir.as_ref())
43− .or_else(|_| Self::from_split_chain(info_dir.as_ref().join("commit-graphs")))
44− }
45−
46− pub fn from_single_file(info_dir: impl AsRef<Path>) -> Result<Self, Error> {
47− let single_graph_file = info_dir.as_ref().join("commit-graph");
48− let file = File::at(&single_graph_file).map_err(|e| Error::File {
49− err: e,
50− path: single_graph_file.clone(),
51− })?;
52− Self::new(vec![file])
44+ pub fn at(path: impl AsRef<Path>) -> Result<Self, Error> {
45+ Self::try_from(path.as_ref())
5346 }
5447
55− pub fn from_split_chain(commit_graphs_dir: impl AsRef<Path>) -> Result<Self, Error> {
56− let commit_graphs_dir = commit_graphs_dir.as_ref();
48+ pub fn from_commit_graphs_dir(path: impl AsRef<Path>) -> Result<Self, Error> {
49+ let commit_graphs_dir = path.as_ref();
5750 let chain_file_path = commit_graphs_dir.join("commit-graph-chain");
5851 let chain_file = std::fs::File::open(&chain_file_path).map_err(|e| Error::Io {
5952 err: e,
@@ -74,6 +67,20 @@ impl Graph { · 14 unmodified lines
7467 Self::new(files)
7568 }
7669
70+ pub fn from_file(path: impl AsRef<Path>) -> Result<Self, Error> {
71+ let path = path.as_ref();
72+ let file = File::at(path).map_err(|e| Error::File {
73+ err: e,
74+ path: path.to_owned(),
75+ })?;
76+ Self::new(vec![file])
77+ }
78+
79+ pub fn from_info_dir(info_dir: impl AsRef<Path>) -> Result<Self, Error> {
80+ Self::from_file(info_dir.as_ref().join("commit-graph"))
81+ .or_else(|_| Self::from_commit_graphs_dir(info_dir.as_ref().join("commit-graphs")))
82+ }
83+
7784 pub fn new(files: Vec<File>) -> Result<Self, Error> {
7885 let num_commits: u64 = files.iter().map(|f| f.num_commits() as u64).sum();
7986 if num_commits > MAX_COMMITS as u64 {
@@ -96,3 +103,23 @@ impl Graph { · 16 unmodified lines
96103 Ok(Self { files })
97104 }
98105 }
106+
107+impl TryFrom<&Path> for Graph {
108+ type Error = Error;
109+
110+ fn try_from(path: &Path) -> Result<Self, Self::Error> {
111+ if path.is_file() {
112+ // Assume we are looking at `.git/objects/info/commit-graph` or
113+ // `.git/objects/info/commit-graphs/graph-*.graph`.
114+ Self::from_file(path)
115+ } else if path.is_dir() {
116+ if path.join("commit-graph-chain").is_file() {
117+ Self::from_commit_graphs_dir(path)
118+ } else {
119+ Self::from_info_dir(path)
120+ }
121+ } else {
122+ Err(Error::InvalidPath(path.to_owned()))
123+ }
124+ }
125+}