branchless/core/rewrite/
evolve.rs1use tracing::instrument;
2
3use crate::core::dag::{CommitSet, Dag};
4use crate::core::eventlog::{Event, EventCursor, EventReplayer};
5use crate::git::{MaybeZeroOid, NonZeroOid};
6
7#[instrument]
16pub fn find_rewrite_target(
17 event_replayer: &EventReplayer,
18 event_cursor: EventCursor,
19 oid: NonZeroOid,
20) -> Option<MaybeZeroOid> {
21 let event = event_replayer.get_cursor_commit_latest_event(event_cursor, oid);
22 let event = match event {
23 Some(event) => event,
24 None => return None,
25 };
26 match event {
27 Event::RewriteEvent {
28 timestamp: _,
29 event_tx_id: _,
30 old_commit_oid: MaybeZeroOid::NonZero(old_commit_oid),
31 new_commit_oid,
32 } => {
33 if *old_commit_oid == oid && *new_commit_oid != MaybeZeroOid::NonZero(oid) {
34 match new_commit_oid {
35 MaybeZeroOid::Zero => Some(MaybeZeroOid::Zero),
36 MaybeZeroOid::NonZero(new_commit_oid) => {
37 let possible_newer_oid =
38 find_rewrite_target(event_replayer, event_cursor, *new_commit_oid);
39 match possible_newer_oid {
40 Some(newer_commit_oid) => Some(newer_commit_oid),
41 None => Some(MaybeZeroOid::NonZero(*new_commit_oid)),
42 }
43 }
44 }
45 } else {
46 None
47 }
48 }
49
50 Event::RewriteEvent {
51 timestamp: _,
52 event_tx_id: _,
53 old_commit_oid: MaybeZeroOid::Zero,
54 new_commit_oid: _,
55 }
56 | Event::RefUpdateEvent { .. }
57 | Event::CommitEvent { .. }
58 | Event::ObsoleteEvent { .. }
59 | Event::UnobsoleteEvent { .. }
60 | Event::WorkingCopySnapshot { .. } => None,
61 }
62}
63
64#[instrument]
69pub fn find_abandoned_children(
70 dag: &Dag,
71 event_replayer: &EventReplayer,
72 event_cursor: EventCursor,
73 oid: NonZeroOid,
74) -> eyre::Result<Option<(NonZeroOid, Vec<NonZeroOid>)>> {
75 let rewritten_oid = match find_rewrite_target(event_replayer, event_cursor, oid) {
76 Some(MaybeZeroOid::NonZero(rewritten_oid)) => rewritten_oid,
77 Some(MaybeZeroOid::Zero) => oid,
78 None => return Ok(None),
79 };
80 let children = dag.query_children(CommitSet::from(oid))?;
81 let children = dag.filter_visible_commits(children)?;
82 let non_obsolete_children = children.difference(&dag.query_obsolete_commits());
83 let non_obsolete_children_oids = dag.commit_set_to_vec(&non_obsolete_children)?;
84
85 Ok(Some((rewritten_oid, non_obsolete_children_oids)))
86}