Skip to content

Commit 9e19cd8

Browse files
committed
but branch show command
for insepecting a branch Show conflicting files and their modifying commits in branch merge check Previously the merge check listed upstream commits that conflicted, which hid which files were actually in conflict and which commits on each side touched those files. Replace the conflicting-commits model with a conflicting-files model that lists each conflicting file and the commits from the branch and from upstream that modified that file. This improves the merge-check output by focusing on problematic files and showing the concrete commits on both sides that caused the conflict.
1 parent 096a2fd commit 9e19cd8

File tree

4 files changed

+1038
-3
lines changed

4 files changed

+1038
-3
lines changed

crates/but/src/args.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,68 @@ For examples see `but rub --help`."
209209
},
210210
}
211211

212+
impl Subcommands {
213+
pub fn to_metrics_command(&self) -> CommandName {
214+
use CommandName::*;
215+
match self {
216+
Subcommands::Log => Log,
217+
Subcommands::Status { .. } => Status,
218+
Subcommands::Stf { .. } => Stf,
219+
Subcommands::Rub { .. } => Rub,
220+
Subcommands::Base(base::Platform { cmd }) => match cmd {
221+
base::Subcommands::Update => BaseUpdate,
222+
base::Subcommands::Check => BaseCheck,
223+
},
224+
Subcommands::Branch(branch::Platform { cmd }) => match cmd {
225+
None | Some(branch::Subcommands::List { .. }) => BranchList,
226+
Some(branch::Subcommands::New { .. }) => BranchNew,
227+
Some(branch::Subcommands::Delete { .. }) => BranchDelete,
228+
Some(branch::Subcommands::Unapply { .. }) => BranchUnapply,
229+
Some(branch::Subcommands::Apply { .. }) => BranchApply,
230+
Some(branch::Subcommands::Show { .. }) => BranchShow,
231+
},
232+
Subcommands::Worktree(crate::worktree::Platform { cmd: _ }) => Worktree,
233+
Subcommands::Mark { .. } => Mark,
234+
Subcommands::Unmark => Unmark,
235+
Subcommands::Gui => Gui,
236+
Subcommands::Commit { .. } => Commit,
237+
Subcommands::Push(_) => Push,
238+
Subcommands::New { .. } => New,
239+
Subcommands::Describe { .. } => Describe,
240+
Subcommands::Oplog { .. } => Oplog,
241+
Subcommands::Restore { .. } => Restore,
242+
Subcommands::Undo => Undo,
243+
Subcommands::Snapshot { .. } => Snapshot,
244+
Subcommands::Claude(claude::Platform { cmd }) => match cmd {
245+
claude::Subcommands::PreTool => ClaudePreTool,
246+
claude::Subcommands::PostTool => ClaudePostTool,
247+
claude::Subcommands::Stop => ClaudeStop,
248+
claude::Subcommands::Last { .. }
249+
| claude::Subcommands::PermissionPromptMcp { .. } => Unknown,
250+
},
251+
Subcommands::Cursor(cursor::Platform { cmd }) => match cmd {
252+
cursor::Subcommands::AfterEdit => CursorAfterEdit,
253+
cursor::Subcommands::Stop { .. } => CursorStop,
254+
},
255+
Subcommands::Forge(forge::integration::Platform { cmd }) => match cmd {
256+
forge::integration::Subcommands::Auth => ForgeAuth,
257+
forge::integration::Subcommands::Forget { .. } => ForgeForget,
258+
forge::integration::Subcommands::ListUsers => ForgeListUsers,
259+
},
260+
Subcommands::Review(forge::review::Platform { cmd }) => match cmd {
261+
forge::review::Subcommands::Publish { .. } => PublishReview,
262+
forge::review::Subcommands::Template { .. } => ReviewTemplate,
263+
},
264+
Subcommands::Completions { .. } => Completions,
265+
Subcommands::Absorb { .. } => Absorb,
266+
Subcommands::Metrics { .. }
267+
| Subcommands::Actions(_)
268+
| Subcommands::Mcp { .. }
269+
| Subcommands::Init { .. } => Unknown,
270+
}
271+
}
272+
}
273+
212274
#[derive(Debug, Clone, Copy, clap::ValueEnum, Default)]
213275
pub enum CommandName {
214276
Log,
@@ -231,6 +293,7 @@ pub enum CommandName {
231293
BranchNew,
232294
BranchDelete,
233295
BranchList,
296+
BranchShow,
234297
BranchUnapply,
235298
BranchApply,
236299
ClaudePreTool,

crates/but/src/branch/mod.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111

1212
mod apply;
1313
mod list;
14+
mod show;
1415

1516
mod json {
1617
use serde::Serialize;
@@ -133,6 +134,26 @@ pub enum Subcommands {
133134
#[clap(long)]
134135
no_check: bool,
135136
},
137+
/// Show commits ahead of base for a specific branch
138+
Show {
139+
/// CLI ID or name of the branch to show
140+
branch_id: String,
141+
/// Fetch and display review information
142+
#[clap(short, long)]
143+
review: bool,
144+
/// Disable pager output
145+
#[clap(long)]
146+
no_pager: bool,
147+
/// Show files modified in each commit with line counts
148+
#[clap(short, long)]
149+
files: bool,
150+
/// Generate AI summary of the branch changes
151+
#[clap(long)]
152+
ai: bool,
153+
/// Check if the branch merges cleanly into upstream and identify conflicting commits
154+
#[clap(long)]
155+
check: bool,
156+
},
136157
/// Apply a branch to the workspace
137158
Apply {
138159
/// Name of the branch to apply
@@ -152,6 +173,7 @@ pub async fn handle(
152173
cmd: Option<Subcommands>,
153174
ctx: &but_ctx::Context,
154175
out: &mut OutputChannel,
176+
json: bool,
155177
) -> anyhow::Result<serde_json::Value> {
156178
let legacy_project = &ctx.legacy_project;
157179
match cmd {
@@ -173,7 +195,8 @@ pub async fn handle(
173195
json,
174196
check,
175197
)
176-
.await
198+
.await?;
199+
Ok(we_need_proper_json_output_here())
177200
}
178201
Some(Subcommands::List {
179202
filter,
@@ -197,9 +220,30 @@ pub async fn handle(
197220
json,
198221
check,
199222
)
200-
.await
223+
.await?;
224+
Ok(we_need_proper_json_output_here())
225+
}
226+
Some(Subcommands::Show {
227+
branch_id,
228+
review,
229+
no_pager,
230+
files,
231+
ai,
232+
check,
233+
}) => {
234+
show::show(
235+
legacy_project,
236+
&branch_id,
237+
json,
238+
review,
239+
!no_pager,
240+
files,
241+
ai,
242+
check,
243+
)
244+
.await?;
245+
Ok(we_need_proper_json_output_here())
201246
}
202-
Some(Subcommands::List { local }) => list::list(legacy_project, local, out).await,
203247
Some(Subcommands::New {
204248
branch_name,
205249
anchor,

0 commit comments

Comments
 (0)