History

wire everything up to have all data where it needs to be, but… (#301)

proper error handling needs more bounds on error E which can be done but really is a lot of typing. Nothing to be done here except for doing it I guess.

Sebastian Thiel committed 4 years ago

Commit 34d0d5c1 parent 883d78d6 files · +100 −37Browse files

Showing the changes to git-worktree/src (5 of 6 files). Show all

Unified · Split

5 files
  1. git-worktree/src/fs/cache/mod.rs +11 −4
  2. git-worktree/src/fs/cache/platform.rs +13 −2
  3. git-worktree/src/fs/cache/state.rs +34 −9
  4. git-worktree/src/fs/mod.rs +2 −2
  5. git-worktree/src/index/entry.rs +1 −1
git-worktree/src/fs/cache/mod.rs+11−4
@@ -1,6 +1,7 @@
11 use super::Cache;
22 use crate::fs;
3−use crate::fs::PathIdMapping;
3+use crate::fs::PathOidMapping;
4+use git_hash::oid;
45 use std::path::{Path, PathBuf};
56
67 #[derive(Clone)]
@@ -66,7 +67,7 @@ impl<'paths> Cache<'paths> { · 59 unmodified lines
6667 state: State,
6768 case: git_glob::pattern::Case,
6869 buf: Vec<u8>,
69− attribute_files_in_index: Vec<PathIdMapping<'paths>>,
70+ attribute_files_in_index: Vec<PathOidMapping<'paths>>,
7071 ) -> Self {
7172 let root = worktree_root.into();
7273 Cache {
@@ -83,15 +84,21 @@ impl<'paths> Cache<'paths> { · 10 unmodified lines
8384 /// path is created as directory. If it's not known it is assumed to be a file.
8485 ///
8586 /// Provide access to cached information for that `relative` entry via the platform returned.
86− pub fn at_entry(
87+ pub fn at_entry<Find, E>(
8788 &mut self,
8889 relative: impl AsRef<Path>,
8990 is_dir: Option<bool>,
90− ) -> std::io::Result<Platform<'_, 'paths>> {
91+ find: Find,
92+ ) -> std::io::Result<Platform<'_, 'paths>>
93+ where
94+ Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Result<git_object::BlobRef<'a>, E>,
95+ {
9196 let mut platform = platform::StackDelegate {
9297 state: &mut self.state,
9398 buf: &mut self.buf,
9499 is_dir,
100+ attribute_files_in_index: &self.attribute_files_in_index,
101+ find,
95102 };
96103 self.stack.make_relative_path_current(relative, &mut platform)?;
97104 Ok(Platform { parent: self, is_dir })
git-worktree/src/fs/cache/platform.rs+13−2
@@ -1,5 +1,7 @@
11 use crate::fs;
22 use crate::fs::cache::{Platform, State};
3+use crate::fs::PathOidMapping;
4+use git_hash::oid;
35 use std::path::Path;
46
57 impl<'a, 'paths> Platform<'a, 'paths> {
@@ -43,13 +45,18 @@ impl<'a, 'paths> std::fmt::Debug for Platform<'a, 'paths> { · 37 unmodified lines
4345 }
4446 }
4547
46−pub struct StackDelegate<'a> {
48+pub struct StackDelegate<'a, 'paths, Find> {
4749 pub state: &'a mut State,
4850 pub buf: &'a mut Vec<u8>,
4951 pub is_dir: Option<bool>,
52+ pub attribute_files_in_index: &'a Vec<PathOidMapping<'paths>>,
53+ pub find: Find,
5054 }
5155
52−impl<'a> fs::stack::Delegate for StackDelegate<'a> {
56+impl<'a, 'paths, Find, E> fs::stack::Delegate for StackDelegate<'a, 'paths, Find>
57+where
58+ Find: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Result<git_object::BlobRef<'b>, E>,
59+{
5360 fn push(&mut self, is_last_component: bool, stack: &fs::Stack) -> std::io::Result<()> {
5461 match &mut self.state {
5562 State::CreateDirectoryAndAttributesStack {
@@ -77,11 +84,15 @@ impl<'a> fs::stack::Delegate for StackDelegate<'a> { · 21 unmodified lines
7784 &stack.root,
7885 stack.current.parent().expect("component was just pushed"),
7986 self.buf,
87+ self.attribute_files_in_index,
88+ &mut self.find,
8089 )?,
8190 State::IgnoreStack(ignore) => ignore.push(
8291 &stack.root,
8392 stack.current.parent().expect("component was just pushed"),
8493 self.buf,
94+ self.attribute_files_in_index,
95+ &mut self.find,
8596 )?,
8697 }
8798 Ok(())
git-worktree/src/fs/cache/state.rs+34−9
@@ -1,7 +1,8 @@
11 use crate::fs::cache::{state, State};
2−use crate::fs::PathIdMapping;
2+use crate::fs::PathOidMapping;
33 use bstr::{BStr, BString, ByteSlice};
44 use git_glob::pattern::Case;
5+use git_hash::oid;
56 use std::path::Path;
67
78 type AttributeMatchGroup = git_attributes::MatchGroup<git_attributes::Attributes>;
@@ -51,16 +52,40 @@ impl Ignore { · 43 unmodified lines
5152 }
5253 }
5354
54− pub fn push(&mut self, root: &Path, dir: &Path, buf: &mut Vec<u8>) -> std::io::Result<()> {
55− let follow_symlinks = true;
55+ pub fn push<Find, E>(
56+ &mut self,
57+ root: &Path,
58+ dir: &Path,
59+ buf: &mut Vec<u8>,
60+ attribute_files_in_index: &Vec<PathOidMapping<'_>>,
61+ _find: Find,
62+ ) -> std::io::Result<()>
63+ where
64+ Find: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Result<git_object::BlobRef<'b>, E>,
65+ {
66+ let ignore_path = git_features::path::convert::to_unix_separators(
67+ git_features::path::into_bytes_or_panic_on_windows(dir.join(".gitignore")),
68+ );
69+ let ignore_file_in_index = attribute_files_in_index.binary_search_by(|t| t.0.cmp(ignore_path.as_bstr()));
70+ let ignore_path = git_features::path::from_byte_vec_or_panic_on_windows(ignore_path);
71+ let follow_symlinks = ignore_file_in_index.is_err();
5672 if !self
5773 .stack
58− .add_patterns_file(dir.join(".gitignore"), follow_symlinks, Some(root), buf)?
74+ .add_patterns_file(ignore_path, follow_symlinks, Some(root), buf)?
5975 {
60− // Need one stack level per component so push and pop matches.
61− self.stack.patterns.push(Default::default());
76+ match ignore_file_in_index {
77+ Ok(_idx) => {
78+ // let ignore_blob = find(&attribute_files_in_index[0].1, buf)
79+ // .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?;
80+ // self.stack.add_patterns_buffer(ignore_blob.data);
81+ todo!()
82+ }
83+ Err(_) => {
84+ // Need one stack level per component so push and pop matches.
85+ self.stack.patterns.push(Default::default())
86+ }
87+ }
6288 }
63− // TODO: from index
6489 Ok(())
6590 }
6691 }
@@ -108,12 +133,12 @@ impl State { · 41 unmodified lines
108133 /// - ignores entries which aren't blobs
109134 /// - ignores ignore entries which are not skip-worktree
110135 /// - within merges, picks 'our' stage both for ignore and attribute files.
111− pub(crate) fn build_attribute_list<'paths>(
136+ pub fn build_attribute_list<'paths>(
112137 &self,
113138 index: &git_index::State,
114139 paths: &'paths git_index::PathStorage,
115140 case: git_glob::pattern::Case,
116− ) -> Vec<PathIdMapping<'paths>> {
141+ ) -> Vec<PathOidMapping<'paths>> {
117142 let a1_backing;
118143 let a2_backing;
119144 let names = match self {
git-worktree/src/fs/mod.rs+2−2
@@ -65,10 +65,10 @@ pub struct Cache<'paths> { · 64 unmodified lines
6565 /// If case folding should happen when looking up attributes or exclusions.
6666 case: git_glob::pattern::Case,
6767 /// A lookup table for object ids to read from in some situations when looking up attributes or exclusions.
68− attribute_files_in_index: Vec<PathIdMapping<'paths>>,
68+ attribute_files_in_index: Vec<PathOidMapping<'paths>>,
6969 }
7070
71−pub(crate) type PathIdMapping<'paths> = (&'paths BStr, git_hash::ObjectId);
71+pub(crate) type PathOidMapping<'paths> = (&'paths BStr, git_hash::ObjectId);
7272
7373 ///
7474 pub mod cache;
git-worktree/src/index/entry.rs+1−1
@@ -38,7 +38,7 @@ where · 37 unmodified lines
3838 path: entry_path.to_owned(),
3939 })?;
4040 let is_dir = Some(entry.mode == git_index::entry::Mode::COMMIT || entry.mode == git_index::entry::Mode::DIR);
41− let dest = path_cache.at_entry(dest_relative, is_dir)?.path();
41+ let dest = path_cache.at_entry(dest_relative, is_dir, &mut *find)?.path();
4242
4343 let object_size = match entry.mode {
4444 git_index::entry::Mode::FILE | git_index::entry::Mode::FILE_EXECUTABLE => {