Skip to content

Commit 3168d4e

Browse files
committed
the final stretch to make GitLab work
It doesn't currently manage to traverse enough commits to connect a far-away integration branch with the entrypoint, simply master.
1 parent 53f9577 commit 3168d4e

File tree

7 files changed

+786
-253
lines changed

7 files changed

+786
-253
lines changed

crates/but-graph/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ publish = false
88

99
[lib]
1010
doctest = false
11-
test = false
11+
test = true
1212

1313
[dependencies]
1414
but-core.workspace = true

crates/but-graph/src/api.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,7 @@ impl Graph {
232232
.tip_segments()
233233
.map(|s| {
234234
let s = &self[s];
235-
(
236-
s.ref_name.as_ref().map(|rn| rn.clone()),
237-
s.id,
238-
s.flags_of_first_commit(),
239-
)
235+
(s.ref_name.clone(), s.id, s.flags_of_first_commit())
240236
})
241237
.collect();
242238
*segments_at_bottom = self.base_segments().count();

crates/but-graph/src/init/mod.rs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Graph {
107107
gix::head::Kind::Unborn(ref_name) => {
108108
let mut graph = Graph::default();
109109
graph.insert_root(branch_segment_from_name_and_meta(
110-
Some(ref_name),
110+
Some((ref_name, None)),
111111
meta,
112112
None,
113113
)?);
@@ -177,10 +177,10 @@ impl Graph {
177177
hard_limit,
178178
}: Options,
179179
) -> anyhow::Result<Self> {
180-
let limit = Limit::from(limit);
180+
let repo = tip.repo;
181+
let max_limit = Limit::new(limit, repo.object_hash());
181182
// TODO: also traverse (outside)-branches that ought to be in the workspace. That way we have the desired ones
182183
// automatically and just have to find a way to prune the undesired ones.
183-
let repo = tip.repo;
184184
let ref_name = ref_name.into();
185185
if ref_name
186186
.as_ref()
@@ -205,13 +205,15 @@ impl Graph {
205205
None
206206
}),
207207
)?;
208-
let (workspaces, target_refs, desired_refs) =
208+
let (workspaces, target_refs) =
209209
obtain_workspace_infos(repo, ref_name.as_ref().map(|rn| rn.as_ref()), meta)?;
210210
let mut seen = gix::revwalk::graph::IdMap::<SegmentIndex>::default();
211211
let mut goals = Goals::default();
212-
let tip_limit_with_goal = limit.with_goal(tip.detach(), &mut goals);
213212
// The tip transports itself.
214-
let tip_flags = CommitFlags::NotInRemote | tip_limit_with_goal.goal;
213+
let tip_flags = CommitFlags::NotInRemote
214+
| goals
215+
.flag_for(tip.detach())
216+
.expect("we more than one bitflags for this");
215217

216218
let target_symbolic_remote_names = {
217219
let remote_names = repo.remote_names();
@@ -233,15 +235,15 @@ impl Graph {
233235
.any(|(_, wsrn, _)| Some(wsrn) == ref_name.as_ref())
234236
{
235237
let current = graph.insert_root(branch_segment_from_name_and_meta(
236-
ref_name.clone(),
238+
ref_name.clone().map(|rn| (rn, None)),
237239
meta,
238240
Some((&refs_by_id, tip.detach())),
239241
)?);
240242
if next.push_back_exhausted((
241243
tip.detach(),
242244
tip_flags,
243245
Instruction::CollectCommit { into: current },
244-
limit,
246+
max_limit,
245247
)) {
246248
return Ok(graph.with_hard_limit());
247249
}
@@ -261,12 +263,16 @@ impl Graph {
261263
.map(|tid| (trn.clone(), tid))
262264
});
263265

264-
let (ws_flags, ws_limit) = if Some(&ws_ref) == ref_name.as_ref() {
265-
(tip_flags, limit)
266+
let (ws_extra_flags, ws_limit) = if Some(&ws_ref) == ref_name.as_ref() {
267+
(tip_flags, max_limit)
266268
} else {
267-
(CommitFlags::empty(), tip_limit_with_goal)
269+
(
270+
CommitFlags::empty(),
271+
max_limit.with_indirect_goal(tip.detach(), &mut goals, ws_tip),
272+
)
268273
};
269-
let mut ws_segment = branch_segment_from_name_and_meta(Some(ws_ref), meta, None)?;
274+
let mut ws_segment =
275+
branch_segment_from_name_and_meta(Some((ws_ref, None)), meta, None)?;
270276
// The limits for the target ref and the worktree ref are synced so they can always find each other,
271277
// while being able to stop when the entrypoint is included.
272278
ws_segment.metadata = Some(SegmentMetadata::Workspace(workspace_info));
@@ -279,15 +285,15 @@ impl Graph {
279285
// We only allow workspaces that are not remote, and that are not target refs.
280286
// Theoretically they can still cross-reference each other, but then we'd simply ignore
281287
// their status for now.
282-
CommitFlags::NotInRemote | ws_flags,
288+
CommitFlags::NotInRemote | ws_extra_flags,
283289
Instruction::CollectCommit { into: ws_segment },
284290
ws_limit,
285291
)) {
286292
return Ok(graph.with_hard_limit());
287293
}
288294
if let Some((target_ref, target_ref_id)) = target {
289295
let target_segment = graph.insert_root(branch_segment_from_name_and_meta(
290-
Some(target_ref),
296+
Some((target_ref, None)),
291297
meta,
292298
None,
293299
)?);
@@ -297,17 +303,18 @@ impl Graph {
297303
Instruction::CollectCommit {
298304
into: target_segment,
299305
},
300-
tip_limit_with_goal,
306+
// Once the goal was found, be done immediately,
307+
// we are not interested in these.
308+
max_limit
309+
.with_indirect_goal(tip.detach(), &mut goals, target_ref_id)
310+
.without_allowance(),
301311
)) {
302312
return Ok(graph.with_hard_limit());
303313
}
304314
}
305315
}
306316

307317
max_commits_recharge_location.sort();
308-
// Set max-limit so that we compensate for the way this is counted.
309-
// let max_limit = limit.incremented();
310-
let max_limit = limit;
311318
while let Some((id, mut propagated_flags, instruction, mut limit)) = next.pop_front() {
312319
if max_commits_recharge_location.binary_search(&id).is_ok() {
313320
limit.set_but_keep_goal(max_limit);
@@ -329,8 +336,8 @@ impl Graph {
329336
&mut graph,
330337
&mut seen,
331338
&mut next,
332-
id,
333339
limit,
340+
id,
334341
propagated_flags,
335342
src_sidx,
336343
)?;
@@ -358,8 +365,8 @@ impl Graph {
358365
&mut graph,
359366
&mut seen,
360367
&mut next,
361-
id,
362368
limit,
369+
id,
363370
propagated_flags,
364371
parent_above,
365372
)?;
@@ -432,7 +439,7 @@ impl Graph {
432439
}
433440
}
434441

435-
prune_integrated_tips(&mut graph, &mut next, &desired_refs, max_limit);
442+
prune_integrated_tips(&mut graph, &mut next);
436443
}
437444

438445
graph.post_processed(
@@ -459,15 +466,6 @@ struct Queue {
459466
max: Option<usize>,
460467
}
461468

462-
#[derive(Debug, Copy, Clone)]
463-
struct Limit {
464-
inner: Option<usize>,
465-
/// The commit we want to see to be able to assume normal limits. Until then there is no limit.
466-
/// This is represented by bitflag, one for each goal.
467-
/// The flag is empty if no goal is set.
468-
goal: CommitFlags,
469-
}
470-
471469
/// A set of commits to keep track of in bitflags.
472470
#[derive(Default)]
473471
struct Goals(Vec<gix::ObjectId>);

crates/but-graph/src/init/post.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ fn create_connected_multi_segment(
358358
})
359359
{
360360
let ref_name = &refs[ref_idx];
361-
let new_segment = branch_segment_from_name_and_meta(Some(ref_name.clone()), meta, None)?;
361+
let new_segment =
362+
branch_segment_from_name_and_meta(Some((ref_name.clone(), None)), meta, None)?;
362363
let above_commit_idx = {
363364
let s = &graph[above_idx];
364365
let cidx = s.commit_index_of(commit.id);

0 commit comments

Comments
 (0)