History

first stab at basic index file parsing (#293)

Sebastian Thiel committed 4 years ago

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

Showing the changes to git-index (4 of 6 files). Show all

Unified · Split

4 files
  1. git-index/Cargo.toml +6 −0
  2. git-index/src/file.rs +40 −8
  3. git-index/src/lib.rs +25 −5
  4. git-index/tests/file/mod.rs +0 −1
git-index/Cargo.toml+6−0
@@ -10,6 +10,9 @@ edition = "2018" · 9 unmodified lines
10[lib]10[lib]
11doctest = false11doctest = false
12 12
13[features]
14serde1 = ["serde"]
15
13# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html16# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
14 17
15[dependencies]18[dependencies]
@@ -17,6 +20,9 @@ git-hash = { version ="^0.8.0", path = "../git-hash" } · 1 unmodified line
17 20
18quick-error = "2.0.0"21quick-error = "2.0.0"
19memmap2 = "0.5.0"22memmap2 = "0.5.0"
23filetime = "0.2.15"
24
25serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] }
20 26
21[dev-dependencies]27[dev-dependencies]
22git-testtools = { path = "../tests/tools"}28git-testtools = { path = "../tests/tools"}
git-index/src/file.rs+40−8
@@ -1,8 +1,8 @@
1pub mod init {1pub mod init {
2 #![allow(unused)]2 #![allow(unused)]
3 use crate::File;3 use crate::{File, State};
4 use memmap2::Mmap;4 use memmap2::Mmap;
5 use std::path::Path;5 use std::path::{Path, PathBuf};
6 6
7 mod error {7 mod error {
8 use quick_error::quick_error;8 use quick_error::quick_error;
@@ -11,7 +11,7 @@ pub mod init { · 2 unmodified lines
11 #[derive(Debug)]11 #[derive(Debug)]
12 pub enum Error {12 pub enum Error {
13 Io(err: std::io::Error) {13 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")
15 source(err)15 source(err)
16 from()16 from()
17 }17 }
@@ -21,12 +21,44 @@ pub mod init { · 3 unmodified lines
21 pub use error::Error;21 pub use error::Error;
22 22
23 impl File {23 impl File {
24 pub fn at(path: impl AsRef<Path>, object_hash: git_hash::Kind) -> Result<Self, Error> {24 pub fn at(path: impl Into<PathBuf>, 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.25 let path = path.into();
26 #[allow(unsafe_code)]26 let (data, mtime) = {
27 let data = unsafe { Mmap::map(&std::fs::File::open(path)?)? };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 };
28 33
29 todo!("read file")34 Ok(File {
35 state: State { timestamp: mtime },
36 path,
37 })
30 }38 }
31 }39 }
32}40}
41
42pub 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 @@
1#![deny(unsafe_code, missing_docs, rust_2018_idioms)]1#![deny(unsafe_code, missing_docs, rust_2018_idioms)]
2#![allow(missing_docs)]2#![allow(missing_docs, unused)]
3 3
4use filetime::FileTime;
4use std::path::PathBuf;5use std::path::PathBuf;
5 6
6pub mod file;7pub mod file;
7 8
8pub mod init {9pub mod init {
9 use crate::State;10 use crate::State;
11 use filetime::FileTime;
10 12
11 impl State {13 impl State {
12 /// Returns an empty state.14 /// Returns an empty state.
13 /// TODO: figure out if it needs to know some configuration15 /// TODO: figure out if it needs to know some configuration, and if this would actually be used somewhere
14 pub fn new() -> Self {16 fn new() -> Self {
15 State17 State {
18 timestamp: FileTime::from_system_time(std::time::SystemTime::UNIX_EPOCH),
19 }
16 }20 }
17 }21 }
18 22
@@ -23,6 +27,16 @@ pub mod init { · 4 unmodified lines
23 }27 }
24}28}
25 29
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)]
34pub enum Version {
35 V2 = 2,
36 V3 = 3,
37 V4 = 4,
38}
39
26/// An index file whose state was read from a file on disk.40/// An index file whose state was read from a file on disk.
27pub struct File {41pub struct File {
28 pub state: State,42 pub state: State,
@@ -33,4 +47,10 @@ pub struct File { · 4 unmodified lines
33///47///
34/// As opposed to a snapshot, it's meant to be altered and eventually be written back to disk or converted into a tree.48/// As opposed to a snapshot, it's meant to be altered and eventually be written back to disk or converted into a tree.
35/// We treat index and its state synonymous.49/// We treat index and its state synonymous.
36pub struct State;50pub 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
4 }4 }
5 5
6 #[test]6 #[test]
7 #[ignore]
8 fn read_v2() {7 fn read_v2() {
9 let _file = file("v2");8 let _file = file("v2");
10 }9 }

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