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 | use git_object::HashKind; | 5 | use git_object::HashKind; |
| 6 | use std::{ | 6 | use std::{ |
| 7 | convert::TryFrom, | ||
| 7 | io::{BufRead, BufReader}, | 8 | io::{BufRead, BufReader}, |
| 8 | path::{Path, PathBuf}, | 9 | path::{Path, PathBuf}, |
| 9 | }; | 10 | }; |
| @@ -23,7 +24,9 @@ pub enum Error { · 13 unmodified lines | |||
| 23 | path2: PathBuf, | 24 | path2: PathBuf, |
| 24 | hash2: HashKind, | 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 | Io { | 30 | Io { |
| 28 | #[source] | 31 | #[source] |
| 29 | err: std::io::Error, | 32 | err: std::io::Error, |
| @@ -38,22 +41,12 @@ pub enum Error { · 8 unmodified lines | |||
| 38 | 41 | ||
| 39 | /// Instantiate a `Graph` from various sources | 42 | /// Instantiate a `Graph` from various sources |
| 40 | impl Graph { | 43 | impl Graph { |
| 41 | pub fn from_info_dir(info_dir: impl AsRef<Path>) -> Result<Self, Error> { | 44 | pub fn at(path: impl AsRef<Path>) -> Result<Self, Error> { |
| 42 | Self::from_single_file(info_dir.as_ref()) | 45 | Self::try_from(path.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]) | ||
| 53 | } | 46 | } |
| 54 | 47 | ||
| 55 | pub fn from_split_chain(commit_graphs_dir: impl AsRef<Path>) -> Result<Self, Error> { | 48 | pub fn from_commit_graphs_dir(path: impl AsRef<Path>) -> Result<Self, Error> { |
| 56 | let commit_graphs_dir = commit_graphs_dir.as_ref(); | 49 | let commit_graphs_dir = path.as_ref(); |
| 57 | let chain_file_path = commit_graphs_dir.join("commit-graph-chain"); | 50 | let chain_file_path = commit_graphs_dir.join("commit-graph-chain"); |
| 58 | let chain_file = std::fs::File::open(&chain_file_path).map_err(|e| Error::Io { | 51 | let chain_file = std::fs::File::open(&chain_file_path).map_err(|e| Error::Io { |
| 59 | err: e, | 52 | err: e, |
| @@ -74,6 +67,20 @@ impl Graph { · 14 unmodified lines | |||
| 74 | Self::new(files) | 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 | pub fn new(files: Vec<File>) -> Result<Self, Error> { | 84 | pub fn new(files: Vec<File>) -> Result<Self, Error> { |
| 78 | let num_commits: u64 = files.iter().map(|f| f.num_commits() as u64).sum(); | 85 | let num_commits: u64 = files.iter().map(|f| f.num_commits() as u64).sum(); |
| 79 | if num_commits > MAX_COMMITS as u64 { | 86 | if num_commits > MAX_COMMITS as u64 { |
| @@ -96,3 +103,23 @@ impl Graph { · 16 unmodified lines | |||
| 96 | Ok(Self { files }) | 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 | } | ||