Commit Graph
8828 Commits
Author SHA1 Message Date
Stefan HallerandClaude Opus 5.5 e2418047df Let benchmarks use WithSimulationScreen
The next commit adds a benchmark that draws a view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 11:27:59 +01:00
Stefan Haller f07cc9e6f6 Fix a flaky integration test (#6212)
`sync/lock_error_partway_through_pull_with_rebase` failed on CI: every
attempt to continue the rebase ran into index.lock, as if the lock was
never released.

The test hook that holds index.lock starts a background process that
removes the lock once the git command that ran the hook has exited. If
lazygit runs the command in a pty, as it does for a pull, the command's
exit sends SIGHUP to that process. The process ignored SIGHUP, but only
once it got to run. On a busy machine the command can exit before that;
SIGHUP then kills the process and leaves the lock behind. Delaying the
start of the process by 0.3s makes the test fail every time.

Ignore SIGHUP in the hook before starting the background process, so
that the process inherits it. With this, the test passes even with the
delay.
2026-11-12 11:26:36 +01:00
Stefan HallerandClaude Opus 5.5 3f73e56fd3 Ignore SIGHUP in the index.lock test hook before forking
sync/lock_error_partway_through_pull_with_rebase failed on CI: every
attempt to continue the rebase ran into index.lock, as if the lock was
never released.

The test hook that holds index.lock starts a background process that
removes the lock once the git command that ran the hook has exited. If
lazygit runs the command in a pty, as it does for a pull, the command's
exit sends SIGHUP to that process. The process ignored SIGHUP, but only
once it got to run. On a busy machine the command can exit before that;
SIGHUP then kills the process and leaves the lock behind. Delaying the
start of the process by 0.3s makes the test fail every time.

Ignore SIGHUP in the hook before starting the background process, so
that the process inherits it. With this, the test passes even with the
delay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:45:44 +01:00
Stefan Haller 0cfc475000 Improve pasting commit messages (#6210)
When pasting a commit message into the commit message editor (either via
the `ctrl+o` menu or with the terminal's Command-V), we now remove the
hard line breaks so that the text reflows again when you edit it, like
we already do when rewording a message.

When pasting with Command-V, we now avoid the extra blank line at the
beginning of the description; this wasn't really a problem because it
got stripped when committing, but it looked ugly.

Along the way, fix a few minor issues when pasting text into various
views, e.g. the search prompt or a "New branch name" text field.
2026-11-12 10:45:04 +01:00
Stefan HallerandClaude Opus 5.5 14a36053e9 Unexport IsPasting
Nothing outside gocui needs to know about pastes any more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 c28e3576d1 Drop pasted keys for views without an OnPaste handler
Every view that takes text has an OnPaste handler now, and views that
don't take text already ignored pasted keys. Make this a single rule.
While a paste is in progress, keys go to the focused view's OnPaste
handler or nowhere. This replaces the check in execKeybindings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 9765b96790 Let the search prompt receive pasted text in one piece
Treat pasted text like in the other views that take a single line of
text. Before, a pasted newline confirmed the search, and the rest of
the pasted text was lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 417dea6381 Let prompts receive pasted text in one piece
Like a menu's filter, a prompt takes a single line of text, so treat
pasted text the same way. Before, the prompt ignored pasted newlines.
This joined the lines without a space. It also ran the keybindings for
other keys in the text, so a pasted Esc closed the prompt, and a pasted
tab switched to the suggestions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 e68f195e33 Let a menu's filter receive pasted text in one piece
The filter takes a single line of text. Drop the newlines at the start
and end of the pasted text, and replace the remaining newlines and tabs
with spaces. A pasted newline therefore no longer runs the selected
menu item.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 f6ceabdebe Add a test for pasting text into the keybindings menu
The keybindings menu filters as you type. If you paste text that ends
with a newline into it, the text filters the menu, and the newline then
runs the selected item as if you had pressed Enter. The same happens in
the other menus that filter as you type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 f3bc6fc85e Extract what the prompt and menu filter editors do after an edit
Handlers for pasted text are going to need the same steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 ebbd2126db Remove hard line breaks from text pasted into the commit description
Do the same as when pasting a commit message with the commit menu, so
that the paragraphs of the body reflow when you edit them. This also
covers a commit message pasted into the summary, since everything after
its first line goes into the description.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 ce988017f1 Add a test for pasting a wrapped commit message into the summary
If you paste a commit message into the summary with the terminal's
paste command, the body keeps its hard line breaks. This happens even
where auto-wrapping would break the line at the same place. If you
then edit a paragraph of the body, it doesn't reflow. Pasting with the
commit menu already removes these line breaks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 fb21a99035 Return a description driver from Popup.CommitDescriptionPanel
It returned a driver for the summary. This made it impossible to use
the description's driver methods after a test step that moves the
focus to the description, such as pasting a multi-line text into the
summary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 107f0c1352 Don't start the description with an empty line when pasting a message
If you paste text into an empty description, drop the newlines at its
start. This happens when you paste a whole commit message into the
summary with the terminal's paste command. The part after the first
line goes into the description, and it starts with the blank line
between subject and body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 f2a63e2de0 Handle text pasted into the commit message panel in one piece
Use the new OnPaste handler for the summary and the description. This
replaces the IsPasting checks in the keybindings for confirming and for
switching between summary and description. These checks only worked for
the default keys of those keybindings. If a user had bound Enter or Tab
to something else, pasting a newline or a tab ran that command.

Otherwise the behavior stays the same, except that the panel now drops
Esc and control characters in pasted text. Before, it executed them;
for example, a pasted Esc closed the panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 0111d9bd61 Let views receive pasted text in one piece
Editable views receive pasted text as one key press per character, so a
newline or a tab in the text triggers the keybinding for Enter or Tab.
The commit message panel works around this by checking IsPasting in
these keybindings. This is fragile, and it gives the panel no way to
look at the pasted text as a whole.

Add an OnPaste handler to View. For a view that has one, collect the
pasted characters, newlines and tabs while the paste lasts, and pass
them to the handler when it ends. Drop all other keys of the paste. They
are unlikely to occur in pasted text, and dispatching keys like Esc in
the middle of a paste would run them as commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 9d2058fbc4 Add a test for pasting a multi-line commit message into the summary
If you paste a commit message into the summary with the terminal's
paste command, the description starts with an empty line. The first
newline of the pasted text moves to the description, and the second
one (the blank line between subject and body) is typed into the
description. Git strips the empty line when committing, but it looks
broken in the panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 ad52544df8 Add a test for pasting text into the commit description
It checks that the text goes in at the cursor, and that a tab turns
into spaces instead of switching to the summary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 dec9e49162 Add support for pasting text in integration tests
The commit message panel handles pasted text differently from typed
text (see ba6cfc1f85), but integration tests couldn't simulate a
paste, so this had no tests. Let tests replay the events that a
terminal sends for a bracketed paste: the start of the paste, a key
press for each character, and the end of the paste.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 b65298c3b1 Remove hard line breaks when pasting a commit message from the clipboard
Do the same as when rewording a commit, so that the paragraphs of the
body reflow when you edit them.

This also matters for the "Copy commit message to clipboard" entry of
the commit menu. It copies the message with the line breaks that
auto-wrapping inserted. Without this change, pasting the copied
message back into the panel would turn these into hard line breaks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 1c7ccd5833 Add a test for pasting a commit message that has hard line breaks
If you copy a commit's message with `y` in the commits panel and paste
it into the commit message panel with the commit menu, the body keeps
the hard line breaks that git committed. This happens even where
auto-wrapping would break the line at the same place. If you then edit
a paragraph of the body, it doesn't reflow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan HallerandClaude Opus 5.5 8b8e3c05aa Check the auto-wrap config inside the helper that removes hard line breaks
All three callers of TryRemoveHardLineBreaks check the
AutoWrapCommitMessage config first and pass the AutoWrapWidth config.
We are about to add a fourth caller, so move both into a CommitsHelper
method. This also makes it impossible to call it with the wrong width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 10:22:50 +01:00
Stefan Haller 671dfa394e Add "Copy commit message to clipboard" to the commit menu (#6209)
The commit menu (`ctrl+o` in the commit message panel) can paste a
message from the clipboard, but it can't copy the message to it. Copying
is useful for keeping a message around while committing something else
first. For example, if a pre-commit hook fails, users may want to commit
a fix for it before they come back to the original change. Copying the
preserved commit message gives them a chance to park it in an untitled
editor buffer and reuse it later.

Also, add "Clear commit message" to the menu; this is for those users
who don't know that you can quickly clear the message by holding down
`ctrl+u` with auto-repeat. I've seen users hold down backspace with
auto-repeat instead, which takes forever.

This changes the keybinding for the "Paste commit message from
clipboard" menu item from `p` to `V`, so that we can use `C` for
copying. I hope this isn't a problem for anybody's muscle memory, but
the new keys are consistent with copying and pasting commits in the
commits panel.
2026-11-12 10:22:47 +01:00
Stefan HallerandClaude Opus 5.5 b385a4e164 Add "Clear commit message" to the commit menu
Many users don't know that they can clear the commit message panel
quickly by holding down ctrl+u. They hold down backspace instead, and
for a long message this takes a long time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 08:36:14 +01:00
Stefan HallerandClaude Opus 5.5 5a5e3ac696 Add "Copy commit message to clipboard" to the commit menu
The commit menu (ctrl+o in the commit message panel) can paste a message
from the clipboard, but it can't copy the message to it. Copying is
useful for keeping a message around while committing something else
first. For example, if a pre-commit hook fails, users may want to
commit a fix for it before they come back to the original change. If
they commit the fix through the commit message panel, lazygit deletes
the preserved message of the original change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 08:36:14 +01:00
Stefan HallerandClaude Opus 5.5 f11e1dca4c Extract a helper that joins summary and description into a message
The next commit needs to build a commit message from the commit panel
in git's canonical format too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 19:51:44 +01:00
Stefan HallerandClaude Opus 5.5 fc1443dee4 Change the commit menu's key for pasting a commit message to V
We are about to add an entry for copying the commit message to the
clipboard. Its obvious key `c` is already taken by "Add co-author", so
use `C` for copying and `V` for pasting. This matches the keys for
copying and pasting commits in the commits panel.

This means changing the key of an existing entry. We change the one for
pasting and not the one for adding a co-author, because users are
likely to paste a commit message less often than they add a co-author.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 19:51:44 +01:00
Stefan Haller 5d00ff7aac Withhold paste events together with their keys while blocking the UI (#6208)
While a long-running operation blocks input, lazygit buffers key events
and replays them when the operation ends. Paste events weren't buffered,
so they took effect right away. If the user pasted text during the
block, the paste has ended by the time its keys are replayed, and
lazygit treated them as typed keys. In a list panel, every character of
the text then ran the command bound to it, rather than ignoring them as
it would when the UI is not blocked.

To fix this, buffer the paste start/stop events in the same way as the
key events themselves, and replay them after unblocking along with
those.
2026-11-11 19:50:54 +01:00
Stefan HallerandClaude Opus 5.5 044a827a3e Withhold paste events while input is blocked
Buffer the start and end of a paste along with the keys, and replay them
in the same order. This way lazygit still recognizes the replayed keys
as pasted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 18:49:59 +01:00
Stefan HallerandClaude Opus 5.5 1be1a5cbfd Add a test for pasting while input is blocked
While a long-running operation blocks input, lazygit buffers key events
and replays them when the operation ends. Paste events aren't buffered,
so they take effect right away. If the user pastes text during the
block, the paste has ended by the time its keys are replayed, and
lazygit treats them as typed keys. In a list panel, every character of
the text then runs the command bound to it. Without the block, lazygit
ignores keys pasted into a list panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 18:49:59 +01:00
Stefan HallerandClaude Opus 5.5 2a39f2b564 Rename bufferedKeyEvents to bufferedInputEvents
The next commit buffers paste events in it too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 18:49:59 +01:00
Stefan Haller dd1ec8a56b Remove a stray comment line 2026-11-11 18:49:59 +01:00
Stefan Haller 8290cc9357 Fix index.lock error when committing with editor and there are no staged files (#6202)
If you commit with `shift-C` ("Commit changes using git editor") while
no files are staged, lazygit asks whether to stage all files. Confirming
this often fails with "fatal: Unable to create '.../.git/index.lock':
File exists". This is caused by the refresh of the Files view after the
stage-all, which runs `git status` on a worker. Fix this by waiting for
that refresh to be finished before calling `git commit`.

Committing with `c` didn't run into this in practice, because the
refresh is done long before the user has typed a commit message.
2026-11-10 14:06:21 +01:00
Stefan HallerandClaude Opus 5.5 88cf4dd97d Wait for the files refresh before committing after staging all files
If you commit with shift-C ("Commit changes using git editor") while no
files are staged, lazygit asks whether to stage all files. Confirming
this often fails with "fatal: Unable to create '.../.git/index.lock':
File exists".

After staging the files, we refresh the files view and then retry the
commit right away. The refresh runs `git status` on a worker. Since it
is a foreground refresh, git takes index.lock to write its refreshed
stat cache back to the index. So `git commit` can start while the status
command still holds the lock. Committing with `c` doesn't run into this
in practice, because the refresh is done long before the user has typed
a commit message.

Retry the commit in the refresh's Then instead. We already do this when
gui.skipNoStagedFilesWarning is on.

Without the fix, the new test failed in two of six runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 13:15:34 +01:00
Stefan HallerandClaude Opus 5.5 668f4032da Extract a helper that stages all files and then runs a handler
Prepares for using it when the user confirms the "No files staged"
prompt too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 13:13:25 +01:00
Stefan Haller bd4062a1e7 Let the user continue or abort a squash merge (#6197)
If a squash merge stops with conflicts, lazygit didn't show a merge in
progress, because "git merge --squash" doesn't write MERGE_HEAD. After
resolving the conflicts, users had to commit the changes themselves, and
type the message that "Squash merge and commit" would have used. To give
up, they had to discard the changes. The "Abort the merge" item of the
conflicts menu failed with "You are currently neither rebasing nor
merging".

Improve this by showing a merge in progress when a "Squash merge and
commit" fails with conflicts, so that users can continue or abort it
like they would with a regular merge. We even enter this state after
"Squash merge and leave uncommitted", so that users can use the `m` menu
to continue and create a commit with the right message. This is a change
in behavior that I hope won't disturb anyone's workflows; please file an
issue if it does.
2026-11-08 15:53:39 +01:00
Stefan HallerandClaude Opus 5.5 8683f60761 End a squash merge when the user discards all of its changes
Discarding a file or directory in the files panel runs git commands on
these paths only, and these leave SQUASH_MSG alone. If users discard
all changes of a squash merge this way, lazygit keeps showing a merge
in progress, and the next commit gets the squash merge message.

Abort the squash merge after "Discard all changes" if no changes are
left. Untracked files don't count, because a squash merge stages the
files that it adds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:36:41 +01:00
Stefan HallerandClaude Opus 5.5 09780de32e Use the squash merge message when committing a squash merge
After "Squash merge and leave uncommitted", the commit panel opens
empty, or with the commit prefix of the branch. Users have to type a
message for the squash merge themselves. "git commit" from the terminal
suggests the message in SQUASH_MSG instead.

Show the message in SQUASH_MSG in the commit panel, unless there is a
preserved message. It takes precedence over the commit prefix, like the
message of "Squash merge and commit" does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:36:41 +01:00
Stefan HallerandClaude Opus 5.5 c7c514fa44 Let the user continue or abort a squash merge
If a squash merge stops with conflicts, lazygit doesn't show a merge in
progress, because "git merge --squash" doesn't write MERGE_HEAD. After
resolving the conflicts, users have to commit the changes themselves,
and type the message that "Squash merge and commit" would have used. To
give up, they have to discard the changes. The "Abort the merge" item
of the conflicts menu fails with "You are currently neither rebasing
nor merging".

"git merge --squash" writes SQUASH_MSG, a message for committing the
changes. Git removes it when the changes are committed, reset or
stashed, and when switching branches. Show a merge in progress while
the file exists. Continue it with "git commit", and abort it with "git
reset --merge", like "git merge --abort" does.

Write the configured squashMergeMessage into SQUASH_MSG, so that
continuing uses it. Do this for "Squash merge and leave uncommitted"
too, so that both variants make the same commit. A merge in progress is
now shown after this variant until the user commits the changes. We
don't offer to continue it when its conflicts are resolved, though,
because the user asked us not to commit.

Select the new commit after "Squash merge and commit", like after other
merges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:36:41 +01:00
Stefan HallerandClaude Opus 5.5 9942101b3e Identify the operation to continue or abort by its working tree state
GenericMergeOrRebaseAction takes the name of the git command whose
--continue, --skip or --abort option it runs. We are about to show a
squash merge as an operation in progress, and it has no such command.
"git merge --continue" and "git merge --abort" refuse to run without
MERGE_HEAD, and a squash merge doesn't write it. Pass the working tree
state instead, so that GenericMergeOrRebaseAction can decide which
commands to run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:36:41 +01:00
Stefan HallerandClaude Opus 5.5 c7002e5e52 Discard edits on top of staged changes when aborting a merge or cherry-pick
If a merge, cherry-pick, revert or "git am" stops with conflicts, users
often edit the files that git changed, for example to fix the build. If
they then decide to give up and abort, git fails with "Entry 'file' not
uptodate. Cannot merge." It keeps unstaged changes when aborting, but it
can't reset the staged changes of a file underneath them. "git am
--abort" even stops halfway, after it has reset the conflicted files.

Git refuses to start any of these operations if there are staged
changes, or if a file that it has to change has unstaged changes. So
unstaged changes on top of staged ones were made after git stopped.
Discard them before aborting, but ask the user first, listing the
files. A rebase doesn't need this, because "git rebase --abort"
discards all changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:36:41 +01:00
Stefan HallerandClaude Opus 5.5 acb54f73d1 Disable squash merging while there are staged changes
Git refuses to merge a branch while there are staged changes, unless
the merge is a fast-forward. A fast-forward keeps the staged changes as
they are. A squash merge that git can fast-forward adds the changes of
the branch to them, though, and "Squash merge and commit" then commits
them all.

Disable both squash merge items in the merge menu while there are
staged changes, so that squash merges behave like other merges. We will
rely on this when we let the user abort a squash merge. Aborting resets
the staged changes, so they must all come from the merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:36:41 +01:00
Stefan HallerandClaude Opus 5.5 a7fcae2ca1 Add a test for squash merging while there are staged changes
If the checked-out branch can be fast-forwarded to the selected branch,
"git merge --squash" doesn't refuse to run while there are staged
changes, unlike a merge that can't be fast-forwarded. It adds the
changes of the branch to the ones that are already staged. "Squash
merge and commit" then commits the staged changes along with the
squashed ones, without the user noticing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:36:41 +01:00
Stefan Haller f2b182df45 When a "git am" in progress, let the user continue, skip or abort it (#6196)
Users can copy commits from one repo to another with "git format-patch"
and "git am", for example with custom commands. If "git am" stopped with
a conflict, lazygit showed this as a rebase, because git am uses the
rebase-apply directory too. The rebase options in the m menu didn't work
either; git refuses to run "git rebase --continue" during an am.

Recognize an am by the rebase-apply/applying file, and call this state
"applying patches". The `m` menu then offers "git am --continue",
"--abort" and "--skip".
2026-11-08 15:35:48 +01:00
Stefan HallerandClaude Opus 5.5 df21b8cca0 Show the patches that "git am" hasn't applied yet
Show them in the commits panel under a "Pending patches" header, like
the todos of a rebase or cherry-pick. The patches usually come from
another repository, so we can't look up their commits. Instead, take
the subject, author and date from the patch files in .git/rebase-apply,
and show the patch itself in the main view.

Git has no way of editing these todos, so disable the actions that
would edit them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:17:17 +01:00
Stefan HallerandClaude Opus 5.5 20c6ae4c86 Return the reason why todos can't be edited from a single function
All callers turned the result of isCherryPickingOrReverting into the
same disabled reason. The next commit adds a second reason for "git
am", so return the reason itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:17:17 +01:00
Stefan HallerandClaude Opus 5.5 7adcfff244 Show a "git am" in progress, and let the user continue, skip or abort it
Users can copy commits from one repo to another with "git format-patch"
and "git am", for example with custom commands. If "git am" stopped
with a conflict, lazygit showed this as a rebase, because git am uses
the rebase-apply directory too. The rebase options in the m menu didn't
work either; git refuses to run "git rebase --continue" during an am.

Recognize an am by the rebase-apply/applying file, and call this state
"applying patches". The m menu then offers "git am --continue",
"--abort" and "--skip".

If "git am --continue" finds nothing to commit, it says "No changes -
did you forget to use 'git add'?". Unlike for a rebase, don't skip the
patch in that case. Without --3way, git am leaves the files alone if a
patch doesn't apply, and skipping would lose the patch.

If a lock error stops "git am --continue" or "--skip" after it has moved
on to the next patch, don't run it again; this could skip that patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:17:17 +01:00
Stefan HallerandClaude Opus 5.5 6a0ef0b750 Describe the operation in progress with a translated phrase
The texts for aborting or continuing a merge, rebase, cherry-pick or
revert insert the git command name into the sentence, as in "Abort the
rebase". We are going to support "git am" next, and "Abort the am"
makes no sense.

Give each operation a translated phrase like "the rebase" instead, and
use it as a placeholder in these texts. Rename the texts too. The
existing translations still use %s, and this way lazygit ignores them
until they are updated.

This changes the wording of the abort confirmation slightly, from
"Abort rebase" to "Abort the rebase", and from "abort the current
rebase" to "abort the rebase".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:17:17 +01:00
Stefan Haller f15055584f Fix index.lock retry logic for rebase and cherry-pick commands (#6195)
Our git command runner has logic to retry a failed git command if it can
determine that the failure was caused by an index.lock held by a
background process. This is great, but it's the wrong thing to do for an
interactive rebase that fails while applying one of its pick todos; in
that case, git stops in the middle of the rebase, and retrying it
results in a confusing error ("a rebase is already in progress").

This is just one of many examples of what can go wrong when retrying
rebase, cherry-pick, or revert commands that fail with an index.lock
error; this PR tries to handle as many situations as reasonable
automatically (e.g. by issuing `git rebase --continue` when a pick
failed and lazygit can confirm that the pick was rescheduled by git).
See the individual commits for details.
2026-11-08 15:16:49 +01:00