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`.
Showing the changes to git-commitgraph/src/graph (1 of 2 files). Show all
Unified · Split
| @@ -4,6 +4,7 @@ use crate::{ · 3 unmodified lines | ||
| 4 | 4 | }; |
| 5 | 5 | use git_object::HashKind; |
| 6 | 6 | use std::{ |
| 7 | + convert::TryFrom, | |
| 7 | 8 | io::{BufRead, BufReader}, |
| 8 | 9 | path::{Path, PathBuf}, |
| 9 | 10 | }; |
| @@ -23,7 +24,9 @@ pub enum Error { · 13 unmodified lines | ||
| 23 | 24 | path2: PathBuf, |
| 24 | 25 | hash2: HashKind, |
| 25 | 26 | }, |
| 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())] | |
| 27 | 30 | Io { |
| 28 | 31 | #[source] |
| 29 | 32 | err: std::io::Error, |
| @@ -38,22 +41,12 @@ pub enum Error { · 8 unmodified lines | ||
| 38 | 41 | |
| 39 | 42 | /// Instantiate a `Graph` from various sources |
| 40 | 43 | 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()) | |
| 53 | 46 | } |
| 54 | 47 | |
| 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(); | |
| 57 | 50 | let chain_file_path = commit_graphs_dir.join("commit-graph-chain"); |
| 58 | 51 | let chain_file = std::fs::File::open(&chain_file_path).map_err(|e| Error::Io { |
| 59 | 52 | err: e, |
| @@ -74,6 +67,20 @@ impl Graph { · 14 unmodified lines | ||
| 74 | 67 | Self::new(files) |
| 75 | 68 | } |
| 76 | 69 | |
| 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 | + | |
| 77 | 84 | pub fn new(files: Vec<File>) -> Result<Self, Error> { |
| 78 | 85 | let num_commits: u64 = files.iter().map(|f| f.num_commits() as u64).sum(); |
| 79 | 86 | if num_commits > MAX_COMMITS as u64 { |
| @@ -96,3 +103,23 @@ impl Graph { · 16 unmodified lines | ||
| 96 | 103 | Ok(Self { files }) |
| 97 | 104 | } |
| 98 | 105 | } |
| 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 | +} | |