Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/but/src/args/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub enum CommandName {
Stf,
Rub,
Diff,
Squash,
Commit,
Push,
New,
Expand Down
34 changes: 34 additions & 0 deletions crates/but/src/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,40 @@ pub enum Subcommands {
force: bool,
},

/// Squash multiple commits together and use AI to generate a combined commit message.
///
/// This command takes two or more commit IDs or CLI short IDs. All commits must be
/// in the same stack and form a contiguous range. The commits are squashed together
/// into the oldest (parent-most) commit, and AI is used to generate a new combined
/// commit message from all original messages.
Comment on lines +425 to +427
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation says "All commits must be in the same stack and form a contiguous range" but the current implementation doesn't verify the contiguous range requirement (see the bug in the verification logic at lines 209-228). Either fix the verification logic to truly enforce contiguity, or update this documentation to match what the code actually does.

Suggested change
/// in the same stack and form a contiguous range. The commits are squashed together
/// into the oldest (parent-most) commit, and AI is used to generate a new combined
/// commit message from all original messages.
/// in the same stack. The commits are squashed together into the oldest (parent-most)
/// commit, and AI is used to generate a new combined commit message from all original
/// messages.

Copilot uses AI. Check for mistakes.
///
/// ## Examples
///
/// Squash two commits using their SHAs:
///
/// ```text
/// but squash abc1234 def5678
/// ```
///
/// Squash three commits using CLI short IDs from `but status`:
///
/// ```text
/// but squash 3a 4b 5c
/// ```
///
/// Squash a range of commits:
///
/// ```text
/// but squash 2a 3a 4a 5a
/// ```
///
#[cfg(feature = "legacy")]
Squash {
/// The commit IDs or CLI short IDs to squash together (minimum 2)
#[clap(required = true, num_args = 2..)]
commits: Vec<String>,
},

/// Undo the last operation by reverting to the previous snapshot.
///
/// This is a shorthand for restoring to the last oplog entry before the
Expand Down
2 changes: 1 addition & 1 deletion crates/but/src/command/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn print_grouped(out: &mut dyn std::fmt::Write) -> std::fmt::Result {
("Server Interactions".yellow(), vec!["push", "pr", "forge"]),
(
"Editing Commits".yellow(),
vec!["rub", "describe", "absorb"],
vec!["rub", "squash", "describe", "absorb"],
),
(
"Operation History".yellow(),
Expand Down
1 change: 1 addition & 0 deletions crates/but/src/command/legacy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ pub mod oplog;
pub mod pull;
pub mod push;
pub mod rub;
pub mod squash;
pub mod status;
pub mod worktree;
Loading
Loading