mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-27 06:27:43 +00:00
index: add flag indicating pruned commit
This commit is contained in:
parent
d80903ce48
commit
3a53a187ff
1 changed files with 144 additions and 66 deletions
210
lib/src/index.rs
210
lib/src/index.rs
|
@ -138,39 +138,43 @@ struct CommitGraphEntry<'a> {
|
|||
// lowest set bit to determine which generation number the pointers point to.
|
||||
impl CommitGraphEntry<'_> {
|
||||
fn size(hash_length: usize) -> usize {
|
||||
28 + hash_length
|
||||
32 + hash_length
|
||||
}
|
||||
|
||||
fn is_pruned(&self) -> bool {
|
||||
(&self.data[0..]).read_u32::<LittleEndian>().unwrap() != 0
|
||||
}
|
||||
|
||||
fn generation_number(&self) -> u32 {
|
||||
(&self.data[0..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn num_parents(&self) -> u32 {
|
||||
(&self.data[4..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn parent1_pos(&self) -> u32 {
|
||||
fn num_parents(&self) -> u32 {
|
||||
(&self.data[8..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn parent2_overflow_pos(&self) -> u32 {
|
||||
fn parent1_pos(&self) -> u32 {
|
||||
(&self.data[12..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn num_predecessors(&self) -> u32 {
|
||||
fn parent2_overflow_pos(&self) -> u32 {
|
||||
(&self.data[16..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn predecessor1_pos(&self) -> u32 {
|
||||
fn num_predecessors(&self) -> u32 {
|
||||
(&self.data[20..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn predecessor2_overflow_pos(&self) -> u32 {
|
||||
fn predecessor1_pos(&self) -> u32 {
|
||||
(&self.data[24..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn predecessor2_overflow_pos(&self) -> u32 {
|
||||
(&self.data[28..]).read_u32::<LittleEndian>().unwrap()
|
||||
}
|
||||
|
||||
fn commit_id(&self) -> CommitId {
|
||||
CommitId(self.data[28..28 + self.hash_length].to_vec())
|
||||
CommitId(self.data[32..32 + self.hash_length].to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,6 +364,7 @@ impl PrefixResolution {
|
|||
#[derive(Debug)]
|
||||
struct MutableGraphEntry {
|
||||
commit_id: CommitId,
|
||||
is_pruned: bool,
|
||||
generation_number: u32,
|
||||
parent_positions: Vec<u32>,
|
||||
predecessor_positions: Vec<u32>,
|
||||
|
@ -406,6 +411,7 @@ impl MutableIndex {
|
|||
pub fn add_commit(&mut self, commit: &Commit) {
|
||||
self.add_commit_data(
|
||||
commit.id().clone(),
|
||||
commit.is_pruned(),
|
||||
commit.parent_ids(),
|
||||
commit.predecessor_ids(),
|
||||
);
|
||||
|
@ -414,6 +420,7 @@ impl MutableIndex {
|
|||
fn add_commit_data(
|
||||
&mut self,
|
||||
id: CommitId,
|
||||
is_pruned: bool,
|
||||
parent_ids: Vec<CommitId>,
|
||||
predecessor_ids: Vec<CommitId>,
|
||||
) {
|
||||
|
@ -422,6 +429,7 @@ impl MutableIndex {
|
|||
}
|
||||
let mut entry = MutableGraphEntry {
|
||||
commit_id: id,
|
||||
is_pruned,
|
||||
generation_number: 0,
|
||||
parent_positions: vec![],
|
||||
predecessor_positions: vec![],
|
||||
|
@ -475,6 +483,9 @@ impl MutableIndex {
|
|||
let mut parent_overflow = vec![];
|
||||
let mut predecessor_overflow = vec![];
|
||||
for entry in self.graph {
|
||||
let flags = if entry.is_pruned { 1 } else { 0 };
|
||||
buf.write_u32::<LittleEndian>(flags).unwrap();
|
||||
|
||||
buf.write_u32::<LittleEndian>(entry.generation_number)
|
||||
.unwrap();
|
||||
|
||||
|
@ -574,7 +585,12 @@ impl MutableIndex {
|
|||
.iter()
|
||||
.map(|pos| self.entry_by_pos(*pos).commit_id())
|
||||
.collect();
|
||||
squashed.add_commit_data(entry.commit_id(), parent_ids, predecessor_ids);
|
||||
squashed.add_commit_data(
|
||||
entry.commit_id(),
|
||||
entry.is_pruned(),
|
||||
parent_ids,
|
||||
predecessor_ids,
|
||||
);
|
||||
}
|
||||
squashed
|
||||
}
|
||||
|
@ -663,6 +679,8 @@ trait IndexSegment {
|
|||
|
||||
fn segment_resolve_prefix(&self, prefix: &HexPrefix) -> PrefixResolution;
|
||||
|
||||
fn segment_is_pruned(&self, local_pos: u32) -> bool;
|
||||
|
||||
fn segment_generation_number(&self, local_pos: u32) -> u32;
|
||||
|
||||
fn segment_commit_id(&self, local_pos: u32) -> CommitId;
|
||||
|
@ -1089,6 +1107,11 @@ impl IndexSegment for ReadonlyIndex {
|
|||
}
|
||||
}
|
||||
|
||||
fn segment_is_pruned(&self, local_pos: u32) -> bool {
|
||||
let graph_entry = self.graph_entry(local_pos);
|
||||
graph_entry.is_pruned()
|
||||
}
|
||||
|
||||
fn segment_generation_number(&self, local_pos: u32) -> u32 {
|
||||
self.graph_entry(local_pos).generation_number()
|
||||
}
|
||||
|
@ -1197,6 +1220,10 @@ impl IndexSegment for MutableIndex {
|
|||
}
|
||||
}
|
||||
|
||||
fn segment_is_pruned(&self, local_pos: u32) -> bool {
|
||||
self.graph[local_pos as usize].is_pruned
|
||||
}
|
||||
|
||||
fn segment_generation_number(&self, local_pos: u32) -> u32 {
|
||||
self.graph[local_pos as usize].generation_number
|
||||
}
|
||||
|
@ -1254,6 +1281,10 @@ impl IndexEntry<'_> {
|
|||
self.source.segment_commit_id(self.local_pos)
|
||||
}
|
||||
|
||||
fn is_pruned(&self) -> bool {
|
||||
self.source.segment_is_pruned(self.local_pos)
|
||||
}
|
||||
|
||||
pub fn num_parents(&self) -> u32 {
|
||||
self.source.segment_num_parents(self.local_pos)
|
||||
}
|
||||
|
@ -1574,7 +1605,7 @@ mod tests {
|
|||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let mut index = MutableIndex::full(temp_dir.path().to_owned(), 3);
|
||||
let id_0 = CommitId::from_hex("000000");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
let index = if on_disk {
|
||||
IndexRef::Readonly(index.save().unwrap())
|
||||
} else {
|
||||
|
@ -1610,7 +1641,7 @@ mod tests {
|
|||
let mut index = MutableIndex::full(temp_dir.path().to_owned(), 3);
|
||||
let id_0 = CommitId::from_hex("000000");
|
||||
let id_1 = CommitId::from_hex("111111");
|
||||
index.add_commit_data(id_1, vec![id_0], vec![]);
|
||||
index.add_commit_data(id_1, false, vec![id_0], vec![]);
|
||||
}
|
||||
|
||||
#[test_case(false, false; "full in memory")]
|
||||
|
@ -1630,9 +1661,9 @@ mod tests {
|
|||
let id_0 = CommitId::from_hex("000000");
|
||||
let id_1 = CommitId::from_hex("111111");
|
||||
let id_2 = CommitId::from_hex("222222");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
|
||||
// If testing incremental indexing, write the first three commits to one file
|
||||
// now and build the remainder as another segment on top.
|
||||
|
@ -1644,13 +1675,19 @@ mod tests {
|
|||
let id_3 = CommitId::from_hex("333333");
|
||||
let id_4 = CommitId::from_hex("444444");
|
||||
let id_5 = CommitId::from_hex("555555");
|
||||
index.add_commit_data(id_3.clone(), vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_4.clone(),
|
||||
false,
|
||||
vec![id_1.clone()],
|
||||
vec![id_2.clone(), id_3.clone()],
|
||||
);
|
||||
index.add_commit_data(id_5.clone(), vec![id_4.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_5.clone(),
|
||||
false,
|
||||
vec![id_4.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
let index = if on_disk {
|
||||
IndexRef::Readonly(index.save().unwrap())
|
||||
} else {
|
||||
|
@ -1722,14 +1759,15 @@ mod tests {
|
|||
let id_4 = CommitId::from_hex("444444");
|
||||
let id_5 = CommitId::from_hex("555555");
|
||||
let id_6 = CommitId::from_hex("666666");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_5.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_5.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_6.clone(),
|
||||
false,
|
||||
vec![
|
||||
id_1.clone(),
|
||||
id_2.clone(),
|
||||
|
@ -1769,9 +1807,9 @@ mod tests {
|
|||
let id_0 = CommitId::from_hex("000000");
|
||||
let id_1 = CommitId::from_hex("009999");
|
||||
let id_2 = CommitId::from_hex("055488");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![], vec![]);
|
||||
|
||||
// Write the first three commits to one file and build the remainder on top.
|
||||
let initial_file = index.save().unwrap();
|
||||
|
@ -1780,9 +1818,9 @@ mod tests {
|
|||
let id_3 = CommitId::from_hex("055444");
|
||||
let id_4 = CommitId::from_hex("055555");
|
||||
let id_5 = CommitId::from_hex("033333");
|
||||
index.add_commit_data(id_3.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_5.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_4.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_5.clone(), false, vec![], vec![]);
|
||||
|
||||
// Can find commits given the full hex number
|
||||
assert_eq!(
|
||||
|
@ -1844,12 +1882,17 @@ mod tests {
|
|||
let id_3 = CommitId::from_hex("333333");
|
||||
let id_4 = CommitId::from_hex("444444");
|
||||
let id_5 = CommitId::from_hex("555555");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(id_5.clone(), vec![id_4.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), false, vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_5.clone(),
|
||||
false,
|
||||
vec![id_4.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
|
||||
assert!(index.is_ancestor(&id_0, &id_0));
|
||||
assert!(index.is_ancestor(&id_0, &id_1));
|
||||
|
@ -1882,12 +1925,17 @@ mod tests {
|
|||
let id_3 = CommitId::from_hex("333333");
|
||||
let id_4 = CommitId::from_hex("444444");
|
||||
let id_5 = CommitId::from_hex("555555");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(id_5.clone(), vec![id_4.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), false, vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_5.clone(),
|
||||
false,
|
||||
vec![id_4.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
index.common_ancestors(&[id_0.clone()], &[id_0.clone()]),
|
||||
|
@ -1963,11 +2011,21 @@ mod tests {
|
|||
let id_2 = CommitId::from_hex("222222");
|
||||
let id_3 = CommitId::from_hex("333333");
|
||||
let id_4 = CommitId::from_hex("444444");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), vec![id_1.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![id_1.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_3.clone(),
|
||||
false,
|
||||
vec![id_1.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
index.add_commit_data(
|
||||
id_4.clone(),
|
||||
false,
|
||||
vec![id_1.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
|
||||
let mut common_ancestors = index.common_ancestors(&[id_3.clone()], &[id_4.clone()]);
|
||||
common_ancestors.sort();
|
||||
|
@ -1989,12 +2047,22 @@ mod tests {
|
|||
let id_3 = CommitId::from_hex("333333");
|
||||
let id_4 = CommitId::from_hex("444444");
|
||||
let id_5 = CommitId::from_hex("555555");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![id_0.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_5.clone(), vec![id_0.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_4.clone(),
|
||||
false,
|
||||
vec![id_0.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
index.add_commit_data(
|
||||
id_5.clone(),
|
||||
false,
|
||||
vec![id_0.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
|
||||
let mut common_ancestors = index.common_ancestors(&[id_4.clone()], &[id_5.clone()]);
|
||||
common_ancestors.sort();
|
||||
|
@ -2018,12 +2086,17 @@ mod tests {
|
|||
let id_3 = CommitId::from_hex("333333");
|
||||
let id_4 = CommitId::from_hex("444444");
|
||||
let id_5 = CommitId::from_hex("555555");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(id_5.clone(), vec![id_4.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), false, vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_5.clone(),
|
||||
false,
|
||||
vec![id_4.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
|
||||
// No wanted commits
|
||||
let revs: Vec<CommitId> = index.walk_revs(&[], &[]).collect();
|
||||
|
@ -2086,12 +2159,17 @@ mod tests {
|
|||
let id_3 = CommitId::from_hex("333333");
|
||||
let id_4 = CommitId::from_hex("444444");
|
||||
let id_5 = CommitId::from_hex("555555");
|
||||
index.add_commit_data(id_0.clone(), vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(id_5.clone(), vec![id_4.clone(), id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_0.clone(), false, vec![], vec![]);
|
||||
index.add_commit_data(id_1.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_2.clone(), false, vec![id_0.clone()], vec![]);
|
||||
index.add_commit_data(id_3.clone(), false, vec![id_2.clone()], vec![]);
|
||||
index.add_commit_data(id_4.clone(), false, vec![id_1.clone()], vec![]);
|
||||
index.add_commit_data(
|
||||
id_5.clone(),
|
||||
false,
|
||||
vec![id_4.clone(), id_2.clone()],
|
||||
vec![],
|
||||
);
|
||||
|
||||
// Empty input
|
||||
assert!(index.heads(&[]).is_empty());
|
||||
|
|
Loading…
Reference in a new issue