Commit graph

931 commits

Author SHA1 Message Date
Stefan Haller 3ecca88bd8 Convert JumpToBlock to a list of multi-key bindings
JumpToBlock is special: each of its 5 elements is the binding for one side
window (status / files / branches / commits / stash), not an alternate for a
single command. Change the field from []string to []Keybinding so each window
slot can have alternates of its own.

The schema becomes "an array of 5 keybindings, each itself a string or array of
strings", which falls out cleanly from how the Keybinding type inlines into the
generated schema. Existing configs (a flat array of 5 strings) keep validating
because each element is unmarshalled through Keybinding's scalar-or-sequence
decoder.
2026-05-25 15:32:47 +02:00
Stefan Haller 5748d82073 Convert keybinding fields to Keybinding
Until now every keybinding config field was a plain string. That meant a user
couldn't ask for two keys to invoke a command — the config silently accepted
only one form.

Convert every string-typed field across all 13 KeybindingXxxConfig structs to
Keybinding so the union type extends to every command. Defaults wrap their
single-key value in Keybinding{...} so the generated Config.md still renders one
scalar key per binding.

The alt fields keep their separate Binding registrations for now: this commit
does not yet introduce the merge mechanism that folds them into the main field —
that comes in a follow-up. Consumers previously calling opts.GetKeys on a string
field now call opts.GetKeys on the Keybinding, or take .String() / Keys[0] where
a single value is needed.

Adds a Keybinding.String helper for rendering, schema-generator work that
inlines the Keybinding union into each consuming property, and a unit test
covering the user-facing scalar/sequence YAML forms for quit.
2026-05-25 15:32:47 +02:00
Stefan Haller 12cfb9be1f Remove OptionMenuAlt1
For legacy reasons, OptionMenu was set to `<disabled>`, and OptionMenuAlt1 to
`?`. This doesn't make a lot of sense any more; get rid of OptionMenuAlt1 and
bind OptionMenu to `?` by default. This is a breaking change for users who
rebound OptionMenuAlt1 in their config, but it doesn't strike me as very likely,
and it's easy enough to fix.
2026-05-25 15:18:18 +02:00
Stefan Haller 3c279614bf Change SetKeybinding to not return an error
It always returned nil.
2026-05-25 15:18:18 +02:00
Stefan Haller 880064b987 Use the isolated test env for shell commands
Shell.RunShellCommand was passing os.Environ() to its child, while its
sibling runCommandWithOutputAndEnv has used the minimal
NewTestEnvironment since late 2023 when env isolation was introduced;
the sh path was just missed.

This matters when integration tests run from inside a `git rebase -x`
exec in a linked worktree: git sets GIT_DIR=<main>/.git/worktrees/<name>
for the exec, and it leaks all the way down through bash, just, go test,
and the test process, into every git invocation RunShellCommand spawns.
cmd.Dir becomes irrelevant — git resolves GIT_DIR over cwd-based
discovery, with the work-tree taken from the gitdir file (i.e. the
worktree root). So `git checkout -b conflict` in a test fixture creates
the branch on the real worktree and switches its HEAD, hijacking the
in-progress rebase and trashing the working tree. (In the main worktree
git doesn't set GIT_DIR for rebase exec, which is why the bug was only
visible from linked worktrees.)

Using self.env also incidentally restores GIT_CONFIG_GLOBAL for shell
commands, so commits made via RunShellCommand are now authored by the
test config's CI identity rather than whatever the host's ~/.gitconfig
resolves to.
2026-05-25 15:18:18 +02:00
Stefan Haller 4f6cdedb1e Refresh worktrees before auto-forwarding branches
AutoForwardBranches relies on the worktree model to skip any branch
that's currently checked out in another worktree (so we don't update
its ref behind the worktree's back). The post-fetch refresh wasn't
including the worktrees scope, so any external change to the worktree
list between lazygit's startup and the fetch — a `git worktree add`,
a `git checkout` in a linked worktree, a branch rename — left the
in-memory model stale and the skip check returned false negatives.

Add WORKTREES to the post-fetch refresh scope when auto-forwarding is
enabled. We gate on the config so users with auto-forward disabled
don't pay for an extra `git worktree list` plus per-worktree rev-parse
on every fetch tick.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 13:59:18 +02:00
Stefan Haller 532cce4873 Add test for auto-forwarding a branch checked out in another worktree
When the linked worktree's branch is changed externally — by another
shell, by another tool, or by git running outside lazygit — lazygit's
worktrees model goes stale. The next post-fetch auto-forward then
doesn't realise the branch is now checked out elsewhere, and advances
its ref behind the worktree's back. The worktree's HEAD then resolves
to a commit its index/working tree haven't been updated to, and the
user sees that diff as the inverse of what was fetched — files
appearing as pending changes that they didn't make.

The test sets up a linked worktree initially on a side branch, then
externally checks out master in it before pressing fetch. Two
EXPECTED/ACTUAL pairs capture the symptoms: the branches view shows
master as `✓` rather than `↓1`, and switching to the linked worktree
shows master's would-be incoming file as a pending deletion against
HEAD.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 13:59:18 +02:00
Stefan Haller 7a2d1ab544 Clear cherry-pick buffer when copying after a paste
After a successful paste DidPaste is true, hiding the "X commits copied"
indicator but leaving the buffer populated. From the user's perspective
this looks like a clean slate, so a new shift+C should start fresh. It is
important to reset DidPaste first, before populating the buffer with the new
commits, because otherwise each loop iteration would overwrite the previous one
since Add() rebuilds the set via SelectedHashSet() which returns empty while
DidPaste is set.
2026-05-09 14:02:42 +02:00
Stefan Haller f264d43a1a Add test for missing commits when range-copying after a paste
After a successful paste, the "X commits copied" indicator hides and
DidPaste is set, but the buffer is not cleared. If the user then
range-selects multiple commits and presses shift+C, every Add() call
rebuilds the set via SelectedHashSet(), which returns empty while
DidPaste is true; each iteration of the copy loop therefore overwrites
the previous one and only the last commit in the range survives.
2026-05-09 14:02:42 +02:00
Stefan Haller ee94e215e7 Remove dead Modifier field from keybindings
Modifiers were moved into Key in 22169e22f, but the separate Modifier field
on types.Binding and gocui.keybinding was left behind. The keypress matcher
already compares modifiers via Key.Equals, so the old field is never read on
the dispatch path; it just got passed through SetKeybinding and stored.

Drop it from gocui.keybinding, types.Binding, and the SetKeybinding /
DeleteKeybinding signatures, and remove every now-redundant Modifier:
gocui.ModNone struct field. Mouse bindings keep their own Modifier (on
ViewMouseBinding) since that path still consults it.
2026-05-06 09:51:23 +02:00
Stefan Haller cb0ecda3e4 Disable gh telemetry when running integration tests 2026-05-05 18:42:28 +02:00
Stefan Haller 35d3659cce Use more widely-supported Unicode symbols for the commit graph
The commit graph used '⏣' (U+23E3 BENZENE RING WITH CIRCLE) for merge
commits and '◯' (U+25EF LARGE CIRCLE) for regular commits. Both have
very poor coverage in popular monospace fonts:

- '⏣' lives in the Misc Technical block and is essentially absent from
  every common monospace font (Source Code Pro, JetBrains Mono, Fira
  Code, Cascadia Code, Hack, Iosevka, Menlo, Consolas, Monaco, IBM
  Plex Mono, Ubuntu Mono, Noto Sans Mono, Inconsolata). It is always
  drawn from a system fallback font.
- '◯' is the late-addition LARGE CIRCLE codepoint. It is present in
  some fonts (Cascadia, Fira Code, Hack, Iosevka, Menlo, Noto Sans
  Mono) but missing from many others, including Source Code Pro and
  most Nerd Font derivatives based on it.

This is why the graph renders inconsistently across platforms even
when the same monospace font is configured: each OS picks a different
fallback font (Apple Symbols on macOS, Segoe UI Symbol on Windows,
Noto/DejaVu/Symbola on Linux), and the substituted glyphs differ in
shape, weight, and advance width. '◯' is also East Asian Ambiguous
width, so some terminals render it wider than one cell, exaggerating
the misalignment.

Replace the symbols with codepoints from the foundational 1991
Geometric Shapes block, which has far broader font coverage:

- Merge: '◎' U+25CE BULLSEYE -- concentric circles, the visually
  closest cousin to the previous benzene-ring glyph.
- Commit: '○' U+25CB WHITE CIRCLE -- the same hollow-circle silhouette
  as before, just a more universally available codepoint.

The new symbols are present in the font directly in significantly
more cases; and when fallback is still required, they are universally
well-drawn (unlike '⏣', which many fallback fonts also lack).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 13:06:29 +02:00
Stefan Haller 6663867bb5 Change keybinding syntax to spell out full modifier names, and use + instead of -
The change to filter_menu_by_keybinding.go is needed because + now occurs in
many keybindings, so pick a different one that occurs only once.
2026-04-30 22:38:53 +02:00
Stefan Haller 22169e22ff Move modifiers into Key
This changes not only how we store modifiers (inside of Key instead of passing
it separately), but also how we parse keybinding strings: it supports all
combinations of modifiers now (if the terminal supports it, that is).
2026-04-30 22:22:53 +02:00
Stefan Haller 64996d12d9 Add Key type
This bundles the keyName and a rune, so that we don't have to pass these around
separately everywhere. This should make it easier to swap out the rune for a
string when we upgrade to tcell v3.
2026-04-30 22:14:26 +02:00
Stefan Haller bff77fc4f9 Rename Key to KeyName
This is to free up the name Key for a type that can be either a KeyName or a
rune (or later a string when we upgrade to tcell v3).
2026-04-30 22:14:26 +02:00
Stefan Haller 196e0a3c17 Copy gocui files into lazygit repo under pkg/gocui
I copied all files except dot files (.github and .gitignore), the _examples
folder, and go.mod/go.sum.

At some point we may want to copy the files back to the gocui repo when other
clients (e.g. lazydocker) want to use the newer versions of them.
2026-04-30 14:29:08 +02:00
Stefan Haller 227081f1d1 Preserve whitespace when remembering a commit message
This is useful when cancelling out of the commit panel mid-sentence (after
having typed the space for the next word); when entering the commit message
panel again, the space was gone and you had to type it again. Small thing, but
it just seems better to resume the panel in exactly the state that you left it
in. (Which we actually don't do; we don't remember the cursor position, or which
of the subject/description panels was active. That would be a separate
improvement.)

The save path and the load path used to be asymmetric. On save, the textarea
getters applied strings.TrimSpace, which stripped any leading blank lines, a
trailing newline after the cursor, or indentation on the very first line of the
description — all of which are legitimate user content. On load,
SplitCommitMessageAndDescription did TrimSpace on the description as well, and
the preserved message was routed through that same git-format split because
HandleCommitPress passed it as OpenCommitMessagePanel's InitialMessage. The
result: every round-trip through "escape and reopen" silently mutated the
message.

The fix is to treat our own preservation file as its own format, distinct from
git's canonical "summary\n\nbody" format:

- The textarea getters return raw content. strings.TrimSpace moves to the one
  place that still needs it: the empty-summary check in HandleCommitConfirm (git
  itself strips trailing whitespace and blank lines, so no pre-trim is needed
  before -m).
- SplitPreservedCommitMessage / SetPreservedMessageInView split on the single
  "\n" our Join uses, without any trimming — truly lossless.
- SplitCommitMessageAndDescription keeps its git-format behavior but replaces
  TrimSpace with TrimPrefix("\n"), so it strips only the blank-line separator
  and leaves body indentation intact.
- HandleCommitPress now mirrors HandleWIPCommitPress: it no longer passes the
  preserved message as InitialMessage. OpenCommitMessagePanel resolves the
  preserved content itself, uses it for display via the preservation-format
  setter, and stores it as the initial message so the close-time "did the user
  change anything?" check still correctly detects a cleared panel.
- GetInitialMessage no longer trims. With raw getters on both sides of the
  comparison, trimming here caused spurious non-matches (e.g. for preserved
  content with trailing whitespace). The original motivation — matching a
  "WIP: " prefix with trailing space — works unchanged.
- UpdateCommitPanelView becomes dead code and is removed; its one remaining
  caller (history cycling, always git-format) goes directly through
  SetMessageAndDescriptionInView.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 18:51:17 +02:00
Stefan Haller 07a5bb5867 Add integration test demonstrating whitespace loss in preserved commit messages
Typing a description with leading blank lines, canceling the commit panel, and
reopening it currently drops leading blank lines.
2026-04-21 18:51:17 +02:00
Stefan Haller d3095f6fd4 Fix copying a file's absolute path when running in a linked worktree 2026-04-19 11:16:02 +02:00
Stefan Haller 94d6fce3cc Change clipboard tests to demonstrate bug with copying absolute file path
Change the tests so that they run in a linked worktree; this uncovers the bug
that copying a file's absolute path uses the main repo path rather than the
worktree's path.
2026-04-19 08:13:22 +02:00
Martin T. 4cb6fafb08 Add condition field to custom command prompts
When building multi-step custom command forms, some prompts are only
relevant depending on earlier answers. Without conditional logic,
users must dismiss irrelevant prompts manually.

Prompts now accept a `condition` field with a template expression
evaluated against prior form values. Skipped prompts default to
an empty string.

The template expression is a string pre- and suffixed with double curly
braces - {{}}.

Form keys can be reused, a guard ensures that skipped prompts do not
reset already set form keys with an empty string. This allows the
conditional flow to remind a user to set a key that was left empty
because additional conditions want that key to be set. This removes the
need to have additional if checks in the command that uses the form
keys.
2026-04-06 19:14:51 +02:00
Stefan Haller b8d23dd5a5 Make file sort order and case sensitivity configurable
Set the sort order's default from the former foldersFirst to mixed, so this is a
change in behavior. I find this useful because it now matches git's order, so if
you look at the diff of a commit, the TOC at the top has the same order as the
file tree you see when entering the commit.
2026-03-30 17:53:25 +02:00
Stefan Haller 9f38d02a4e Don't stage out-of-date submodules when asking user to auto-stage after resolving conflicts
When you rebase a branch and there are conflicts, lazygit asks you to continue
the rebase when it detects that all conflicts have been resolved. However, it is
common to make additional changes beyond just fixing the conflicts (e.g. to fix
build failures), and when doing that while the "Continue the rebase?" prompt is
showing, lazygit detects that too and asks you if you want to stage those newly
modified files too. This is all well and good (and can be disabled for those who
don't like it); however, lazygit would treat out-of-date submodules as unstaged
changes and would offer to stage those as well, and this is pretty bad and
almost never what you want. Fix this by excluding submodules from that second
check.
2026-03-30 17:41:53 +02:00
Stefan Haller 58bcfc4347 Add test to demonstrate the problem 2026-03-30 17:34:18 +02:00
Stefan Haller ad31400818 Improve performance of discarding changes in large directories
Previously it would iterate over all changed files and call git checkout or git
reset for each one, which can take forever if there are hundreds or thousands of
files. Now it batches these into a single command if possible (taking care of
still passing the individual path names to the git call rather than just the
directory, which is necessary for making it work correctly when filtering --
this was actually broken for the "Discard unstaged changes" command, which is
fixed here).
2026-03-27 14:34:47 +01:00
Stefan Haller f987b35a9e Add integration tests for discarding dir changes when filtering by path
When discarding a directory, we only want to discard those files that are
visible in the current filter view. The tests show that this already works
correctly for discarding all changes, but it doesn't for discarding only
unstaged changes: in this case, untracked files are handled correctly, but
changes to tracked files are discarded without respecting the filter.
2026-03-27 14:34:47 +01:00
blakemckeany ee3bb06b2a Add support for clicking on arrows in the file list to expand/collapse directories
Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
2026-03-25 17:08:35 +01:00
Stefan Haller e1e042fb66 Revert test workaround
Now that the bug with selecting the next stageable line is fixed, we can go back
to the original, simpler way of expressing the test.
2026-03-19 16:57:53 +01:00
Stefan Haller 6bfcab3d89 Fix selection after staging an added line
In some cases, staging an added line could result in the previous deleted line
to become selected, rather than the next added line.
2026-03-19 16:57:53 +01:00
Stefan Haller 8fbc70bf84 Fix staging only some lines of a block of consecutive changes
This fixes the problem; a consequence of this change is that given the following
scenario:

@@ -1,3 +1,3 @@
 1
-2
+2b
 3

staging only the line `+2b` will put it *before* the unchanged `2` line, rather
than after it as you might expect (the changed unit tests demonstrate this).
Since this should be a pretty uncommon scenario, I guess it is an ok compromise.

As you can see in the changed tests, while the behavior of what gets staged is
fixed now, it doesn't always correctly select the next line to stage. We'll
address this in the next commit.
2026-03-19 16:57:53 +01:00
Stefan Haller b8ed4faf9b Add test for how the selection advances after staging lines
This is currently working correctly, but will break with the next commit; we'll
fix this again afterwards.
2026-03-19 16:44:55 +01:00
Stefan Haller 7929519ccf Add regression test for staging a single added line
This is a pretty special case (see comment in the test for details). It is
working correctly, but I almost broke it during development, so it's good to
cover it with a test.
2026-03-19 16:44:55 +01:00
Stefan Haller b95bfeb164 Add test demonstrating problem with staging only some changed lines
Given a block of consecutive changed lines, trying to stage only some of them
doesn't work correctly in all cases:

- if the staged lines are the last lines in the block of changes, it already
  works
- when staging some changes in the middle of the block, it doesn't work as
  desired, but we also don't try to fix this case in this branch, because it's
  harder to do, and not as common as the other two
- staging the first lines of the block doesn't work as desired, and we will fix
  that in this branch.
2026-03-19 16:44:55 +01:00
Ruud Kamphuis 6ad56d5852
Show worktree name next to branch in branches list
When a branch is checked out by another worktree, show the worktree
name in the label, e.g. "(worktree cosmos2)" instead of just
"(worktree)", so you can immediately see which worktree holds it.
2026-03-09 11:34:34 +01:00
Zak Siddiqui 7d32e45f73 Add backward cycling support for all branches log view
This commit implements the ability to cycle backward through different
all branches log visualization modes, complementing the existing forward
cycling functionality. Users can now press 'A' (Shift+a) to cycle in
reverse through the available log graph views, improving navigation
efficiency when they overshoot their desired view.

Changes:
- Added RotateAllBranchesLogIdxBackward() method to BranchCommands for
  backward rotation through log command candidates
- Introduced AllBranchesLogGraphReverse keybinding configuration with
  default key 'A' (uppercase)
- Implemented switchToOrRotateAllBranchesLogsBackward() handler in
  StatusController that mirrors forward cycling logic
- Added English translation for "Show/cycle all branch logs (reverse)"

The implementation uses modulo arithmetic with proper handling of
negative indices to ensure seamless backward cycling through the
available log visualization options.
2026-03-08 17:06:17 +01:00
cobyfrombrooklyn-bot 30154aa9c5 Fix #5302: Create .git/info directory before writing exclude file
When .git/info directory does not exist (can happen with bare clones
or manual deletion), the Exclude function failed with 'no such file
or directory'. Added os.MkdirAll to create the directory before
opening the exclude file.

Added integration test exclude_without_info_dir that removes .git/info
before attempting to exclude a file.
2026-03-08 16:23:39 +01:00
Ruud Kamphuis 727b4b56dd Show branch name and detached HEAD in worktrees tab
The worktrees tab now displays the checked-out branch (or detached HEAD
state) for each worktree, making it much easier to see which worktree
holds which branch.

This is useful when you need to "unlock" a branch that's occupied by
another worktree: you can now clearly see which worktrees are on a
branch vs detached, without having to select each one individually.

Also rename the "(main)" label to "(main worktree)" to avoid confusion
with the common "main" branch name, and move it after the branch column.
2026-03-08 12:51:46 +01:00
Jesse Duffield 615c566ac4 Filter file views rather than search
Change working tree files and commit files panels to use filtering
(reducing the list) instead of search (highlighting matches). This
matches the behavior of other filterable views.

The text filter matches against the full file path, not just the
filename, which is more useful for navigating large directory trees.

When toggling a directory for a custom patch while a text filter is
active, only the visible filtered files in the directory are affected,
consistent with how staging a directory in the files panel works.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:04:31 +01:00
Jesse Duffield 8728da7985 Only reset selection in ReApplyFilter when search prompt is active
Without this check, the selection was being reset to 0 whenever
ReApplyFilter was called for the current filter context, even when
the user wasn't actively typing in the search prompt (e.g. when the
model updates in the background). This was causing unexpected cursor
jumps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:04:31 +01:00
Jesse Duffield 0f2f20b900 Allow discarding lines from patch directly
I always press 'd' in the patch building view, expecting that I can do
exactly what I can do in the staging view, to find out I need to go
space -> ctrl+p -> d and I think it's time to honour the muscle memory
and support this convenience keybinding.
2026-03-07 20:47:20 +11:00
Stefan Haller 7f9bfaec08 Warn more prominently about resetting the patch when discarding changes
Only mention resetting the patch when there actually is one. This way users have
to read less text in the normal case, and the added note hopefully stands out
more if there is one. Also, separate the note from the previous text by a blank
line.
2026-03-07 20:47:19 +11:00
Stefan Haller b256215397 Say "discard" instead of "remove" when discard changes from a commit
"Remove" can be confusing when a deleted file is selected; in this cases it
actually "un-removes" it. "Discard" hopefully makes it clearer that we are
talking about the change to a file, and not the file itself.
2026-03-07 20:47:19 +11:00
Dawid Pietrykowski 48a8a71d31 Fix gitignore path collisions
Paths added to ignore/exclude files need to be prefixed with a forward
slash to point to a specific file in the directory tree.

Without that prefix a file at root called `file` (added to `.gitignore`
as `file`) would match with `./file` and `./src/file`.
2026-01-28 21:10:29 +01:00
Jesse Duffield f317a97ac1 Support using the selected commit's message in a fixup
I've optimised for muscle memory backwards compatibility here:
  - Outside interactive rebase: press 'f' then instead of a confirmation
panel, a menu appears where you can choose to keep the selected commit's
message
  - Inside interactive rebase: press 'f' then press 'c' to see the menu
for keeping the message, where if you press 'c' again it will retain the
current message. so 'fcc' is the chord to press.

We're also now showing the -C flag (which is what enables the behaviour)
against the todo.

I've picked the 'c' keybinding because 'C' was taken and it corresponds
to the flag. Previously that showed a warning about a change in
keybinding for cherry picking but it's been ages since we've made that
change so I'm happy to retire it.
2026-01-28 10:28:52 +01:00
Stefan Haller 268d1934f8 Ignore fixup commits for a found base commit when doing ctrl-f 2026-01-24 16:04:35 +01:00
Stefan Haller b41bb8f845 Add a test that documents the current behavior
Currently we get an annoying error message, but we'd like the base commit to be
selected, disregarding the fixup.
2026-01-24 16:04:35 +01:00
Stefan Haller 65edd99fd0 Update search position (match x of y) when changing the selection in a list view
or in the staging view.
2026-01-04 18:51:45 +01:00
Stefan Haller 3ccd33b388 Show an error when checking out a file would overwrite local modifications 2026-01-03 20:09:55 +01:00
Stefan Haller efd4298b5e Avoid scrolling the selection into view on refresh
It is possible to scroll the selection out of view using the mouse wheel; after
doing this, it would sometimes scroll into view by itself again, for example
when a background fetch occurred. In the files panel this would even happen
every 10s with every regular files refresh.

Fix this by adding a scrollIntoView parameter to HandleFocus, which is false by
default, and is only set to true from controllers that change the selection.
2025-12-23 15:34:38 +01:00
Stefan Haller a415d1b529 Fix the main view display after reverting a commit
We move the selection down by the number of commits that were reverted (to keep
the same commits selected). However, this only happens after refreshing, which
has rendered the main view with the wrong commit, so we need to render it again
after moving the selection.

There are many other callers of MoveSelection in LocalCommitsController, but all
of them happen before the refresh. Revert is special because it needs to move
the selection after refreshing, e.g. when reverting the only commit of a branch.
2025-12-23 14:55:58 +01:00
Stefan Haller 0a48f307b1 Add test expectation showing a problem with revert
After the revert, the main view shows the diff of the wrong commit.
2025-12-23 14:48:58 +01:00
Karl Wikström 62913ee25d
feat: support custom keybinds in custom command prompt menus 2025-12-22 13:43:52 +01:00
Stefan Haller 344d3866a6 Make menu keybindings take precedence over builtin ones, except for confirm/esc
This makes it possible to use 'j', 'k', 'H' or 'L' as menu item keybindings.
2025-12-22 09:37:06 +01:00
Stefan Haller 7e3b24d496 In menus, remove not just the confirm binding, but also esc and up/down
This is not really super important because we are very unlikely to assign a key
such as esc or up/down to a menu item. However, users might do this in a custom
commands menu, and in that case it is important that the builtin keys still
work; or they might remap those builtin commands to other keys, in which case
they might conflict with single-letter keys in normal menus.
2025-12-22 09:37:06 +01:00
Stefan Haller e19544a42b Add a test that demonstrates problems with custom menu keybindings
The test shows two problems: a <down> keybinding is not removed from a menu item
(the 'y' binding is removed though, which is correct), and keybindings such as
'j' and 'H' don't work. We will fix both of these separately in the following
commits.
2025-12-22 09:37:06 +01:00
Stefan Haller e2b3601c57 Fix order of fixup base commits shown in ctrl-f error message 2025-11-30 14:06:31 +01:00
Stefan Haller c16b4b1d2e Make find_base_commit_for_fixup tests more specific
We want to test the order in which the commits are listed in the error message.
For one of the tests the order is already as we want it, but for the other it's
not (we want them to show up in log order). We'll fix this in the next commit.
2025-11-30 14:06:31 +01:00
Stefan Haller 9334bf0333 Don't use "HEADLESS" environment variable for running tests
It is a bit generic, it seems that users sometimes set it for other reasons, and
then they are confused why they don't see anything. Use a more specific name
instead.
2025-11-28 12:06:42 +01:00
Stefan Haller 11a6a73be5 Fix deleting a remote tag when a remote branch with the same name exists 2025-11-27 19:52:18 +01:00
Stefan Haller 7809823064 Fix deleting a remote branch when a remote tag with the same name exists 2025-11-27 19:51:24 +01:00
Stefan Haller 4d4b143cc7 Add tests demonstrating the problem
Trying to delete a remote tag when a remote branch with the same name exists
results in an error, and vice versa.
2025-11-27 19:51:13 +01:00
Stefan Haller 19a4454599 Cleanup: remove unnecessary keypress
Seems to be a copy/paste error from another test.
2025-11-27 19:32:22 +01:00
Stefan Haller 221e025ee6 Switch to branches view when checking out a commit
We move the code to push the branches context into CheckoutRef, this way it
works consistently no matter where we call it from. Previously, checking out
remote branches or tags would switch to the branches view, but checking out a
commit did not.

Note that it now also takes effect for undoing or redoing a checkout, which may
be a bit questionable; but I still think it makes sense for this, too.
2025-11-16 21:23:40 +01:00
Stefan Haller e3a09eacd1 Cleanup: reformat
We usually put Lines() on a line by itself, and it makes the diff of the next
commit much easier to read.
2025-11-16 19:10:21 +01:00
Karol Zwolak 3892c40666 feat: add fork remote command
The command allows you to quickly add a fork remote by replacing the owner in the origin URL and optionally check out a branch from new remote.
2025-11-16 17:26:00 +01:00
phanium d88f95275f Modernize all codes
go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...
2025-11-15 10:46:23 +01:00
rlkandela 374f0f0766 Add SelectedSubmodule to SessionState
Introduce the 'SelectedSubmodule' struct and allow using it as a
placeholder value.
Add a corresponding test.
Update the documentation to include it among the listed placeholder
values.
2025-11-12 08:54:34 +01:00
Stefan Haller 62854026a3 Add no-ff merge option
This will put whatever git's default merge variant is as the first menu item,
and add a second item which is the opposite (no-ff if the default is ff, and
vice versa).

If users prefer to always have the same option first no matter whether it's
applicable, they can make ff always appear first by setting git's "merge.ff"
config to "true" or "only", or by setting lazygit's "git.merging.args" config to
"--ff" or "--ff-only"; if they want no-ff to appear first, they can do that by
setting git's "merge.ff" config to "false", or by setting lazygit's
"git.merging.args" config to "--no-ff". Which of these they choose depends on
whether they want the config to also apply to other git clients including the
cli, or only to lazygit.
2025-10-19 21:24:28 +02:00
Stefan Haller 3ac9003298 Add tests
I can't do my usual "add the tests first, with EXPECTED/ACTUAL sections that
document the bug" method here, because the tests would hang without the bug
being fixed.

We need two different tests here: one where a cherry-picked commit simply
becomes empty "by itself", because the change is already present on the
destination branch (this was only a problem with git versions older than 2.45),
and the other where the cherry-pick stops with conflicts, and the user resolves
them such that no changes are left, and then continues the cherry-pick. This
would still fail even with git 2.45 or later. The fix is the same for both cases
though.

The tests show that the selection behavior after skipping an empty cherry-picked
commit is not ideal, but since that's only a minor cosmetic problem we don't
bother fixing it here.
2025-10-14 12:27:32 +02:00
Stefan Haller 3415ed975b Offer to force-delete a worktree if it contains submodules 2025-10-14 12:19:49 +02:00
Stefan Haller 7568f5bf05 Add test demonstrating the problem
For a worktree that contains submodules, trying to delete it shows an error and
doesn't offer to force-remove it.
2025-10-14 12:19:49 +02:00
Stefan Haller c1e52fc807 Fix dropping submodule changes from a commit
Our logic to decide if a file needs to be checked out from the previous commit
or deleted because it didn't exist in the previous commit didn't work for
submodules. We were using `git cat-file -e` to ask whether the file existed, but
this returns an error for submodules, so we were always deleting those instead
of reverting them back to their previous state.

Switch to using `git ls-tree -- file` instead, which works for both files and
submodules.
2025-10-10 12:55:58 +02:00
Stefan Haller 0904bf9969 Add test demonstrating the problem
When dropping changes to the submodule, we expect it to get rolled back to the
previous version; however, it is removed entirely instead.
2025-10-10 12:55:58 +02:00
Stefan Haller 21483b259c Rename AddFileInWorktree to AddFileInWorktreeOrSubmodule
It works for submodules too.

Also, pass file name and file content explicitly; the existing tests don't care
about these, but when writing tests that do, it makes them easier to understand.
2025-10-10 12:55:58 +02:00
Stefan Haller 7fe73c1ee2 When entering a commit in path filtering mode, select the filtered path 2025-10-09 09:58:15 +02:00
Krystof Gartner 703f053a7e Add merge options menu
Replace merge-tool with merge options menu that allows resolving all
conflicts for selected files as ours, theirs, or union, while still
providing access to the merge tool.
2025-10-09 08:45:58 +02:00
Stefan Haller b413710d8c Add separate keybindings for confirmMenu and confirmSuggestion
It seems useful to have the flexibility to remap "enter" in confirmations to
"y", but keep "enter" for menus and suggestions (even though we sometimes use
menus as confirmations, but it's still good to give users the choice).
2025-09-05 10:42:04 +02:00
Stefan Haller 81868de264 Hard-code "enter" for adding lines in integration tests
This one doesn't make a difference in practice because we don't remap the key in
tests, but if we would, then this would no longer work correctly. It's just more
correct this way.
2025-09-05 10:42:04 +02:00
Stefan Haller 5a630aeda1 Refactor: add a separate Prompt view
So far, confirmations and prompts were handled by the same view, context, and
controller, with a bunch of conditional code based on whether the view is
editable. This was more or less ok so far, since it does save a little bit of
code duplication; however, now we need separate views, because we don't have
dynamic keybindings, but we want to map "confirm" to different keys in
confirmations (the "universal.confirm" user config) and prompts (hard-coded to
enter, because it doesn't make sense to customize it there).

It also allows us to get rid of the conditional code, which is a nice benefit;
and the code duplication is actually not *that* bad.
2025-09-05 10:42:03 +02:00
Stefan Haller bf419abb8e Fix dropping a range of stashes in filtered mode
To fix the problem described in the previous commit, iterate backwards over the
stashes that we want to delete. This allows us to use their Index field.
2025-08-25 18:41:06 +02:00
Stefan Haller ef3e899f5b Add test demonstrating problem with dropping stashes in filtering mode
As can be seen from the test, it deletes the wrong stashes in this case, because
it assumes the selection is contiguous.
2025-08-25 15:56:39 +02:00
Stefan Haller a0f4614fdc Cleanup: remove unnecessary ToggleRangeSelect
The next RangeSelectDown actually cancels the sticky range select and turns it
into a non-sticky one.
2025-08-25 14:58:48 +02:00
Stefan Haller 235ab15d7b Don't auto-forward branches that are checked out by another worktree 2025-08-20 10:43:19 +02:00
Stefan Haller 7130cb2947 Add test for auto-forwarding branches that are checked out by another worktree
The test shows that we are currently auto-forwarding branches even if they are
checked out by another worktree; this is quite bad, because when you switch to
that other worktree you'll see that the files that are touched by the fetched
commits are all modified (which we don't test here).
2025-08-20 10:43:19 +02:00
kyu08 3fa5a8eddd Add "CopyToClipboard" command to ConfirmationController 2025-08-15 17:17:06 +02:00
Stefan Haller 0573529f8a Cleanup: remove unnecessary code in test
This was needed in an earlier version of the test, when we asserted the file
content in a more complicated way. It should have been removed in caca62b89e.
2025-08-15 17:17:06 +02:00
Stefan Haller bb17072ed8 Clean up build tags
- Remove old-style build tags (the +build syntax has become obsolete with 1.17)
- Remove redundant build tags from '*_windows.go' files
2025-08-14 20:40:44 +02:00
Stefan Haller 7bf05dfca4 Avoid showing <esc> in options map when it doesn't do anything
The code duplication between Escape and EscapeEnabled is unfortunate, but I
don't see a better way to solve this.
2025-08-14 17:59:38 +02:00
Stefan Haller 2ed11336b5 Allow filtering for keybindings by prepending filter string with '@' 2025-08-14 15:02:48 +02:00
Stefan Haller f1c07b3aed Strengthen text expectation
This assertion didn't test anything useful, given that the filtered view already
has two lines. This should have been adapted in 9f0b4d0000 when we added
section headers while filtering.
2025-08-14 15:02:48 +02:00
Stefan Haller 4d51234ee2 Enable hunk staging mode by default 2025-08-01 10:35:16 +02:00
Stefan Haller abb7bed0c4 Draw divergence from base branch right-aligned in branches view
Also, remove it from the status view. I'd say it isn't really needed there,
although I don't have a strong opinion about that.
2025-07-30 14:23:31 +02:00
Stefan Haller 9c0e103b90 Stage only tracked files when staging all in filter-by-tracked-files view
Also, fix two other commands that stage all files under the hood:
- when continuing a rebase after resolving conflicts, we auto-stage all files,
  but in this case we never want to include untracked files, regardless of the
  filter
- likewise, pressing ctrl-f to find a base commit for fixup stages all files for
  convenience, but again, this should only stage files that are already tracked
2025-07-28 14:10:38 +02:00
Stefan Haller 8cc49e3be5 Add test demonstrating the problem
When filtering to show only tracked files, pressing `a` would also stage
untracked files, which is confusing and undesired.
2025-07-28 14:05:25 +02:00
Stefan Haller 44159ff926 Add tests for tag information rendering
These should have been added when we started rendering this information in
e5b09f34e0; apparently I was too lazy back then. Adding them now to guard
against breaking it in the next commit.

I'm adding these to the CRUD tests, it doesn't seem worth adding separate tests
just for these assertions.
2025-07-28 10:53:51 +02:00
Stefan Haller 52be6964ed Allow rewording and dropping commits in filtering mode
There's no reason not to allow these.

Technically we could enable a few more, but I chose not to because some might be
surprising or confusing in filtering mode. For example, creating a fixup commit
would work (shift-F), but the newly created commit might not show up if it
doesn't match the filter. Similarly, pressing `f` to fixup a commit into its
parent would work, but that parent commit might not be visible, so users might
expect to be fixing up into the next visible commit.
2025-07-27 12:48:38 +02:00
Stefan Haller bc936e8d1b Extract helper function for integration test
We are going to reuse it in two other tests that we are going to add in the next
commit.
2025-07-27 12:48:38 +02:00
Stefan Haller a1aeedd5d5 Fix showing range diff across a rename when filtering by path
We need to pass the union of filter paths at both ends of the range.
2025-07-27 12:05:41 +02:00
Stefan Haller e716617a82 Add test for range diff across rename
When shift-selecting a range of commits across a file rename in
filtering-by-path mode, the diff currently shows an added file rather than a
renamed file. Add a test that demonstrates this, we'll fix this in the next
commit.
2025-07-27 12:05:41 +02:00
Stefan Haller 0f7f1a56df Fix showing diffs for renamed file when filtering by path
When filtering for a file path we use the --follow option for "git log", so it
will follow renames of the file, which is great. However, if you then selected
one of the commits before a rename, you didn't see a diff, because we would pass
the original filter path to the "git show" call.

To fix this, call git log with the --name-status option when filtering by path,
so that each commit reports which file paths are touched in this commit;
remember these in the commit object, so that we can pass them to the "git show"
call later.

Be careful not to store too many such paths unnecessarily. When filtering by
folder rather than file, all these paths will necessarily be inside the original
filter path, so detect this and don't store them in this case.

There is some unfortunate code duplication between loading commits and loading
reflog commits, which I am too lazy to clean up right now.
2025-07-27 12:05:41 +02:00
Stefan Haller 8515c74722 Add test that demonstrates problem with showing filtered history of file with renames
The test shows that selecting a commit before the rename shows an empty diff,
and selecting the rename itself shows an added file rather than a rename.
2025-07-27 12:05:41 +02:00
Stefan Haller ec82e7c1e7 Make stash filtering work when filtering on a folder 2025-07-27 12:03:06 +02:00
Stefan Haller 09cbaf2cba Make stash loading work in filtering mode
This broke with the introduction of the age in the stashes list in bc330b8ff3
(which was included in 0.41, so 12 minor versions ago).

This makes it work again when filtering by file, but it still doesn't work when
filtering by folder (and never has). We'll fix that next.
2025-07-27 12:03:06 +02:00
Stefan Haller ea84d5ee96 Add integration test for filtering the stashes list by file path
The test shows that it doesn't work, the list is empty both when filtering by
file and by folder.

I could have added test cases for these to the unit tests in
stash_loader_test.go instead, but I don't find tests that need to mock git's
output very valuable, so I opted for an integration test even though it takes
much longer to run.
2025-07-27 12:03:06 +02:00
kyu08 5b1292006d Add new command "Checkout previous branch" 2025-07-12 18:17:25 +02:00
Stefan Haller bf19475733 Fix more unstable tests
Similar to what was done in 457cdce61d, and for the same reason.

However, instead of waiting and fixing them one by one as we see them fail, I
decided to go about it more systematically. To do that, I added calls to
`time.Sleep(1 * time.Second)` in all the Shell.Commit* helper functions; this
ensures that all the commits we make get different committer time stamps, making
all these tests fail. With this I'm pretty confident that we're good now.
2025-07-10 08:59:01 +02:00
Stefan Haller 4981419ba9 Fix stale main view content when entering/exiting filtering view
When entering filtering we would only call FocusLine, which takes care of
highlighting the selected line in the commits list, but not of re-rendering the
main view. HandleFocus does that.

When exiting filtering, the HandleFocus call was missing entirely.

The tests needed to be reworked a little bit to make this testable.
2025-07-09 16:00:46 +02:00
Stefan Haller 457cdce61d Fix unstable tests
Now that -committerdate is the default sort order, we could get different
results for the sort order of the branches list depending on whether the commits
on both branches have the same committer time stamp (likely in an integration
test, since git time stamps have second resolution), in which case git will fall
back to alphabetical order, or not (rare, but possible), in which case master
will have the newer commit and will come first. Make this stable by forcing the
sort order to alphabetical.

We might have more tests with this problem, we'll just have to fix them one by
one as we see them fail.
2025-07-09 16:00:46 +02:00
Stefan Haller df48667253 Add a prompt for the sort order menus for branches 2025-07-09 13:16:42 +02:00
Stefan Haller 562a2aaa6b Un-deprecate UserConfig.Git.Log.Order and ShowGraph
And remove them from AppState.
2025-07-09 13:15:03 +02:00
Stefan Haller 703256e92d Move LocalBranchSortOrder and RemoteBranchSortOrder to user config
At the same time, we change the defaults for both of them to "date" (they were
"recency" and "alphabetical", respectively, before). This is the reason we need
to touch so many integration tests. For some of them I decided to adapt the test
assertions to the changed sort order; for others, I added a SetupConfig step to
set the order back to "recency" so that I don't have to change what the test
does (e.g. how many SelectNextItem() calls are needed to get to a certain
branch).
2025-07-09 13:15:03 +02:00
Stefan Haller c739357eb9 Remove git version specific code for versions we no longer support 2025-07-09 12:18:58 +02:00
Stefan Haller 93c5849c86 Remove obsolete git version restrictions 2025-07-09 12:18:57 +02:00
Stefan Haller 6a9fe2e604 Remove obsolete tests
These only ran for git versions that we no longer support.
2025-07-09 12:18:57 +02:00
Stefan Haller a1a2925c9c Remove obsolete git version restriction in test
We have been requiring 2.22 for a while now.
2025-07-09 11:15:45 +02:00
Stefan Haller 7153305174 Add confirmation for hard reset when there are uncommitted changes 2025-07-08 16:41:22 +02:00
Stefan Haller a6096f4702 In hunk staging mode, select blocks of changes rather than actual hunks
Also, pressing right or left arrow moves between blocks of changes rather than
actual hunks. I find this to be much more useful.
2025-07-04 19:31:35 +02:00
Stefan Haller 039831a27a Move to next stageable line after adding a line to a custom patch
While it's true that the behavior is a little different from the staging panel,
where the staged lines are actually removed from the view and in many cases the
selection stays more or less in the same place, it is still very useful to move
to the next stageable thing in the custom patch building view too.
2025-07-04 10:14:35 +02:00
Stefan Haller dc795b5db7 Remove unnecessary refresh
CheckMergeOrRebase calls Refresh already. However, it does an async refresh by
default, so we must turn this into a sync refresh so that moving the selection
down by one works even for the very first commit in history. Also, we must add
an explicit call to FocusLine so that the view selection is in sync with the
model selection; previously this was taken care of by the PostRefreshUpdate call
that happens as part of a refresh.
2025-07-03 17:04:10 +02:00
Stefan Haller 0fc107c8c1 Adjust selection after cherry-picking commits
Keep the same commit selected, by moving the selection down by the number of
cherry-picked commits. We also do this when reverting commits, and it is
possible now that we use a sync waiting status.

We also need to turn the refresh that happens as part of CheckMergeOrRebase into
a sync one, so that the commits list is up to date and the new selection isn't
clamped.
2025-07-03 17:04:10 +02:00
Stefan Haller 09a4e0b209 Add selection assertions to cherry-pick tests
We are about to change the selection behavior when cherry-picking, and it's good
to have tests that document in what way it changes in the next commit.
2025-07-03 16:58:56 +02:00
Stefan Haller 3df894ec92 Stage affected unstaged files when applying or reverting a patch
Unlike moving a patch to the index, applying or reverting a patch didn't
auto-stash, which means that applying a patch when there's a modified (but
unstaged) file in the working tree would error out with the message "error:
file1: does not match index", regardless of whether those modifications conflict
with the patch or not.

To fix this, we *could* add auto-stashing like we do for the "move patch to
index" command. However, in this case we rather simply stage the affected files
(after asking for confirmation). This has a few advantages:

- it only changes the staging state of those files that are contained in the
patch (whereas auto-stashing always changes all files to unstaged)
- it doesn't unnecessarily show a confirmation if none of the modified files are
affected by the patch
- if the patch conflicts with the modified files, the conflicts were "backwards"
("ours" was the patch, "theirs" the modified file); it is more logical if "ours"
is the current state of the file, and "theirs" is the patch.

It's a little unfortunate that the behavior isn't exactly the same as for "move
patch to index", but for that one we do need the auto-stash because of the
rebase that runs behind the scenes.
2025-07-02 16:19:06 +02:00
Stefan Haller c440a208a6 Add tests for applying a patch when there's a modified file
The tests show that this currently fails with the confusing error message "does
not match index", regardless of whether the patch conflicts with the
modifications or not. We'll improve this in the next commit.

I don't bother adding tests for reverting a patch, as the code is basically the
same as for apply.
2025-07-02 16:19:06 +02:00
Stefan Haller 32bd9e6029 Drop stash when successfully unstashing files after moving patch to index 2025-07-02 16:19:06 +02:00
Stefan Haller 823aa640b9 Add test for moving patch to index when there's a modified file
This is functionality that works already, we only add the test for more complete
test coverage. However, there's a detail problem, and the test demonstrates
this: we keep the stash even if there was no conflict. We'll fix this next.
2025-07-02 16:19:06 +02:00
Stefan Haller 7aa426fa71 Enable errorlint linter, and fix warnings 2025-06-30 18:30:11 +02:00
Stefan Haller 0471dbaa84 Enable intrange linter, and fix warnings 2025-06-30 18:30:11 +02:00
Stefan Haller 1e92d8b7f3 Enable nolintlint linter, and fix warnings 2025-06-30 18:30:11 +02:00
Stefan Haller 03abdfcfe2 Fix the CurrentBranchName function
The function would return "head/branchname" when there was either a tag or a
remote with the same name.

While fixing this we slightly change the semantic of the function (and of
determineCheckedOutBranchName, which calls it): for a detached head it now
returns an empty string rather than the commit hash. I actually think this is
better.
2025-06-30 16:08:03 +02:00
Stefan Haller 61815c10e7 Add a test showing undesired branch icon at head commit
The icon will appear when there's a tag with the same name as the current branch
(that's what we're testing here), or even when there's a remote with the same
name. I'm not adding a test for this latter case, but this was actually how I
discovered the issue.
2025-06-30 16:08:03 +02:00
Chris McDonnell 265557afa2 Add unambigious refs/ prefix to all stash references
Pretty basic fix, didn't seem to have any complications.
I only added the refs/ prefix to the FullRefName() method
to align with other similar methods, and to make this change
not impact any user facing modals.

Fixes: https://github.com/jesseduffield/lazygit/issues/4634

Also adds a test demonstrating that the stash show behavior is now fixed
2025-06-15 16:14:59 +02:00
Stefan Haller 9e64f7dd66 Bump gocui and adapt lazygit code
Adaptions are for this gocui commit:

Cleanup: remove Is* error functions

- Use errors.Is instead of quality comparisons. This is better because it
  matches wrapped errors as well, which we will need later in this branch.
- Inline the errors.Is calls at the call sites. This is idiomatic go, we don't
  need helper functions for this.

See https://go.dev/blog/go1.13-errors for more about this.
2025-06-05 13:20:38 +02:00
Chris McDonnell 706891e92b Add integration test for resetting to upstream branch with duplicate name 2025-06-04 20:43:01 +02:00
Chris McDonnell 737a99b1c8 Add integration tests showing resetting to duplicate named tags and branches 2025-06-04 20:43:01 +02:00
Elias Assaf fdf9726c37 Use branchPrefix on moving commits to a new branch
Signed-off-by: Elias Assaf <elyas51000@gmail.com>
2025-05-29 22:39:26 +02:00
Stefan Haller 3cff48437e Add user config gui.addRootItemInFileTree 2025-05-24 18:17:25 +02:00
Chris McDonnell e67bc45d48 Split behavior of rendering allBranchesLogCmd and switching to next cmd
This now allows for leaving the status panel and returning back to the
same log command. Previously any return to the status panel would result
in the next command in the list being shown. Now, you need to press `a`,
with a log command being rendered, to rotate to the next
allBranchesLogCmd.
2025-05-21 08:17:09 +02:00
Stefan Haller f6d13330dd Add custom patch command "Move patch into new commit before the original commit"
This is often useful to extract preparatory refactoring commits from a bigger
one.
2025-05-10 18:57:28 +02:00
Stefan Haller 5321101276 Use 'break' instead of 'edit' for BeginInteractiveRebaseForCommit with merge commit
BeginInteractiveRebaseForCommit is used for all the patch commands, and for
rewording. It works by setting the commit we want to stop at to 'edit'; this
doesn't work for merge commits. This wasn't a problem for the patch commands so
far, because you typically don't use custom patches with merge commits (although
we don't prevent this; maybe we should?).

However, it was a problem when you tried to reword a merge commit; this
previously failed with an error, as the test added in the previous commit
demonstrated.

Also, we want to add a new patch command that has to stop *before* the selected
commit (pull patch to new commit before the original one), and this wouldn't
work for the first commit in a feature branch, because it would have to set the
last commit before that to 'edit', which isn't possible if that's a merge (which
is likely).

To fix all this, use a 'break' before the selected commit if the commit is a
merge. It is important that we only do it in that case and not always, otherwise
we would break the new regression tests that were added a few commits ago.
2025-05-10 18:44:31 +02:00
Stefan Haller 50b2aa5843 Add test for rewording a merge commit
This currently fails with an error.
2025-05-10 18:19:35 +02:00
Stefan Haller b02441cdca Regression test for moving custom patch to new commit from last commit of a stacked branch
I almost broke this during the development of this branch, so add a test to
guard against that. The point here is that the stack remains intact, i.e. the
newly created commit is the last commit of the lower branch, and thus shows the
"*".
2025-05-10 18:19:35 +02:00
Stefan Haller 0c0f95168c Regression test for renaming the last commit of a stacked branch
I almost broke this during the development of this branch, so add a test to
guard against that. The point here is that the stack remains intact, i.e. the
renamed commit is the head of the lower branch, and thus shows the "*".
2025-05-10 18:19:09 +02:00
Stefan Haller 144565ee03 Cleanup: remove unnecessary setup steps 2025-05-10 18:15:42 +02:00
Chris McDonnell 1028f8efb8 Migrate deprecated AllBranchesLogCmd to AllBranchesLogCmds
This solves https://github.com/jesseduffield/lazygit/issues/3961 because
we no longer have a combination of the default and the user defined
list. We just have the user defined list.
2025-05-06 23:33:17 -04:00
Stefan Haller a9f9dee30d Combine customCommand's subprocess, stream, and showOutput fields into a single output enum 2025-05-01 15:46:06 +02:00
Stefan Haller 6402c830d5 Remove space after rebase todo
This is very old; I can only guess that this was added at a time where today's
list column handling wasn't in place yet, so the space was needed to separate
columns. This now causes a gap of two spaces between the rebase todo column and
the author column, which I'm sure wasn't intended. Funny that I never noticed.
2025-04-29 11:30:37 +02:00
Stefan Haller da24deb881 Allow changing diff context size and rename threshold when main view is focused 2025-04-23 08:38:46 +02:00
Stefan Haller 30868eead8 Add new command "Move commits to new branch" 2025-04-21 18:12:50 +02:00
Stefan Haller eaaa937315 Add config for auto-forwarding branches after fetching 2025-04-21 18:06:09 +02:00