-
Notifications
You must be signed in to change notification settings - Fork 679
v1 of many gitbutler cli commands #10058
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
schacon
wants to merge
40
commits into
master
Choose a base branch
from
sc-but
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The latest updates on your projects. Learn more about Vercel for GitHub.
|
26484aa
to
7311dcf
Compare
Adding a but config that by default shows some of the important config Values like name and email.
Introduce an explicit "Undo" subcommand (alias: undo) and an "Oplog" subcommand (alias: oplog) in the CLI to expose operation history and restore functionality. Add the new gitbutler-oplog workspace, wire the new modules into main, and implement a new undo module that finds the previous snapshot, acquires exclusive worktree access, and restores the repository to that snapshot. This change was needed to replace a generic "revert" behavior with a clearer "but restore"/undo flow so users can inspect the oplog and reliably roll back the last operation. Log: add --short option to display branch topology with commit counts Add a --short (-s) flag to the Log subcommand to provide a concise view of the branch topology that shows only branch names and the number of commits (upstream vs local) instead of full commit details. This was needed to support a compact, high-level overview mode for users who only want topology and commit counts. Changes: - Add short: bool to the Log CLI subcommand. - Extend commit_graph signature to accept a short flag and route Log to the new signature. - Implement commit_graph_short to render branch topology with commit counts and simplified symbols, and return early when short is requested.
The status output now prints base information, then iterates stacks to show each branch as a section containing upstream/local commits and its assigned files, followed by an Unassigned Changes section for files not assigned to any stack. This reorganizes the previous single print_group into focused helpers (print_base_info, print_branch_sections, print_unassigned_section) and groups assignments by file so the UI matches the requested layout.
Make base/behind calculations and display conditional on the -b/--base flag so the status command only shows base branch and behind counts when explicitly requested. This avoids unnecessary computation and clutter in the default status output. Also update status rendering to correctly connect stacked branches visually: compute prefixes and connectors, track nesting and branch counts, and print closing connectors so stacked branches appear as a connected graph rather than independent entries. Command argument parsing and call sites were adjusted to pass the new flag into the status worktree function. Show assigned files only on top branch and fix graph gaps Prevent assigned files from appearing on every stacked branch by only printing assignments for the first (topmost) branch in a stack. Files are associated with the stack rather than individual branches, so this change filters assignments by stack_id only for the first branch and avoids duplicating file listings across stacked branches. Also simplify connector logic, tighten prefix/connector printing, and fix graph closing/spacing so connectors and nesting lines render correctly (fill gaps and ensure proper trailing lines between stacks). Show stack-assigned files above commit list Show assigned files for the stack before printing the branch commit list so that files (which are associated with the stack, not individual branches) appear above the commits for the topmost branch. This reorders the output: assigned files are displayed first (only for the stack's first branch) and commits (upstream then local) are shown afterwards, improving clarity of the status view. Fix branch graph ASCII and show base commit Adjust the branch graph printing to match the requested ASCII layout and include the repository base commit. Changes include: cloning project path where needed, passing project to print_branch_sections, correcting the final nesting line from └─╯ to ├─╯, and appending code to compute and print the 7-char base SHA as “● <sha> (base)”. These updates ensure the visual stack/tree output matches the prompt and that the graph explicitly shows the common merge base. Fix broken graph rendering for second branch Correct the stack-closing logic in status display to avoid incorrect nesting and a broken graph for the second branch. Remove unused mutable nesting, simplify the closure behavior for last vs non-last stacks, and ensure proper blank-line separation so the rendered graph lines (like "├─╯") appear correctly for the second branch.
Add a new branch subcommand and implementation to create virtual branches. This introduces a `Branch::New` clap subcommand (with optional base id) and a new module that can create either an empty virtual branch or a stacked branch based on an existing branch id.
This commit enhances the branch resolution logic in the `crates/but/src/branch/mod.rs` file. The changes include: - First, it tries to resolve the provided ID as a CLI ID. If it matches a single branch, it uses the branch name from the CLI ID. - If the ID does not match any CLI ID, it treats it as a direct branch name and checks if the branch exists locally. If it does, it uses the provided name. - If the ID does not match any branch, it returns an error. - The commit also updates the log messages to reflect the new logic.
All unassigned files and all files assigned to the stack will be committed to the first stack. If there is more than one stack, list out the stacks and prompt the user which one they want to commit to. You cando `but commit -m 'my cache testing changes'` with a `-m` or `--message` to supply a message on the command line, or if you don't, it will open $EDITOR or read the `core.editor` git config and launch that editor with a tempfile for you to supply the message.
Introduce a `new` subcommand and corresponding CLI parsing to allow inserting a blank commit before a specified commit or at the top of a stack when given a branch.
When displaying commit lists in but status and but log, blank commit messages were shown as empty lines, making output ambiguous. Introduce format_commit_message helper functions in both log and status modules that return the first line of the commit message or "(blank message)" when the first line is empty.
This commit adds the ability to restore the workspace to a previous state based on an oplog snapshot. The key changes are: - Implement the `restore_to_oplog` function in the `restore` module - Add support for partial SHA matching when looking up the target snapshot - Display information about the target snapshot before confirming the restore - Acquire exclusive access to the worktree before performing the restore - Provide a success message with the new snapshot ID after the restore The restore functionality is an important feature to allow users to easily revert their workspace to a known good state, which is useful for debugging or undoing unwanted changes.
The next_help_heading attributes on Subcommands were unused; remove them to clean up args.rs. Replace the hardcoded grouped help text in print_grouped_help() with logic that builds groups from an array and pulls each subcommand's oneline description from the clap spec (via CommandFactory). This avoids duplicating descriptions, centralizes subcommand metadata, and makes group ordering explicit. Group unspecified Clap subcommands into MISC Avoid hardcoding a MISC list by automatically collecting and printing any subcommands that aren't included in the explicit groups. This adds a HashSet to track printed commands, filters out hidden commands, and prints remaining commands under a MISC heading so help output stays accurate and requires less manual maintenance.
Add a --files / -f option to the status command to list files modified in each commit, each annotated with a CliId shortcode for rubbing. This change was needed so users can inspect per-commit file changes directly from `but status -f` and reference files by a stable shortcode. Add 'st' alias for 'but status’ and `stf` for `but status -f`
Ensure all CliId representations start with only letters g–z by replacing the previous base-36 (0-9, a-z) encoding with a base-20 alphabet of "ghijklmnopqrstuvwxyz". The second part of the ID can be the full 36-char range. This is to ensure there is no confusion with a SHA. Special-case unassigned area as "00"
Distinguish committed files from uncommitted/unassigned ones by adding a CommittedFile variant to CliId, generating hashes that include the commit OID so identical paths in different commits get unique shortcodes. Update display in status to use the committed file IDs, and add handling in rub to reject or explicitly bail on unsupported operations involving committed files (extracting/moving between commits/branches) with clear error messages. This was needed so files with the same path but different contexts (unassigned, assigned to a branch, or present in a specific commit) receive distinct short IDs and to prevent invalid rub operations against committed files.
Add plumbing to allow uncommitting files from commits via the `rub` subcommand so the UI's "uncommit" action (alt-click) can call into the CLI.
Support identifying branches and commits by branch name (exact or partial) and by partial SHA prefixes in addition to the existing CliId lookup. This change adds helper functions to find branches by name and commits by SHA prefix, extends the CliId.from_str resolution to try branch-name and SHA matching before/alongside existing prefix/exact CliId matching, and de-duplicates results. It also improves ambiguity error messages in rub to include branch names and suggest using longer SHAs or full branch names to disambiguate.
Clarify why a commit might not be found and suggest running 'but status' to refresh state. Provide more context in errors for source/target lookups, and include the short commit id in squash/undo errors so users know which commit is affected.
Add simple colored status decorations to commits to indicate whether a commit is remote-only (R), pushed/both (P), or local-only (L). This makes it easier to visually distinguish commits that exist only upstream, those already pushed and present locally, and local-only commits.
Introduce a new ‘unapply' branch subcommand and implement unapply_branch to unapply a virtual branch (or branch by CLI ID/full name). This changeadds the CLI variant, wires the handler into main, and implements logic to resolve CLI IDs, locate the associated stack, call unapply_stack, and print user-facing messages.
This change implements creating a new virtual branch based on the target branch by locating the target stack, creating a BranchCreateRequest, and calling create_virtual_branch. Note: proper stacking relationships and full integration with the stacking system remain TODO and will require further work.
When attempting to assign a file that is locked by hunks on other commits, the code previously printed a debug-style rejection list and then misleadingly reported success. Instead, fail fast with a user-friendly error that explains the file is locked to other commit(s) and suggests using git to modify commits or move the changes. This prevents confusing output and makes the failure reason clear.
Add an -o/--only option to the commit command so only files assigned to the target stack are committed and unassigned files are excluded when requested. This was needed to provide finer control over commits (commit only assigned files) instead of always including unassigned files. Changes: - CLI: add --only (-o) boolean flag to commit args. - Commit logic: respect the only flag and skip adding unassigned files when true. - Main wiring: pass the only flag from CLI into commit handler.
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.
Committing to a stacked branch was unstacking it because the commit routine let the parent be auto-detected, which could detach the stack. This change finds the intended target branch (honoring an optional branch hint via exact name or CLI id parsing), uses that branch's tip as the explicit parent for create_commit_simple, and thus preserves the stack relationship. - Resolve target stack and branch selection: try branch hint first, fall back to stack HEAD. - Parse CLI branch hints to match branch names when needed. - Pass branch tip as parent_id to the simple commit engine to avoid unstacking.
Ensure each `but rub` command records an oplog entry by creating a snapshot before performing state-changing operations. The change imports oplog types and adds a helper create_snapshot that uses the project's exclusive worktree access and CommandContext::create_snapshot. Snapshot creation calls (with appropriate OperationKind values) are added across all relevant match arms (moves, assigns, amends, undo, squash, etc.).
Ensure "but undo" only reverts the most recent non-restore command instead of stepping back multiple times. Previously the code always inspected the second snapshot which could point to a restore operation and cause undo to jump back further; now we fetch more snapshots, skip the current one, and select the first snapshot whose operation is not a RestoreFromSnapshot. If no such snapshot exists, we print a message and exit. This prevents undo from reverting more than the last actual user operation. Undo: restore oplog head as undo target Simplify the undo command to use the oplog head (the last operation before the current state) as the target to restore. The previous logic fetched many snapshots and attempted to skip restore operations to find a prior non-restore operation; this was more complex than necessary. Fetch only the last snapshot and treat it as the target, remove unused OperationKind import and the verbose current-operation printout. This makes undo behavior clearer and reduces snapshot traversal complexity. Restore second-most recent snapshot instead of latest The undo command was intended to restore the second-most recent operation (i.e., step back one more change), but it only listed one snapshot and selected the most recent. Change to request two snapshots and validate that at least two exist, then select snapshots[1] as the target. This ensures the command restores the previous oplog entry instead of the current head.
so if you have status: ❯ but st ╭ jy [my-stacked-branch4] │ lz A t.md │ ● L rg 6f9a7dd hite ● L vy 31f83d6 test ● L qr 07f46fb move network info │ │ ● b2f17f4 (base) 00 Unassigned Changes l9 M hello_world.rb g6 A t1.md rj A t2.md ix A t3.md you can run but rub g6-ix jy and it will rub all three of those files. or but rub g6,ix jy and it will only rub those two.
Allow commands to accept multiple source identifiers by parsing ranges (start-end), comma-separated lists, or single IDs. Previously the ids() function enforced exactly one source and returned a single CliId; now it returns a Vec<CliId> for sources and a single target. This change adds parse_sources, parse_range, and parse_list helpers, uses status/committed lists to resolve ranges, and improves error messages for not-found or ambiguous items.
Use the same display order as the status command when resolving a start..end file range. The previous implementation searched an unordered file list (and fell back to committed files), which could omit files that appear between the endpoints in the UI. This change adds get_all_files_in_display_order() to build the file list in the exact order shown by status (grouping assignments by file, iterating assigned files per stack, then unassigned files) and uses it to compute ranges. This ensures ranges include all files shown between the endpoints in the status view.
Allow the oplog command to return JSON when the json flag is set. Previously the json parameter was unused; this change wires the flag into show_oplog, prints an empty JSON array when no snapshots are found, and emits pretty-printed JSON for the snapshots. When not in JSON mode, the existing human-readable, colorized output is preserved. Additionally, minor refactoring fixes variable indentation and ensures snapshot details are handled correctly for both output modes.
Add key/value handling to the Config subcommand so `but config <key> [value]` can get or set configuration values (e.g.,user.name / user.email). Implement config::handle to dispatch: setting writes to the local repo config, getting uses existing lookup logic (including user.name/email helpers) and prints JSON when requested; fall back to the original show() behavior when no key is provided. Update CLI args to accept optional key and value and wire the new handler into main. This change was needed so that commands like `but config user.name <name>` actually set the name and `but config user.name` returns the effective value using the same lookup order as other config reads. It preserves existing behavior for showing all configuration and improves UX by supporting direct get/set operations.
Fix a thing
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds the first testing version of many gitbutler cli workspace commands:
This is the rebased, cleaned up and combined version of #9971 #9987 #9991 and #9993.