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
1818 #indent cargo diet -n --package-size-limit 25KB - fails right now because of dotted profile.dev.package
1919 (enter cargo-smart-release && indent cargo diet -n --package-size-limit 85KB)
2020 (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)
2222 (enter git-bitmap && indent cargo diet -n --package-size-limit 5KB)
2323 (enter git-tempfile && indent cargo diet -n --package-size-limit 25KB)
2424 (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
4141 extension::resolve_undo::SIGNATURE => {
4242 ext.resolve_undo = extension::resolve_undo::decode(ext_data, object_hash);
4343 }
44− extension::untracked::SIGNATURE => {
45− ext.untracked = extension::untracked::decode(ext_data, object_hash);
44+ extension::untracked_cache::SIGNATURE => {
45+ ext.untracked = extension::untracked_cache::decode(ext_data, object_hash);
4646 }
4747 extension::end_of_index_entry::SIGNATURE => {} // skip already done
4848 extension::index_entry_offset_table::SIGNATURE => {} // not relevant/obtained already
@@ -68,6 +68,6 @@ pub struct Outcome { · 19 unmodified lines
6868 pub tree: Option<extension::Tree>,
6969 pub link: Option<extension::Link>,
7070 pub resolve_undo: Option<extension::resolve_undo::Paths>,
71− pub untracked: Option<extension::Untracked>,
71+ pub untracked: Option<extension::UntrackedCache>,
7272 pub is_sparse: bool,
7373 }
git-index/src/extension/mod.rs+79−4
@@ -1,3 +1,4 @@
1+use bstr::BString;
12 use smallvec::SmallVec;
23
34 const MIN_SIZE: usize = 4 /* signature */ + 4 /* size */;
@@ -25,7 +26,18 @@ pub struct Link { · 21 unmodified lines
2526 pub bitmaps: Option<link::Bitmaps>,
2627 }
2728
28−pub struct Untracked;
29+pub 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+}
2941
3042 mod iter;
3143
@@ -41,15 +53,78 @@ pub mod link; · 9 unmodified lines
4153
4254 pub(crate) mod resolve_undo;
4355
44−pub(crate) mod untracked {
45− use crate::extension::{Signature, Untracked};
56+pub mod untracked_cache {
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+ }
4673
4774 /// Only used as an indicator
4875 pub const SIGNATURE: Signature = *b"UNTR";
4976
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+
5194 todo!("decode UNTR")
5295 }
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+ }
53128 }
54129
55130 pub mod sparse {
git-index/src/lib.rs+1−1
@@ -76,7 +76,7 @@ pub struct State { · 75 unmodified lines
7676 tree: Option<extension::Tree>,
7777 link: Option<extension::Link>,
7878 resolve_undo: Option<extension::resolve_undo::Paths>,
79− untracked: Option<extension::Untracked>,
79+ untracked: Option<extension::UntrackedCache>,
8080 }
8181
8282 pub(crate) mod util {