Always generate test repos on demand instead. This saves some repo space and keeps us from having to worry about fixture scripts being out of sync with the generated fixtures. It also lets us use git to inspect repos instead of hardcoding expected commit data. On the flip side, tests take ~400ms instead of ~20ms.
Showing the changes to git-commitgraph (40 of 41 files). Show all
Unified · Split
| @@ -20,3 +20,6 @@ bstr = { version = "0.2.13", default-features = false, features = ["std"] } · 19 unmodified lines | |||
| 20 | byteorder = "1.2.3" | 20 | byteorder = "1.2.3" |
| 21 | filebuffer = "0.4.0" | 21 | filebuffer = "0.4.0" |
| 22 | quick-error = "2.0.0" | 22 | quick-error = "2.0.0" |
| 23 | |||
| 24 | [dev-dependencies] | ||
| 25 | tempfile = "3.1.0" | ||
| @@ -80,7 +80,7 @@ impl<'a> CommitData<'a> { · 79 unmodified lines | |||
| 80 | self.generation | 80 | self.generation |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | pub fn iter_parent_indices(&'a self) -> impl Iterator<Item = Result<GraphPosition, Error>> + 'a { | 83 | pub fn iter_parents(&'a self) -> impl Iterator<Item = Result<GraphPosition, Error>> + 'a { |
| 84 | // I didn't find a combinator approach that a) was as strict as ParentIterator, b) supported | 84 | // I didn't find a combinator approach that a) was as strict as ParentIterator, b) supported |
| 85 | // fuse-after-first-error behavior, and b) was significantly shorter or more understandable | 85 | // fuse-after-first-error behavior, and b) was significantly shorter or more understandable |
| 86 | // than ParentIterator. So here we are. | 86 | // than ParentIterator. So here we are. |
| @@ -95,7 +95,7 @@ impl<'a> CommitData<'a> { · 8 unmodified lines | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | pub fn parent1(&self) -> Result<Option<GraphPosition>, Error> { | 97 | pub fn parent1(&self) -> Result<Option<GraphPosition>, Error> { |
| 98 | self.iter_parent_indices().next().transpose() | 98 | self.iter_parents().next().transpose() |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | pub fn root_tree_id(&self) -> borrowed::Id { | 101 | pub fn root_tree_id(&self) -> borrowed::Id { |
| @@ -1,140 +1,31 @@ | |||
| 1 | use crate::{fixture_path, hex_to_id}; | 1 | use crate::{check_common, create_repo, inspect_refs}; |
| 2 | use git_commitgraph::{Graph, GraphPosition}; | 2 | use git_commitgraph::Graph; |
| 3 | |||
| 4 | const ROOT: &[u8] = b"09e3185550fdb352031df65f0e81e74df3b9a556"; | ||
| 5 | const ROOT_INDEX: GraphPosition = GraphPosition(0); | ||
| 6 | const COMMIT1: &[u8] = b"33316871b4ab988ea87ba60aaf0138ddb4fb0d21"; | ||
| 7 | const COMMIT1_INDEX: GraphPosition = GraphPosition(2); | ||
| 8 | const COMMIT2: &[u8] = b"cbfe147d1826a0d2701f7c80dbe0e2cfba385b15"; | ||
| 9 | const COMMIT2_INDEX: GraphPosition = GraphPosition(6); | ||
| 10 | const COMMIT3: &[u8] = b"9dab5d610702ceca4bd889a5ef2662cacfd53178"; | ||
| 11 | const COMMIT3_INDEX: GraphPosition = GraphPosition(5); | ||
| 12 | const COMMIT4: &[u8] = b"2ec748404455c0b0451b186851a815da13918ebb"; | ||
| 13 | const COMMIT4_INDEX: GraphPosition = GraphPosition(1); | ||
| 14 | const THREE_PARENTS: &[u8] = b"7070cd0b59cd46a0f0fa0c50ca9148390ae1e7c7"; | ||
| 15 | const THREE_PARENTS_INDEX: GraphPosition = GraphPosition(4); | ||
| 16 | const FOUR_PARENTS: &[u8] = b"5ca46a72d91817add3a7218f3eaf8b2b6c1caa13"; | ||
| 17 | const FOUR_PARENTS_INDEX: GraphPosition = GraphPosition(3); | ||
| 18 | 3 | ||
| 19 | #[test] | 4 | #[test] |
| 20 | fn v1() -> Result<(), Box<dyn std::error::Error>> { | 5 | fn test() -> Result<(), Box<dyn std::error::Error>> { |
| 21 | let root_id = hex_to_id(ROOT); | 6 | let repo_dir = create_repo("octopus_merges.sh"); |
| 22 | let commit1_id = hex_to_id(COMMIT1); | 7 | let refs = inspect_refs( |
| 23 | let commit2_id = hex_to_id(COMMIT2); | 8 | repo_dir.path(), |
| 24 | let commit3_id = hex_to_id(COMMIT3); | 9 | &[ |
| 25 | let commit4_id = hex_to_id(COMMIT4); | 10 | "root", |
| 26 | let three_parents_id = hex_to_id(THREE_PARENTS); | 11 | "parent1", |
| 27 | let four_parents_id = hex_to_id(FOUR_PARENTS); | 12 | "parent2", |
| 28 | 13 | "parent3", | |
| 29 | let cg = Graph::from_info_dir(fixture_path("v1/octopus_merges/info"))?; | 14 | "parent4", |
| 30 | assert_eq!(cg.num_commits(), 7); | 15 | "three_parents", |
| 31 | assert_eq!(cg.id_at(ROOT_INDEX), root_id.to_borrowed()); | 16 | "four_parents", |
| 32 | assert_eq!(cg.id_at(COMMIT1_INDEX), commit1_id.to_borrowed()); | 17 | ], |
| 33 | assert_eq!(cg.id_at(COMMIT2_INDEX), commit2_id.to_borrowed()); | 18 | ); |
| 34 | assert_eq!(cg.id_at(COMMIT3_INDEX), commit3_id.to_borrowed()); | 19 | let cg = Graph::from_info_dir(repo_dir.path().join(".git").join("objects").join("info"))?; |
| 35 | assert_eq!(cg.id_at(COMMIT4_INDEX), commit4_id.to_borrowed()); | 20 | check_common(&cg, &refs); |
| 36 | assert_eq!(cg.id_at(THREE_PARENTS_INDEX), three_parents_id.to_borrowed()); | 21 | |
| 37 | assert_eq!(cg.id_at(FOUR_PARENTS_INDEX), four_parents_id.to_borrowed()); | 22 | assert_eq!(cg.commit_at(refs["root"].pos()).generation(), 1); |
| 38 | assert_eq!( | 23 | assert_eq!(cg.commit_at(refs["parent1"].pos()).generation(), 2); |
| 39 | cg.iter_ids().collect::<Vec<_>>(), | 24 | assert_eq!(cg.commit_at(refs["parent2"].pos()).generation(), 2); |
| 40 | vec![ | 25 | assert_eq!(cg.commit_at(refs["parent3"].pos()).generation(), 2); |
| 41 | root_id.to_borrowed(), | 26 | assert_eq!(cg.commit_at(refs["parent4"].pos()).generation(), 2); |
| 42 | commit4_id.to_borrowed(), | 27 | assert_eq!(cg.commit_at(refs["three_parents"].pos()).generation(), 3); |
| 43 | commit1_id.to_borrowed(), | 28 | assert_eq!(cg.commit_at(refs["four_parents"].pos()).generation(), 3); |
| 44 | four_parents_id.to_borrowed(), | ||
| 45 | three_parents_id.to_borrowed(), | ||
| 46 | commit3_id.to_borrowed(), | ||
| 47 | commit2_id.to_borrowed(), | ||
| 48 | ] | ||
| 49 | ); | ||
| 50 | |||
| 51 | let root = cg.commit_at(ROOT_INDEX); | ||
| 52 | assert_eq!(root.generation(), 1); | ||
| 53 | assert_eq!(root.id(), root_id.to_borrowed()); | ||
| 54 | assert_eq!(root.parent1()?, None); | ||
| 55 | assert_eq!( | ||
| 56 | root.root_tree_id(), | ||
| 57 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 58 | ); | ||
| 59 | assert_eq!(root.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, vec![]); | ||
| 60 | |||
| 61 | let commit1 = cg.commit_at(COMMIT1_INDEX); | ||
| 62 | assert_eq!(commit1.generation(), 2); | ||
| 63 | assert_eq!(commit1.id(), commit1_id.to_borrowed()); | ||
| 64 | assert_eq!(commit1.parent1()?, Some(ROOT_INDEX)); | ||
| 65 | assert_eq!( | ||
| 66 | commit1.root_tree_id(), | ||
| 67 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 68 | ); | ||
| 69 | assert_eq!( | ||
| 70 | commit1.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 71 | vec![ROOT_INDEX], | ||
| 72 | ); | ||
| 73 | |||
| 74 | let commit2 = cg.commit_at(COMMIT2_INDEX); | ||
| 75 | assert_eq!(commit2.generation(), 2); | ||
| 76 | assert_eq!(commit2.id(), commit2_id.to_borrowed()); | ||
| 77 | assert_eq!(commit2.parent1()?, Some(ROOT_INDEX)); | ||
| 78 | assert_eq!( | ||
| 79 | commit2.root_tree_id(), | ||
| 80 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 81 | ); | ||
| 82 | assert_eq!( | ||
| 83 | commit2.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 84 | vec![ROOT_INDEX], | ||
| 85 | ); | ||
| 86 | |||
| 87 | let commit3 = cg.commit_at(COMMIT3_INDEX); | ||
| 88 | assert_eq!(commit3.generation(), 2); | ||
| 89 | assert_eq!(commit3.id(), commit3_id.to_borrowed()); | ||
| 90 | assert_eq!(commit3.parent1()?, Some(ROOT_INDEX)); | ||
| 91 | assert_eq!( | ||
| 92 | commit3.root_tree_id(), | ||
| 93 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 94 | ); | ||
| 95 | assert_eq!( | ||
| 96 | commit3.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 97 | vec![ROOT_INDEX], | ||
| 98 | ); | ||
| 99 | |||
| 100 | let commit4 = cg.commit_at(COMMIT4_INDEX); | ||
| 101 | assert_eq!(commit4.generation(), 2); | ||
| 102 | assert_eq!(commit4.id(), commit4_id.to_borrowed()); | ||
| 103 | assert_eq!(commit4.parent1()?, Some(ROOT_INDEX)); | ||
| 104 | assert_eq!( | ||
| 105 | commit4.root_tree_id(), | ||
| 106 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 107 | ); | ||
| 108 | assert_eq!( | ||
| 109 | commit4.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 110 | vec![ROOT_INDEX], | ||
| 111 | ); | ||
| 112 | |||
| 113 | let three_parents = cg.commit_at(THREE_PARENTS_INDEX); | ||
| 114 | assert_eq!(three_parents.generation(), 3); | ||
| 115 | assert_eq!(three_parents.id(), three_parents_id.to_borrowed()); | ||
| 116 | assert_eq!(three_parents.parent1()?, Some(COMMIT1_INDEX)); | ||
| 117 | assert_eq!( | ||
| 118 | three_parents.root_tree_id(), | ||
| 119 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 120 | ); | ||
| 121 | assert_eq!( | ||
| 122 | three_parents.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 123 | vec![COMMIT1_INDEX, COMMIT2_INDEX, COMMIT3_INDEX], | ||
| 124 | ); | ||
| 125 | |||
| 126 | let four_parents = cg.commit_at(FOUR_PARENTS_INDEX); | ||
| 127 | assert_eq!(four_parents.generation(), 3); | ||
| 128 | assert_eq!(four_parents.id(), four_parents_id.to_borrowed()); | ||
| 129 | assert_eq!(four_parents.parent1()?, Some(COMMIT2_INDEX)); | ||
| 130 | assert_eq!( | ||
| 131 | four_parents.root_tree_id(), | ||
| 132 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 133 | ); | ||
| 134 | assert_eq!( | ||
| 135 | four_parents.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 136 | vec![COMMIT2_INDEX, COMMIT1_INDEX, COMMIT3_INDEX, COMMIT4_INDEX], | ||
| 137 | ); | ||
| 138 | 29 | ||
| 139 | Ok(()) | 30 | Ok(()) |
| 140 | } | 31 | } |
| @@ -1,26 +1,14 @@ | |||
| 1 | use crate::{fixture_path, hex_to_id}; | 1 | use crate::{check_common, create_repo, inspect_refs}; |
| 2 | use git_commitgraph::{Graph, GraphPosition}; | 2 | use git_commitgraph::Graph; |
| 3 | |||
| 4 | const COMMIT: &[u8] = b"771fa42310bb3d221f4cf82613a491b0957d2003"; | ||
| 5 | 3 | ||
| 6 | #[test] | 4 | #[test] |
| 7 | fn v1() -> Result<(), Box<dyn std::error::Error>> { | 5 | fn test() -> Result<(), Box<dyn std::error::Error>> { |
| 8 | let commit_id = hex_to_id(COMMIT); | 6 | let repo_dir = create_repo("single_commit.sh"); |
| 9 | 7 | let refs = inspect_refs(repo_dir.path(), &["commit"]); | |
| 10 | let cg = Graph::from_info_dir(fixture_path("v1/single_commit/info"))?; | 8 | let cg = Graph::from_info_dir(repo_dir.path().join(".git").join("objects").join("info"))?; |
| 11 | assert_eq!(cg.num_commits(), 1); | 9 | check_common(&cg, &refs); |
| 12 | assert_eq!(cg.id_at(GraphPosition(0)), commit_id.to_borrowed()); | ||
| 13 | assert_eq!(cg.iter_ids().collect::<Vec<_>>(), vec![commit_id.to_borrowed()]); | ||
| 14 | 10 | ||
| 15 | let commit = cg.commit_at(GraphPosition(0)); | 11 | assert_eq!(cg.commit_at(refs["commit"].pos()).generation(), 1); |
| 16 | assert_eq!(commit.generation(), 1); | ||
| 17 | assert_eq!(commit.id(), commit_id.to_borrowed()); | ||
| 18 | assert_eq!(commit.parent1()?, None); | ||
| 19 | assert_eq!( | ||
| 20 | commit.root_tree_id(), | ||
| 21 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 22 | ); | ||
| 23 | assert_eq!(commit.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, vec![]); | ||
| 24 | 12 | ||
| 25 | Ok(()) | 13 | Ok(()) |
| 26 | } | 14 | } |
| @@ -1,44 +1,15 @@ | |||
| 1 | use crate::{fixture_path, hex_to_id}; | 1 | use crate::{check_common, create_repo, inspect_refs}; |
| 2 | use git_commitgraph::{Graph, GraphPosition}; | 2 | use git_commitgraph::Graph; |
| 3 | |||
| 4 | const PARENT: &[u8] = b"ddbbe1220676705c5b7a6bb7047e0d63b58cfc28"; | ||
| 5 | const CHILD: &[u8] = b"91bfe17bfdfef01c4c38e34e577b01a14a1ef2d4"; | ||
| 6 | 3 | ||
| 7 | #[test] | 4 | #[test] |
| 8 | fn v1() -> Result<(), Box<dyn std::error::Error>> { | 5 | fn test() -> Result<(), Box<dyn std::error::Error>> { |
| 9 | let parent_id = hex_to_id(PARENT); | 6 | let repo_dir = create_repo("single_parent.sh"); |
| 10 | let child_id = hex_to_id(CHILD); | 7 | let refs = inspect_refs(repo_dir.path(), &["parent", "child"]); |
| 11 | 8 | let cg = Graph::from_info_dir(repo_dir.path().join(".git").join("objects").join("info"))?; | |
| 12 | let cg = Graph::from_info_dir(fixture_path("v1/single_parent/info"))?; | 9 | check_common(&cg, &refs); |
| 13 | assert_eq!(cg.num_commits(), 2); | 10 | |
| 14 | assert_eq!(cg.id_at(GraphPosition(0)), child_id.to_borrowed()); | 11 | assert_eq!(cg.commit_at(refs["parent"].pos()).generation(), 1); |
| 15 | assert_eq!( | 12 | assert_eq!(cg.commit_at(refs["child"].pos()).generation(), 2); |
| 16 | cg.iter_ids().collect::<Vec<_>>(), | ||
| 17 | vec![child_id.to_borrowed(), parent_id.to_borrowed()] | ||
| 18 | ); | ||
| 19 | |||
| 20 | let parent = cg.commit_at(GraphPosition(1)); | ||
| 21 | assert_eq!(parent.generation(), 1); | ||
| 22 | assert_eq!(parent.id(), parent_id.to_borrowed()); | ||
| 23 | assert_eq!(parent.parent1()?, None); | ||
| 24 | assert_eq!( | ||
| 25 | parent.root_tree_id(), | ||
| 26 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 27 | ); | ||
| 28 | assert_eq!(parent.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, vec![]); | ||
| 29 | |||
| 30 | let child = cg.commit_at(GraphPosition(0)); | ||
| 31 | assert_eq!(child.generation(), 2); | ||
| 32 | assert_eq!(child.id(), child_id.to_borrowed()); | ||
| 33 | assert_eq!(child.parent1()?, Some(GraphPosition(1))); | ||
| 34 | assert_eq!( | ||
| 35 | child.root_tree_id(), | ||
| 36 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 37 | ); | ||
| 38 | assert_eq!( | ||
| 39 | child.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 40 | vec![GraphPosition(1)] | ||
| 41 | ); | ||
| 42 | 13 | ||
| 43 | Ok(()) | 14 | Ok(()) |
| 44 | } | 15 | } |
| @@ -1,65 +1,16 @@ | |||
| 1 | use crate::{fixture_path, hex_to_id}; | 1 | use crate::{check_common, create_repo, inspect_refs}; |
| 2 | use git_commitgraph::{Graph, GraphPosition}; | 2 | use git_commitgraph::Graph; |
| 3 | |||
| 4 | const PARENT1: &[u8] = b"7506a95b8062f0bee6ccdee717021a0c710a1959"; | ||
| 5 | const PARENT1_INDEX: GraphPosition = GraphPosition(2); | ||
| 6 | const PARENT2: &[u8] = b"12ae061ac737392973e59d5df2103a72f1088e45"; | ||
| 7 | const PARENT2_INDEX: GraphPosition = GraphPosition(0); | ||
| 8 | const MERGE: &[u8] = b"6a23d4bb5ef62fff1b57b898240bf5a9d5813800"; | ||
| 9 | const MERGE_INDEX: GraphPosition = GraphPosition(1); | ||
| 10 | 3 | ||
| 11 | #[test] | 4 | #[test] |
| 12 | fn v1() -> Result<(), Box<dyn std::error::Error>> { | 5 | fn test() -> Result<(), Box<dyn std::error::Error>> { |
| 13 | let parent1_id = hex_to_id(PARENT1); | 6 | let repo_dir = create_repo("two_parents.sh"); |
| 14 | let parent2_id = hex_to_id(PARENT2); | 7 | let refs = inspect_refs(repo_dir.path(), &["parent1", "parent2", "child"]); |
| 15 | let merge_id = hex_to_id(MERGE); | 8 | let cg = Graph::from_info_dir(repo_dir.path().join(".git").join("objects").join("info"))?; |
| 16 | 9 | check_common(&cg, &refs); | |
| 17 | let cg = Graph::from_info_dir(fixture_path("v1/two_parents/info"))?; | ||
| 18 | assert_eq!(cg.num_commits(), 3); | ||
| 19 | assert_eq!(cg.id_at(PARENT1_INDEX), parent1_id.to_borrowed()); | ||
| 20 | assert_eq!(cg.id_at(PARENT2_INDEX), parent2_id.to_borrowed()); | ||
| 21 | assert_eq!(cg.id_at(MERGE_INDEX), merge_id.to_borrowed()); | ||
| 22 | assert_eq!( | ||
| 23 | cg.iter_ids().collect::<Vec<_>>(), | ||
| 24 | vec![ | ||
| 25 | parent2_id.to_borrowed(), | ||
| 26 | merge_id.to_borrowed(), | ||
| 27 | parent1_id.to_borrowed() | ||
| 28 | ] | ||
| 29 | ); | ||
| 30 | |||
| 31 | let parent1 = cg.commit_at(PARENT1_INDEX); | ||
| 32 | assert_eq!(parent1.generation(), 1); | ||
| 33 | assert_eq!(parent1.id(), parent1_id.to_borrowed()); | ||
| 34 | assert_eq!(parent1.parent1()?, None); | ||
| 35 | assert_eq!( | ||
| 36 | parent1.root_tree_id(), | ||
| 37 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 38 | ); | ||
| 39 | assert_eq!(parent1.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, vec![]); | ||
| 40 | |||
| 41 | let parent2 = cg.commit_at(PARENT2_INDEX); | ||
| 42 | assert_eq!(parent2.generation(), 1); | ||
| 43 | assert_eq!(parent2.id(), parent2_id.to_borrowed()); | ||
| 44 | assert_eq!(parent2.parent1()?, None); | ||
| 45 | assert_eq!( | ||
| 46 | parent2.root_tree_id(), | ||
| 47 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 48 | ); | ||
| 49 | assert_eq!(parent2.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, vec![]); | ||
| 50 | 10 | ||
| 51 | let merge = cg.commit_at(MERGE_INDEX); | 11 | assert_eq!(cg.commit_at(refs["parent1"].pos()).generation(), 1); |
| 52 | assert_eq!(merge.generation(), 2); | 12 | assert_eq!(cg.commit_at(refs["parent2"].pos()).generation(), 1); |
| 53 | assert_eq!(merge.id(), merge_id.to_borrowed()); | 13 | assert_eq!(cg.commit_at(refs["child"].pos()).generation(), 2); |
| 54 | assert_eq!(merge.parent1()?, Some(PARENT1_INDEX)); | ||
| 55 | assert_eq!( | ||
| 56 | merge.root_tree_id(), | ||
| 57 | hex_to_id(b"4b825dc642cb6eb9a060e54bf8d69288fbee4904").to_borrowed(), | ||
| 58 | ); | ||
| 59 | assert_eq!( | ||
| 60 | merge.iter_parent_indices().collect::<Result<Vec<_>, _>>()?, | ||
| 61 | vec![PARENT1_INDEX, PARENT2_INDEX] | ||
| 62 | ); | ||
| 63 | 14 | ||
| 64 | Ok(()) | 15 | Ok(()) |
| 65 | } | 16 | } |
| @@ -1,8 +1,71 @@ | |||
| 1 | use git_object::owned; | 1 | use git_commitgraph::{Graph, GraphPosition}; |
| 2 | use std::path::PathBuf; | 2 | use git_object::{borrowed, owned}; |
| 3 | use std::collections::{HashMap, HashSet}; | ||
| 4 | use std::convert::{TryFrom, TryInto}; | ||
| 5 | use std::hash::BuildHasher; | ||
| 6 | use std::io::{BufRead, Cursor}; | ||
| 7 | use std::path::{Path, PathBuf}; | ||
| 8 | use std::process::Command; | ||
| 3 | 9 | ||
| 4 | mod access; | 10 | mod access; |
| 5 | 11 | ||
| 12 | pub fn check_common(cg: &Graph, expected: &HashMap<String, RefInfo, impl BuildHasher>) { | ||
| 13 | assert_eq!( | ||
| 14 | usize::try_from(cg.num_commits()).expect("an architecture able to hold 32 bits of integer"), | ||
| 15 | expected.len() | ||
| 16 | ); | ||
| 17 | for ref_info in expected.values() { | ||
| 18 | assert_eq!(cg.id_at(ref_info.pos()), ref_info.id(), "id_at({})", ref_info.pos()); | ||
| 19 | assert_eq!( | ||
| 20 | cg.lookup(ref_info.id()), | ||
| 21 | Some(ref_info.pos()), | ||
| 22 | "lookup({})", | ||
| 23 | ref_info.id() | ||
| 24 | ); | ||
| 25 | |||
| 26 | let expected_parents: Vec<_> = ref_info | ||
| 27 | .parent_ids() | ||
| 28 | .into_iter() | ||
| 29 | .map(|id| { | ||
| 30 | expected | ||
| 31 | .values() | ||
| 32 | .find(|item| item.id() == id) | ||
| 33 | .expect("find RefInfo by id") | ||
| 34 | }) | ||
| 35 | .collect(); | ||
| 36 | let commit = cg.commit_at(ref_info.pos()); | ||
| 37 | assert_eq!(commit.id(), ref_info.id()); | ||
| 38 | assert_eq!(commit.root_tree_id(), ref_info.root_tree_id()); | ||
| 39 | assert_eq!( | ||
| 40 | commit.parent1().expect("failed to access commit's parent1"), | ||
| 41 | expected_parents.iter().map(|x| x.pos()).next() | ||
| 42 | ); | ||
| 43 | assert_eq!( | ||
| 44 | commit | ||
| 45 | .iter_parents() | ||
| 46 | .collect::<Result<Vec<_>, _>>() | ||
| 47 | .expect("failed to access commit's parents"), | ||
| 48 | expected_parents.iter().map(|x| x.pos()).collect::<Vec<_>>() | ||
| 49 | ); | ||
| 50 | } | ||
| 51 | |||
| 52 | assert_eq!( | ||
| 53 | cg.iter_ids().collect::<HashSet<_>>(), | ||
| 54 | expected.values().map(|x| x.id()).collect::<HashSet<_>>() | ||
| 55 | ); | ||
| 56 | } | ||
| 57 | |||
| 58 | pub fn create_repo(script_path: &str) -> tempfile::TempDir { | ||
| 59 | let dir = tempfile::tempdir().expect("failed to create temp dir"); | ||
| 60 | let status = Command::new(fixture_path(script_path)) | ||
| 61 | .arg(dir.path()) | ||
| 62 | .env_remove("GIT_DIR") | ||
| 63 | .status() | ||
| 64 | .expect("failed to run repo script"); | ||
| 65 | assert!(status.success(), "repo script failed"); | ||
| 66 | dir | ||
| 67 | } | ||
| 68 | |||
| 6 | pub fn fixture_path(path: &str) -> PathBuf { | 69 | pub fn fixture_path(path: &str) -> PathBuf { |
| 7 | PathBuf::from("tests").join("fixtures").join(path) | 70 | PathBuf::from("tests").join("fixtures").join(path) |
| 8 | } | 71 | } |
| @@ -10,3 +73,84 @@ pub fn fixture_path(path: &str) -> PathBuf { · 1 unmodified line | |||
| 10 | pub fn hex_to_id(hex: &[u8]) -> owned::Id { | 73 | pub fn hex_to_id(hex: &[u8]) -> owned::Id { |
| 11 | owned::Id::from_40_bytes_in_hex(hex).expect("40 bytes hex") | 74 | owned::Id::from_40_bytes_in_hex(hex).expect("40 bytes hex") |
| 12 | } | 75 | } |
| 76 | |||
| 77 | pub struct RefInfo { | ||
| 78 | id: owned::Id, | ||
| 79 | parent_ids: Vec<owned::Id>, | ||
| 80 | pos: GraphPosition, | ||
| 81 | root_tree_id: owned::Id, | ||
| 82 | } | ||
| 83 | |||
| 84 | impl RefInfo { | ||
| 85 | pub fn id(&self) -> borrowed::Id { | ||
| 86 | self.id.to_borrowed() | ||
| 87 | } | ||
| 88 | |||
| 89 | pub fn pos(&self) -> GraphPosition { | ||
| 90 | self.pos | ||
| 91 | } | ||
| 92 | |||
| 93 | pub fn parent_ids(&self) -> impl IntoIterator<Item = borrowed::Id> { | ||
| 94 | self.parent_ids.iter().map(|x| x.to_borrowed()) | ||
| 95 | } | ||
| 96 | |||
| 97 | pub fn root_tree_id(&self) -> borrowed::Id { | ||
| 98 | self.root_tree_id.to_borrowed() | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | pub fn inspect_refs(repo_dir: impl AsRef<Path>, refs: &[&'static str]) -> HashMap<String, RefInfo> { | ||
| 103 | let output = Command::new("git") | ||
| 104 | .arg("-C") | ||
| 105 | .arg(repo_dir.as_ref()) | ||
| 106 | .arg("show") | ||
| 107 | .arg("--no-patch") | ||
| 108 | .arg("--pretty=format:%S %H %T %P") | ||
| 109 | .args(refs) | ||
| 110 | .arg("--") | ||
| 111 | .env_remove("GIT_DIR") | ||
| 112 | .output() | ||
| 113 | .expect("failed to execute `git show`"); | ||
| 114 | // Output format: <refname> <id> <tree_id> <parent_ids> | ||
| 115 | let mut infos: Vec<_> = Cursor::new(output.stdout) | ||
| 116 | .lines() | ||
| 117 | .map(|x| x.expect("failed to read `git show` output")) | ||
| 118 | .map(|x| { | ||
| 119 | let parts = x.trim_end().split(' ').collect::<Vec<_>>(); | ||
| 120 | ( | ||
| 121 | parts[0].to_string(), | ||
| 122 | owned::Id::from_40_bytes_in_hex(parts[1].as_bytes()).expect("40 bytes hex"), | ||
| 123 | owned::Id::from_40_bytes_in_hex(parts[2].as_bytes()).expect("40 bytes hex"), | ||
| 124 | parts[3..] | ||
| 125 | .iter() | ||
| 126 | .map(|x| owned::Id::from_40_bytes_in_hex(x.as_bytes()).expect("40 bytes hex")) | ||
| 127 | .collect(), | ||
| 128 | ) | ||
| 129 | }) | ||
| 130 | .collect(); | ||
| 131 | infos.sort_by_key(|x| x.1); | ||
| 132 | |||
| 133 | let get_pos = |id: borrowed::Id| -> GraphPosition { | ||
| 134 | let pos = infos | ||
| 135 | .binary_search_by_key(&id, |x| x.1.to_borrowed()) | ||
| 136 | .expect("sorted_ids to contain id"); | ||
| 137 | let pos: u32 = pos.try_into().expect("graph position to fit in u32"); | ||
| 138 | GraphPosition(pos) | ||
| 139 | }; | ||
| 140 | |||
| 141 | infos | ||
| 142 | .iter() | ||
| 143 | .cloned() | ||
| 144 | .map(|(name, id, root_tree_id, parent_ids)| { | ||
| 145 | ( | ||
| 146 | name, | ||
| 147 | RefInfo { | ||
| 148 | id, | ||
| 149 | parent_ids, | ||
| 150 | root_tree_id, | ||
| 151 | pos: get_pos(id.to_borrowed()), | ||
| 152 | }, | ||
| 153 | ) | ||
| 154 | }) | ||
| 155 | .collect() | ||
| 156 | } | ||
| @@ -15,23 +15,23 @@ git init -q · 14 unmodified lines | |||
| 15 | git checkout -q --orphan root | 15 | git checkout -q --orphan root |
| 16 | git commit -q --allow-empty -m root | 16 | git commit -q --allow-empty -m root |
| 17 | 17 | ||
| 18 | git checkout -q -b commit1 root | 18 | git checkout -q -b parent1 root |
| 19 | git commit -q --allow-empty -m commit1 | 19 | git commit -q --allow-empty -m parent1 |
| 20 | 20 | ||
| 21 | git checkout -q -b commit2 root | 21 | git checkout -q -b parent2 root |
| 22 | git commit -q --allow-empty -m commit2 | 22 | git commit -q --allow-empty -m parent2 |
| 23 | 23 | ||
| 24 | git checkout -q -b commit3 root | 24 | git checkout -q -b parent3 root |
| 25 | git commit -q --allow-empty -m commit3 | 25 | git commit -q --allow-empty -m parent3 |
| 26 | 26 | ||
| 27 | git checkout -q -b commit4 root | 27 | git checkout -q -b parent4 root |
| 28 | git commit -q --allow-empty -m commit4 | 28 | git commit -q --allow-empty -m parent4 |
| 29 | 29 | ||
| 30 | git checkout -q -b three_parents commit1 | 30 | git checkout -q -b three_parents parent1 |
| 31 | git merge -q -m three_parents --no-ff commit2 commit3 >/dev/null | 31 | git merge -q -m three_parents --no-ff parent2 parent3 >/dev/null |
| 32 | 32 | ||
| 33 | git checkout -q -b four_parents commit2 | 33 | git checkout -q -b four_parents parent2 |
| 34 | git merge -q -m four_parents --no-ff commit1 commit3 commit4 >/dev/null | 34 | git merge -q -m four_parents --no-ff parent1 parent3 parent4 >/dev/null |
| 35 | 35 | ||
| 36 | git commit-graph write --no-progress --reachable | 36 | git commit-graph write --no-progress --reachable |
| 37 | git repack -adq | 37 | git repack -adq |
| @@ -18,8 +18,8 @@ git commit -q --allow-empty -m parent1 · 17 unmodified lines | |||
| 18 | git checkout -q --orphan parent2 | 18 | git checkout -q --orphan parent2 |
| 19 | git commit -q --allow-empty -m parent2 | 19 | git commit -q --allow-empty -m parent2 |
| 20 | 20 | ||
| 21 | git checkout -q -b merge parent1 | 21 | git checkout -q -b child parent1 |
| 22 | git merge -q --allow-unrelated-histories --no-ff -m merge parent2 >/dev/null | 22 | git merge -q --allow-unrelated-histories --no-ff -m child parent2 >/dev/null |
| 23 | 23 | ||
| 24 | git commit-graph write --no-progress --reachable | 24 | git commit-graph write --no-progress --reachable |
| 25 | git repack -adq | 25 | git repack -adq |
Binary file not shown.
| @@ -1,2 +0,0 @@ | |||
| 1 | P pack-317d17c824d1a0b6991949219f7b6ba9ad51c3e6.pack | ||
| 2 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1,2 +0,0 @@ | |||
| 1 | P pack-b7a28066d2c1e9511d1a60349d0d6e3bf803d1b6.pack | ||
| 2 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1,2 +0,0 @@ | |||
| 1 | P pack-976438ba1bde7d9c944d8681cbfad266feec7068.pack | ||
| 2 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1,2 +0,0 @@ | |||
| 1 | P pack-07779428eae7661b1471110dda1efc99e3e954e7.pack | ||
| 2 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1,2 +0,0 @@ | |||
| 1 | P pack-ba89c2e6239315806e37d189aebf4a582e96a6d5.pack | ||
| 2 | |||
Binary file not shown.
Binary file not shown.
| @@ -1,3 +0,0 @@ | |||
| 1 | ca9f15bcd6129d304e0f4d4c8c6545467dcc78e1 | ||
| 2 | 422d4c835a8a22a401b80f8a76f0fa0be550db1b | ||
| 3 | eda6e3e68ac22be2ae8191ed2c80113e7f0344c6 | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1,2 +0,0 @@ | |||
| 1 | P pack-35e0a0e2cb2913c7990d1c6a6aa4747d9b3b5306.pack | ||
| 2 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1,2 +0,0 @@ | |||
| 1 | P pack-ca696e967b89b66c96f70bcb9d9e8bba42417bcc.pack | ||
| 2 | |||
Binary file not shown.
Binary file not shown.