History

First portion of reading the untracked cache (#293)

A lot of dynamic elements are still to be done though.

Sebastian Thiel committed 4 years ago

Commit ed2fe5d1 parent 223f2cc4 files · +84 −9Browse files

Unified · Split

4 files
  1. etc/check-package-size.sh +1 −1
  2. git-index/src/extension/decode.rs +3 −3
  3. git-index/src/extension/mod.rs +79 −4
  4. git-index/src/lib.rs +1 −1
etc/check-package-size.sh+1−1
@@ -18,7 +18,7 @@ echo "in root: gitoxide CLI" · 17 unmodified lines
18#indent cargo diet -n --package-size-limit 25KB - fails right now because of dotted profile.dev.package18#indent cargo diet -n --package-size-limit 25KB - fails right now because of dotted profile.dev.package
19(enter cargo-smart-release && indent cargo diet -n --package-size-limit 85KB)19(enter cargo-smart-release && indent cargo diet -n --package-size-limit 85KB)
20(enter git-actor && indent cargo diet -n --package-size-limit 5KB)20(enter git-actor && indent cargo diet -n --package-size-limit 5KB)
21(enter git-index && indent cargo diet -n --package-size-limit 15KB)21(enter git-index && indent cargo diet -n --package-size-limit 20KB)
22(enter git-bitmap && indent cargo diet -n --package-size-limit 5KB)22(enter git-bitmap && indent cargo diet -n --package-size-limit 5KB)
23(enter git-tempfile && indent cargo diet -n --package-size-limit 25KB)23(enter git-tempfile && indent cargo diet -n --package-size-limit 25KB)
24(enter git-lock && indent cargo diet -n --package-size-limit 15KB)24(enter git-lock && indent cargo diet -n --package-size-limit 15KB)
git-index/src/extension/decode.rs+3−3
@@ -41,8 +41,8 @@ pub fn all(maybe_beginning_of_extensions: &[u8], object_hash: git_hash::Kind) -> · 40 unmodified lines
41 extension::resolve_undo::SIGNATURE => {41 extension::resolve_undo::SIGNATURE => {
42 ext.resolve_undo = extension::resolve_undo::decode(ext_data, object_hash);42 ext.resolve_undo = extension::resolve_undo::decode(ext_data, object_hash);
43 }43 }
44 extension::untracked::SIGNATURE => {44 extension::untracked_cache::SIGNATURE => {
45 ext.untracked = extension::untracked::decode(ext_data, object_hash);45 ext.untracked = extension::untracked_cache::decode(ext_data, object_hash);
46 }46 }
47 extension::end_of_index_entry::SIGNATURE => {} // skip already done47 extension::end_of_index_entry::SIGNATURE => {} // skip already done
48 extension::index_entry_offset_table::SIGNATURE => {} // not relevant/obtained already48 extension::index_entry_offset_table::SIGNATURE => {} // not relevant/obtained already
@@ -68,6 +68,6 @@ pub struct Outcome { · 19 unmodified lines
68 pub tree: Option<extension::Tree>,68 pub tree: Option<extension::Tree>,
69 pub link: Option<extension::Link>,69 pub link: Option<extension::Link>,
70 pub resolve_undo: Option<extension::resolve_undo::Paths>,70 pub resolve_undo: Option<extension::resolve_undo::Paths>,
71 pub untracked: Option<extension::Untracked>,71 pub untracked: Option<extension::UntrackedCache>,
72 pub is_sparse: bool,72 pub is_sparse: bool,
73}73}
git-index/src/extension/mod.rs+79−4
@@ -1,3 +1,4 @@
1use bstr::BString;
1use smallvec::SmallVec;2use smallvec::SmallVec;
2 3
3const MIN_SIZE: usize = 4 /* signature */ + 4 /* size */;4const MIN_SIZE: usize = 4 /* signature */ + 4 /* size */;
@@ -25,7 +26,18 @@ pub struct Link { · 21 unmodified lines
25 pub bitmaps: Option<link::Bitmaps>,26 pub bitmaps: Option<link::Bitmaps>,
26}27}
27 28
28pub struct Untracked;29pub struct UntrackedCache {
30 /// Something identifying the location and machine that this cache is for.
31 /// Should the repository be copied to a different machine, the entire cache can immediately be invalidated.
32 identifier: BString,
33 /// Stat for the .git/info/exclude file
34 info_exclude: Option<untracked_cache::OidStat>,
35 /// Stat for the `core.excludesfile`
36 excludes_file: Option<untracked_cache::OidStat>,
37 /// Usually `.gitignore`
38 exclude_filename_per_dir: BString,
39 dir_flags: u32,
40}
29 41
30mod iter;42mod iter;
31 43
@@ -41,15 +53,78 @@ pub mod link; · 9 unmodified lines
41 53
42pub(crate) mod resolve_undo;54pub(crate) mod resolve_undo;
43 55
44pub(crate) mod untracked {56pub mod untracked_cache {
45 use crate::extension::{Signature, Untracked};57 use crate::entry;
58 use crate::extension::{Signature, UntrackedCache};
59 use crate::util::{read_u32, split_at_byte_exclusive, split_at_pos};
60 use git_hash::ObjectId;
61
62 pub struct OidStat {
63 pub mtime: entry::Time,
64 pub ctime: entry::Time,
65 pub dev: u32,
66 pub ino: u32,
67 pub uid: u32,
68 pub gid: u32,
69 /// The size of bytes on disk. Capped to u32 so files bigger than that will need thorough checking (and hopefully never make it)
70 pub size: u32,
71 pub id: ObjectId,
72 }
46 73
47 /// Only used as an indicator74 /// Only used as an indicator
48 pub const SIGNATURE: Signature = *b"UNTR";75 pub const SIGNATURE: Signature = *b"UNTR";
49 76
50 pub fn decode(_data: &[u8], _object_hash: git_hash::Kind) -> Option<Untracked> {77 #[allow(unused)]
78 pub fn decode(data: &[u8], object_hash: git_hash::Kind) -> Option<UntrackedCache> {
79 if !data.last().map(|b| *b == 0).unwrap_or(false) {
80 return None;
81 }
82 let (identifier_len, consumed) = git_features::decode::leb64(data);
83 let (_, data) = data.split_at(consumed);
84 let (identifier, data) = split_at_pos(data, identifier_len.try_into().ok()?)?;
85 dbg!(String::from_utf8_lossy(identifier));
86
87 let hash_len = object_hash.len_in_bytes();
88 let (info_exclude, data) = decode_oid_stat(data, hash_len)?;
89 let (excludes_file, data) = decode_oid_stat(data, hash_len)?;
90 let (dir_flags, data) = read_u32(data)?;
91 let (exclude_filename_per_dir, data) = split_at_byte_exclusive(data, 0)?;
92 dbg!(String::from_utf8_lossy(exclude_filename_per_dir));
93
51 todo!("decode UNTR")94 todo!("decode UNTR")
52 }95 }
96
97 fn decode_oid_stat(data: &[u8], hash_len: usize) -> Option<(OidStat, &[u8])> {
98 let (ctime_secs, data) = read_u32(data)?;
99 let (ctime_nsecs, data) = read_u32(data)?;
100 let (mtime_secs, data) = read_u32(data)?;
101 let (mtime_nsecs, data) = read_u32(data)?;
102 let (dev, data) = read_u32(data)?;
103 let (ino, data) = read_u32(data)?;
104 let (uid, data) = read_u32(data)?;
105 let (gid, data) = read_u32(data)?;
106 let (size, data) = read_u32(data)?;
107 let (hash, data) = split_at_pos(data, hash_len)?;
108 Some((
109 OidStat {
110 mtime: entry::Time {
111 secs: ctime_secs,
112 nsecs: ctime_nsecs,
113 },
114 ctime: entry::Time {
115 secs: mtime_secs,
116 nsecs: mtime_nsecs,
117 },
118 dev,
119 ino,
120 uid,
121 gid,
122 size,
123 id: ObjectId::from(hash),
124 },
125 data,
126 ))
127 }
53}128}
54 129
55pub mod sparse {130pub mod sparse {
git-index/src/lib.rs+1−1
@@ -76,7 +76,7 @@ pub struct State { · 75 unmodified lines
76 tree: Option<extension::Tree>,76 tree: Option<extension::Tree>,
77 link: Option<extension::Link>,77 link: Option<extension::Link>,
78 resolve_undo: Option<extension::resolve_undo::Paths>,78 resolve_undo: Option<extension::resolve_undo::Paths>,
79 untracked: Option<extension::Untracked>,79 untracked: Option<extension::UntrackedCache>,
80}80}
81 81
82pub(crate) mod util {82pub(crate) mod util {