Skip to content

Commit 27471e7

Browse files
committed
Add a test for --intend-to-add and clarify what this flag means.
1 parent cae539b commit 27471e7

File tree

6 files changed

+47
-13
lines changed

6 files changed

+47
-13
lines changed

gix-index/src/entry/flags.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@ use bitflags::bitflags;
33
use crate::entry::Stage;
44

55
bitflags! {
6-
/// In-memory flags
6+
/// In-memory flags.
7+
///
8+
/// Notably, not all of these will be persisted but can be used to aid all kinds of operations.
79
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
810
pub struct Flags: u32 {
9-
/// The mask to apply to obtain the stage number of an entry.
10-
const STAGE_MASK = 0x3000;
11-
/// If set, additional bits need to be written to storage.
12-
const EXTENDED = 0x4000;
1311
// TODO: could we use the pathlen ourselves to save 8 bytes? And how to handle longer paths than that? 0 as sentinel maybe?
14-
/// The mask to obtain the length of the path associated with this entry.
12+
/// The mask to obtain the length of the path associated with this entry, up to 4095 characters without extension.
1513
const PATH_LEN = 0x0fff;
14+
/// The mask to apply to obtain the stage number of an entry, encoding three value: 0 = base, 1 = ours, 2 = theirs.
15+
const STAGE_MASK = 1<<12 | 1<<13;
16+
/// If set, additional bits need to be written to storage.
17+
const EXTENDED = 1<<14;
1618
/// If set, the entry be assumed to match with the version on the working tree, as a way to avoid `lstat()` checks.
1719
const ASSUME_VALID = 1 << 15;
1820
/// Indicates that an entry needs to be updated as it's in-memory representation doesn't match what's on disk.
1921
const UPDATE = 1 << 16;
2022
/// Indicates an entry should be removed - this typically happens during writing, by simply skipping over them.
2123
const REMOVE = 1 << 17;
22-
/// Indicates that an entry is known to be uptodate.
24+
/// Indicates that an entry is known to be up-to-date.
2325
const UPTODATE = 1 << 18;
24-
/// Only temporarily used by unpack_trees() (in C)
26+
/// Only temporarily used by unpack_trees() (in C).
2527
const ADDED = 1 << 19;
2628

2729
/// Whether an up-to-date object hash exists for the entry.
@@ -46,8 +48,8 @@ bitflags! {
4648
/// Indicates the entry name is present in the base/shared index, and thus doesn't have to be stored in this one.
4749
const STRIP_NAME = 1 << 28;
4850

49-
///
50-
/// stored at rest, see at_rest::FlagsExtended
51+
/// Created with `git add --intent-to-add` to mark empty entries that have their counter-part in the worktree, but not
52+
/// yet in the object database.
5153
const INTENT_TO_ADD = 1 << 29;
5254
/// Stored at rest
5355
const SKIP_WORKTREE = 1 << 30;
@@ -102,7 +104,7 @@ pub(crate) mod at_rest {
102104

103105
bitflags! {
104106
/// Extended flags - add flags for serialization here and offset them down to u16.
105-
#[derive(Copy, Clone, Debug)]
107+
#[derive(Copy, Clone, Debug, PartialEq)]
106108
pub struct FlagsExtended: u16 {
107109
const INTENT_TO_ADD = 1 << (29 - 16);
108110
const SKIP_WORKTREE = 1 << (30 - 16);
@@ -124,6 +126,18 @@ pub(crate) mod at_rest {
124126
mod tests {
125127
use super::*;
126128

129+
#[test]
130+
fn flags_extended_conversion() {
131+
assert_eq!(
132+
FlagsExtended::all().to_flags(),
133+
Some(super::super::Flags::INTENT_TO_ADD | super::super::Flags::SKIP_WORKTREE)
134+
);
135+
assert_eq!(
136+
FlagsExtended::from_flags(super::super::Flags::all()),
137+
FlagsExtended::all()
138+
);
139+
}
140+
127141
#[test]
128142
fn flags_from_bits_with_conflict() {
129143
let input = 0b1110_0010_1000_1011;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:ee69ff44520a277ed76b928c5e19986310f5628ca09f46e62f6b1eb73d310a2c
3+
size 9288
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:105298714e7ee6b7c58b702cec3d4ff13b7488732c6389602b5b349a38da61e8
3-
size 10632
2+
oid sha256:5b507facc0ca80e92997a75cd6f53c8e13da1582cac52ad202949a8af3f0491b
3+
size 9308
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
set -eu -o pipefail
3+
4+
git init -q
5+
6+
touch a
7+
git add --intent-to-add a

gix-index/tests/index/file/read.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use gix_index::{
66
Version,
77
};
88

9+
use crate::index::Fixture;
910
use crate::{hex_to_id, loose_file_path};
1011

1112
fn verify(index: gix_index::File) -> gix_index::File {
@@ -186,6 +187,14 @@ fn fsmn_v1() {
186187
assert!(file.fs_monitor().is_some());
187188
}
188189

190+
#[test]
191+
fn v3_added_files() {
192+
let file = Fixture::Generated("v3_added_files").open();
193+
assert_eq!(file.version(), Version::V3, "uses extended attributes");
194+
assert_eq!(file.entries().len(), 1);
195+
assert_eq!(file.entries()[0].flags, Flags::EXTENDED | Flags::INTENT_TO_ADD);
196+
}
197+
189198
#[test]
190199
fn file_with_conflicts() {
191200
let file = loose_file("conflicting-file");

gix-index/tests/index/file/write.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ fn state_comparisons_with_various_extension_configurations() {
9696
// the fixture artificially sets the version to V4 and gitoxide writes it back out as the lowest required version, V2
9797
// Generated("v4_more_files_IEOT"),
9898
Generated("v3_skip_worktree"),
99+
Generated("v3_added_files"),
99100
Generated("v3_sparse_index_non_cone"),
100101
Generated("v3_sparse_index"),
101102
// TODO: this fails because git writes the sdir extension in this case while gitoxide doesn't

0 commit comments

Comments
 (0)