feat(hunk-staging-2): separator-stacked staged/unstaged diff - #30
Merged
Merged
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Blankeos
force-pushed
the
feat/hunk-staging-2
branch
from
September 4, 2026 18:48
a25e2e9 to
c5e7b4e
Compare
…taging actions - Combine HEAD and unstaged diffs so the Files pane renders staged/unstaged hunks in a single buffer, tinting each hunk by its staged state (with untracked-file support and fallbacks for unborn HEAD) - Open hunk context menu on revert hover/selection and offer actions based on the specific hunk's staged state, with s/r/u keyboard shortcuts - Map viewed HEAD-buffer hunks onto per-side diff blocks via matching_side_blocks for stage/unstage/revert, handling multiple targets and stale hunks gracefully
…yphs Alternative to the single-buffer HEAD view: the Files pane renders unstaged hunks, a 'Staged changes' separator, then staged hunks, with a uniform marker glyph throughout. Directory hovers stack the unstaged and staged multi-file diffs the same way. Per-hunk Stage/Unstage/Revert menu (with s/r/u hotkeys) and click-to-menu behavior are unchanged; each section keeps its own side's line numbers so patch slicing applies directly.
Blankeos
force-pushed
the
feat/hunk-staging-2
branch
from
September 4, 2026 18:49
c5e7b4e to
80df285
Compare
…)` headers Replace the generic `Staged changes` separator with per-file headers suffixed `(Unstaged)`/`(Staged)`, both for single-file combined diffs and multi-file directory hovers. Staged hunks now appear directly after their file's unstaged hunks, and header resolution (`file_at_line`) strips the suffix back to the plain path.
tmih06
referenced
this pull request
in tmih06/lazygitrs
Sep 20, 2026
* fix(git): handle rename/copy paths consistently across diffs and file actions
Preserve rename/copy labels for display while using explicit old/new pathspecs for all git operations, filesystem actions, and diff parsing so renamed files are diffed, opened, discarded, and staged correctly without path mismatches; group renamed files under their new path in trees and render rename-only diffs as a visible changed row. Add tests for rename path helpers, tree grouping, and rename-only parse behavior.
* fix(gui): resolve previous branch checkout via explicit ref name
`checkout_previous` now resolves the current `@{-1}` branch name first and checks that out directly, avoiding failures from `git checkout -` with stale/non-local reflog entries. Updated the previous-branch picker entry to store the concrete branch name while preserving "-" discoverability in the label.
* fix(graph): restore head-marker behavior for merge nodes
Merge nodes now follow commit-cell logic for head highlighting: when a merge is at HEAD it renders as a solid circle, while non-head merges remain hexagons. This also marks the related graph TODO as completed.
* chore(release): publish Homebrew formula via release workflow
- Configure dist-workspace to generate and publish Homebrew installer metadata to the tap repo. - Add a new `publish-homebrew-formula` job in the release pipeline and gate announce on its success/skip. - Update README, npm install docs, fallback messages, and installer script with Homebrew install guidance. - Add `homepage` field to `Cargo.toml` for package metadata.
* release: lazygitrs v0.0.23
* fix(pager): render unified modified hunks in old-then-new chunk order
* perf(git,gui): avoid extra branch recency calls and gate auto-refresh on fetch output
- include commit recency in the branch format query and parse it directly, removing per-branch `git log` calls - make background fetch return whether it produced output, and update auto-fetch handling to refresh UI only when needed
* fix(pager): ignore no-newline metadata in unified diff parsing
Skip `\\ No newline at end of file` marker lines while building old/new unified-diff content to prevent highlight row drift in markdown rendering. Add a regression test to ensure marker lines do not shift rendered output.
* fix(stash): force plain unified output for stash diff
Add `--color=never` to `git stash show -p` so stash diffs are always uncolored, even when Git is configured with forced color output. Add a regression test asserting `stash_diff(0)` contains no ANSI escapes and correctly maps replacement diff rows.
* feat(gui): make diff layout toggle keybinding configurable
- Add `toggleDiffViewLayout` to universal keybindings with default `\\` - Route unified/side-by-side diff mode toggling through the configured key in diff controllers and global handlers - Replace hardcoded `v` bindings in diff help/status hints with the configured key and update docs to mention unified + side-by-side diff support
* feat(gui): show diff layout mode in status and help hints
Update commit and stash/branch-reflog file views to display the diff layout toggle (`\\`) target mode in status/help text, and switch the diff mode bar hint from a generic label to the current next-state (`unified view` / `split view`) so users can tell what the toggle will do.
* feat(gui): add confirmation before committing from detached HEAD
Show a confirm popup when invoking the commit flow while on a detached HEAD, requiring explicit acknowledgement before continuing. Update TODOs to reflect the completed detached-head task and refine cherry-pick tip wording.
* feat(gui): clarify cherry-pick copy/paste UX
Improve commit-pane help and status hints to call out `C` as **Copy (cherry-pick)** and `V` as **Paste (cherry-pick)**, and update the paste confirmation to include the actual target branch (or detached HEAD) before applying cherry-picks. Also mark the related TODO checklist items as completed.
* feat(ui): show inline diff stats in staged file lists
Add per-file hunk/addition/deletion stats to file model data from git diff, and render right-aligned `*N +A -D` indicators in both flat and tree views with width-aware truncation. Update existing file/tree tests and fixtures to cover the new file stat fields and parsing behavior.
* feat(diff): show current hunk position in side-by-side header
Display viewport hunk progress as `[current/total]` in the diff pane border while navigating shifts, and add tests for the hunk index calculation and rendered indicator. Also complete the corresponding TODO entry.
* feat(gui): show diff hunk/addition/deletion stats in commit file lists
Populate `CommitFile` with `hunk_count`, `additions`, and `deletions`, sourced from bulk `git diff --numstat`/hunk parsing, and thread these values through commit diff/file list and tree renderers so list entries now display concise right-aligned change stats with truncation-safe layout handling.
* release: lazygitrs v0.0.24
* feat(commits): add branch-aware commit checkout menu
Replace confirm-only detached-HEAD checkout with a menu offering branch checkout options for any local branch pointing at the selected commit (excluding current branch and empty hashes), plus detached-head fallback. Add numeric shortcuts (1–9) for branch actions.
Tests added for branch-at-commit matching/order and shortcut assignment.
* fix(gui): persist file-tree visibility in compare mode
Keep W diff/compare mode aligned with Files/Commit Files by initializing its tree state from the current `show_file_tree` preference, syncing backtick toggles to the shared tree visibility flags, and persisting the updated preference so list/tree mode is retained across entries.
* fix: #20 hover disabled optimistic so it doesn't hit ghostty users
* release: lazygitrs v0.0.25
* fix(gui): preserve terminal text input when enabling keyboard enhancements
Only request `DISAMBIGUATE_ESCAPE_CODES` so crossterm keeps normal text input paths; remove `REPORT_ALL_KEYS_AS_ESCAPE_CODES` and `REPORT_EVENT_TYPES` that could remap key identities or drop repeat events, and add a test asserting the safe flag set.
* release: lazygitrs v0.0.26
* fix(gui): handle fragmented escape sequences and suppress command modifiers
Handle terminal escape fragments (including Kitty-formatted modifiers) by buffering and reconstructing split events before dispatch, then avoid treating command-modified plain characters as in-app shortcuts or textarea text. This prevents unintended actions (e.g., numeric/window/app shortcuts) from terminal-level Cmd/Alt key combinations. Add regression tests for fragmented sequence parsing and modifier filtering behavior.
* perf(gui): optimize async diff loading and commit detail fetching
- Add bounded diff scheduling with generation-aware coalescing to cap concurrent diff jobs and drop stale work. - Add diff preview and commit graph caches with revision-based invalidation for instant revisits and faster commit-list rendering. - Replace inflight-sets with debounced latest-only commit details worker and simplify stats/message cache usage. - Include `--no-ext-diff`/`--no-textconv` on internal diff/stash commands for consistent output. - Add tests for revision mutators, diff scheduler behavior, preview cache eviction, and job coalescing.
* release: lazygitrs v0.0.27
* feat: Show async Loading modal during remote operations
* feat: Allow rewording empty commits
* feat: Show co-located branch labels on tags
* finish todos
* feat(tags): display remote tag presence and gate remote deletion
Load tags now detect whether each tag exists on any configured remote and store that as `on_remote`. Use this flag in the tag list to label each row as `(local)` or `(local,remote)`, and only expose remote delete actions for tags that actually exist remotely.
* perf(gui): run commit actions through async ops and streaming refresh
* fix(gui): render commit graph with per-row width and single separator space
- remove global graph width padding from commit row layout/caching - update `render_graph_spans` to infer spacing from each row only - keep exactly one space between graph symbols and commit metadata so alignment is no longer forced across rows
* fix(gui,os): harden terminal input handling and isolate background commands (#23)
- add async `InputReader` with per-keystroke sequence reassembly and bounded batch delivery - move fragmented escape/Cursor/report parsing logic and tests into new `src/gui/input.rs` - refactor main loop to consume event batches and centralize resize reflow handling - make spawned commands non-interactive (`GIT_TERMINAL_PROMPT=0`, `SSH_ASKPASS_REQUIRE=never`, optional `GIT_SSH_COMMAND`, `setsid`, stdin null) - add `libc` dependency for session-detaching background processes
* chore: added automated npm/cratesio publishing
* fix(gui): avoid overwriting commits while branch filter is active
When `commit_branch_filter` is set, skip applying streamed commit payloads so the filtered commit history remains visible during refresh. The filtered set is still reloaded afterward by `after_model_refresh` when the refresh completes.
* feat(gui): replace remote operation modal with lightweight loading toast
* feat(gui): add popup mouse selection + click-to-activate behavior
Implement staged left-click handling for action menus and checklists using popup item hit-testing helpers and new tests (`menu_item_at`, `checklist_item_at`), with first-click selection and second-click confirm/toggle behavior. Also fix side-by-side file header rendering to pad using Unicode display width for correct alignment.
* feat(gui): add draggable sidebar divider interaction
Implement mouse-driven resizing for the side/main pane split in normal mode by adding sidebar divider hit-testing, tracking an active resize gesture state, and updating the side panel ratio during drag in both portrait and landscape layouts.
* release: lazygitrs v0.0.28
* fix(gui): restore syntax highlighting for multi-file commit previews
Commit previews now build section highlighters from `parse_unified_diff` output, matching single-file behavior so multi-file side-by-side diffs retain syntax coloring instead of using default no-op highlighters.
* fix(gui): fix portrait sidebar resize hit-testing and ratio mapping
- add portrait-specific row offset state for sidebar drag tracking and reset on mouse-up/cancel - include both expanded panel bottom border and diff top border in portrait divider hit area while keeping a single-row grab target - apply the captured offset when computing sidebar ratio so all portrait drag grips map to a consistent resize position
* fix(diff): include `--root` for root-commit file diffs
`git diff-tree` without a parent can return no output for initial commits, so files in root commits were omitted. Adding `--root` makes root commits diff against the empty tree and correctly return changed files.
* perf(gui): batch directory diffs and parallelize multi-file highlighting
Directory diff generation in Files and Commit Files now uses single git pathspec calls instead of per-file loops, with dedicated pathspec-based diff helpers in `GitCommands` for staged, commit, and HEAD-comparison flows. Untracked file diffs are synthesized only for missing files and appended to the bulk pathspec diff result. Also refactors multi-file unified-diff parsing to avoid string reassembly and builds Tree-sitter highlighters in parallel for large directory/commit diffs.
* fix(gui): show placeholder for binary files in diff views
- Detect binary paths via UTF-8 and NUL-byte heuristics before reading file contents. - Synthesize binary diff output for new binary files so the pager receives a viewable placeholder. - Render binary-diff output as a stable “Binary file (not viewable)” line in side-by-side mode. - Add parser test covering binary diff placeholder rendering.
* feat(gui): support AI commit message generation for commit rewording
- Add commit/reword popup variants with context-specific titles and focus handling - Populate reword editor with existing commit summary/body split by blank line - Track AI generation source to generate messages from staged diff or selected commit diff - Extract generic diff-based AI message generator and improve cancellation/empty-diff behavior - Update commit diff retrieval to use `git show` and add coverage for new parsing paths
* perf(stash): skip commit file stats when loading stash contents
Refactor `commit_files` into an internal helper and add `commit_files_without_stats` for fast paths. Use this new API when entering stash files so large stashes stay responsive, while keeping full stats path intact. Also update TODOs to mark sidebar resize by mouse drag as completed.
* feat(gui): add global reset picker and share reset actions
- Add uppercase `G` binding for a global reset-to-any ref picker, then soft/mixed/hard reset options. - Extract shared reset-menu logic (`show_reset_menu_for_ref` and `reset_ref_display`) and reuse it from commits, reflog, and tags handlers. - Refactor branch/commit picker item generation into a shared helper so interactive rebase (`I`) and global reset (`G`) reuse the same ref sources. - Update help and README, and add tests for ref display/keybinding behavior.
* feat(gui): migrate help overlays to executable command palettes
Replace static help popups with a unified command-palette model across GUI, diff, rebase, branch, and tag flows. Introduce `CommandSection`/`CommandEntry` with `CommandAction`, add key-command dispatch + special actions, and standardize on the new command-palette search textbox.
* readme tweaks
* release: lazygitrs v0.0.29
* feat: stream HEAD metadata during model loading
Refresh the current HEAD hash and branch name asynchronously so the commit graph and UI stay synchronized during model updates.
* feat(filtering): ctrl-s, add commit filtering by branch, path, and author
Add filtering menus with path suggestions, author selection, selected-item shortcuts, and filter reset support across commit-related views.
* feat: support multi-author commit filtering
Allow selecting multiple known authors or entering custom author values, display active filters in the commit filter menu, and preserve checklist state for custom entries.
* feat(gui): add list search match highlighting in rendered panels
Add a lazy-mode-style substring highlight pass for `/` search results, applied after list widgets render so existing selection styling is preserved. Introduce `render_list_search_highlights` and invoke it for active/full-mode list surfaces in `views.rs`, using theme `search_match` style for case-insensitive contiguous matches.
* release: lazygitrs v0.0.30
* fix(git,gui): prevent concurrent fetch races causing divergent branch errors
Git fetch commands now pass `--no-write-fetch-head` to avoid `FETCH_HEAD` races, and auto-fetch is skipped while a remote operation is in progress to prevent overlapping remote ref updates. This addresses the first-`pull` divergent-branch failure scenario. Also updates the TODO to mark the `/` filter UX task as done.
* fix(gui): render pure rename diffs by falling back to file content
Handle rename/copy diffs with no hunks as full-file views (for both working-tree and commit-history diffs), so moved files display useful content instead of path-only output. Also stop resetting commit history when any commit filter (path/author/branch) is active.
* feat(presentation): fix tree row spacing for status icons
Align leading whitespace so status icons and file names line up consistently across file tree, diff tree, and commit file tree renders.
* fix(gui): migrate checklist search input to textarea with enhanced editing
Replace checklist popup filtering state from a plain `String` to a `TextArea` and route key handling through the shared textarea input helper so filtering now supports cursor movement and word/home/end/backspace shortcuts (Cmd/Ctrl/Alt variants). Also update rendering and hit-testing to read from the textarea contents while keeping free-entry sync and checklist visibility behavior intact.
* fix: errors when partially adding filetrees
* perf(gui): make stage/unstage and checkout paths non-blocking
- split file refresh into full vs status-only and use status-only on interactive paths - add optimistic in-memory stage/unstage and branch head updates for immediate UI feedback - add background refresh pipeline for files with coalescing to avoid blocking on rapid actions - retain full `load_files`/`refresh_files_only` behavior for paths needing numstat/hunk data
* perf(gui): optimize stage-all toggling with optimistic UI updates
Update stage/unstage-all to apply optimistic file-state changes immediately, rebuild the file tree from model state, and offload git operations plus status-only refresh to background work. Add `enqueue_stage_all_then_refresh` to queue background `stage_all`/`unstage_all` with completion-based file refresh handling and pending refresh coalescing. Also normalize checkout async closure formatting in `start_async_checkout` for style consistency.
* feat(git): skip expensive untracked file stats in diff/file loading
- Use `git diff --cached --shortstat` when HEAD is unborn instead of failing `git diff HEAD`. - Stop reading untracked file contents to compute additions/hunks in `load_files`, matching lazygit behavior and improving large-worktree performance. - Add regression test for fast `load_files` on repos with many untracked files and no commits.
* release: lazygitrs v0.0.31
* feat(cli): add lazygitrs self-upgrade command
- add `lazygitrs upgrade [version]` subcommand and dispatch in `main.rs` - implement `upgrade` module to detect install method (brew/npm/bun/pnpm/yarn/cargo/install script) and execute matching upgrade flow - fetch latest GitHub release when target is omitted and handle already-up-to-date/versioned upgrades - add README usage docs and TODO entry for the new upgrade capability
* perf(gui): make commit diff navigation instant with prefetch and churn fix (#24)
Commit diffs took 1-2s+ to appear during startup and after every
auto-refresh, and rapid j/k scrolling showed blank panes. Three causes,
three fixes:
- Fix refresh-churn generation race: the streaming model loader set
needs_diff_refresh on a cumulative counter, so every frame of a
stream re-requested the same diff and the generation bump invalidated
the in-flight result just before it applied (95 duplicate git jobs
per load; diffs only settled when streaming finished). Trigger only
when parts arrive that frame, and never respawn a same-key load for
hash-keyed (immutable) diffs that are already loading or on screen.
- Prefetch neighbor diffs: a low-priority two-worker lane warms the
preview cache with selection±N in commit-like panels and the Commits
selection while other panels are focused, so j/k and panel switches
hit warm cache. Interactive requests for keys with an in-flight
prefetch wait for it instead of duplicating the work. Hash-keyed
entries survive refreshes (retain_immutable) since their content
cannot change.
- Stop blanking the pane while loading: keep the outgoing diff visible
(with a dimmed "loading…" border hint past 50ms) and stash it into
the revisit cache only when the replacement arrives, tracked via
displayed_diff_key. Contexts with no diff still clear explicitly.
Also compile tree-sitter highlight queries on a background thread at
startup, removing the ~40-60ms lazy-init cost the first rendered diff
used to pay.
Measured on this repo: 10-commit burst during startup streaming went
from ~2s to ~20ms; single-step navigation renders the next diff within
one frame.
* feat(gui): add remote edit and fork-remote workflows
Introduce interactive remote-editing and fork-remote support in the Remotes view by: - adding `e`/`F` keybindings for editing a remote (name+URL) and adding a fork remote - wiring new Git commands for `remote rename` and `remote set-url` - adding fork-URL rewriting + fetch/checkout flow for `origin`-based forks
* release: lazygitrs v0.0.32
* feat: display co-authors in commit details and offer branch creation on checkout miss
Parse `Co-authored-by` trailers from commit messages, render them as styled author lines in the commit details panel, and strip the trailers from the message body to avoid duplication.
When checking out a branch that does not exist, show a confirm dialog offering to create the new branch instead of a plain error popup.
* feat: support suspending TUI for terminal editors (hx/nvim/vim)
Add an editor-preset system that resolves editor commands, detects whether the editor is terminal-based, and suspends the TUI (alt screen, input reader, crossterm state) so the subprocess can own stdin/stdout. The input reader gains pause/resume/drain and an interruptible poll loop to avoid stealing keystrokes. GUI editors (vscode, zed, emacs) continue to spawn without blocking. A new `editPreset` and `editInTerminal` config pair controls the behavior, with automatic fallback via `$EDITOR`/`$VISUAL`.
* feat: add edit and open-file shortcuts to commit files panel
Allow opening files in the editor (e) or default program (o) directly from the commit files sidebar, matching the Files tab behavior without requiring Enter to focus the file first.
* release: lazygitrs v0.0.33
* feat: add startup path filter (-f/--filter) and fix list picker search filtering
Add a `-f/--filter` CLI flag (lazygit-compatible) that filters commits by file path on startup. Also refactor list picker navigation to skip non-matching items when a search query is active, fixing scroll/selection behavior in ref pickers and other list picker popups.
* fix: make TUI work under Helix `:insert-output` by claiming `/dev/tty`
Add `os::tty` module that detects when stdin/stdout are redirected (e.g. Helix's `:insert-output`), claims the terminal foreground process group to prevent Helix's EventStream from stealing keystrokes, and draws on `/dev/tty` instead of stdout. On exit, restore the parent's foreground group and do not tear down Helix-owned alt-screen/raw-mode/mouse state. Enable crossterm's `use-dev-tty` feature so event polling works on `/dev/tty` under macOS.
* doc: document how to do editor integrations
* fix(rebase): replace sed-based GIT_SEQUENCE_EDITOR with temp-file scripts
Switch all interactive rebase operations from shelling out with inline sed commands to writing a prepared todo file and a small executable script. This fixes the interactive rebase 'e' (edit) bug where the wrong commit was targeted, and eliminates fragile quoting issues in sed expressions.
- Extract `write_todo_editor` helper to DRY temp-file + script creation - Rewrite `rebase_interactive_action`, `move_commit_up/down`, `reword_commit_rebase`, and `rebase_interactive_batch` to use it - Add `rebase_interactive_batch_root` for rebasing from root - Add `is_ancestor` and `write_rebase_todo` utilities - Use full commit hashes in todo entries for unambiguous matching - Add integration tests for edit-on-target and divergent-branch cases
* fix(commit-editor): preserve logical newlines in commit body soft-wrap editor
- Stop joining consecutive non-blank lines in `unwrap_commit_body` (was collapsing `- a\n- b` into `- a - b`); now only normalizes `\r\n`/`\r`
- Switch `WrapLayout` to measure by unicode display width instead of char count so wide glyphs don't cause horizontal scroll
- Add `apply_cursor_into` for pure cursor moves (preserves viewport/scroll) vs full `render_into` on content edits
- Track `content_changed`/`cursor_moved` separately in the body key handler to avoid unnecessary rebuilds on navigation
- Clamp `wrap_width` to `max(1)` to prevent division/empty-range issues
- Add unit tests for unwrap, wrap layout line breaks, display-width wrapping, and soft-wrap round-trip
* feat(themes): add theme appearance tracking and update generated theme colors
Add `ThemeAppearance` enum (dark/light) to classify themes by terminal background, inferred from background luminance or declared in JSON metadata. Includes:
- `appearance` field in theme JSON schema and gen-themes script
- Luminance-based fallback (`appearance_from_hex`) when appearance is unset
- Updated opencode upstream URL to match new repo structure
- Regenerated theme files with refreshed color values
* fix(gui): reset scroll position when replacing commit summary text
- Add `set_commit_summary_text` helper that rebuilds a fresh `TextArea` instead of reusing select_all/cut/insert_str, which left stale horizontal scroll.
- Preserve cursor style, cursor line style, and base style from the original widget.
- Replace all four sites in `gui/mod.rs` that previously did the select_all/cut/insert dance with the new helper.
* feat(perf): apply commit filters at stream time instead of re-fetching after load
- Pass `-f` path filter into `Gui::new` so the initial model stream loads filtered commits immediately, matching lazygit's startup path filter behavior
- Add `CommitFilter` parameter to `load_model_streaming` to load filtered or unfiltered commits from the start
- Move unpushed-commit detection to a single call per page load via new `apply_unpushed_status`, removing redundant `git log @{u}..HEAD` from `parse_commit_log`
- Make path-filter picker async with `filter_paths_rx` so `git ls-files` doesn't block the UI
- Add `reload_filtered_commits_async` for scoped async commit reload on ctrl-s filter apply, replacing full model refresh
- Add `replace` flag to `CommitPageResult` to distinguish filter-reload from pagination-append
- Remove duplicate filtered-commit re-fetch from `after_model_refresh`
- Add `Model::clear_commits` and `ContextManager::set_selection_for` helpers
* fix(themes): theme picker filter and up/down
* fix(pickers): cycle list picker selection and deduplicate scroll-after-navigation logic
- Make next/prev match cycle through filtered items instead of clamping at boundaries
- Extract list_picker_scroll_after_nav to consolidate duplicated scroll logic
- Fix wrap-around behavior for Up at first item and Down at last item
* feat(themes): generate light-mode themes from OpenCode source data
- Add `mode` parameter to theme generation pipeline so each OpenCode theme can emit both a dark and a light variant
- Skip light variants when the source theme has no distinct light palette
- Sort themes dark-first, then light, with alphabetical ordering within each group
- Generate light variants for all supported themes (catppuccin, dracula, gruvbox, github, etc.)
* consider done
* release: lazygitrs v0.0.34
* fix: commit message dialog hardcoded height crash
* fix: allow squash/fixup as first rebase action by rebasing onto parent
Previously `rebase_interactive_batch` rejected squash/fixup as the first
action because git cannot start a todo with those actions. Now it detects
this case and rewrites the todo to `pick` the onto commit and rebase onto
its parent (or `--root` for root commits), making squash/fixup work as
the first operation in a batch.
- Extract shared `run_interactive_rebase` helper from `rebase_interactive_batch`
and `rebase_interactive_batch_root` to eliminate code duplication.
- Add `try_commit_parent` returning `Option` and refactor `commit_parent` to
use it. Switch from `rev-parse` to `log -1 --format=%P` for parent lookup.
- Add `first_kept_is_squash_or_fixup` helper that skips leading drops when
checking the first kept action.
- Remove the "cannot squash first commit" validation from the GUI controller.
- Add tests for squash/fixup into onto, root squash, and drop-then-squash.
* feat(perf): discard performance #25 (#26)
* chore(release): refuse tagging unless on main
just tag on a feature branch still created a GitHub Release and
updated Homebrew; only registry publish required the tag to be on
main. Guard the local script and cargo-dist plan job.
* release: lazygitrs v0.0.35
* feat(hunk-staging-2): separator-stacked staged/unstaged diff (#30)
* feat(hunk-staging): add hunk staging
fixes #28
* feat(gui): show staged and unstaged hunks in one diff with per-hunk staging actions
- Combine HEAD and unstaged diffs so the Files pane renders staged/unstaged hunks in a single buffer, tinting each hunk by its staged state (with untracked-file support and fallbacks for unborn HEAD)
- Open hunk context menu on revert hover/selection and offer actions based on the specific hunk's staged state, with s/r/u keyboard shortcuts
- Map viewed HEAD-buffer hunks onto per-side diff blocks via matching_side_blocks for stage/unstage/revert, handling multiple targets and stale hunks gracefully
* feat(gui): stack staged hunks below a separator instead of tinting glyphs
Alternative to the single-buffer HEAD view: the Files pane renders
unstaged hunks, a 'Staged changes' separator, then staged hunks, with a
uniform marker glyph throughout. Directory hovers stack the unstaged and
staged multi-file diffs the same way. Per-hunk Stage/Unstage/Revert menu
(with s/r/u hotkeys) and click-to-menu behavior are unchanged; each
section keeps its own side's line numbers so patch slicing applies
directly.
* feat(pager): group combined diffs per file with `(Unstaged)`/`(Staged)` headers
Replace the generic `Staged changes` separator with per-file headers suffixed `(Unstaged)`/`(Staged)`, both for single-file combined diffs and multi-file directory hovers. Staged hunks now appear directly after their file's unstaged hunks, and header resolution (`file_at_line`) strips the suffix back to the plain path.
* refactor(gui): split file status indicator into per-char styled spans
Replace `file_status_display` with `file_status_spans`, which returns two spans so the index (staged) and worktree (unstaged) status chars are colored independently — green when staged, yellow when unstaged, split for partially-staged files. Update file list and tree rendering to use the new spans.
* chore preview as first-class
* feat(stripes): better looking stripes (inspired by lumen)
* feat(hunk-staging): better hunk staging without separators (like zed/vscode) (#31)
* feat(hunk-staging): better hunk staging without separators (like zed/vscode)
* fix(gui): change unstage hunk menu shortcut from "u" to "s"
* feat(pager): fill line background to full panel width in side-by-side diff
* fix(pager): wrap hunk navigation at ends and guard empty hunk lists
* feat(gui): open selected directories in editor and default program
- Add helpers to resolve the selected tree node's directory absolute path (files.rs, commit_files.rs)
- Open directories via `plan_open_dir`/`plan_open` with fallback to `Platform::open_file` in editor and default-program actions
- Simplify selected commit file path resolution in tree view
* release: lazygitrs v0.0.36
* fix(stash): refresh diff and show conflict output on failed pop/apply
- Always trigger diff refresh for stash pop/apply, even on conflict, since the worktree is still modified
- Defer error propagation so refresh flags are set before returning the error
- Add CmdResult::combined_output() and use it in error messages, since git reports conflicts on stdout
* fix(gui): match lazygit commit and merge glyphs
Use `○` for commits and `◎` for merges instead of `◯`/`⏣`, and stop swapping to a filled circle for HEAD since lazygit indicates HEAD via ref labels.
* feat(gui): match lazygit commit list row layout with local-time dates and author columns
* feat(gui): render commit refs and tags lazygit-style
- Combine refs and `tag: x` decorations into a single parenthesized group in maximised view, colored with `ref_tag`
- Show bare tags only in compact view
- Drop per-ref HEAD/remote/local coloring in favor of unified tag styling
* release: lazygitrs v0.0.37
* fix(gui): change j/k hint to arrow symbols in popup hint bar
* feat(gui): add Ctrl-F grep over diff contents
- Searches hunk lines in Files, Commit Files (incl. stash/branch commits), and compare views via a synchronous ListPicker with token-AND filtering
- Enter selects the matched file in the originating list, expanding tree ancestors as needed
- Handles untracked file content, binary patches, /dev/null sides, and C-quoted paths; caps results at 5000 rows
* docs(readme): simplify Helix and Neovim integration instructions
- Replace Helix Ctrl-g binding with Space G g/gF-style keymaps under `[keys.normal.space.G]`, including a `-f '%{file_path_absolute}'` file-history binding
- Add `<leader>gF` file-history keymap for Neovim via `Snacks.terminal`
- Drop the `os.editPreset`/`open` config steps, noting `o` uses the OS opener by default
- Condense examples and clarify absolute-path to repo-relative resolution in monorepos
* refactor(gui): extract search bar/status bar rendering into helper
Move the inline search bar vs status bar rendering logic from the render function into a new `render_search_bar_or_status_bar` helper for readability and reuse.
* release: lazygitrs v0.0.38
* fix(gui): use localtime_s on Windows for commit dates
this was the release blocker
* chore: backtrack unreleased v0.0.37/v0.0.38 to v0.0.36
* release: lazygitrs v0.0.37
* fix: size graph rows for deferred merge connectors
* release: lazygitrs v0.0.38
* fix: repair merge fallout — Key→String palette args, queue_diff_job ports, fmt
- CommandEntry::keybinding takes String; convert Key via to_string()
- Port file-explorer preview and branch-diff loads to upstream's
queue_diff_job (diff_tx field no longer stored on Gui)
- Restore Ok(()) tail in after_model_refresh
- Drop unused imports; cargo fmt
---------
Co-authored-by: Blankeos <carloantonioct@gmail.com>
Co-authored-by: Carlo Taleon <38070918+Blankeos@users.noreply.github.com>
Co-authored-by: Josh Daniel Bañares <joshxfi.dev@gmail.com>
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
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.
Alternative to #feat/hunk-staging (single HEAD buffer with green ✓ tint).
This variant stacks sections instead: unstaged hunks on top, a
Staged changesseparator, then staged hunks — for both single files and directory hovers. Uniform marker glyph throughout (blue when focused, no green); the separator carries the staged/unstaged meaning.Per-hunk Hunk menu (Stage
s/ Revertr/ Unstageu), click-to-menu, and cycling behavior are unchanged. Each section keeps its own side's line numbers so patch slicing applies directly without cross-side remapping.