use std::collections::HashMap;
use std::path::{Path, PathBuf};
use branchless::git::{dehydrate_tree, get_changed_paths_between_trees, hydrate_tree, FileMode};
use branchless::testing::make_git;
#[test]
fn test_hydrate_tree() -> eyre::Result<()> {
let git = make_git()?;
git.init_repo()?;
git.write_file_txt("foo", "foo")?;
git.write_file_txt("bar/bar", "bar")?;
git.write_file_txt("bar/baz", "qux")?;
git.write_file_txt("xyzzy", "xyzzy")?;
git.run(&["add", "."])?;
git.run(&["commit", "-m", "commit"])?;
let repo = git.get_repo()?;
let head_oid = repo.get_head_info()?.oid.unwrap();
let head_commit = repo.find_commit_or_fail(head_oid)?;
let head_tree = head_commit.get_tree()?;
insta::assert_debug_snapshot!(head_tree.get_entries_for_testing(), @r###"
[
(
"bar",
"778e23a1e80b1feb10e00b15b29a33315929c5b5",
),
(
"foo.txt",
"19102815663d23f8b75a47e7a01965dcdc96468c",
),
(
"initial.txt",
"63af22885f8665a312ba8b83db722134f1f8290d",
),
(
"xyzzy.txt",
"7c465afc533f95ff7d2c91e18921f94aac8292fc",
),
]
"###);
{
let hydrated_tree = {
let hydrated_tree_oid = hydrate_tree(&repo, Some(&head_tree), {
let mut result = HashMap::new();
result.insert(
PathBuf::from("foo-copy.txt"),
Some((
head_tree
.get_oid_for_path(&PathBuf::from("foo.txt"))?
.unwrap()
.try_into()?,
FileMode::from(0o100644),
)),
);
result.insert(PathBuf::from("foo.txt"), None);
result
})?;
repo.find_tree(hydrated_tree_oid)?.unwrap()
};
insta::assert_debug_snapshot!(hydrated_tree.get_entries_for_testing(), @r###"
[
(
"bar",
"778e23a1e80b1feb10e00b15b29a33315929c5b5",
),
(
"foo-copy.txt",
"19102815663d23f8b75a47e7a01965dcdc96468c",
),
(
"initial.txt",
"63af22885f8665a312ba8b83db722134f1f8290d",
),
(
"xyzzy.txt",
"7c465afc533f95ff7d2c91e18921f94aac8292fc",
),
]
"###);
}
{
let hydrated_tree = {
let hydrated_tree_oid = hydrate_tree(&repo, Some(&head_tree), {
let mut result = HashMap::new();
result.insert(PathBuf::from("bar/bar.txt"), None);
result
})?;
repo.find_tree(hydrated_tree_oid)?.unwrap()
};
insta::assert_debug_snapshot!(hydrated_tree.get_entries_for_testing(), @r###"
[
(
"bar",
"08ee88e1c53fbd01ab76f136a4f2c9d759b981d0",
),
(
"foo.txt",
"19102815663d23f8b75a47e7a01965dcdc96468c",
),
(
"initial.txt",
"63af22885f8665a312ba8b83db722134f1f8290d",
),
(
"xyzzy.txt",
"7c465afc533f95ff7d2c91e18921f94aac8292fc",
),
]
"###);
}
{
let hydrated_tree = {
let hydrated_tree_oid = hydrate_tree(&repo, Some(&head_tree), {
let mut result = HashMap::new();
result.insert(PathBuf::from("bar/bar.txt"), None);
result.insert(PathBuf::from("bar/baz.txt"), None);
result
})?;
repo.find_tree(hydrated_tree_oid)?.unwrap()
};
insta::assert_debug_snapshot!(hydrated_tree.get_entries_for_testing(), @r###"
[
(
"foo.txt",
"19102815663d23f8b75a47e7a01965dcdc96468c",
),
(
"initial.txt",
"63af22885f8665a312ba8b83db722134f1f8290d",
),
(
"xyzzy.txt",
"7c465afc533f95ff7d2c91e18921f94aac8292fc",
),
]
"###);
}
{
let dehydrated_tree_oid = dehydrate_tree(
&repo,
&head_tree,
&[Path::new("bar/baz.txt"), Path::new("foo.txt")],
)?;
let dehydrated_tree = repo.find_tree(dehydrated_tree_oid)?.unwrap();
insta::assert_debug_snapshot!(dehydrated_tree.get_entries_for_testing(), @r###"
[
(
"bar",
"08ee88e1c53fbd01ab76f136a4f2c9d759b981d0",
),
(
"foo.txt",
"19102815663d23f8b75a47e7a01965dcdc96468c",
),
]
"###);
}
Ok(())
}
#[test]
fn test_detect_path_only_changed_file_mode() -> eyre::Result<()> {
let git = make_git()?;
git.init_repo()?;
git.run(&["update-index", "--chmod=+x", "initial.txt"])?;
git.run(&["commit", "-m", "update file mode"])?;
let repo = git.get_repo()?;
let oid = repo.get_head_info()?.oid.unwrap();
let commit = repo.find_commit_or_fail(oid)?;
let lhs = commit.get_only_parent().unwrap();
let lhs_tree = lhs.get_tree()?;
let rhs_tree = commit.get_tree()?;
let changed_paths = get_changed_paths_between_trees(&repo, Some(&lhs_tree), Some(&rhs_tree))?;
insta::assert_debug_snapshot!(changed_paths, @r###"
{
"initial.txt",
}
"###);
Ok(())
}