Skip to content

Commit 2b59fa2

Browse files
committed
Allow specifying branch instead of --stack for commit
Remove the --stack option and accept an optional branch ID or name to derive the stack to commit to. This lets users run commands like `but commit -m "message" x4` or `but commit my-branch-name`. Changes: - CLI: replace `--stack`/-s with a positional/optional `branch` argument. - commit API: rename `stack_hint` to `branch_hint` and thread it through callers. - Selection logic: update select_stack to accept a CommandContext, match exact branch names first, then attempt to parse CLI IDs and resolve branch CLI IDs to stacks, and improve error messages to reference branches. - Main: pass `branch` through to the commit handler.
1 parent 1b48823 commit 2b59fa2

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

crates/but/src/args.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@ pub enum Subcommands {
6161
/// Commit message
6262
#[clap(short = 'm', long = "message")]
6363
message: Option<String>,
64-
/// Stack ID or name to commit to (if multiple stacks exist)
65-
#[clap(short = 's', long = "stack")]
66-
stack: Option<String>,
64+
/// Branch CLI ID or name to derive the stack to commit to
65+
branch: Option<String>,
6766
/// Only commit assigned files, not unassigned files
6867
#[clap(short = 'o', long = "only")]
6968
only: bool,

crates/but/src/commit/mod.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub(crate) fn commit(
1818
repo_path: &Path,
1919
_json: bool,
2020
message: Option<&str>,
21-
stack_hint: Option<&str>,
21+
branch_hint: Option<&str>,
2222
only: bool,
2323
) -> anyhow::Result<()> {
2424
let project = Project::from_path(repo_path)?;
@@ -46,7 +46,7 @@ pub(crate) fn commit(
4646
stacks[0].0
4747
} else {
4848
// Multiple stacks - need to select one
49-
select_stack(&stacks, stack_hint)?
49+
select_stack(&mut ctx, &stacks, branch_hint)?
5050
};
5151

5252
// Get changes and assignments
@@ -172,20 +172,43 @@ pub(crate) fn commit(
172172
}
173173

174174
fn select_stack(
175+
ctx: &mut CommandContext,
175176
stacks: &[(but_workspace::StackId, but_workspace::ui::StackDetails)],
176-
stack_hint: Option<&str>,
177+
branch_hint: Option<&str>,
177178
) -> anyhow::Result<but_workspace::StackId> {
178-
// If a stack hint is provided, try to find it
179-
if let Some(hint) = stack_hint {
180-
// Try to match by branch name in stacks
179+
// If a branch hint is provided, try to find it
180+
if let Some(hint) = branch_hint {
181+
// First, try to find by exact branch name match
181182
for (stack_id, stack_details) in stacks {
182183
for branch in &stack_details.branch_details {
183184
if branch.name.to_string() == hint {
184185
return Ok(*stack_id);
185186
}
186187
}
187188
}
188-
anyhow::bail!("Stack '{}' not found", hint);
189+
190+
// If no exact match, try to parse as CLI ID
191+
match crate::id::CliId::from_str(ctx, hint) {
192+
Ok(cli_ids) => {
193+
// Filter for branch CLI IDs and find corresponding stack
194+
for cli_id in cli_ids {
195+
if let crate::id::CliId::Branch { name } = cli_id {
196+
for (stack_id, stack_details) in stacks {
197+
for branch in &stack_details.branch_details {
198+
if branch.name.to_string() == name {
199+
return Ok(*stack_id);
200+
}
201+
}
202+
}
203+
}
204+
}
205+
}
206+
Err(_) => {
207+
// Ignore CLI ID parsing errors and continue with other methods
208+
}
209+
}
210+
211+
anyhow::bail!("Branch '{}' not found", hint);
189212
}
190213

191214
// No hint provided, show options and prompt

crates/but/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ async fn main() -> Result<()> {
130130
metrics_if_configured(app_settings, CommandName::Restore, props(start, &result)).ok();
131131
result
132132
}
133-
Subcommands::Commit { message, stack, only } => {
133+
Subcommands::Commit { message, branch, only } => {
134134
let result = commit::commit(
135135
&args.current_dir,
136136
args.json,
137137
message.as_deref(),
138-
stack.as_deref(),
138+
branch.as_deref(),
139139
*only,
140140
);
141141
metrics_if_configured(app_settings, CommandName::Commit, props(start, &result)).ok();

0 commit comments

Comments
 (0)