Skip to content

Commit 826ca0c

Browse files
committed
first stab at basic index file parsing (#293)
1 parent 494ed46 commit 826ca0c

File tree

6 files changed

+74
-14
lines changed

6 files changed

+74
-14
lines changed

Diff for: Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ check: ## Build all code in suitable configurations
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 \

Diff for: git-index/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ edition = "2018"
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]
1619
git-hash = { version ="^0.8.0", path = "../git-hash" }
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"}

Diff for: git-index/src/file.rs

+40-8
Original file line numberDiff line numberDiff line change
@@ -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 {
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 {
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+
}

Diff for: git-index/src/lib.rs

+25-5
Original file line numberDiff line numberDiff line change
@@ -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 {
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 {
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+
}

Diff for: git-index/tests/file/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ mod init {
44
}
55

66
#[test]
7-
#[ignore]
87
fn read_v2() {
98
let _file = file("v2");
109
}

0 commit comments

Comments
 (0)