Skip to content

Commit 4585795

Browse files
committed
Automatically setup the remote tracking of branches on apply
1 parent 2af0789 commit 4585795

File tree

3 files changed

+50
-13
lines changed

3 files changed

+50
-13
lines changed

crates/but-workspace/src/branch/apply.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,8 @@ pub(crate) mod function {
139139
order,
140140
}: Options,
141141
) -> anyhow::Result<Outcome<'graph>> {
142-
let branch_ref = repo.try_find_reference(branch)?;
143-
if branch_ref
144-
.as_ref()
145-
.is_some_and(|r| matches!(r.target(), gix::refs::TargetRef::Symbolic(_)))
146-
{
147-
bail!(
148-
"Refusing to apply symbolic ref '{}' due to potential ambiguity",
149-
branch.shorten()
150-
);
151-
}
142+
let branch_orig = branch;
143+
let mut branch_ref = try_find_validated_ref(repo, branch)?;
152144
if workspace.is_branch_the_target_or_its_local_tracking_branch(branch) {
153145
bail!("Cannot add the target '{branch}' branch to its own workspace");
154146
}
@@ -169,6 +161,7 @@ pub(crate) mod function {
169161
branch_storage = upstream_branch_name;
170162
// Pretend the upstream branch is also the local tracking name.
171163
branch = branch_storage.as_ref();
164+
branch_ref = try_find_validated_ref(repo, branch)?;
172165
}
173166
let conflicting_stack_ids = Vec::new();
174167
if workspace.is_reachable_from_entrypoint(branch) {
@@ -370,6 +363,9 @@ pub(crate) mod function {
370363
}
371364
// We will want to merge, but be sure the branch exists, can't apply non-existing.
372365
if branch_ref.is_none() {
366+
if !std::ptr::eq(branch_orig, branch) {
367+
todo!("Create local tracking branch");
368+
}
373369
bail!(
374370
"Cannot apply non-existing branch '{branch}'",
375371
branch = branch.shorten()
@@ -720,4 +716,21 @@ pub(crate) mod function {
720716
))
721717
}
722718
}
719+
720+
fn try_find_validated_ref<'repo>(
721+
repo: &'repo gix::Repository,
722+
branch: &gix::refs::FullNameRef,
723+
) -> anyhow::Result<Option<gix::Reference<'repo>>> {
724+
let branch_ref = repo.try_find_reference(branch)?;
725+
if branch_ref
726+
.as_ref()
727+
.is_some_and(|r| matches!(r.target(), gix::refs::TargetRef::Symbolic(_)))
728+
{
729+
bail!(
730+
"Refusing to apply symbolic ref '{}' due to potential ambiguity",
731+
branch.shorten()
732+
);
733+
}
734+
Ok(branch_ref)
735+
}
723736
}

crates/but-workspace/tests/fixtures/scenario/main-with-advanced-remote.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ commit M1
99
commit only-on-remote
1010
setup_target_to_match_main
1111
git reset --hard @~1
12+
13+
git checkout -b soon-tracking-of-feature
14+
commit without-local-tracking
15+
git checkout main
16+
turn_into_remote_branch soon-tracking-of-feature feature

crates/but-workspace/tests/workspace/branch/apply_unapply_commit_uncommit.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,17 @@ fn ws_ref_no_ws_commit_two_virtual_stacks_on_same_commit_apply_dependent_first()
105105
}
106106

107107
#[test]
108-
fn main_with_advanced_remote() -> anyhow::Result<()> {
108+
fn main_with_advanced_remote_tracking_branch() -> anyhow::Result<()> {
109109
let (_tmp, graph, repo, _vb_version_cannot_have_remotes, _description) =
110110
named_writable_scenario_with_description_and_graph(
111111
"main-with-advanced-remote",
112112
|_meta| {},
113113
)?;
114114

115115
insta::assert_snapshot!(visualize_commit_graph_all(&repo)?, @r"
116-
* 552e7dc (origin/main) only-on-remote
116+
* 6b40b15 (origin/feature) without-local-tracking
117+
| * 552e7dc (origin/main) only-on-remote
118+
|/
117119
* 3183e43 (HEAD -> main) M1
118120
");
119121

@@ -146,7 +148,24 @@ fn main_with_advanced_remote() -> anyhow::Result<()> {
146148
}
147149
");
148150

149-
// TODO: show how a proper local tracking branch is created on the fly.
151+
// Set up an automatic tracking of origin/feature, as remote tracking branches can't be in the workspace.
152+
let out = but_workspace::branch::apply(
153+
r("refs/remotes/origin/feature"),
154+
&ws,
155+
&repo,
156+
&mut meta,
157+
default_options(),
158+
)?;
159+
insta::assert_debug_snapshot!(out, @r"
160+
Outcome {
161+
workspace_changed: true,
162+
workspace_ref_created: true,
163+
}
164+
");
165+
let graph = out.graph;
166+
let ws = graph.to_workspace()?;
167+
// both branches, main and feature, are available in the newly created workspace ref.
168+
insta::assert_snapshot!(graph_workspace(&ws), @r"");
150169
Ok(())
151170
}
152171

0 commit comments

Comments
 (0)