Skip to content

Commit a9c736b

Browse files
committed
Test for the current problem
1 parent 4a82426 commit a9c736b

File tree

5 files changed

+189
-24
lines changed

5 files changed

+189
-24
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ impl Options {
128128
self.commits_limit_recharge_location.extend(commits);
129129
self
130130
}
131+
132+
/// Set the extra-target which should be included in the workspace.
133+
pub fn with_extra_target_commit_id(mut self, id: impl Into<gix::ObjectId>) -> Self {
134+
self.extra_target_commit_id = Some(id.into());
135+
self
136+
}
131137
}
132138

133139
/// Lifecycle

crates/but-graph/src/projection/workspace.rs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,6 @@ impl Graph {
569569
ws.stacks.extend(
570570
self.collect_stack_segments(
571571
stack_top_sidx,
572-
lowest_base_sidx,
573572
entrypoint_sidx,
574573
|s| {
575574
let stop = true;
@@ -644,7 +643,6 @@ impl Graph {
644643
self.collect_stack_segments(
645644
start.id,
646645
None,
647-
None,
648646
|s| {
649647
let stop = true;
650648
if segment_name_is_special(s) {
@@ -853,7 +851,6 @@ impl Graph {
853851
fn collect_stack_segments(
854852
&self,
855853
from: SegmentIndex,
856-
mut lowest_base_sidx: Option<SegmentIndex>,
857854
mut entrypoint_sidx: Option<SegmentIndex>,
858855
mut is_one_past_end_of_stack_segment: impl FnMut(&Segment) -> bool,
859856
mut starts_next_stack_segment: impl FnMut(&Segment) -> bool,
@@ -863,27 +860,18 @@ impl Graph {
863860
let mut out = Vec::new();
864861
let mut next = Some(from);
865862
while let Some(from) = next.take() {
866-
if lowest_base_sidx.take().is_some_and(|base| base == from) {
867-
let mut segment = StackSegment::from_graph_segments(&vec![&self[from]], self)?;
868-
segment.base = segment.commits.first().map(|c| c.id);
869-
segment.commits.clear();
870-
out.push(segment);
871-
} else {
872-
let start = &self[from];
873-
let (segments, stopped_at) = self.collect_first_parent_segments_until(
874-
start,
875-
&mut is_one_past_end_of_stack_segment,
876-
);
877-
let mut segment = StackSegment::from_graph_segments(&segments, self)?;
878-
if entrypoint_sidx.is_some_and(|id| segment.id == id) {
879-
segment.is_entrypoint = true;
880-
entrypoint_sidx = None;
881-
}
882-
out.push(segment);
883-
next = stopped_at
884-
.filter(|s| starts_next_stack_segment(s))
885-
.map(|s| s.id);
863+
let start = &self[from];
864+
let (segments, stopped_at) = self
865+
.collect_first_parent_segments_until(start, &mut is_one_past_end_of_stack_segment);
866+
let mut segment = StackSegment::from_graph_segments(&segments, self)?;
867+
if entrypoint_sidx.is_some_and(|id| segment.id == id) {
868+
segment.is_entrypoint = true;
869+
entrypoint_sidx = None;
886870
}
871+
out.push(segment);
872+
next = stopped_at
873+
.filter(|s| starts_next_stack_segment(s))
874+
.map(|s| s.id);
887875
}
888876

889877
fn is_entrypoint_or_local(s: &StackSegment) -> bool {

crates/but-graph/tests/fixtures/scenarios.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,65 @@ git init special-branches
205205

206206
mkdir ws
207207
(cd ws
208+
git init remote-and-integrated-tracking-linear
209+
(cd remote-and-integrated-tracking-linear
210+
commit M1
211+
commit M-base
212+
git branch A
213+
git checkout -b soon-origin-A main
214+
commit A-remote
215+
git checkout main
216+
commit M-advanced
217+
setup_target_to_match_main
218+
219+
git checkout A
220+
create_workspace_commit_once A
221+
setup_remote_tracking soon-origin-A A "move"
222+
)
223+
224+
git init remote-and-integrated-tracking
225+
(cd remote-and-integrated-tracking
226+
commit M1
227+
commit M2
228+
git checkout -b tmp1
229+
commit X
230+
git checkout main
231+
commit Y
232+
git merge --no-ff tmp1 -m "M-base"
233+
git branch A
234+
git checkout -b soon-origin-A main
235+
commit A-remote
236+
git checkout main
237+
commit M-advanced
238+
setup_target_to_match_main
239+
240+
git checkout A
241+
create_workspace_commit_once A
242+
setup_remote_tracking soon-origin-A A "move"
243+
)
244+
245+
git init remote-and-integrated-tracking-extra-commit
246+
(cd remote-and-integrated-tracking-extra-commit
247+
commit M1
248+
commit M2
249+
git checkout -b tmp1
250+
commit X
251+
git checkout main
252+
commit Y
253+
git merge --no-ff tmp1 -m "M-base"
254+
git checkout -b A
255+
commit A-local
256+
git checkout -b soon-origin-A main
257+
commit A-remote
258+
git checkout main
259+
commit M-advanced
260+
setup_target_to_match_main
261+
262+
git checkout A
263+
create_workspace_commit_once A
264+
setup_remote_tracking soon-origin-A A "move"
265+
)
266+
208267
git init single-stack-ambiguous
209268
(cd single-stack-ambiguous
210269
commit init

crates/but-graph/tests/graph/init/with_workspace.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5218,6 +5218,118 @@ fn dependent_branch_on_base() -> anyhow::Result<()> {
52185218
Ok(())
52195219
}
52205220

5221+
#[test]
5222+
fn remote_and_integrated_tracking_branch_on_merge() -> anyhow::Result<()> {
5223+
let (repo, mut meta) = read_only_in_memory_scenario("ws/remote-and-integrated-tracking")?;
5224+
insta::assert_snapshot!(visualize_commit_graph_all(&repo)?, @r"
5225+
* d018f71 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
5226+
| * c1e26b0 (origin/main, main) M-advanced
5227+
|/
5228+
| * 2181501 (origin/A) A-remote
5229+
|/
5230+
* 1ee1e34 (A) M-base
5231+
|\
5232+
| * efc3b77 (tmp1) X
5233+
* | c822d66 Y
5234+
|/
5235+
* bce0c5e M2
5236+
* 3183e43 M1
5237+
");
5238+
add_stack_with_segments(&mut meta, 1, "A", StackState::InWorkspace, &[]);
5239+
5240+
let graph = Graph::from_head(
5241+
&repo,
5242+
&*meta,
5243+
standard_options().with_extra_target_commit_id(repo.rev_parse_single("origin/main")?),
5244+
)?
5245+
.validated()?;
5246+
// TODO: this shouldn't move past the base on 1ee1e34!
5247+
insta::assert_snapshot!(graph_workspace(&graph.to_workspace()?), @r"
5248+
📕🏘️:0:gitbutler/workspace <> ✓refs/remotes/origin/main⇣1 on 1ee1e34
5249+
└── ≡📙:3:A <> origin/A →:4:⇣1 {1}
5250+
└── 📙:3:A <> origin/A →:4:⇣1
5251+
├── 🟣2181501
5252+
├── ❄️1ee1e34 (🏘️|✓)
5253+
├── ❄️c822d66 (🏘️|✓)
5254+
├── ❄️bce0c5e (🏘️|✓)
5255+
└── ❄️3183e43 (🏘️|✓)
5256+
");
5257+
5258+
Ok(())
5259+
}
5260+
5261+
#[test]
5262+
fn remote_and_integrated_tracking_branch_on_linear_segment() -> anyhow::Result<()> {
5263+
let (repo, mut meta) =
5264+
read_only_in_memory_scenario("ws/remote-and-integrated-tracking-linear")?;
5265+
insta::assert_snapshot!(visualize_commit_graph_all(&repo)?, @r"
5266+
* 21e584f (HEAD -> gitbutler/workspace) GitButler Workspace Commit
5267+
| * 8dc508f (origin/main, main) M-advanced
5268+
|/
5269+
| * 197ddce (origin/A) A-remote
5270+
|/
5271+
* 081bae9 (A) M-base
5272+
* 3183e43 M1
5273+
");
5274+
add_stack_with_segments(&mut meta, 1, "A", StackState::InWorkspace, &[]);
5275+
5276+
let graph = Graph::from_head(
5277+
&repo,
5278+
&*meta,
5279+
standard_options().with_extra_target_commit_id(repo.rev_parse_single("origin/main")?),
5280+
)?
5281+
.validated()?;
5282+
// TODO: Can we arbitrarily split the segment below the low base of all stacks to prevent
5283+
// it from going all the way down?
5284+
insta::assert_snapshot!(graph_workspace(&graph.to_workspace()?), @r"
5285+
📕🏘️:0:gitbutler/workspace <> ✓refs/remotes/origin/main⇣1 on 081bae9
5286+
└── ≡📙:3:A <> origin/A →:4:⇣1 {1}
5287+
└── 📙:3:A <> origin/A →:4:⇣1
5288+
├── 🟣197ddce
5289+
├── ❄️081bae9 (🏘️|✓)
5290+
└── ❄️3183e43 (🏘️|✓)
5291+
");
5292+
5293+
Ok(())
5294+
}
5295+
5296+
#[test]
5297+
fn remote_and_integrated_tracking_branch_on_merge_extra_target() -> anyhow::Result<()> {
5298+
let (repo, mut meta) =
5299+
read_only_in_memory_scenario("ws/remote-and-integrated-tracking-extra-commit")?;
5300+
insta::assert_snapshot!(visualize_commit_graph_all(&repo)?, @r"
5301+
* 5f2810f (HEAD -> gitbutler/workspace) GitButler Workspace Commit
5302+
* 9f47a25 (A) A-local
5303+
| * c1e26b0 (origin/main, main) M-advanced
5304+
|/
5305+
| * 2181501 (origin/A) A-remote
5306+
|/
5307+
* 1ee1e34 M-base
5308+
|\
5309+
| * efc3b77 (tmp1) X
5310+
* | c822d66 Y
5311+
|/
5312+
* bce0c5e M2
5313+
* 3183e43 M1
5314+
");
5315+
add_stack_with_segments(&mut meta, 1, "A", StackState::InWorkspace, &[]);
5316+
let graph = Graph::from_head(
5317+
&repo,
5318+
&*meta,
5319+
standard_options().with_extra_target_commit_id(repo.rev_parse_single("origin/main")?),
5320+
)?
5321+
.validated()?;
5322+
insta::assert_snapshot!(graph_workspace(&graph.to_workspace()?), @r"
5323+
📕🏘️:0:gitbutler/workspace <> ✓refs/remotes/origin/main⇣1 on 1ee1e34
5324+
└── ≡📙:3:A <> origin/A →:4:⇡1⇣1 on 1ee1e34 {1}
5325+
└── 📙:3:A <> origin/A →:4:⇡1⇣1
5326+
├── 🟣2181501
5327+
└── ·9f47a25 (🏘️)
5328+
");
5329+
5330+
Ok(())
5331+
}
5332+
52215333
#[test]
52225334
fn unapplied_branch_on_base() -> anyhow::Result<()> {
52235335
let (repo, mut meta) = read_only_in_memory_scenario("ws/unapplied-branch-on-base")?;

crates/gitbutler-project/src/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl Project {
202202
let mut projects = crate::dangerously_list_projects_without_migration()?;
203203
// Sort projects by longest pathname to shortest.
204204
// We need to do this because users might have one gitbutler project
205-
// nexted insided of another via a gitignored folder.
205+
// nexted inside another via a gitignored folder.
206206
// We want to match on the longest project path.
207207
projects.sort_by(|a, b| {
208208
a.worktree_dir

0 commit comments

Comments
 (0)