History

first stab at basic index file parsing (#293)

Sebastian Thiel committed 4 years ago

Commit 826ca0c1 parent 494ed466 files · +74 −14Browse files

Unified · Split

6 files
  1. Cargo.lock +2 −0
  2. Makefile +1 −0
  3. git-index/Cargo.toml +6 −0
  4. git-index/src/file.rs +40 −8
  5. git-index/src/lib.rs +25 −5
  6. git-index/tests/file/mod.rs +0 −1
Cargo.lock+2−0
@@ -1228,10 +1228,12 @@ dependencies = [ · 1227 unmodified lines
12281228 name = "git-index"
12291229 version = "0.0.0"
12301230 dependencies = [
1231+ "filetime",
12311232 "git-hash 0.8.0",
12321233 "git-testtools",
12331234 "memmap2",
12341235 "quick-error",
1236+ "serde",
12351237 ]
12361238
12371239 [[package]]
Makefile+1−0
@@ -82,6 +82,7 @@ check: ## Build all code in suitable configurations · 81 unmodified lines
8282 && cargo check
8383 cd git-object && cargo check --all-features \
8484 && cargo check --features verbose-object-parsing-errors
85+ cd git-index && cargo check --features serde1
8586 cd git-actor && cargo check --features serde1
8687 cd git-pack && cargo check --features serde1 \
8788 && cargo check --features pack-cache-lru-static \
git-index/Cargo.toml+6−0
@@ -10,6 +10,9 @@ edition = "2018" · 9 unmodified lines
1010 [lib]
1111 doctest = false
1212
13+[features]
14+serde1 = ["serde"]
15+
1316 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1417
1518 [dependencies]
@@ -17,6 +20,9 @@ git-hash = { version ="^0.8.0", path = "../git-hash" } · 1 unmodified line
1720
1821 quick-error = "2.0.0"
1922 memmap2 = "0.5.0"
23+filetime = "0.2.15"
24+
25+serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] }
2026
2127 [dev-dependencies]
2228 git-testtools = { path = "../tests/tools"}
git-index/src/file.rs+40−8
@@ -1,8 +1,8 @@
11 pub mod init {
22 #![allow(unused)]
3− use crate::File;
3+ use crate::{File, State};
44 use memmap2::Mmap;
5− use std::path::Path;
5+ use std::path::{Path, PathBuf};
66
77 mod error {
88 use quick_error::quick_error;
@@ -11,7 +11,7 @@ pub mod init { · 2 unmodified lines
1111 #[derive(Debug)]
1212 pub enum Error {
1313 Io(err: std::io::Error) {
14− display("An IO error occurred while reading the index")
14+ display("An IO error occurred while opening the index")
1515 source(err)
1616 from()
1717 }
@@ -21,12 +21,44 @@ pub mod init { · 3 unmodified lines
2121 pub use error::Error;
2222
2323 impl File {
24− pub fn at(path: impl AsRef<Path>, object_hash: git_hash::Kind) -> Result<Self, Error> {
25− // SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file.
26− #[allow(unsafe_code)]
27− let data = unsafe { Mmap::map(&std::fs::File::open(path)?)? };
24+ pub fn at(path: impl Into<PathBuf>, object_hash: git_hash::Kind) -> Result<Self, Error> {
25+ let path = path.into();
26+ let (data, mtime) = {
27+ // SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file.
28+ let file = std::fs::File::open(&path)?;
29+ #[allow(unsafe_code)]
30+ let data = unsafe { Mmap::map(&file)? };
31+ (data, filetime::FileTime::from_last_modification_time(&file.metadata()?))
32+ };
2833
29− todo!("read file")
34+ Ok(File {
35+ state: State { timestamp: mtime },
36+ path,
37+ })
3038 }
3139 }
3240 }
41+
42+pub mod decode {
43+ pub mod header {
44+ mod error {
45+ use quick_error::quick_error;
46+
47+ quick_error! {
48+ #[derive(Debug)]
49+ pub enum Error {
50+ Io(err: std::io::Error) {
51+ display("An IO error occurred while opening the index")
52+ source(err)
53+ from()
54+ }
55+ }
56+ }
57+ }
58+ pub use error::Error;
59+ }
60+
61+ fn header(data: &[u8]) -> Result<(crate::Version, &[u8]), header::Error> {
62+ todo!("header parsing")
63+ }
64+}
git-index/src/lib.rs+25−5
@@ -1,18 +1,22 @@
11 #![deny(unsafe_code, missing_docs, rust_2018_idioms)]
2−#![allow(missing_docs)]
2+#![allow(missing_docs, unused)]
33
4+use filetime::FileTime;
45 use std::path::PathBuf;
56
67 pub mod file;
78
89 pub mod init {
910 use crate::State;
11+ use filetime::FileTime;
1012
1113 impl State {
1214 /// Returns an empty state.
13− /// TODO: figure out if it needs to know some configuration
14− pub fn new() -> Self {
15− State
15+ /// TODO: figure out if it needs to know some configuration, and if this would actually be used somewhere
16+ fn new() -> Self {
17+ State {
18+ timestamp: FileTime::from_system_time(std::time::SystemTime::UNIX_EPOCH),
19+ }
1620 }
1721 }
1822
@@ -23,6 +27,16 @@ pub mod init { · 4 unmodified lines
2327 }
2428 }
2529
30+/// All known versions of a git index file.
31+#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
32+#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
33+#[allow(missing_docs)]
34+pub enum Version {
35+ V2 = 2,
36+ V3 = 3,
37+ V4 = 4,
38+}
39+
2640 /// An index file whose state was read from a file on disk.
2741 pub struct File {
2842 pub state: State,
@@ -33,4 +47,10 @@ pub struct File { · 4 unmodified lines
3347 ///
3448 /// As opposed to a snapshot, it's meant to be altered and eventually be written back to disk or converted into a tree.
3549 /// We treat index and its state synonymous.
36−pub struct State;
50+pub struct State {
51+ /// The time at which the state was created, indicating its freshness compared to other files on disk.
52+ ///
53+ /// Note that on platforms that only have a precisions of a second for this time, we will treat all entries with the
54+ /// same timestamp as this as potentially changed, checking more thoroughly if a change actually happened.
55+ timestamp: FileTime,
56+}
git-index/tests/file/mod.rs+0−1
@@ -4,7 +4,6 @@ mod init { · 3 unmodified lines
44 }
55
66 #[test]
7− #[ignore]
87 fn read_v2() {
98 let _file = file("v2");
109 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t