repo_path: split RepoPath into owned and borrowed types

This enables cheap str-to-RepoPath cast, which is useful when sorting and
filtering a large Vec<(String, _)> list by using matcher for example. It
will also eliminate temporary allocation by repo_path.parent().
This commit is contained in:
Yuya Nishihara 2023-11-26 19:21:46 +09:00
parent 0a1bc2ba42
commit 28ab9593c3
23 changed files with 432 additions and 351 deletions

View file

@ -1119,7 +1119,7 @@ fn cmd_git_submodule_print_gitmodules(
let repo = workspace_command.repo();
let commit = workspace_command.resolve_single_rev(&args.revisions, ui)?;
let tree = commit.tree()?;
let gitmodules_path = &RepoPath::from_internal_string(".gitmodules");
let gitmodules_path = RepoPath::from_internal_string(".gitmodules");
let mut gitmodules_file = match tree.path_value(gitmodules_path).into_resolved() {
Ok(None) => {
writeln!(ui.stderr(), "No submodules!")?;

View file

@ -558,10 +558,10 @@ mod tests {
let test_repo = TestRepo::init();
let store = test_repo.repo.store();
let unused_path = &RepoPath::from_internal_string("unused");
let unchanged = &RepoPath::from_internal_string("unchanged");
let changed_path = &RepoPath::from_internal_string("changed");
let added_path = &RepoPath::from_internal_string("added");
let unused_path = RepoPath::from_internal_string("unused");
let unchanged = RepoPath::from_internal_string("unchanged");
let changed_path = RepoPath::from_internal_string("changed");
let added_path = RepoPath::from_internal_string("added");
let left_tree = testutils::create_tree(
&test_repo.repo,
&[
@ -716,7 +716,7 @@ mod tests {
let test_repo = TestRepo::init();
let store = test_repo.repo.store();
let path = &RepoPath::from_internal_string("file");
let path = RepoPath::from_internal_string("file");
let base_tree = testutils::create_tree(
&test_repo.repo,
&[(path, "base 1\nbase 2\nbase 3\nbase 4\nbase 5\n")],

View file

@ -885,7 +885,7 @@ fn has_diff_from_parent(
if let [parent] = parents.as_slice() {
// Fast path: no need to load the root tree
let unchanged = commit.tree_id() == parent.tree_id();
if matcher.visit(&RepoPath::root()) == Visit::AllRecursively {
if matcher.visit(RepoPath::root()) == Visit::AllRecursively {
return !unchanged;
} else if unchanged {
return false;

View file

@ -1232,7 +1232,7 @@ mod tests {
let root_tree = backend
.read_tree(
&RepoPath::root(),
RepoPath::root(),
&TreeId::from_bytes(root_tree_id.as_bytes()),
)
.block_on()
@ -1248,7 +1248,7 @@ mod tests {
let dir_tree = backend
.read_tree(
&RepoPath::from_internal_string("dir"),
RepoPath::from_internal_string("dir"),
&TreeId::from_bytes(dir_tree_id.as_bytes()),
)
.block_on()

View file

@ -80,7 +80,7 @@ impl LocalBackend {
fs::create_dir(store_path.join("conflicts")).unwrap();
let backend = Self::load(store_path);
let empty_tree_id = backend
.write_tree(&RepoPath::root(), &Tree::default())
.write_tree(RepoPath::root(), &Tree::default())
.unwrap();
assert_eq!(empty_tree_id, backend.empty_tree_id);
backend

View file

@ -647,7 +647,7 @@ impl TreeState {
};
let matcher = IntersectionMatcher::new(sparse_matcher.as_ref(), fsmonitor_matcher);
if matcher.visit(&RepoPath::root()).is_nothing() {
if matcher.visit(RepoPath::root()).is_nothing() {
// No need to load file states
self.watchman_clock = watchman_clock;
return Ok(is_dirty);
@ -796,7 +796,7 @@ impl TreeState {
// If the whole directory is ignored, visit only paths we're already
// tracking.
let tracked_paths = file_states
.range((Bound::Excluded(&path), Bound::Unbounded))
.range::<RepoPath, _>((Bound::Excluded(&*path), Bound::Unbounded))
.take_while(|(sub_path, _)| path.contains(sub_path))
.map(|(sub_path, file_state)| (sub_path.clone(), file_state.clone()))
.collect_vec();

View file

@ -343,34 +343,34 @@ mod tests {
use super::*;
fn repo_path(value: &str) -> RepoPath {
fn repo_path(value: &str) -> &RepoPath {
RepoPath::from_internal_string(value)
}
#[test]
fn test_repo_path_tree_empty() {
let tree = RepoPathTree::new();
assert_eq!(tree.get_visit_sets(&RepoPath::root()), Visit::Nothing);
assert_eq!(tree.get_visit_sets(RepoPath::root()), Visit::Nothing);
}
#[test]
fn test_repo_path_tree_root() {
let mut tree = RepoPathTree::new();
tree.add_dir(&RepoPath::root());
assert_eq!(tree.get_visit_sets(&RepoPath::root()), Visit::Nothing);
tree.add_dir(RepoPath::root());
assert_eq!(tree.get_visit_sets(RepoPath::root()), Visit::Nothing);
}
#[test]
fn test_repo_path_tree_dir() {
let mut tree = RepoPathTree::new();
tree.add_dir(&repo_path("dir"));
tree.add_dir(repo_path("dir"));
assert_eq!(
tree.get_visit_sets(&RepoPath::root()),
tree.get_visit_sets(RepoPath::root()),
Visit::sets(hashset! {RepoPathComponentBuf::from("dir")}, hashset! {}),
);
tree.add_dir(&repo_path("dir/sub"));
tree.add_dir(repo_path("dir/sub"));
assert_eq!(
tree.get_visit_sets(&repo_path("dir")),
tree.get_visit_sets(repo_path("dir")),
Visit::sets(hashset! {RepoPathComponentBuf::from("sub")}, hashset! {}),
);
}
@ -378,13 +378,13 @@ mod tests {
#[test]
fn test_repo_path_tree_file() {
let mut tree = RepoPathTree::new();
tree.add_file(&repo_path("dir/file"));
tree.add_file(repo_path("dir/file"));
assert_eq!(
tree.get_visit_sets(&RepoPath::root()),
tree.get_visit_sets(RepoPath::root()),
Visit::sets(hashset! {RepoPathComponentBuf::from("dir")}, hashset! {}),
);
assert_eq!(
tree.get_visit_sets(&repo_path("dir")),
tree.get_visit_sets(repo_path("dir")),
Visit::sets(hashset! {}, hashset! {RepoPathComponentBuf::from("file")}),
);
}
@ -392,17 +392,17 @@ mod tests {
#[test]
fn test_nothingmatcher() {
let m = NothingMatcher;
assert!(!m.matches(&repo_path("file")));
assert!(!m.matches(&repo_path("dir/file")));
assert_eq!(m.visit(&RepoPath::root()), Visit::Nothing);
assert!(!m.matches(repo_path("file")));
assert!(!m.matches(repo_path("dir/file")));
assert_eq!(m.visit(RepoPath::root()), Visit::Nothing);
}
#[test]
fn test_filesmatcher_empty() {
let m = FilesMatcher::new([] as [&RepoPath; 0]);
assert!(!m.matches(&repo_path("file")));
assert!(!m.matches(&repo_path("dir/file")));
assert_eq!(m.visit(&RepoPath::root()), Visit::Nothing);
assert!(!m.matches(repo_path("file")));
assert!(!m.matches(repo_path("dir/file")));
assert_eq!(m.visit(RepoPath::root()), Visit::Nothing);
}
#[test]
@ -414,21 +414,21 @@ mod tests {
repo_path("file4"),
]);
assert!(!m.matches(&repo_path("dir1")));
assert!(!m.matches(&repo_path("dir1/subdir1")));
assert!(m.matches(&repo_path("dir1/subdir1/file1")));
assert!(m.matches(&repo_path("dir1/subdir1/file2")));
assert!(!m.matches(&repo_path("dir1/subdir1/file3")));
assert!(!m.matches(repo_path("dir1")));
assert!(!m.matches(repo_path("dir1/subdir1")));
assert!(m.matches(repo_path("dir1/subdir1/file1")));
assert!(m.matches(repo_path("dir1/subdir1/file2")));
assert!(!m.matches(repo_path("dir1/subdir1/file3")));
assert_eq!(
m.visit(&RepoPath::root()),
m.visit(RepoPath::root()),
Visit::sets(
hashset! {RepoPathComponentBuf::from("dir1")},
hashset! {RepoPathComponentBuf::from("file4")}
)
);
assert_eq!(
m.visit(&repo_path("dir1")),
m.visit(repo_path("dir1")),
Visit::sets(
hashset! {
RepoPathComponentBuf::from("subdir1"),
@ -438,7 +438,7 @@ mod tests {
)
);
assert_eq!(
m.visit(&repo_path("dir1/subdir1")),
m.visit(repo_path("dir1/subdir1")),
Visit::sets(
hashset! {},
hashset! {
@ -448,7 +448,7 @@ mod tests {
)
);
assert_eq!(
m.visit(&repo_path("dir1/subdir2")),
m.visit(repo_path("dir1/subdir2")),
Visit::sets(hashset! {}, hashset! {RepoPathComponentBuf::from("file3")})
);
}
@ -456,20 +456,20 @@ mod tests {
#[test]
fn test_prefixmatcher_empty() {
let m = PrefixMatcher::new([] as [&RepoPath; 0]);
assert!(!m.matches(&repo_path("file")));
assert!(!m.matches(&repo_path("dir/file")));
assert_eq!(m.visit(&RepoPath::root()), Visit::Nothing);
assert!(!m.matches(repo_path("file")));
assert!(!m.matches(repo_path("dir/file")));
assert_eq!(m.visit(RepoPath::root()), Visit::Nothing);
}
#[test]
fn test_prefixmatcher_root() {
let m = PrefixMatcher::new([RepoPath::root()]);
// Matches all files
assert!(m.matches(&repo_path("file")));
assert!(m.matches(&repo_path("dir/file")));
assert!(m.matches(repo_path("file")));
assert!(m.matches(repo_path("dir/file")));
// Visits all directories
assert_eq!(m.visit(&RepoPath::root()), Visit::AllRecursively);
assert_eq!(m.visit(&repo_path("foo/bar")), Visit::AllRecursively);
assert_eq!(m.visit(RepoPath::root()), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo/bar")), Visit::AllRecursively);
}
#[test]
@ -477,63 +477,63 @@ mod tests {
let m = PrefixMatcher::new([repo_path("foo/bar")]);
// Parts of the prefix should not match
assert!(!m.matches(&repo_path("foo")));
assert!(!m.matches(&repo_path("bar")));
assert!(!m.matches(repo_path("foo")));
assert!(!m.matches(repo_path("bar")));
// A file matching the prefix exactly should match
assert!(m.matches(&repo_path("foo/bar")));
assert!(m.matches(repo_path("foo/bar")));
// Files in subdirectories should match
assert!(m.matches(&repo_path("foo/bar/baz")));
assert!(m.matches(&repo_path("foo/bar/baz/qux")));
assert!(m.matches(repo_path("foo/bar/baz")));
assert!(m.matches(repo_path("foo/bar/baz/qux")));
// Sibling files should not match
assert!(!m.matches(&repo_path("foo/foo")));
assert!(!m.matches(repo_path("foo/foo")));
// An unrooted "foo/bar" should not match
assert!(!m.matches(&repo_path("bar/foo/bar")));
assert!(!m.matches(repo_path("bar/foo/bar")));
// The matcher should only visit directory foo/ in the root (file "foo"
// shouldn't be visited)
assert_eq!(
m.visit(&RepoPath::root()),
m.visit(RepoPath::root()),
Visit::sets(hashset! {RepoPathComponentBuf::from("foo")}, hashset! {})
);
// Inside parent directory "foo/", both subdirectory "bar" and file "bar" may
// match
assert_eq!(
m.visit(&repo_path("foo")),
m.visit(repo_path("foo")),
Visit::sets(
hashset! {RepoPathComponentBuf::from("bar")},
hashset! {RepoPathComponentBuf::from("bar")}
)
);
// Inside a directory that matches the prefix, everything matches recursively
assert_eq!(m.visit(&repo_path("foo/bar")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo/bar")), Visit::AllRecursively);
// Same thing in subdirectories of the prefix
assert_eq!(m.visit(&repo_path("foo/bar/baz")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo/bar/baz")), Visit::AllRecursively);
// Nothing in directories that are siblings of the prefix can match, so don't
// visit
assert_eq!(m.visit(&repo_path("bar")), Visit::Nothing);
assert_eq!(m.visit(repo_path("bar")), Visit::Nothing);
}
#[test]
fn test_prefixmatcher_nested_prefixes() {
let m = PrefixMatcher::new([repo_path("foo"), repo_path("foo/bar/baz")]);
assert!(m.matches(&repo_path("foo")));
assert!(!m.matches(&repo_path("bar")));
assert!(m.matches(&repo_path("foo/bar")));
assert!(m.matches(repo_path("foo")));
assert!(!m.matches(repo_path("bar")));
assert!(m.matches(repo_path("foo/bar")));
// Matches because the "foo" pattern matches
assert!(m.matches(&repo_path("foo/baz/foo")));
assert!(m.matches(repo_path("foo/baz/foo")));
assert_eq!(
m.visit(&RepoPath::root()),
m.visit(RepoPath::root()),
Visit::sets(
hashset! {RepoPathComponentBuf::from("foo")},
hashset! {RepoPathComponentBuf::from("foo")}
)
);
// Inside a directory that matches the prefix, everything matches recursively
assert_eq!(m.visit(&repo_path("foo")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo")), Visit::AllRecursively);
// Same thing in subdirectories of the prefix
assert_eq!(m.visit(&repo_path("foo/bar/baz")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo/bar/baz")), Visit::AllRecursively);
}
#[test]
@ -542,14 +542,14 @@ mod tests {
let m2 = PrefixMatcher::new([repo_path("foo/bar")]);
let m = DifferenceMatcher::new(&m1, &m2);
assert!(m.matches(&repo_path("foo")));
assert!(!m.matches(&repo_path("foo/bar")));
assert!(!m.matches(&repo_path("foo/bar/baz")));
assert!(m.matches(&repo_path("foo/baz")));
assert!(m.matches(&repo_path("bar")));
assert!(m.matches(repo_path("foo")));
assert!(!m.matches(repo_path("foo/bar")));
assert!(!m.matches(repo_path("foo/bar/baz")));
assert!(m.matches(repo_path("foo/baz")));
assert!(m.matches(repo_path("bar")));
assert_eq!(
m.visit(&RepoPath::root()),
m.visit(RepoPath::root()),
Visit::sets(
hashset! {
RepoPathComponentBuf::from("foo"),
@ -562,15 +562,15 @@ mod tests {
)
);
assert_eq!(
m.visit(&repo_path("foo")),
m.visit(repo_path("foo")),
Visit::Specific {
dirs: VisitDirs::All,
files: VisitFiles::All,
}
);
assert_eq!(m.visit(&repo_path("foo/bar")), Visit::Nothing);
assert_eq!(m.visit(&repo_path("foo/baz")), Visit::AllRecursively);
assert_eq!(m.visit(&repo_path("bar")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo/bar")), Visit::Nothing);
assert_eq!(m.visit(repo_path("foo/baz")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("bar")), Visit::AllRecursively);
}
#[test]
@ -579,13 +579,13 @@ mod tests {
let m2 = PrefixMatcher::new([repo_path("foo")]);
let m = DifferenceMatcher::new(&m1, &m2);
assert!(!m.matches(&repo_path("foo")));
assert!(!m.matches(&repo_path("foo/bar")));
assert!(m.matches(&repo_path("bar")));
assert!(m.matches(&repo_path("bar/foo")));
assert!(!m.matches(repo_path("foo")));
assert!(!m.matches(repo_path("foo/bar")));
assert!(m.matches(repo_path("bar")));
assert!(m.matches(repo_path("bar/foo")));
assert_eq!(
m.visit(&RepoPath::root()),
m.visit(RepoPath::root()),
Visit::sets(
hashset! {
RepoPathComponentBuf::from("foo"),
@ -597,10 +597,10 @@ mod tests {
},
)
);
assert_eq!(m.visit(&repo_path("foo")), Visit::Nothing);
assert_eq!(m.visit(&repo_path("foo/bar")), Visit::Nothing);
assert_eq!(m.visit(&repo_path("bar")), Visit::AllRecursively);
assert_eq!(m.visit(&repo_path("bar/foo")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo")), Visit::Nothing);
assert_eq!(m.visit(repo_path("foo/bar")), Visit::Nothing);
assert_eq!(m.visit(repo_path("bar")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("bar/foo")), Visit::AllRecursively);
}
#[test]
@ -609,26 +609,26 @@ mod tests {
let m2 = PrefixMatcher::new([repo_path("bar"), repo_path("baz")]);
let m = IntersectionMatcher::new(&m1, &m2);
assert!(!m.matches(&repo_path("foo")));
assert!(!m.matches(&repo_path("foo/bar")));
assert!(m.matches(&repo_path("bar")));
assert!(m.matches(&repo_path("bar/foo")));
assert!(!m.matches(&repo_path("baz")));
assert!(!m.matches(&repo_path("baz/foo")));
assert!(!m.matches(repo_path("foo")));
assert!(!m.matches(repo_path("foo/bar")));
assert!(m.matches(repo_path("bar")));
assert!(m.matches(repo_path("bar/foo")));
assert!(!m.matches(repo_path("baz")));
assert!(!m.matches(repo_path("baz/foo")));
assert_eq!(
m.visit(&RepoPath::root()),
m.visit(RepoPath::root()),
Visit::sets(
hashset! {RepoPathComponentBuf::from("bar")},
hashset! {RepoPathComponentBuf::from("bar")}
)
);
assert_eq!(m.visit(&repo_path("foo")), Visit::Nothing);
assert_eq!(m.visit(&repo_path("foo/bar")), Visit::Nothing);
assert_eq!(m.visit(&repo_path("bar")), Visit::AllRecursively);
assert_eq!(m.visit(&repo_path("bar/foo")), Visit::AllRecursively);
assert_eq!(m.visit(&repo_path("baz")), Visit::Nothing);
assert_eq!(m.visit(&repo_path("baz/foo")), Visit::Nothing);
assert_eq!(m.visit(repo_path("foo")), Visit::Nothing);
assert_eq!(m.visit(repo_path("foo/bar")), Visit::Nothing);
assert_eq!(m.visit(repo_path("bar")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("bar/foo")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("baz")), Visit::Nothing);
assert_eq!(m.visit(repo_path("baz/foo")), Visit::Nothing);
}
#[test]
@ -637,24 +637,24 @@ mod tests {
let m2 = PrefixMatcher::new([repo_path("foo/bar")]);
let m = IntersectionMatcher::new(&m1, &m2);
assert!(!m.matches(&repo_path("foo")));
assert!(!m.matches(&repo_path("bar")));
assert!(m.matches(&repo_path("foo/bar")));
assert!(m.matches(&repo_path("foo/bar/baz")));
assert!(!m.matches(&repo_path("foo/baz")));
assert!(!m.matches(repo_path("foo")));
assert!(!m.matches(repo_path("bar")));
assert!(m.matches(repo_path("foo/bar")));
assert!(m.matches(repo_path("foo/bar/baz")));
assert!(!m.matches(repo_path("foo/baz")));
assert_eq!(
m.visit(&RepoPath::root()),
m.visit(RepoPath::root()),
Visit::sets(hashset! {RepoPathComponentBuf::from("foo")}, hashset! {})
);
assert_eq!(m.visit(&repo_path("bar")), Visit::Nothing);
assert_eq!(m.visit(repo_path("bar")), Visit::Nothing);
assert_eq!(
m.visit(&repo_path("foo")),
m.visit(repo_path("foo")),
Visit::sets(
hashset! {RepoPathComponentBuf::from("bar")},
hashset! {RepoPathComponentBuf::from("bar")}
)
);
assert_eq!(m.visit(&repo_path("foo/bar")), Visit::AllRecursively);
assert_eq!(m.visit(repo_path("foo/bar")), Visit::AllRecursively);
}
}

View file

@ -133,7 +133,7 @@ impl MergedTree {
.into_iter()
.map(|builder| {
let tree_id = builder.write_tree();
store.get_tree(&RepoPath::root(), &tree_id)
store.get_tree(RepoPath::root(), &tree_id)
})
.try_collect()?;
Ok(MergedTree::Merge(Merge::from_vec(new_trees)))
@ -245,7 +245,7 @@ impl MergedTree {
/// `self` is a `Conflict`, which happens if the value at the path can be
/// trivially merged.
pub fn path_value(&self, path: &RepoPath) -> MergedTreeValue {
assert_eq!(self.dir(), &RepoPath::root());
assert_eq!(self.dir(), RepoPath::root());
match path.split() {
Some((dir, basename)) => match self.sub_tree_recursive(dir.components()) {
None => Merge::absent(),
@ -761,7 +761,7 @@ impl<'matcher> TreeDiffIterator<'matcher> {
/// Creates a iterator over the differences between two trees. Generally
/// prefer `MergedTree::diff()` of calling this directly.
pub fn new(tree1: MergedTree, tree2: MergedTree, matcher: &'matcher dyn Matcher) -> Self {
let root_dir = &RepoPath::root();
let root_dir = RepoPath::root();
let mut stack = Vec::new();
if !matcher.visit(root_dir).is_nothing() {
stack.push(TreeDiffItem::Dir(TreeDiffDirItem::from_trees(
@ -1239,7 +1239,7 @@ impl MergedTreeBuilder {
}
let legacy_id = tree_builder.write_tree();
if store.use_tree_conflict_format() {
let legacy_tree = store.get_tree(&RepoPath::root(), &legacy_id)?;
let legacy_tree = store.get_tree(RepoPath::root(), &legacy_id)?;
let merged_tree = MergedTree::from_legacy_tree(legacy_tree)?;
Ok(merged_tree.id())
} else {

View file

@ -159,21 +159,35 @@ impl DoubleEndedIterator for RepoPathComponentsIter<'_> {
impl FusedIterator for RepoPathComponentsIter<'_> {}
// TODO: make RepoPath a borrowed type
pub type RepoPathBuf = RepoPath;
/// Owned repository path.
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct RepoPath {
pub struct RepoPathBuf {
// Don't add more fields. Eq, Hash, and Ord must be compatible with the
// borrowed RepoPath type.
value: String,
}
/// Borrowed repository path.
#[derive(Eq, Hash, PartialEq, RefCastCustom)]
#[repr(transparent)]
pub struct RepoPath {
value: str,
}
impl Debug for RepoPath {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
f.write_fmt(format_args!("{:?}", &self.value))
}
}
impl Debug for RepoPathBuf {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
<RepoPath as Debug>::fmt(self, f)
}
}
impl RepoPathBuf {
/// Creates owned repository path pointing to the root.
pub const fn root() -> Self {
RepoPathBuf {
value: String::new(),
@ -236,6 +250,23 @@ impl RepoPathBuf {
}
impl RepoPath {
/// Returns repository path pointing to the root.
pub const fn root() -> &'static Self {
Self::from_internal_string_unchecked("")
}
/// Wraps valid string representation as `RepoPath`.
///
/// The input `value` must not contain empty path components. For example,
/// `"/"`, `"/foo"`, `"foo/"`, `"foo//bar"` are all invalid.
pub fn from_internal_string(value: &str) -> &Self {
assert!(is_valid_repo_path_str(value));
Self::from_internal_string_unchecked(value)
}
#[ref_cast_custom]
const fn from_internal_string_unchecked(value: &str) -> &Self;
/// The full string form used internally, not for presenting to users (where
/// we may want to use the platform's separator). This format includes a
/// trailing slash, unless this path represents the root directory. That
@ -316,6 +347,39 @@ impl AsRef<RepoPath> for RepoPath {
}
}
impl AsRef<RepoPath> for RepoPathBuf {
fn as_ref(&self) -> &RepoPath {
self
}
}
impl Borrow<RepoPath> for RepoPathBuf {
fn borrow(&self) -> &RepoPath {
self
}
}
impl Deref for RepoPathBuf {
type Target = RepoPath;
fn deref(&self) -> &Self::Target {
RepoPath::from_internal_string_unchecked(&self.value)
}
}
impl ToOwned for RepoPath {
type Owned = RepoPathBuf;
fn to_owned(&self) -> Self::Owned {
let value = self.value.to_owned();
RepoPathBuf { value }
}
fn clone_into(&self, target: &mut Self::Owned) {
self.value.clone_into(&mut target.value);
}
}
impl Ord for RepoPath {
fn cmp(&self, other: &Self) -> Ordering {
// If there were leading/trailing slash, components-based Ord would
@ -325,12 +389,24 @@ impl Ord for RepoPath {
}
}
impl Ord for RepoPathBuf {
fn cmp(&self, other: &Self) -> Ordering {
<RepoPath as Ord>::cmp(self, other)
}
}
impl PartialOrd for RepoPath {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialOrd for RepoPathBuf {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[derive(Clone, Debug, Eq, Error, PartialEq)]
pub enum FsPathParseError {
#[error(r#"Path "{}" is not in the repo"#, .0.display())]
@ -353,7 +429,7 @@ mod tests {
use super::*;
fn repo_path(value: &str) -> RepoPath {
fn repo_path(value: &str) -> &RepoPath {
RepoPath::from_internal_string(value)
}
@ -366,6 +442,13 @@ mod tests {
#[test]
fn test_from_internal_string() {
let repo_path_buf = |value: &str| RepoPathBuf::from_internal_string(value);
assert_eq!(repo_path_buf(""), RepoPathBuf::root());
assert!(panic::catch_unwind(|| repo_path_buf("/")).is_err());
assert!(panic::catch_unwind(|| repo_path_buf("/x")).is_err());
assert!(panic::catch_unwind(|| repo_path_buf("x/")).is_err());
assert!(panic::catch_unwind(|| repo_path_buf("x//y")).is_err());
assert_eq!(repo_path(""), RepoPath::root());
assert!(panic::catch_unwind(|| repo_path("/")).is_err());
assert!(panic::catch_unwind(|| repo_path("/x")).is_err());
@ -389,20 +472,20 @@ mod tests {
#[test]
fn test_contains() {
assert!(repo_path("").contains(&repo_path("")));
assert!(repo_path("").contains(&repo_path("x")));
assert!(!repo_path("x").contains(&repo_path("")));
assert!(repo_path("").contains(repo_path("")));
assert!(repo_path("").contains(repo_path("x")));
assert!(!repo_path("x").contains(repo_path("")));
assert!(repo_path("x").contains(&repo_path("x")));
assert!(repo_path("x").contains(&repo_path("x/y")));
assert!(!repo_path("x").contains(&repo_path("xy")));
assert!(!repo_path("y").contains(&repo_path("x/y")));
assert!(repo_path("x").contains(repo_path("x")));
assert!(repo_path("x").contains(repo_path("x/y")));
assert!(!repo_path("x").contains(repo_path("xy")));
assert!(!repo_path("y").contains(repo_path("x/y")));
assert!(repo_path("x/y").contains(&repo_path("x/y")));
assert!(repo_path("x/y").contains(&repo_path("x/y/z")));
assert!(!repo_path("x/y").contains(&repo_path("x/yz")));
assert!(!repo_path("x/y").contains(&repo_path("x")));
assert!(!repo_path("x/y").contains(&repo_path("xy")));
assert!(repo_path("x/y").contains(repo_path("x/y")));
assert!(repo_path("x/y").contains(repo_path("x/y/z")));
assert!(!repo_path("x/y").contains(repo_path("x/yz")));
assert!(!repo_path("x/y").contains(repo_path("x")));
assert!(!repo_path("x/y").contains(repo_path("xy")));
}
#[test]
@ -425,11 +508,11 @@ mod tests {
fn test_join() {
let root = RepoPath::root();
let dir = root.join(RepoPathComponent::new("dir"));
assert_eq!(dir, repo_path("dir"));
assert_eq!(dir.as_ref(), repo_path("dir"));
let subdir = dir.join(RepoPathComponent::new("subdir"));
assert_eq!(subdir, repo_path("dir/subdir"));
assert_eq!(subdir.as_ref(), repo_path("dir/subdir"));
assert_eq!(
subdir.join(RepoPathComponent::new("file")),
subdir.join(RepoPathComponent::new("file")).as_ref(),
repo_path("dir/subdir/file")
);
}
@ -444,7 +527,7 @@ mod tests {
let subdir = dir.join(subdir_component);
assert_eq!(root.parent(), None);
assert_eq!(dir.parent(), Some(root));
assert_eq!(dir.parent().as_deref(), Some(root));
assert_eq!(subdir.parent(), Some(dir));
}
@ -458,7 +541,7 @@ mod tests {
let file = dir.join(file_component);
assert_eq!(root.split(), None);
assert_eq!(dir.split(), Some((root, dir_component)));
assert_eq!(dir.split(), Some((root.to_owned(), dir_component)));
assert_eq!(file.split(), Some((dir, file_component)));
}
@ -520,15 +603,15 @@ mod tests {
let wc_path = &cwd_path;
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, ""),
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, "").as_deref(),
Ok(RepoPath::root())
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, "."),
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, ".").as_deref(),
Ok(RepoPath::root())
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, "file"),
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, "file").as_deref(),
Ok(repo_path("file"))
);
// Both slash and the platform's separator are allowed
@ -537,11 +620,12 @@ mod tests {
&cwd_path,
wc_path,
format!("dir{}file", std::path::MAIN_SEPARATOR)
),
)
.as_deref(),
Ok(repo_path("dir/file"))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, "dir/file"),
RepoPathBuf::parse_fs_path(&cwd_path, wc_path, "dir/file").as_deref(),
Ok(repo_path("dir/file"))
);
assert_eq!(
@ -549,11 +633,11 @@ mod tests {
Err(FsPathParseError::InputNotInRepo("..".into()))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &cwd_path, "../repo"),
RepoPathBuf::parse_fs_path(&cwd_path, &cwd_path, "../repo").as_deref(),
Ok(RepoPath::root())
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &cwd_path, "../repo/file"),
RepoPathBuf::parse_fs_path(&cwd_path, &cwd_path, "../repo/file").as_deref(),
Ok(repo_path("file"))
);
// Input may be absolute path with ".."
@ -562,7 +646,8 @@ mod tests {
&cwd_path,
&cwd_path,
cwd_path.join("../repo").to_str().unwrap()
),
)
.as_deref(),
Ok(RepoPath::root())
);
}
@ -574,23 +659,23 @@ mod tests {
let wc_path = cwd_path.parent().unwrap().to_path_buf();
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, ""),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "").as_deref(),
Ok(repo_path("dir"))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "."),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, ".").as_deref(),
Ok(repo_path("dir"))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "file"),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "file").as_deref(),
Ok(repo_path("dir/file"))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "subdir/file"),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "subdir/file").as_deref(),
Ok(repo_path("dir/subdir/file"))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, ".."),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "..").as_deref(),
Ok(RepoPath::root())
);
assert_eq!(
@ -598,7 +683,7 @@ mod tests {
Err(FsPathParseError::InputNotInRepo("../..".into()))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "../other-dir/file"),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "../other-dir/file").as_deref(),
Ok(repo_path("other-dir/file"))
);
}
@ -618,15 +703,15 @@ mod tests {
Err(FsPathParseError::InputNotInRepo("not-repo".into()))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "repo"),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "repo").as_deref(),
Ok(RepoPath::root())
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "repo/file"),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "repo/file").as_deref(),
Ok(repo_path("file"))
);
assert_eq!(
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "repo/dir/file"),
RepoPathBuf::parse_fs_path(&cwd_path, &wc_path, "repo/dir/file").as_deref(),
Ok(repo_path("dir/file"))
);
}

View file

@ -78,7 +78,7 @@ pub fn restore_tree(
destination: &MergedTree,
matcher: &dyn Matcher,
) -> BackendResult<MergedTreeId> {
if matcher.visit(&RepoPath::root()) == Visit::AllRecursively {
if matcher.visit(RepoPath::root()) == Visit::AllRecursively {
// Optimization for a common case
Ok(source.id())
} else {

View file

@ -171,11 +171,11 @@ impl Store {
pub fn get_root_tree(self: &Arc<Self>, id: &MergedTreeId) -> BackendResult<MergedTree> {
match &id {
MergedTreeId::Legacy(id) => {
let tree = self.get_tree(&RepoPath::root(), id)?;
let tree = self.get_tree(RepoPath::root(), id)?;
Ok(MergedTree::Legacy(tree))
}
MergedTreeId::Merge(ids) => {
let trees = ids.try_map(|id| self.get_tree(&RepoPath::root(), id))?;
let trees = ids.try_map(|id| self.get_tree(RepoPath::root(), id))?;
Ok(MergedTree::Merge(trees))
}
}

View file

@ -136,7 +136,7 @@ impl Tree {
}
pub fn path_value(&self, path: &RepoPath) -> Option<TreeValue> {
assert_eq!(self.dir(), &RepoPath::root());
assert_eq!(self.dir(), RepoPath::root());
match path.split() {
Some((dir, basename)) => self
.sub_tree_recursive(dir.components())

View file

@ -33,8 +33,8 @@ fn test_initial(backend: TestRepoBackend) {
let repo = &test_repo.repo;
let store = repo.store();
let root_file_path = &RepoPath::from_internal_string("file");
let dir_file_path = &RepoPath::from_internal_string("dir/file");
let root_file_path = RepoPath::from_internal_string("file");
let dir_file_path = RepoPath::from_internal_string("dir/file");
let tree = create_tree(
repo,
&[
@ -105,8 +105,8 @@ fn test_rewrite(backend: TestRepoBackend) {
let repo = &test_repo.repo;
let store = repo.store().clone();
let root_file_path = &RepoPath::from_internal_string("file");
let dir_file_path = &RepoPath::from_internal_string("dir/file");
let root_file_path = RepoPath::from_internal_string("file");
let dir_file_path = RepoPath::from_internal_string("dir/file");
let initial_tree = create_tree(
repo,
&[

View file

@ -28,7 +28,7 @@ fn test_materialize_conflict_basic() {
let test_repo = TestRepo::init();
let store = test_repo.repo.store();
let path = &RepoPath::from_internal_string("file");
let path = RepoPath::from_internal_string("file");
let base_id = testutils::write_file(
store,
path,
@ -118,7 +118,7 @@ fn test_materialize_conflict_multi_rebase_conflicts() {
let store = test_repo.repo.store();
// Create changes (a, b, c) on top of the base, and linearize them.
let path = &RepoPath::from_internal_string("file");
let path = RepoPath::from_internal_string("file");
let base_id = testutils::write_file(
store,
path,
@ -236,7 +236,7 @@ fn test_materialize_parse_roundtrip() {
let test_repo = TestRepo::init();
let store = test_repo.repo.store();
let path = &RepoPath::from_internal_string("file");
let path = RepoPath::from_internal_string("file");
let base_id = testutils::write_file(
store,
path,
@ -331,7 +331,7 @@ fn test_materialize_conflict_modify_delete() {
let test_repo = TestRepo::init();
let store = test_repo.repo.store();
let path = &RepoPath::from_internal_string("file");
let path = RepoPath::from_internal_string("file");
let base_id = testutils::write_file(
store,
path,
@ -595,7 +595,7 @@ fn test_update_conflict_from_content() {
let test_repo = TestRepo::init();
let store = test_repo.repo.store();
let path = &RepoPath::from_internal_string("dir/file");
let path = RepoPath::from_internal_string("dir/file");
let base_file_id = testutils::write_file(store, path, "line 1\nline 2\nline 3\n");
let left_file_id = testutils::write_file(store, path, "left 1\nline 2\nleft 3\n");
let right_file_id = testutils::write_file(store, path, "right 1\nline 2\nright 3\n");
@ -647,7 +647,7 @@ fn test_update_conflict_from_content_modify_delete() {
let test_repo = TestRepo::init();
let store = test_repo.repo.store();
let path = &RepoPath::from_internal_string("dir/file");
let path = RepoPath::from_internal_string("dir/file");
let before_file_id = testutils::write_file(store, path, "line 1\nline 2 before\nline 3\n");
let after_file_id = testutils::write_file(store, path, "line 1\nline 2 after\nline 3\n");
let conflict =

View file

@ -26,10 +26,10 @@ fn test_types() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let clean_path = &RepoPath::from_internal_string("clean");
let modified_path = &RepoPath::from_internal_string("modified");
let added_path = &RepoPath::from_internal_string("added");
let removed_path = &RepoPath::from_internal_string("removed");
let clean_path = RepoPath::from_internal_string("clean");
let modified_path = RepoPath::from_internal_string("modified");
let added_path = RepoPath::from_internal_string("added");
let removed_path = RepoPath::from_internal_string("removed");
let tree1 = create_tree(
repo,
@ -64,8 +64,8 @@ fn test_tree_file_transition() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let dir_file_path = &RepoPath::from_internal_string("dir/file");
let dir_path = &RepoPath::from_internal_string("dir");
let dir_file_path = RepoPath::from_internal_string("dir/file");
let dir_path = RepoPath::from_internal_string("dir");
let tree1 = create_tree(repo, &[(dir_file_path, "contents")]);
let tree2 = create_tree(repo, &[(dir_path, "contents")]);
@ -93,15 +93,15 @@ fn test_sorting() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let a_path = &RepoPath::from_internal_string("a");
let b_path = &RepoPath::from_internal_string("b");
let f_a_path = &RepoPath::from_internal_string("f/a");
let f_b_path = &RepoPath::from_internal_string("f/b");
let f_f_a_path = &RepoPath::from_internal_string("f/f/a");
let f_f_b_path = &RepoPath::from_internal_string("f/f/b");
let n_path = &RepoPath::from_internal_string("n");
let s_b_path = &RepoPath::from_internal_string("s/b");
let z_path = &RepoPath::from_internal_string("z");
let a_path = RepoPath::from_internal_string("a");
let b_path = RepoPath::from_internal_string("b");
let f_a_path = RepoPath::from_internal_string("f/a");
let f_b_path = RepoPath::from_internal_string("f/b");
let f_f_a_path = RepoPath::from_internal_string("f/f/a");
let f_f_b_path = RepoPath::from_internal_string("f/f/b");
let n_path = RepoPath::from_internal_string("n");
let s_b_path = RepoPath::from_internal_string("s/b");
let z_path = RepoPath::from_internal_string("z");
let tree1 = create_tree(
repo,
@ -150,8 +150,8 @@ fn test_matcher_dir_file_transition() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let a_path = &RepoPath::from_internal_string("a");
let a_a_path = &RepoPath::from_internal_string("a/a");
let a_path = RepoPath::from_internal_string("a");
let a_a_path = RepoPath::from_internal_string("a/a");
let tree1 = create_tree(repo, &[(a_path, "before")]);
let tree2 = create_tree(repo, &[(a_a_path, "after")]);
@ -216,10 +216,10 @@ fn test_matcher_normal_cases() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let a_path = &RepoPath::from_internal_string("a");
let dir1_a_path = &RepoPath::from_internal_string("dir1/a");
let dir2_b_path = &RepoPath::from_internal_string("dir2/b");
let z_path = &RepoPath::from_internal_string("z");
let a_path = RepoPath::from_internal_string("a");
let dir1_a_path = RepoPath::from_internal_string("dir1/a");
let dir2_b_path = RepoPath::from_internal_string("dir2/b");
let z_path = RepoPath::from_internal_string("z");
let tree1 = create_tree(repo, &[(a_path, "before"), (dir1_a_path, "before")]);
// File "a" gets modified

View file

@ -275,7 +275,7 @@ fn test_conflict_subdirectory() {
let mut test_workspace = TestWorkspace::init(&settings);
let repo = &test_workspace.repo;
let path = &RepoPath::from_internal_string("sub/file");
let path = RepoPath::from_internal_string("sub/file");
let empty_tree = create_tree(repo, &[]);
let tree1 = create_tree(repo, &[(path, "0")]);
let tree2 = create_tree(repo, &[(path, "1")]);
@ -298,13 +298,13 @@ fn test_tree_builder_file_directory_transition() {
let mut ws = test_workspace.workspace;
let workspace_root = ws.workspace_root().clone();
let mut check_out_tree = |tree_id: &TreeId| {
let tree = repo.store().get_tree(&RepoPath::root(), tree_id).unwrap();
let tree = repo.store().get_tree(RepoPath::root(), tree_id).unwrap();
let commit = commit_with_tree(repo.store(), MergedTreeId::Legacy(tree.id().clone()));
ws.check_out(repo.op_id().clone(), None, &commit).unwrap();
};
let parent_path = &RepoPath::from_internal_string("foo/bar");
let child_path = &RepoPath::from_internal_string("foo/bar/baz");
let parent_path = RepoPath::from_internal_string("foo/bar");
let child_path = RepoPath::from_internal_string("foo/bar/baz");
// Add file at parent_path
let mut tree_builder = store.tree_builder(store.empty_tree_id().clone());
@ -342,11 +342,11 @@ fn test_conflicting_changes_on_disk() {
let workspace_root = ws.workspace_root().clone();
// file on disk conflicts with file in target commit
let file_file_path = &RepoPath::from_internal_string("file-file");
let file_file_path = RepoPath::from_internal_string("file-file");
// file on disk conflicts with directory in target commit
let file_dir_path = &RepoPath::from_internal_string("file-dir");
let file_dir_path = RepoPath::from_internal_string("file-dir");
// directory on disk conflicts with file in target commit
let dir_file_path = &RepoPath::from_internal_string("dir-file");
let dir_file_path = RepoPath::from_internal_string("dir-file");
let tree = create_tree(
repo,
&[
@ -410,8 +410,8 @@ fn test_reset() {
let op_id = repo.op_id().clone();
let workspace_root = test_workspace.workspace.workspace_root().clone();
let ignored_path = &RepoPath::from_internal_string("ignored");
let gitignore_path = &RepoPath::from_internal_string(".gitignore");
let ignored_path = RepoPath::from_internal_string("ignored");
let gitignore_path = RepoPath::from_internal_string(".gitignore");
let tree_without_file = create_tree(repo, &[(gitignore_path, "ignored\n")]);
let tree_with_file = create_tree(
@ -463,8 +463,8 @@ fn test_checkout_discard() {
let repo = test_workspace.repo.clone();
let workspace_root = test_workspace.workspace.workspace_root().clone();
let file1_path = &RepoPath::from_internal_string("file1");
let file2_path = &RepoPath::from_internal_string("file2");
let file1_path = RepoPath::from_internal_string("file1");
let file2_path = RepoPath::from_internal_string("file2");
let store = repo.store();
let tree1 = create_tree(&repo, &[(file1_path, "contents")]);
@ -551,10 +551,10 @@ fn test_snapshot_special_file() {
let store = test_workspace.repo.store();
let ws = &mut test_workspace.workspace;
let file1_path = &RepoPath::from_internal_string("file1");
let file1_path = RepoPath::from_internal_string("file1");
let file1_disk_path = file1_path.to_fs_path(&workspace_root);
std::fs::write(&file1_disk_path, "contents".as_bytes()).unwrap();
let file2_path = &RepoPath::from_internal_string("file2");
let file2_path = RepoPath::from_internal_string("file2");
let file2_disk_path = file2_path.to_fs_path(&workspace_root);
std::fs::write(file2_disk_path, "contents".as_bytes()).unwrap();
let socket_disk_path = workspace_root.join("socket");
@ -615,13 +615,13 @@ fn test_gitignores() {
let mut test_workspace = TestWorkspace::init(&settings);
let workspace_root = test_workspace.workspace.workspace_root().clone();
let gitignore_path = &RepoPath::from_internal_string(".gitignore");
let added_path = &RepoPath::from_internal_string("added");
let modified_path = &RepoPath::from_internal_string("modified");
let removed_path = &RepoPath::from_internal_string("removed");
let ignored_path = &RepoPath::from_internal_string("ignored");
let subdir_modified_path = &RepoPath::from_internal_string("dir/modified");
let subdir_ignored_path = &RepoPath::from_internal_string("dir/ignored");
let gitignore_path = RepoPath::from_internal_string(".gitignore");
let added_path = RepoPath::from_internal_string("added");
let modified_path = RepoPath::from_internal_string("modified");
let removed_path = RepoPath::from_internal_string("removed");
let ignored_path = RepoPath::from_internal_string("ignored");
let subdir_modified_path = RepoPath::from_internal_string("dir/modified");
let subdir_ignored_path = RepoPath::from_internal_string("dir/ignored");
testutils::write_working_copy_file(&workspace_root, gitignore_path, "ignored\n");
testutils::write_working_copy_file(&workspace_root, modified_path, "1");
@ -676,9 +676,9 @@ fn test_gitignores_in_ignored_dir() {
let op_id = test_workspace.repo.op_id().clone();
let workspace_root = test_workspace.workspace.workspace_root().clone();
let gitignore_path = &RepoPath::from_internal_string(".gitignore");
let nested_gitignore_path = &RepoPath::from_internal_string("ignored/.gitignore");
let ignored_path = &RepoPath::from_internal_string("ignored/file");
let gitignore_path = RepoPath::from_internal_string(".gitignore");
let nested_gitignore_path = RepoPath::from_internal_string("ignored/.gitignore");
let ignored_path = RepoPath::from_internal_string("ignored/file");
let tree1 = create_tree(&test_workspace.repo, &[(gitignore_path, "ignored\n")]);
let commit1 = commit_with_tree(test_workspace.repo.store(), tree1.id());
@ -727,9 +727,9 @@ fn test_gitignores_checkout_never_overwrites_ignored() {
let workspace_root = test_workspace.workspace.workspace_root().clone();
// Write an ignored file called "modified" to disk
let gitignore_path = &RepoPath::from_internal_string(".gitignore");
let gitignore_path = RepoPath::from_internal_string(".gitignore");
testutils::write_working_copy_file(&workspace_root, gitignore_path, "modified\n");
let modified_path = &RepoPath::from_internal_string("modified");
let modified_path = RepoPath::from_internal_string("modified");
testutils::write_working_copy_file(&workspace_root, modified_path, "garbage");
// Create a tree that adds the same file but with different contents
@ -758,10 +758,10 @@ fn test_gitignores_ignored_directory_already_tracked() {
let workspace_root = test_workspace.workspace.workspace_root().clone();
let repo = test_workspace.repo.clone();
let gitignore_path = &RepoPath::from_internal_string(".gitignore");
let unchanged_path = &RepoPath::from_internal_string("ignored/unchanged");
let modified_path = &RepoPath::from_internal_string("ignored/modified");
let deleted_path = &RepoPath::from_internal_string("ignored/deleted");
let gitignore_path = RepoPath::from_internal_string(".gitignore");
let unchanged_path = RepoPath::from_internal_string("ignored/unchanged");
let modified_path = RepoPath::from_internal_string("ignored/modified");
let deleted_path = RepoPath::from_internal_string("ignored/deleted");
let tree = create_tree(
&repo,
&[
@ -813,7 +813,7 @@ fn test_dotgit_ignored() {
std::fs::create_dir(&dotgit_path).unwrap();
testutils::write_working_copy_file(
&workspace_root,
&RepoPath::from_internal_string(".git/file"),
RepoPath::from_internal_string(".git/file"),
"contents",
);
let new_tree = test_workspace.snapshot().unwrap();
@ -824,7 +824,7 @@ fn test_dotgit_ignored() {
// Test with a .git file
testutils::write_working_copy_file(
&workspace_root,
&RepoPath::from_internal_string(".git"),
RepoPath::from_internal_string(".git"),
"contents",
);
let new_tree = test_workspace.snapshot().unwrap();
@ -843,9 +843,9 @@ fn test_gitsubmodule() {
let mut tree_builder = store.tree_builder(store.empty_tree_id().clone());
let added_path = &RepoPath::from_internal_string("added");
let submodule_path = &RepoPath::from_internal_string("submodule");
let added_submodule_path = &RepoPath::from_internal_string("submodule/added");
let added_path = RepoPath::from_internal_string("added");
let submodule_path = RepoPath::from_internal_string("submodule");
let added_submodule_path = RepoPath::from_internal_string("submodule/added");
tree_builder.set(
added_path.to_owned(),
@ -902,7 +902,7 @@ fn test_existing_directory_symlink() {
// Creates a symlink in working directory, and a tree that will add a file under
// the symlinked directory.
std::os::unix::fs::symlink("..", workspace_root.join("parent")).unwrap();
let file_path = &RepoPath::from_internal_string("parent/escaped");
let file_path = RepoPath::from_internal_string("parent/escaped");
let tree = create_tree(repo, &[(file_path, "contents")]);
let commit = commit_with_tree(repo.store(), tree.id());
@ -927,15 +927,15 @@ fn test_fsmonitor() {
vec![RepoPathBuf::root()]
);
let foo_path = &RepoPath::from_internal_string("foo");
let bar_path = &RepoPath::from_internal_string("bar");
let nested_path = &RepoPath::from_internal_string("path/to/nested");
let foo_path = RepoPath::from_internal_string("foo");
let bar_path = RepoPath::from_internal_string("bar");
let nested_path = RepoPath::from_internal_string("path/to/nested");
testutils::write_working_copy_file(&workspace_root, foo_path, "foo\n");
testutils::write_working_copy_file(&workspace_root, bar_path, "bar\n");
testutils::write_working_copy_file(&workspace_root, nested_path, "nested\n");
let ignored_path = &RepoPath::from_internal_string("path/to/ignored");
let gitignore_path = &RepoPath::from_internal_string("path/.gitignore");
let ignored_path = RepoPath::from_internal_string("path/to/ignored");
let gitignore_path = RepoPath::from_internal_string("path/.gitignore");
testutils::write_working_copy_file(&workspace_root, ignored_path, "ignored\n");
testutils::write_working_copy_file(&workspace_root, gitignore_path, "to/ignored\n");
@ -1021,8 +1021,8 @@ fn test_snapshot_max_new_file_size() {
);
let mut test_workspace = TestWorkspace::init(&settings);
let workspace_root = test_workspace.workspace.workspace_root().clone();
let small_path = &RepoPath::from_internal_string("small");
let large_path = &RepoPath::from_internal_string("large");
let small_path = RepoPath::from_internal_string("small");
let large_path = RepoPath::from_internal_string("large");
std::fs::write(small_path.to_fs_path(&workspace_root), vec![0; 1024]).unwrap();
test_workspace
.snapshot()

View file

@ -96,7 +96,7 @@ fn test_checkout_parallel() {
// first update
let tree = create_tree(
repo,
&[(&RepoPath::from_internal_string("other file"), "contents")],
&[(RepoPath::from_internal_string("other file"), "contents")],
);
let commit = commit_with_tree(repo.store(), tree.id());
test_workspace
@ -147,7 +147,7 @@ fn test_racy_checkout() {
let op_id = repo.op_id().clone();
let workspace_root = test_workspace.workspace.workspace_root().clone();
let path = &RepoPath::from_internal_string("file");
let path = RepoPath::from_internal_string("file");
let tree = create_tree(repo, &[(path, "1")]);
let commit = commit_with_tree(repo.store(), tree.id());

View file

@ -31,15 +31,15 @@ fn test_sparse_checkout() {
let repo = &test_workspace.repo;
let working_copy_path = test_workspace.workspace.workspace_root().clone();
let root_file1_path = &RepoPath::from_internal_string("file1");
let root_file2_path = &RepoPath::from_internal_string("file2");
let dir1_path = &RepoPath::from_internal_string("dir1");
let dir1_file1_path = &RepoPath::from_internal_string("dir1/file1");
let dir1_file2_path = &RepoPath::from_internal_string("dir1/file2");
let dir1_subdir1_path = &RepoPath::from_internal_string("dir1/subdir1");
let dir1_subdir1_file1_path = &RepoPath::from_internal_string("dir1/subdir1/file1");
let dir2_path = &RepoPath::from_internal_string("dir2");
let dir2_file1_path = &RepoPath::from_internal_string("dir2/file1");
let root_file1_path = RepoPath::from_internal_string("file1");
let root_file2_path = RepoPath::from_internal_string("file2");
let dir1_path = RepoPath::from_internal_string("dir1");
let dir1_file1_path = RepoPath::from_internal_string("dir1/file1");
let dir1_file2_path = RepoPath::from_internal_string("dir1/file2");
let dir1_subdir1_path = RepoPath::from_internal_string("dir1/subdir1");
let dir1_subdir1_file1_path = RepoPath::from_internal_string("dir1/subdir1/file1");
let dir2_path = RepoPath::from_internal_string("dir2");
let dir2_file1_path = RepoPath::from_internal_string("dir2/file1");
let tree = create_tree(
repo,
@ -163,11 +163,11 @@ fn test_sparse_commit() {
let op_id = repo.op_id().clone();
let working_copy_path = test_workspace.workspace.workspace_root().clone();
let root_file1_path = &RepoPath::from_internal_string("file1");
let dir1_path = &RepoPath::from_internal_string("dir1");
let dir1_file1_path = &RepoPath::from_internal_string("dir1/file1");
let dir2_path = &RepoPath::from_internal_string("dir2");
let dir2_file1_path = &RepoPath::from_internal_string("dir2/file1");
let root_file1_path = RepoPath::from_internal_string("file1");
let dir1_path = RepoPath::from_internal_string("dir1");
let dir1_file1_path = RepoPath::from_internal_string("dir1/file1");
let dir2_path = RepoPath::from_internal_string("dir2");
let dir2_file1_path = RepoPath::from_internal_string("dir2/file1");
let tree = create_tree(
repo,
@ -239,9 +239,9 @@ fn test_sparse_commit_gitignore() {
let repo = &test_workspace.repo;
let working_copy_path = test_workspace.workspace.workspace_root().clone();
let dir1_path = &RepoPath::from_internal_string("dir1");
let dir1_file1_path = &RepoPath::from_internal_string("dir1/file1");
let dir1_file2_path = &RepoPath::from_internal_string("dir1/file2");
let dir1_path = RepoPath::from_internal_string("dir1");
let dir1_file1_path = RepoPath::from_internal_string("dir1/file1");
let dir1_file2_path = RepoPath::from_internal_string("dir1/file2");
// Set sparse patterns to only dir1/
let mut locked_ws = test_workspace

View file

@ -55,13 +55,13 @@ fn test_same_type() {
if contents != "_" {
testutils::write_normal_file(
&mut tree_builder,
&RepoPath::from_internal_string(path),
RepoPath::from_internal_string(path),
contents,
);
}
}
let tree_id = tree_builder.write_tree();
store.get_tree(&RepoPath::root(), &tree_id).unwrap()
store.get_tree(RepoPath::root(), &tree_id).unwrap()
};
let base_tree = write_tree(0);
@ -116,7 +116,7 @@ fn test_same_type() {
match merged_tree.value(component).unwrap() {
TreeValue::Conflict(id) => {
let conflict = store
.read_conflict(&RepoPath::from_internal_string("_ab"), id)
.read_conflict(RepoPath::from_internal_string("_ab"), id)
.unwrap();
assert_eq!(
conflict.adds().map(|v| v.as_ref()).collect_vec(),
@ -133,7 +133,7 @@ fn test_same_type() {
match merged_tree.value(component).unwrap() {
TreeValue::Conflict(id) => {
let conflict = store
.read_conflict(&RepoPath::from_internal_string("a_b"), id)
.read_conflict(RepoPath::from_internal_string("a_b"), id)
.unwrap();
assert_eq!(
conflict.removes().map(|v| v.as_ref()).collect_vec(),
@ -150,7 +150,7 @@ fn test_same_type() {
match merged_tree.value(component).unwrap() {
TreeValue::Conflict(id) => {
let conflict = store
.read_conflict(&RepoPath::from_internal_string("ab_"), id)
.read_conflict(RepoPath::from_internal_string("ab_"), id)
.unwrap();
assert_eq!(
conflict.removes().map(|v| v.as_ref()).collect_vec(),
@ -167,7 +167,7 @@ fn test_same_type() {
match merged_tree.value(component).unwrap() {
TreeValue::Conflict(id) => {
let conflict = store
.read_conflict(&RepoPath::from_internal_string("abc"), id)
.read_conflict(RepoPath::from_internal_string("abc"), id)
.unwrap();
assert_eq!(
conflict.removes().map(|v| v.as_ref()).collect_vec(),
@ -195,7 +195,7 @@ fn test_executable() {
let write_tree = |files: &[(&str, bool)]| -> Tree {
let mut tree_builder = store.tree_builder(store.empty_tree_id().clone());
for &(path, executable) in files {
let repo_path = &RepoPath::from_internal_string(path);
let repo_path = RepoPath::from_internal_string(path);
if executable {
testutils::write_executable_file(&mut tree_builder, repo_path, "contents");
} else {
@ -203,7 +203,7 @@ fn test_executable() {
}
}
let tree_id = tree_builder.write_tree();
store.get_tree(&RepoPath::root(), &tree_id).unwrap()
store.get_tree(RepoPath::root(), &tree_id).unwrap()
};
fn contents_in_tree<'a>(files: &[&'a str], index: usize) -> Vec<(&'a str, bool)> {
@ -246,12 +246,12 @@ fn test_subtrees() {
for path in paths {
testutils::write_normal_file(
&mut tree_builder,
&RepoPath::from_internal_string(path),
RepoPath::from_internal_string(path),
&format!("contents of {path:?}"),
);
}
let tree_id = tree_builder.write_tree();
store.get_tree(&RepoPath::root(), &tree_id).unwrap()
store.get_tree(RepoPath::root(), &tree_id).unwrap()
};
let base_tree = write_tree(vec!["f1", "d1/f1", "d1/d1/f1", "d1/d1/d1/f1"]);
@ -300,12 +300,12 @@ fn test_subtree_becomes_empty() {
for path in paths {
testutils::write_normal_file(
&mut tree_builder,
&RepoPath::from_internal_string(path),
RepoPath::from_internal_string(path),
&format!("contents of {path:?}"),
);
}
let tree_id = tree_builder.write_tree();
store.get_tree(&RepoPath::root(), &tree_id).unwrap()
store.get_tree(RepoPath::root(), &tree_id).unwrap()
};
let base_tree = write_tree(vec!["f1", "d1/f1", "d1/d1/d1/f1", "d1/d1/d1/f2"]);
@ -329,12 +329,12 @@ fn test_subtree_one_missing() {
for path in paths {
testutils::write_normal_file(
&mut tree_builder,
&RepoPath::from_internal_string(path),
RepoPath::from_internal_string(path),
&format!("contents of {path:?}"),
);
}
let tree_id = tree_builder.write_tree();
store.get_tree(&RepoPath::root(), &tree_id).unwrap()
store.get_tree(RepoPath::root(), &tree_id).unwrap()
};
let tree1 = write_tree(vec![]);
@ -372,40 +372,40 @@ fn test_types() {
let mut side2_tree_builder = store.tree_builder(store.empty_tree_id().clone());
testutils::write_normal_file(
&mut base_tree_builder,
&RepoPath::from_internal_string("normal_executable_symlink"),
RepoPath::from_internal_string("normal_executable_symlink"),
"contents",
);
testutils::write_executable_file(
&mut side1_tree_builder,
&RepoPath::from_internal_string("normal_executable_symlink"),
RepoPath::from_internal_string("normal_executable_symlink"),
"contents",
);
testutils::write_symlink(
&mut side2_tree_builder,
&RepoPath::from_internal_string("normal_executable_symlink"),
RepoPath::from_internal_string("normal_executable_symlink"),
"contents",
);
let tree_id = store.empty_tree_id().clone();
base_tree_builder.set(
RepoPath::from_internal_string("tree_normal_symlink"),
RepoPath::from_internal_string("tree_normal_symlink").to_owned(),
TreeValue::Tree(tree_id),
);
testutils::write_normal_file(
&mut side1_tree_builder,
&RepoPath::from_internal_string("tree_normal_symlink"),
RepoPath::from_internal_string("tree_normal_symlink"),
"contents",
);
testutils::write_symlink(
&mut side2_tree_builder,
&RepoPath::from_internal_string("tree_normal_symlink"),
RepoPath::from_internal_string("tree_normal_symlink"),
"contents",
);
let base_tree_id = base_tree_builder.write_tree();
let base_tree = store.get_tree(&RepoPath::root(), &base_tree_id).unwrap();
let base_tree = store.get_tree(RepoPath::root(), &base_tree_id).unwrap();
let side1_tree_id = side1_tree_builder.write_tree();
let side1_tree = store.get_tree(&RepoPath::root(), &side1_tree_id).unwrap();
let side1_tree = store.get_tree(RepoPath::root(), &side1_tree_id).unwrap();
let side2_tree_id = side2_tree_builder.write_tree();
let side2_tree = store.get_tree(&RepoPath::root(), &side2_tree_id).unwrap();
let side2_tree = store.get_tree(RepoPath::root(), &side2_tree_id).unwrap();
// Created the merged tree
let merged_tree = merge_trees(&side1_tree, &base_tree, &side2_tree).unwrap();
@ -416,7 +416,7 @@ fn test_types() {
TreeValue::Conflict(id) => {
let conflict = store
.read_conflict(
&RepoPath::from_internal_string("normal_executable_symlink"),
RepoPath::from_internal_string("normal_executable_symlink"),
id,
)
.unwrap();
@ -435,7 +435,7 @@ fn test_types() {
match merged_tree.value(component).unwrap() {
TreeValue::Conflict(id) => {
let conflict = store
.read_conflict(&RepoPath::from_internal_string("tree_normal_symlink"), id)
.read_conflict(RepoPath::from_internal_string("tree_normal_symlink"), id)
.unwrap();
assert_eq!(
conflict.removes().map(|v| v.as_ref()).collect_vec(),
@ -457,7 +457,7 @@ fn test_simplify_conflict() {
let store = repo.store();
let component = RepoPathComponent::new("file");
let path = &RepoPath::from_internal_string("file");
let path = RepoPath::from_internal_string("file");
let write_tree = |contents: &str| -> Tree { create_single_tree(repo, &[(path, contents)]) };
let base_tree = write_tree("base contents");
@ -495,7 +495,7 @@ fn test_simplify_conflict() {
match further_rebased_tree.value(component).unwrap() {
TreeValue::Conflict(id) => {
let conflict = store
.read_conflict(&RepoPath::from_internal_string(component.as_str()), id)
.read_conflict(RepoPath::from_internal_string(component.as_str()), id)
.unwrap();
assert_eq!(
conflict.removes().map(|v| v.as_ref()).collect_vec(),
@ -550,7 +550,7 @@ fn test_simplify_conflict_after_resolving_parent() {
// which creates a conflict. We resolve the conflict in the first line and
// rebase C2 (the rebased C) onto the resolved conflict. C3 should not have
// a conflict since it changed an unrelated line.
let path = &RepoPath::from_internal_string("dir/file");
let path = RepoPath::from_internal_string("dir/file");
let mut tx = repo.start_transaction(&settings, "test");
let tree_a = create_tree(repo, &[(path, "abc\ndef\nghi\n")]);
let commit_a = tx

View file

@ -57,12 +57,12 @@ fn test_from_legacy_tree() {
let mut tree_builder = store.tree_builder(repo.store().empty_tree_id().clone());
// file1: regular file without conflicts
let file1_path = &RepoPath::from_internal_string("no_conflict");
let file1_path = RepoPath::from_internal_string("no_conflict");
let file1_id = write_file(store.as_ref(), file1_path, "foo");
tree_builder.set(file1_path.to_owned(), file_value(&file1_id));
// file2: 3-way conflict
let file2_path = &RepoPath::from_internal_string("3way");
let file2_path = RepoPath::from_internal_string("3way");
let file2_v1_id = write_file(store.as_ref(), file2_path, "file2_v1");
let file2_v2_id = write_file(store.as_ref(), file2_path, "file2_v2");
let file2_v3_id = write_file(store.as_ref(), file2_path, "file2_v3");
@ -80,7 +80,7 @@ fn test_from_legacy_tree() {
);
// file3: modify/delete conflict
let file3_path = &RepoPath::from_internal_string("modify_delete");
let file3_path = RepoPath::from_internal_string("modify_delete");
let file3_v1_id = write_file(store.as_ref(), file3_path, "file3_v1");
let file3_v2_id = write_file(store.as_ref(), file3_path, "file3_v2");
let file3_conflict = Merge::from_removes_adds(
@ -94,7 +94,7 @@ fn test_from_legacy_tree() {
);
// file4: add/add conflict
let file4_path = &RepoPath::from_internal_string("add_add");
let file4_path = RepoPath::from_internal_string("add_add");
let file4_v1_id = write_file(store.as_ref(), file4_path, "file4_v1");
let file4_v2_id = write_file(store.as_ref(), file4_path, "file4_v2");
let file4_conflict = Merge::from_removes_adds(
@ -111,7 +111,7 @@ fn test_from_legacy_tree() {
);
// file5: 5-way conflict
let file5_path = &RepoPath::from_internal_string("5way");
let file5_path = RepoPath::from_internal_string("5way");
let file5_v1_id = write_file(store.as_ref(), file5_path, "file5_v1");
let file5_v2_id = write_file(store.as_ref(), file5_path, "file5_v2");
let file5_v3_id = write_file(store.as_ref(), file5_path, "file5_v3");
@ -143,7 +143,7 @@ fn test_from_legacy_tree() {
tree_builder.set(dir1_filename.to_owned(), file_value(&dir1_filename_id));
let tree_id = tree_builder.write_tree();
let tree = store.get_tree(&RepoPath::root(), &tree_id).unwrap();
let tree = store.get_tree(RepoPath::root(), &tree_id).unwrap();
let merged_tree = MergedTree::from_legacy_tree(tree.clone()).unwrap();
assert_eq!(
@ -260,13 +260,13 @@ fn test_path_value_and_entries() {
let repo = &test_repo.repo;
// Create a MergedTree
let resolved_file_path = &RepoPath::from_internal_string("dir1/subdir/resolved");
let resolved_file_path = RepoPath::from_internal_string("dir1/subdir/resolved");
let resolved_dir_path = &resolved_file_path.parent().unwrap();
let conflicted_file_path = &RepoPath::from_internal_string("dir2/conflicted");
let missing_path = &RepoPath::from_internal_string("dir2/missing_file");
let modify_delete_path = &RepoPath::from_internal_string("dir2/modify_delete");
let file_dir_conflict_path = &RepoPath::from_internal_string("file_dir");
let file_dir_conflict_sub_path = &RepoPath::from_internal_string("file_dir/file");
let conflicted_file_path = RepoPath::from_internal_string("dir2/conflicted");
let missing_path = RepoPath::from_internal_string("dir2/missing_file");
let modify_delete_path = RepoPath::from_internal_string("dir2/modify_delete");
let file_dir_conflict_path = RepoPath::from_internal_string("file_dir");
let file_dir_conflict_sub_path = RepoPath::from_internal_string("file_dir/file");
let tree1 = create_single_tree(
repo,
&[
@ -301,7 +301,7 @@ fn test_path_value_and_entries() {
// Get the root tree
assert_eq!(
merged_tree.path_value(&RepoPath::root()),
merged_tree.path_value(RepoPath::root()),
Merge::from_removes_adds(
vec![Some(TreeValue::Tree(tree1.id().clone()))],
vec![
@ -384,13 +384,13 @@ fn test_resolve_success() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let unchanged_path = &RepoPath::from_internal_string("unchanged");
let trivial_file_path = &RepoPath::from_internal_string("trivial-file");
let trivial_hunk_path = &RepoPath::from_internal_string("trivial-hunk");
let both_added_dir_path = &RepoPath::from_internal_string("added-dir");
let unchanged_path = RepoPath::from_internal_string("unchanged");
let trivial_file_path = RepoPath::from_internal_string("trivial-file");
let trivial_hunk_path = RepoPath::from_internal_string("trivial-hunk");
let both_added_dir_path = RepoPath::from_internal_string("added-dir");
let both_added_dir_file1_path = &both_added_dir_path.join(RepoPathComponent::new("file1"));
let both_added_dir_file2_path = &both_added_dir_path.join(RepoPathComponent::new("file2"));
let emptied_dir_path = &RepoPath::from_internal_string("to-become-empty");
let emptied_dir_path = RepoPath::from_internal_string("to-become-empty");
let emptied_dir_file1_path = &emptied_dir_path.join(RepoPathComponent::new("file1"));
let emptied_dir_file2_path = &emptied_dir_path.join(RepoPathComponent::new("file2"));
let base1 = create_single_tree(
@ -452,8 +452,8 @@ fn test_resolve_root_becomes_empty() {
let repo = &test_repo.repo;
let store = repo.store();
let path1 = &RepoPath::from_internal_string("dir1/file");
let path2 = &RepoPath::from_internal_string("dir2/file");
let path1 = RepoPath::from_internal_string("dir1/file");
let path2 = RepoPath::from_internal_string("dir2/file");
let base1 = create_single_tree(repo, &[(path1, "base1"), (&path2, "base1")]);
let side1 = create_single_tree(repo, &[(path2, "base1")]);
let side2 = create_single_tree(repo, &[(path1, "base1")]);
@ -470,8 +470,8 @@ fn test_resolve_with_conflict() {
// The trivial conflict should be resolved but the non-trivial should not (and
// cannot)
let trivial_path = &RepoPath::from_internal_string("dir1/trivial");
let conflict_path = &RepoPath::from_internal_string("dir2/file_conflict");
let trivial_path = RepoPath::from_internal_string("dir1/trivial");
let conflict_path = RepoPath::from_internal_string("dir2/file_conflict");
let base1 = create_single_tree(repo, &[(trivial_path, "base1"), (conflict_path, "base1")]);
let side1 = create_single_tree(repo, &[(trivial_path, "side1"), (conflict_path, "side1")]);
let side2 = create_single_tree(repo, &[(trivial_path, "base1"), (conflict_path, "side2")]);
@ -495,16 +495,16 @@ fn test_conflict_iterator() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let unchanged_path = &RepoPath::from_internal_string("dir/subdir/unchanged");
let trivial_path = &RepoPath::from_internal_string("dir/subdir/trivial");
let trivial_hunk_path = &RepoPath::from_internal_string("dir/non_trivial");
let file_conflict_path = &RepoPath::from_internal_string("dir/subdir/file_conflict");
let modify_delete_path = &RepoPath::from_internal_string("dir/subdir/modify_delete");
let same_add_path = &RepoPath::from_internal_string("dir/subdir/same_add");
let different_add_path = &RepoPath::from_internal_string("dir/subdir/different_add");
let dir_file_path = &RepoPath::from_internal_string("dir/subdir/dir_file");
let added_dir_path = &RepoPath::from_internal_string("dir/new_dir");
let modify_delete_dir_path = &RepoPath::from_internal_string("dir/modify_delete_dir");
let unchanged_path = RepoPath::from_internal_string("dir/subdir/unchanged");
let trivial_path = RepoPath::from_internal_string("dir/subdir/trivial");
let trivial_hunk_path = RepoPath::from_internal_string("dir/non_trivial");
let file_conflict_path = RepoPath::from_internal_string("dir/subdir/file_conflict");
let modify_delete_path = RepoPath::from_internal_string("dir/subdir/modify_delete");
let same_add_path = RepoPath::from_internal_string("dir/subdir/same_add");
let different_add_path = RepoPath::from_internal_string("dir/subdir/different_add");
let dir_file_path = RepoPath::from_internal_string("dir/subdir/dir_file");
let added_dir_path = RepoPath::from_internal_string("dir/new_dir");
let modify_delete_dir_path = RepoPath::from_internal_string("dir/modify_delete_dir");
let base1 = create_single_tree(
repo,
&[
@ -629,8 +629,8 @@ fn test_conflict_iterator_higher_arity() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let two_sided_path = &RepoPath::from_internal_string("dir/2-sided");
let three_sided_path = &RepoPath::from_internal_string("dir/3-sided");
let two_sided_path = RepoPath::from_internal_string("dir/2-sided");
let three_sided_path = RepoPath::from_internal_string("dir/3-sided");
let base1 = create_single_tree(
repo,
&[(two_sided_path, "base1"), (three_sided_path, "base1")],
@ -706,10 +706,10 @@ fn test_diff_resolved() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let clean_path = &RepoPath::from_internal_string("dir1/file");
let modified_path = &RepoPath::from_internal_string("dir2/file");
let removed_path = &RepoPath::from_internal_string("dir3/file");
let added_path = &RepoPath::from_internal_string("dir4/file");
let clean_path = RepoPath::from_internal_string("dir1/file");
let modified_path = RepoPath::from_internal_string("dir2/file");
let removed_path = RepoPath::from_internal_string("dir3/file");
let added_path = RepoPath::from_internal_string("dir4/file");
let before = create_single_tree(
repo,
&[
@ -777,10 +777,10 @@ fn test_diff_conflicted() {
// path2 is a conflict before and different conflict after
// path3 is resolved before and a conflict after
// path4 is missing before and a conflict after
let path1 = &RepoPath::from_internal_string("dir1/file");
let path2 = &RepoPath::from_internal_string("dir2/file");
let path3 = &RepoPath::from_internal_string("dir4/file");
let path4 = &RepoPath::from_internal_string("dir6/file");
let path1 = RepoPath::from_internal_string("dir1/file");
let path2 = RepoPath::from_internal_string("dir2/file");
let path3 = RepoPath::from_internal_string("dir4/file");
let path4 = RepoPath::from_internal_string("dir6/file");
let left_base = create_single_tree(
repo,
&[(path1, "clean-base"), (path2, "left-base"), (path3, "left")],
@ -882,12 +882,12 @@ fn test_diff_dir_file() {
// path4: file1+(file2-file3) -> directory1+(directory2-directory3)
// path5: directory1 -> file1+(file2-absent)
// path6: directory1 -> file1+(directory1-absent)
let path1 = &RepoPath::from_internal_string("path1");
let path2 = &RepoPath::from_internal_string("path2");
let path3 = &RepoPath::from_internal_string("path3");
let path4 = &RepoPath::from_internal_string("path4");
let path5 = &RepoPath::from_internal_string("path5");
let path6 = &RepoPath::from_internal_string("path6");
let path1 = RepoPath::from_internal_string("path1");
let path2 = RepoPath::from_internal_string("path2");
let path3 = RepoPath::from_internal_string("path3");
let path4 = RepoPath::from_internal_string("path4");
let path5 = RepoPath::from_internal_string("path5");
let path6 = RepoPath::from_internal_string("path6");
let file = RepoPathComponent::new("file");
let left_base = create_single_tree(
repo,
@ -1176,8 +1176,8 @@ fn test_merge_simple() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let path1 = &RepoPath::from_internal_string("dir1/file");
let path2 = &RepoPath::from_internal_string("dir2/file");
let path1 = RepoPath::from_internal_string("dir1/file");
let path2 = RepoPath::from_internal_string("dir2/file");
let base1 = create_single_tree(repo, &[(path1, "base"), (path2, "base")]);
let side1 = create_single_tree(repo, &[(path1, "side1"), (path2, "base")]);
let side2 = create_single_tree(repo, &[(path1, "base"), (path2, "side2")]);
@ -1198,8 +1198,8 @@ fn test_merge_partial_resolution() {
let repo = &test_repo.repo;
// path1 can be resolved, path2 cannot
let path1 = &RepoPath::from_internal_string("dir1/file");
let path2 = &RepoPath::from_internal_string("dir2/file");
let path1 = RepoPath::from_internal_string("dir1/file");
let path2 = RepoPath::from_internal_string("dir2/file");
let base1 = create_single_tree(repo, &[(path1, "base"), (path2, "base")]);
let side1 = create_single_tree(repo, &[(path1, "side1"), (path2, "side1")]);
let side2 = create_single_tree(repo, &[(path1, "base"), (path2, "side2")]);
@ -1224,11 +1224,11 @@ fn test_merge_with_empty_legacy_tree() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let path1 = &RepoPath::from_internal_string("dir1/file");
let path2 = &RepoPath::from_internal_string("dir2/file");
let path1 = RepoPath::from_internal_string("dir1/file");
let path2 = RepoPath::from_internal_string("dir2/file");
let base1 = repo
.store()
.get_tree(&RepoPath::root(), repo.store().empty_tree_id())
.get_tree(RepoPath::root(), repo.store().empty_tree_id())
.unwrap();
let side1 = create_single_tree(repo, &[(path1, "side1")]);
let side2 = create_single_tree(repo, &[(path2, "side2")]);
@ -1249,7 +1249,7 @@ fn test_merge_simplify_only() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let path = &RepoPath::from_internal_string("dir1/file");
let path = RepoPath::from_internal_string("dir1/file");
let tree1 = create_single_tree(repo, &[(path, "1")]);
let tree2 = create_single_tree(repo, &[(path, "2")]);
let tree3 = create_single_tree(repo, &[(path, "3")]);
@ -1283,8 +1283,8 @@ fn test_merge_simplify_result() {
let repo = &test_repo.repo;
// The conflict in path1 cannot be resolved, but the conflict in path2 can.
let path1 = &RepoPath::from_internal_string("dir1/file");
let path2 = &RepoPath::from_internal_string("dir2/file");
let path1 = RepoPath::from_internal_string("dir1/file");
let path2 = RepoPath::from_internal_string("dir2/file");
let tree1 = create_single_tree(repo, &[(path1, "1"), (path2, "1")]);
let tree2 = create_single_tree(repo, &[(path1, "2"), (path2, "2")]);
let tree3 = create_single_tree(repo, &[(path1, "3"), (path2, "3")]);
@ -1318,8 +1318,8 @@ fn test_merge_simplify_file_conflict() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let conflict_path = &RepoPath::from_internal_string("CHANGELOG.md");
let other_path = &RepoPath::from_internal_string("other");
let conflict_path = RepoPath::from_internal_string("CHANGELOG.md");
let other_path = RepoPath::from_internal_string("other");
let prefix = r#"### New features

View file

@ -2583,9 +2583,9 @@ fn test_evaluate_expression_file() {
let mut tx = repo.start_transaction(&settings, "test");
let mut_repo = tx.mut_repo();
let added_clean_clean = &RepoPath::from_internal_string("added_clean_clean");
let added_modified_clean = &RepoPath::from_internal_string("added_modified_clean");
let added_modified_removed = &RepoPath::from_internal_string("added_modified_removed");
let added_clean_clean = RepoPath::from_internal_string("added_clean_clean");
let added_modified_clean = RepoPath::from_internal_string("added_modified_clean");
let added_modified_removed = RepoPath::from_internal_string("added_modified_removed");
let tree1 = create_tree(
repo,
&[
@ -2692,8 +2692,8 @@ fn test_evaluate_expression_conflict() {
let mut_repo = tx.mut_repo();
// Create a few trees, including one with a conflict in `file1`
let file_path1 = &RepoPath::from_internal_string("file1");
let file_path2 = &RepoPath::from_internal_string("file2");
let file_path1 = RepoPath::from_internal_string("file1");
let file_path2 = RepoPath::from_internal_string("file2");
let tree1 = create_tree(repo, &[(file_path1, "1"), (file_path2, "1")]);
let tree2 = create_tree(repo, &[(file_path1, "2"), (file_path2, "2")]);
let tree3 = create_tree(repo, &[(file_path1, "3"), (file_path2, "1")]);

View file

@ -34,10 +34,10 @@ fn test_restore_tree() {
let test_repo = TestRepo::init();
let repo = &test_repo.repo;
let path1 = &RepoPath::from_internal_string("file1");
let path2 = &RepoPath::from_internal_string("dir1/file2");
let path3 = &RepoPath::from_internal_string("dir1/file3");
let path4 = &RepoPath::from_internal_string("dir2/file4");
let path1 = RepoPath::from_internal_string("file1");
let path2 = RepoPath::from_internal_string("dir1/file2");
let path3 = RepoPath::from_internal_string("dir1/file3");
let path4 = RepoPath::from_internal_string("dir2/file4");
let left = create_tree(repo, &[(path2, "left"), (path3, "left"), (path4, "left")]);
let right = create_tree(
repo,
@ -877,7 +877,7 @@ fn test_rebase_descendants_contents() {
// |/
// A
let mut tx = repo.start_transaction(&settings, "test");
let path1 = &RepoPath::from_internal_string("file1");
let path1 = RepoPath::from_internal_string("file1");
let tree1 = create_tree(repo, &[(path1, "content")]);
let commit_a = tx
.mut_repo()
@ -888,21 +888,21 @@ fn test_rebase_descendants_contents() {
)
.write()
.unwrap();
let path2 = &RepoPath::from_internal_string("file2");
let path2 = RepoPath::from_internal_string("file2");
let tree2 = create_tree(repo, &[(path2, "content")]);
let commit_b = tx
.mut_repo()
.new_commit(&settings, vec![commit_a.id().clone()], tree2.id())
.write()
.unwrap();
let path3 = &RepoPath::from_internal_string("file3");
let path3 = RepoPath::from_internal_string("file3");
let tree3 = create_tree(repo, &[(path3, "content")]);
let commit_c = tx
.mut_repo()
.new_commit(&settings, vec![commit_b.id().clone()], tree3.id())
.write()
.unwrap();
let path4 = &RepoPath::from_internal_string("file4");
let path4 = RepoPath::from_internal_string("file4");
let tree4 = create_tree(repo, &[(path4, "content")]);
let commit_d = tx
.mut_repo()
@ -1527,11 +1527,7 @@ fn test_empty_commit_option(empty: EmptyBehaviour) {
.iter()
.map(|&p| (RepoPath::from_internal_string(p), p))
.collect_vec();
let content_map_ref = content_map
.iter()
.map(|(path, content)| (path, *content))
.collect_vec();
create_tree(repo, &content_map_ref)
create_tree(repo, &content_map)
};
// The commit_with_parents function generates non-empty merge commits, so it

View file

@ -288,7 +288,7 @@ pub fn create_single_tree(repo: &Arc<ReadonlyRepo>, path_contents: &[(&RepoPath,
write_normal_file(&mut tree_builder, path, contents);
}
let id = tree_builder.write_tree();
store.get_tree(&RepoPath::root(), &id).unwrap()
store.get_tree(RepoPath::root(), &id).unwrap()
}
pub fn create_tree(repo: &Arc<ReadonlyRepo>, path_contents: &[(&RepoPath, &str)]) -> MergedTree {