Skip to content

Write V2 Index Files (with TREE and EOIE extensions) #473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Aug 12, 2022
37 changes: 30 additions & 7 deletions git-index/src/entry.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::Version;
use bitflags::bitflags;

/// The stage of an entry, one of 0 = base, 1 = ours, 2 = theirs
Expand Down Expand Up @@ -42,6 +43,13 @@ pub(crate) mod at_rest {
}
}

impl Flags {
pub fn to_memory(self) -> super::Flags {
super::Flags::from_bits((self & (Flags::PATH_LEN | Flags::STAGE_MASK | Flags::ASSUME_VALID)).bits as u32)
.expect("PATHLEN is part of memory representation")
}
}

bitflags! {
/// Extended flags - add flags for serialization here and offset them down to u16.
pub struct FlagsExtended: u16 {
Expand All @@ -56,13 +64,6 @@ pub(crate) mod at_rest {
}
}

impl Flags {
pub fn to_memory(self) -> super::Flags {
super::Flags::from_bits((self & (Flags::PATH_LEN | Flags::STAGE_MASK | Flags::ASSUME_VALID)).bits as u32)
.expect("PATHLEN is part of memory representation")
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -112,6 +113,11 @@ impl Flags {
pub fn stage(&self) -> Stage {
(*self & Flags::STAGE_MASK).bits >> 12
}

pub fn to_storage(&self, version: Version) -> at_rest::Flags {
assert_eq!(version, Version::V2, "Can only encode V2 flags at the moment");
at_rest::Flags::from_bits(self.bits() as u16).unwrap()
}
}

#[derive(Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Copy)]
Expand Down Expand Up @@ -173,3 +179,20 @@ mod _impls {
}
}
}

#[cfg(test)]
mod tests {
use crate::entry::at_rest;
use crate::Version;

#[test]
fn in_mem_flags_to_storage_flags_v2() {
let flag_bytes = u16::from_be_bytes(*b"\x00\x01");
let flags_at_rest = at_rest::Flags::from_bits(flag_bytes).unwrap();
let in_memory_flags = flags_at_rest.to_memory();

let output = in_memory_flags.to_storage(Version::V2);

assert_eq!(output.bits(), flag_bytes);
}
}
2 changes: 1 addition & 1 deletion git-index/src/extension/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct Iter<'a> {
///
/// It allows to more quickly build trees by avoiding as it can quickly re-use portions of the index and its associated tree ids
/// if there was no change to them. Portions of this tree are invalidated as the index is changed.
#[derive(Clone)]
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Tree {
pub name: SmallVec<[u8; 23]>,
/// The id of the directory tree of the associated tree object.
Expand Down
1 change: 1 addition & 0 deletions git-index/src/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ mod impl_ {
}
pub mod init;
pub mod verify;
pub mod write;
12 changes: 12 additions & 0 deletions git-index/src/file/write.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::{write, File};
use git_features::hash;

impl File {
pub fn write_to(&self, mut out: &mut impl std::io::Write, options: write::Options) -> std::io::Result<()> {
let mut hasher = hash::Write::new(&mut out, options.hash_kind);
self.state.write_to(&mut hasher, options)?;

let hash = hasher.hash.digest();
out.write_all(&hash)
}
}
Loading