Skip to content

Commit f48e2e9

Browse files
committed
SQUASH ME
1 parent 6f99b27 commit f48e2e9

File tree

19 files changed

+359
-218
lines changed

19 files changed

+359
-218
lines changed

crates/but-api/src/commands/stack.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ pub fn create_branch(
135135
{
136136
let segment = stack.segments.first().context("BUG: no empty stacks")?;
137137
segment
138-
.ref_name
138+
.ref_info
139139
.as_ref()
140140
.map(|rn| but_workspace::branch::create_reference::Anchor::AtSegment {
141141
ref_name: Cow::Borrowed(rn.as_ref()),

crates/but-graph/src/api.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl Graph {
133133
name: &gix::refs::FullNameRef,
134134
) -> Option<(&Segment, &Commit)> {
135135
self.inner.node_weights().find_map(|s| {
136-
if s.ref_name.as_ref().is_some_and(|rn| rn.as_ref() == name) {
136+
if s.ref_name().is_some_and(|rn| rn == name) {
137137
self.tip_skip_empty(s.id).map(|c| (s, c))
138138
} else {
139139
s.commits.iter().find_map(|c| {
@@ -156,7 +156,7 @@ impl Graph {
156156
pub fn named_segment_by_ref_name(&self, name: &gix::refs::FullNameRef) -> Option<&Segment> {
157157
self.inner
158158
.node_weights()
159-
.find(|s| s.ref_name.as_ref().is_some_and(|rn| rn.as_ref() == name))
159+
.find(|s| s.ref_name().is_some_and(|rn| rn == name))
160160
}
161161

162162
/// Starting a `segment`, ignore all segments that have no commit and return the first commit

crates/but-graph/src/debug.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ impl Graph {
9696
Ok(())
9797
};
9898
for node in self.inner.node_weights_mut() {
99-
if let Some(rn) = node.ref_name.as_mut() {
100-
anon(rn)?;
99+
if let Some(ri) = node.ref_info.as_mut() {
100+
anon(&mut ri.ref_name)?;
101101
}
102102
if let Some(rn) = node.remote_tracking_ref_name.as_mut() {
103103
anon(rn)?;
104104
}
105-
for rn in node.commits.iter_mut().flat_map(|c| c.refs.iter_mut()) {
106-
anon(rn)?;
105+
for ri in node.commits.iter_mut().flat_map(|c| c.refs.iter_mut()) {
106+
anon(&mut ri.ref_name)?;
107107
}
108108
if let Some(SegmentMetadata::Workspace(md)) = node.metadata.as_mut() {
109109
if let Some(rn) = md.target_ref.as_mut() {
@@ -152,9 +152,8 @@ impl Graph {
152152
format!(
153153
" {}",
154154
commit
155-
.refs
156-
.iter()
157-
.map(|rn| format!("►{}", { Self::ref_debug_string(rn) }))
155+
.ref_iter()
156+
.map(|rn| format!("►{}", { Self::ref_debug_string(rn.as_ref()) }))
158157
.collect::<Vec<_>>()
159158
.join(", ")
160159
)
@@ -163,7 +162,7 @@ impl Graph {
163162
}
164163

165164
/// Shorten the given `name` so it's still clear if it is a special ref (like tag) or not.
166-
pub fn ref_debug_string(name: &gix::refs::FullName) -> String {
165+
pub fn ref_debug_string(name: &gix::refs::FullNameRef) -> String {
167166
let (cat, sn) = name.category_and_short_name().expect("valid refs");
168167
// Only shorten those that look good and are unambiguous enough.
169168
if matches!(cat, Category::LocalBranch | Category::RemoteBranch) {
@@ -180,17 +179,17 @@ impl Graph {
180179
/// Return a useful one-line string showing the relationship between `ref_name`, `remote_ref_name` and how
181180
/// they are linked with `sibling_id`.
182181
pub fn ref_and_remote_debug_string(
183-
ref_name: Option<&gix::refs::FullName>,
182+
ref_info: Option<&crate::RefInfo>,
184183
remote_ref_name: Option<&gix::refs::FullName>,
185184
sibling_id: Option<SegmentIndex>,
186185
) -> String {
187186
format!(
188187
"{ref_name}{remote}",
189-
ref_name = ref_name
188+
ref_name = ref_info
190189
.as_ref()
191-
.map(|rn| format!(
190+
.map(|ri| format!(
192191
"{}{maybe_id}",
193-
Graph::ref_debug_string(rn),
192+
Graph::ref_debug_string(ri.ref_name.as_ref()),
194193
maybe_id = sibling_id
195194
.filter(|_| remote_ref_name.is_none())
196195
.map(|id| format!(" →:{}:", id.index()))
@@ -206,7 +205,7 @@ impl Graph {
206205
.as_ref()
207206
.map(|remote_ref_name| format!(
208207
" <> {remote_name}{maybe_id}",
209-
remote_name = Graph::ref_debug_string(remote_ref_name),
208+
remote_name = Graph::ref_debug_string(remote_ref_name.as_ref()),
210209
maybe_id = sibling_id
211210
.map(|id| format!(" →:{}:", id.index()))
212211
.unwrap_or_default()
@@ -289,14 +288,14 @@ impl Graph {
289288
let name = format!(
290289
"{ref_name_and_remote}{maybe_centering_newline}",
291290
ref_name_and_remote = Self::ref_and_remote_debug_string(
292-
s.ref_name.as_ref(),
291+
s.ref_info.as_ref(),
293292
s.remote_tracking_ref_name.as_ref(),
294293
s.sibling_segment_id
295294
),
296295
maybe_centering_newline = if s.commits.is_empty() { "" } else { "\n" },
297296
);
298297
// Reduce noise by preferring ref-based entry-points.
299-
let show_segment_entrypoint = s.ref_name.is_some()
298+
let show_segment_entrypoint = s.ref_info.is_some()
300299
&& entrypoint.is_some_and(|(s, cidx)| s == sidx && matches!(cidx, None | Some(0)));
301300
let mut commits = s
302301
.commits

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

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use gix::{
66
prelude::{ObjectIdExt, ReferenceExt},
77
refs::Category,
88
};
9+
use std::collections::BTreeMap;
910
use tracing::instrument;
1011

1112
use crate::{CommitFlags, CommitIndex, Edge, Graph, Segment, SegmentIndex, SegmentMetadata};
@@ -154,10 +155,17 @@ impl Graph {
154155
// It's OK to default-initialise this here as overlays are only used when redoing
155156
// the traversal.
156157
let (_repo, meta, _entrypoint) = Overlay::default().into_parts(repo, meta);
158+
let wt_by_branch = {
159+
// Assume linked worktrees are never unborn!
160+
let mut m = BTreeMap::new();
161+
m.insert(ref_name.clone(), vec![crate::Worktree::Main]);
162+
m
163+
};
157164
graph.insert_segment_set_entrypoint(branch_segment_from_name_and_meta(
158165
Some((ref_name, None)),
159166
&meta,
160167
None,
168+
&wt_by_branch,
161169
)?);
162170
return Ok(graph);
163171
}
@@ -182,7 +190,7 @@ impl Graph {
182190
if let Some((rn, first_commit)) = s
183191
.commits
184192
.first_mut()
185-
.and_then(|first_commit| s.ref_name.take().map(|rn| (rn, first_commit)))
193+
.and_then(|first_commit| s.ref_info.take().map(|rn| (rn, first_commit)))
186194
{
187195
first_commit.refs.push(rn);
188196
}
@@ -350,6 +358,8 @@ impl Graph {
350358
let tip_is_not_workspace_commit = !workspaces
351359
.iter()
352360
.any(|(_, wsrn, _)| Some(wsrn) == ref_name.as_ref());
361+
let worktree_by_branch = worktree_branches(repo.for_worktree_only())?;
362+
353363
let mut ctx = post::Context {
354364
repo,
355365
symbolic_remote_names: &symbolic_remote_names,
@@ -358,12 +368,14 @@ impl Graph {
358368
refs_by_id,
359369
hard_limit: false,
360370
dangerously_skip_postprocessing_for_debugging,
371+
worktree_by_branch,
361372
};
362373
if tip_is_not_workspace_commit {
363374
let current = graph.insert_segment_set_entrypoint(branch_segment_from_name_and_meta(
364375
None,
365376
meta,
366377
Some((&ctx.refs_by_id, tip)),
378+
&ctx.worktree_by_branch,
367379
)?);
368380
_ = next.push_back_exhausted((
369381
tip,
@@ -406,8 +418,12 @@ impl Graph {
406418
max_limit.with_indirect_goal(tip, &mut goals),
407419
)
408420
};
409-
let mut ws_segment =
410-
branch_segment_from_name_and_meta(Some((ws_ref, None)), meta, None)?;
421+
let mut ws_segment = branch_segment_from_name_and_meta(
422+
Some((ws_ref, None)),
423+
meta,
424+
None,
425+
&ctx.worktree_by_branch,
426+
)?;
411427
// The limits for the target ref and the worktree ref are synced so they can always find each other,
412428
// while being able to stop when the entrypoint is included.
413429
ws_segment.metadata = Some(SegmentMetadata::Workspace(ws_meta));
@@ -439,6 +455,7 @@ impl Graph {
439455
Some((target_ref, None)),
440456
meta,
441457
None,
458+
&ctx.worktree_by_branch,
442459
)?);
443460
let (local_sidx, local_goal) =
444461
if let Some((local_ref_name, target_local_tip)) = local_tip_info {
@@ -448,12 +465,13 @@ impl Graph {
448465
Some(target_segment),
449466
meta,
450467
Some((&ctx.refs_by_id, target_local_tip)),
468+
&ctx.worktree_by_branch,
451469
)?);
452470
// We use auto-naming based on ambiguity - if the name ends up something else,
453471
// remove the nodes sibling link.
454472
let has_sibling_link = {
455473
let s = &mut graph[local_sidx];
456-
if s.ref_name.as_ref().is_none_or(|rn| rn != &local_ref_name) {
474+
if s.ref_name().is_none_or(|rn| rn != local_ref_name.as_ref()) {
457475
s.sibling_segment_id = None;
458476
false
459477
} else {
@@ -504,6 +522,7 @@ impl Graph {
504522
None,
505523
meta,
506524
Some((&ctx.refs_by_id, extra_target)),
525+
&ctx.worktree_by_branch,
507526
)?);
508527
_ = next.push_front_exhausted((
509528
extra_target,
@@ -550,15 +569,19 @@ impl Graph {
550569
None,
551570
meta,
552571
Some((&ctx.refs_by_id, segment_tip.detach())),
572+
&ctx.worktree_by_branch,
553573
)?;
554574

555575
// However, if this is a remote segment that is explicitly mentioned, and we couldn't name
556576
// it, then just fix it up here as we really want that name.
557577
let is_remote = segment_name
558578
.category()
559579
.is_some_and(|c| c == Category::RemoteBranch);
560-
if segment.ref_name.is_none() && is_remote {
561-
segment.ref_name = Some(segment_name.clone());
580+
if segment.ref_info.is_none() && is_remote {
581+
segment.ref_info = Some(crate::RefInfo::from_ref(
582+
segment_name.clone(),
583+
&ctx.worktree_by_branch,
584+
));
562585
segment.metadata = meta
563586
.branch_opt(segment_name.as_ref())?
564587
.map(SegmentMetadata::Branch);
@@ -577,6 +600,7 @@ impl Graph {
577600
&mut graph,
578601
&mut next,
579602
(ws_tips, repo, meta),
603+
&ctx.worktree_by_branch,
580604
)?;
581605
max_commits_recharge_location.sort();
582606
while let Some((id, mut propagated_flags, instruction, mut limit)) = next.pop_front() {
@@ -614,6 +638,7 @@ impl Graph {
614638
&info,
615639
&ctx.refs_by_id,
616640
meta,
641+
&ctx.worktree_by_branch,
617642
)?
618643
.unwrap_or(src_sidx);
619644
e.insert(src_sidx);
@@ -641,6 +666,7 @@ impl Graph {
641666
None,
642667
meta,
643668
Some((&ctx.refs_by_id, id)),
669+
&ctx.worktree_by_branch,
644670
)?;
645671
let segment_below = graph.connect_new_segment(
646672
parent_above,
@@ -672,6 +698,7 @@ impl Graph {
672698
limit,
673699
&mut goals,
674700
&next,
701+
&ctx.worktree_by_branch,
675702
)?;
676703

677704
let segment = &mut graph[segment_idx_for_id];
@@ -700,8 +727,9 @@ impl Graph {
700727
refs_at_commit_before_removal
701728
.clone()
702729
.into_iter()
703-
.filter(|rn| segment.ref_name.as_ref() != Some(rn))
730+
.filter(|rn| segment.ref_name() != Some(rn.as_ref()))
704731
.collect(),
732+
&ctx.worktree_by_branch,
705733
)?,
706734
);
707735

@@ -738,7 +766,7 @@ impl Graph {
738766
.tip_skip_empty(tip_sidx)
739767
.context("BUG: entrypoint must eventually point to a commit")?
740768
.id;
741-
let ref_name = self[tip_sidx].ref_name.clone();
769+
let ref_name = self[tip_sidx].ref_info.clone().map(|ri| ri.ref_name);
742770
(tip, ref_name)
743771
}
744772
};

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ impl<'repo> OverlayRepo<'repo> {
182182
self.inner
183183
}
184184

185+
pub fn for_worktree_only(&self) -> &'repo gix::Repository {
186+
self.inner
187+
}
188+
185189
pub fn remote_names(&self) -> gix::remote::Names<'repo> {
186190
self.inner.remote_names()
187191
}

0 commit comments

Comments
 (0)