Skip to content

Commit 62768ab

Browse files
committed
CLI: Add remote branch support
Implement the ability to specify a remote branch when creating or stacking branches through the but-testing CLI tool. - Add `remote` option to CLI args - Support logic changes for remote branch operations in main command logic and handler This is a prerequisite for creating stacks from remote branches in the system.
1 parent afaaef8 commit 62768ab

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

crates/but-testing/src/args.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ pub enum Subcommands {
215215
/// This is the place where some metadata about the branch can be stored.
216216
#[clap(long, short = 'd')]
217217
description: Option<String>,
218+
/// Whether the branch is a remote branch
219+
#[clap(long, short = 'u', default_value_t = false)]
220+
remote: bool,
218221
},
219222
/// Create a reference at the given position (dependent and independent)
220223
CreateReference {

crates/but-testing/src/command/mod.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,12 @@ pub mod stacks {
162162
use but_settings::AppSettings;
163163
use but_workspace::{StacksFilter, stack_branches, ui};
164164
use gitbutler_command_context::CommandContext;
165+
use gitbutler_reference::{Refname, RemoteRefname};
165166
use gitbutler_stack::StackId;
166167
use gix::bstr::ByteSlice;
167168
use gix::refs::Category;
168169
use std::path::Path;
170+
use std::str::FromStr;
169171

170172
pub fn list(
171173
current_dir: &Path,
@@ -255,9 +257,40 @@ pub mod stacks {
255257
/// Create a new stack containing only a branch with the given name.
256258
fn create_stack_with_branch(
257259
ctx: &CommandContext,
260+
project: gitbutler_project::Project,
258261
name: &str,
262+
remote: bool,
259263
description: Option<&str>,
260-
) -> anyhow::Result<ui::StackEntryNoOpt> {
264+
) -> anyhow::Result<ui::StackEntry> {
265+
let repo = ctx.gix_repo()?;
266+
let remotes = repo.remote_names();
267+
if remote {
268+
let remote_name = remotes
269+
.first()
270+
.map(|r| r.to_str().unwrap())
271+
.context("No remote found in repository")?;
272+
273+
let ref_name = Refname::from_str(&format!("refs/remotes/{remote_name}/{name}"))?;
274+
let remote_ref_name = RemoteRefname::new(remote_name, name);
275+
276+
let (stack_id, _) = gitbutler_branch_actions::create_virtual_branch_from_branch(
277+
ctx,
278+
&ref_name,
279+
Some(remote_ref_name),
280+
None,
281+
)?;
282+
283+
let stack_entries =
284+
but_workspace::stacks(ctx, &project.gb_dir(), &repo, Default::default())?;
285+
let stack_entry = stack_entries
286+
.into_iter()
287+
.find(|entry| entry.id == Some(stack_id))
288+
.ok_or_else(|| {
289+
anyhow::anyhow!("Failed to find newly created stack with ID: {stack_id}")
290+
})?;
291+
return Ok(stack_entry);
292+
};
293+
261294
let creation_request = gitbutler_branch::BranchCreateRequest {
262295
name: Some(name.to_string()),
263296
..Default::default()
@@ -277,7 +310,7 @@ pub mod stacks {
277310
)?;
278311
}
279312

280-
Ok(stack_entry)
313+
Ok(stack_entry.into())
281314
}
282315

283316
/// Add a branch to an existing stack.
@@ -326,6 +359,7 @@ pub mod stacks {
326359
name: &str,
327360
description: Option<&str>,
328361
current_dir: &Path,
362+
remote: bool,
329363
use_json: bool,
330364
ws3: bool,
331365
) -> anyhow::Result<()> {
@@ -348,7 +382,7 @@ pub mod stacks {
348382

349383
let stack_entry = match id {
350384
Some(id) => add_branch_to_stack(&ctx, id, name, description, project.clone(), &repo)?,
351-
None => create_stack_with_branch(&ctx, name, description)?.into(),
385+
None => create_stack_with_branch(&ctx, project.clone(), name, remote, description)?,
352386
};
353387

354388
if use_json {

crates/but-testing/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,14 @@ async fn main() -> Result<()> {
184184
id,
185185
branch_name,
186186
description,
187+
remote,
187188
} => match (branch_name, id) {
188189
(Some(branch_name), maybe_id) => command::stacks::create_branch(
189190
*maybe_id,
190191
branch_name,
191192
description.as_deref(),
192193
&args.current_dir,
194+
*remote,
193195
args.json,
194196
args.v3,
195197
),

0 commit comments

Comments
 (0)