Commit graph

7558 commits

Author SHA1 Message Date
Stefan Haller bb8955f2de Load direnv environment when switching repos
When a user opens a repo from the recent-repos menu or jumps between
worktrees inside lazygit, only the env vars present at process startup
reach subprocesses. That breaks pre-commit hooks and other tools whose
dependencies are pulled in by a per-repo .envrc — users were left with
read-only operations because the env their shell would normally load via
direnv never made it into lazygit's git invocations.

Shell out to `direnv export json` after each chdir and apply the JSON
delta via os.Setenv/Unsetenv. direnv tracks the previous load in its own
DIRENV_DIFF env var, so the delta also unloads vars from the old repo
when entering one without a matching .envrc. If direnv isn't on PATH the
call is a no-op, so users who don't use direnv pay nothing and users who
do need no config to opt in. Any stderr direnv emits (loading messages,
"blocked .envrc" errors, etc.) goes to the command log.

The integration test puts a fake direnv on PATH and asserts that a value
it exports reaches a custom command after switching repos. Wiring this
up needed runner.go to support `{{actualPath}}` placeholders in
ExtraEnvVars, mirroring the existing support for ExtraCmdArgs, so the
test can prepend a fixture-relative directory to PATH.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 09:05:01 +02:00
Stefan Haller 2601556189 Dedupe the recent-repos fallback in setupRepo
The for-loop here was a verbatim copy of openRecentRepo, so call that instead.
2026-06-04 09:05:01 +02:00
Stefan Haller 685dfc87a4 Cleanup: drop unneeded variable 2026-06-04 09:05:01 +02:00
Stefan Haller d86a49ba3f When RecordCurrentDirectory fails, only log the error
If we return the error here, we don't switch repos, but the chdir
happened already, so this would be an inconsistent state (a lot of
lazygit's code assumes that the current directory is always the worktree
root). Only log the error; failing to record the current directory is
not the end of the world.

Also, it is very unlikely to happen; RecordCurrentDirectory only writes
to a small file, and if this fails, then either there is filesystem
corruption of the disk is full, and in both cases the user likely has
much bigger problems.
2026-06-04 09:05:01 +02:00
Stefan Haller 009c8975be
Additions to AGENTS.md (#5667) 2026-06-03 09:21:42 +02:00
Stefan Haller cc6a0374e8 Additions to AGENTS.md 2026-06-03 09:18:31 +02:00
Stefan Haller 16cf2ff1a9
Fix the waiting status display for synchronous operations (#5659)
Commit 4f0393f97b caused a regression: for operations that use
WithWaitingStatusSync (examples are squashing fixups, moving commits up
or down, cherry-picking, creating fixup commits, and more), the waiting
status wouldn't show during the operation; however, it would show after
the operation was done, and then linger forever.

The cause: since 4f0393f97b, layout sizes the bottom line from the
actual content of the AppStatus view rather than from the status
manager. The async render path keeps the view in sync (it sets the
buffer on the first tick and clears it to "" when the status ends), but
the sync path used by WithWaitingStatusSync did not:

- It called ForceLayoutAndRedraw before writing anything to the view, so
layout saw an empty buffer and left no room; the status never appeared
during the operation.
- When the operation finished it just broke out of the loop, leaving the
last spinner frame in the buffer. Every subsequent layout kept reserving
room for that stale content, so the status stuck around forever.

Fix this by writing the status into the view before the initial layout,
and clearing it again when stopping.
2026-05-30 14:25:21 +02:00
Stefan Haller 101d7965ae Fix the waiting status display for synchronous operations
Commit 4f0393f97b caused a regression: for operations that use
WithWaitingStatusSync (examples are squashing fixups, moving commits up or down,
cherry-picking, creating fixup commits, and more), the waiting status wouldn't
show during the operation; however, it would show after the operation was done,
and then linger forever.

The cause: since 4f0393f97b, layout sizes the bottom line from the actual
content of the AppStatus view rather than from the status manager. The async
render path keeps the view in sync (it sets the buffer on the first tick and
clears it to "" when the status ends), but the sync path used by
WithWaitingStatusSync did not:

- It called ForceLayoutAndRedraw before writing anything to the view, so layout
  saw an empty buffer and left no room; the status never appeared during the
  operation.
- When the operation finished it just broke out of the loop, leaving the last
  spinner frame in the buffer. Every subsequent layout kept reserving room for
  that stale content, so the status stuck around forever.

Fix this by writing the status into the view before the initial layout, and
clearing it again when stopping.
2026-05-30 14:20:05 +02:00
Stefan Haller 64d244cfcb Refactor: extract private setAppStatusContent helper method 2026-05-30 13:59:17 +02:00
Stefan Haller f2788e475e
Add docs for how to add the default, non-pager diff to the list of pagers (#5656)
See #5328.
2026-05-28 19:46:47 +02:00
Stefan Haller 115b72d98b Add docs for how to add the default, non-pager diff to the list of pagers 2026-05-28 19:41:45 +02:00
Stefan Haller 371f57c76e Fix minor typos in README.md 2026-05-28 19:36:01 +02:00
Stefan Haller ff8f3d790e
Fix crash when keybindings are disabled that normally show in the status bar (#5655)
If a keybinding that we want to display in the options bar was set to
`<disabled>` by the user, in pre-0.62 versions we would still display
the command, but with no keybinding. This was arguably not very useful
before, but now it actually crashes because we would now try to display
the first key of the slice of configured keys (crash introduced in
3d18ee8f91). Fix the crash by not showing those commands at all.
2026-05-28 19:31:42 +02:00
Stefan Haller b3491f4e37 Cleanup: filter out empty keybindings earlier
This doesn't make a difference for the behavior, it just looks strange to
include the empty bindings first and then filter them out in the next statement.
2026-05-28 19:26:43 +02:00
Stefan Haller 76d0dc15ca Fix crash when keybindings are disabled that we want to show in the status bar
If a keybinding that we want to display in the options bar was set to <disabled>
by the user, in pre-0.62 versions we would still display the command, but with
no keybinding. This was arguably not very useful before, but now it actually
crashes because we would now try to display the first key of the slice of
configured keys (crash introduced in 3d18ee8f91). Fix the crash by not showing
those commands at all.
2026-05-28 19:26:43 +02:00
Stefan Haller 7299b224ef
Fix breaking changes note (#5646)
Ctrl+s used to be a separate binding confirmInEditor-alt, but now that
it was folded into the main confirmInEditor, we need to mention both
bindings here.

Also use the new syntax while we're at it.
2026-05-26 22:31:03 +02:00
Stefan Haller 5e326853dc Fix breaking changes note
Ctrl+s used to be a separate binding confirmInEditor-alt, but now that it was
folded into the main confirmInEditor, we need to mention both bindings here.

Also use the new syntax while we're at it.
2026-05-26 22:27:36 +02:00
Stefan Haller 8b4d043d52
Update docs and schema for release (#5645) 2026-05-26 22:16:14 +02:00
Stefan Haller 07d73fbbee Update docs and schema for release 2026-05-26 22:12:31 +02:00
Stefan Haller a85d81b137
Update translations from Crowdin (#5644) 2026-05-26 22:11:50 +02:00
Stefan Haller 064e9a4c98 Update translations from Crowdin 2026-05-26 22:08:49 +02:00
Stefan Haller 258afbce8f
Add support for git flow using the git-flow-next tool (#5288)
This change enables Lazygit `git-flow` integration to work with
`git-flow-next`. The "official" `git-flow` has been deprecated and
replaced by `git-flow-next`. `got-flow-next` has the same tool and most
of the functionality is compatible but the `git config` is different so
Lazygit doesn't recognise it.

- Support gitflow.branch.<type>.prefix (git-flow-next) in addition to
gitflow.prefix.<type> (legacy)
- Refactor FinishCmdObj to use a prefix map lookup to find the branch
type
2026-05-26 22:06:58 +02:00
Henry Maddocks dd0d90837d Add support for git flow using git-flow-next
git-flow-next (https://github.com/gittower/git-flow-next) uses a
different config schema than legacy git-flow:
gitflow.branch.<type>.prefix instead of gitflow.prefix.<type>.
Recognize both schemas in GetGitFlowPrefixMap by querying each and
merging into a single prefix → branchType map. GitFlowEnabled now
consults the merged map so a next-only setup counts as enabled.

When both schemas configure the same prefix, the legacy entry wins.
In normal usage both schemas agree, so the rule mainly matters as a
deterministic tie-breaker.
2026-05-26 11:57:09 +02:00
Henry Maddocks 415015c66a Pull git-flow prefix parsing into a config-level helper
Lift the inline parsing in FinishCmdObj into parseGitFlowPrefixMap on
ConfigCommands. The caller now does a direct map lookup against the
parsed prefix → branchType map instead of iterating the raw config
output and suffix-matching. This is preparation for adding git-flow-next
support, which needs to merge a second config schema into the same map.

One incidental change: a branch name without a slash now returns
NotAGitFlowBranch immediately, rather than falling through the
line loop with an empty suffix. Previously a configured
gitflow.prefix.X whose value happened to equal the entire branch
name could match — never a useful outcome.
2026-05-26 11:05:22 +02:00
Stefan Haller 53e39dc7b8
Bump goreleaser/goreleaser-action from 7.1.0 to 7.2.2 (#5619)
Bumps
[goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action)
from 7.1.0 to 7.2.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/goreleaser/goreleaser-action/releases">goreleaser/goreleaser-action's
releases</a>.</em></p>
<blockquote>
<h2>v7.2.2</h2>
<h2>What's Changed</h2>
<ul>
<li>ci(deps): bump the actions group with 3 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/560">goreleaser/goreleaser-action#560</a></li>
<li>fix: nightly resolution to select newest published release by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/562">goreleaser/goreleaser-action#562</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Copilot"><code>@​Copilot</code></a> made
their first contribution in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/562">goreleaser/goreleaser-action#562</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.2">https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.2</a></p>
<h2>v7.2.1</h2>
<p>This fully removes the usage of the old <code>nightly</code> moving
tag.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/goreleaser/goreleaser-action/compare/v7.2.0...v7.2.1">https://github.com/goreleaser/goreleaser-action/compare/v7.2.0...v7.2.1</a></p>
<h2>v7.2.0</h2>
<h2>What's Changed</h2>
<ul>
<li>test: cover install across release eras by <a
href="https://github.com/caarlos0"><code>@​caarlos0</code></a> in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/555">goreleaser/goreleaser-action#555</a></li>
<li>feat: add <code>version-file</code> input by <a
href="https://github.com/caarlos0"><code>@​caarlos0</code></a> in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/556">goreleaser/goreleaser-action#556</a></li>
<li>feat: resolve nightly to latest vX.Y.Z-<!-- raw HTML omitted
-->-nightly release by <a
href="https://github.com/caarlos0"><code>@​caarlos0</code></a> in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/558">goreleaser/goreleaser-action#558</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.0">https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5daf1e915a"><code>5daf1e9</code></a>
fix: nightly resolution to select newest published release (<a
href="https://redirect.github.com/goreleaser/goreleaser-action/issues/562">#562</a>)</li>
<li><a
href="5cc7ebb73d"><code>5cc7ebb</code></a>
ci: update actions</li>
<li><a
href="702f5f91c9"><code>702f5f9</code></a>
ci(deps): bump the actions group with 3 updates (<a
href="https://redirect.github.com/goreleaser/goreleaser-action/issues/560">#560</a>)</li>
<li><a
href="1a80836c5c"><code>1a80836</code></a>
ci(nightly): pass GITHUB_TOKEN to nightly integration job</li>
<li><a
href="a71152e827"><code>a71152e</code></a>
refactor: drop legacy 'nightly' tag fallback</li>
<li><a
href="4c6ab561ad"><code>4c6ab56</code></a>
feat: resolve nightly to latest vX.Y.Z-&lt;sha&gt;-nightly release (<a
href="https://redirect.github.com/goreleaser/goreleaser-action/issues/558">#558</a>)</li>
<li><a
href="4f96abf297"><code>4f96abf</code></a>
feat: add <code>version-file</code> input (<a
href="https://redirect.github.com/goreleaser/goreleaser-action/issues/556">#556</a>)</li>
<li><a
href="15fa2a96d4"><code>15fa2a9</code></a>
test: cover install across release eras (<a
href="https://redirect.github.com/goreleaser/goreleaser-action/issues/555">#555</a>)</li>
<li>See full diff in <a
href="e24998b8b6...5daf1e915a">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=goreleaser/goreleaser-action&package-manager=github_actions&previous-version=7.1.0&new-version=7.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2026-05-26 10:07:14 +02:00
dependabot[bot] 7cab05d58f
Bump goreleaser/goreleaser-action from 7.1.0 to 7.2.2
Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 7.1.0 to 7.2.2.
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](e24998b8b6...5daf1e915a)

---
updated-dependencies:
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 7.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 08:04:40 +00:00
Stefan Haller 8bdbfbd928
Bump github.com/gdamore/tcell/v3 from 3.3.0 to 3.4.0 (#5618)
Bumps [github.com/gdamore/tcell/v3](https://github.com/gdamore/tcell)
from 3.3.0 to 3.4.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/gdamore/tcell/releases">github.com/gdamore/tcell/v3's
releases</a>.</em></p>
<blockquote>
<h2>Version 3.4.0 Feature Release</h2>
<p>This release has quite a number of bug fixes, but it <em>also</em>
introduces some substantial new capabilities.
Mostly the new support for advanced key reporting, along with backing
support in the mouse demo, and
enhanced configurability and overrides both for the application and for
the user (environment variables).</p>
<p>This also replaces the old WASM terminal with a new version based on
the libghostty implementation. This
should be much faster, and nicer to work with, with a larger set of full
features such as advanced key reporting,
better support for resizing, etc.</p>
<h2>What's Changed</h2>
<ul>
<li>fix: possible panic in getConsoleInput if no event returned by <a
href="https://github.com/AntoineGS"><code>@​AntoineGS</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1068">gdamore/tcell#1068</a></li>
<li>Sanitize titles and notifications (fixes <a
href="https://redirect.github.com/gdamore/tcell/issues/1066">#1066</a>)
by <a href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1069">gdamore/tcell#1069</a></li>
<li>feat: Optionally sanitize content before putting to the terminal
(fix… by <a href="https://github.com/gdamore"><code>@​gdamore</code></a>
in <a
href="https://redirect.github.com/gdamore/tcell/pull/1071">gdamore/tcell#1071</a></li>
<li>feat: Add reporting of keyboard protocol (fixes <a
href="https://redirect.github.com/gdamore/tcell/issues/967">#967</a>) by
<a href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1073">gdamore/tcell#1073</a></li>
<li>C1 handling improvements by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1074">gdamore/tcell#1074</a></li>
<li>feat(keys): Add support for advanced key reporting by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1075">gdamore/tcell#1075</a></li>
<li>feat(wasm): Introduce ghostty-wasm as backing WASM terminal (fixes
<a href="https://redirect.github.com/gdamore/tcell/issues/7">#7</a>… by
<a href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1076">gdamore/tcell#1076</a></li>
<li>fix: close OSC8 hyperlinks (fixes <a
href="https://redirect.github.com/gdamore/tcell/issues/1078">#1078</a>)
by <a href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1080">gdamore/tcell#1080</a></li>
<li>feat: KeyBacktab updates for advanced mode (fixes <a
href="https://redirect.github.com/gdamore/tcell/issues/1018">#1018</a>)
by <a href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1081">gdamore/tcell#1081</a></li>
<li>feat: support pixel-precision mouse reporting (CSI ?1016h) by <a
href="https://github.com/ImGajeed76"><code>@​ImGajeed76</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1077">gdamore/tcell#1077</a></li>
<li>fix(input): accept Unicode modifyOtherKeys codepoints by <a
href="https://github.com/ayn2op"><code>@​ayn2op</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1083">gdamore/tcell#1083</a></li>
<li>Fix reporting of key releases by <a
href="https://github.com/tihirvon"><code>@​tihirvon</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1088">gdamore/tcell#1088</a></li>
<li>chore(deps): bump golang.org/x/term from 0.42.0 to 0.43.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/gdamore/tcell/pull/1085">gdamore/tcell#1085</a></li>
<li>chore(deps): bump golang.org/x/text from 0.36.0 to 0.37.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/gdamore/tcell/pull/1087">gdamore/tcell#1087</a></li>
<li>MInor bug fixes by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1097">gdamore/tcell#1097</a></li>
<li>Preserve orphaned UTF-16 surrogates on Windows by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1104">gdamore/tcell#1104</a></li>
<li>vt: prune tab stops after resize by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1105">gdamore/tcell#1105</a></li>
<li>vt: ignore malformed SGR parameters by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1106">gdamore/tcell#1106</a></li>
<li>Limit inbound control strings by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1107">gdamore/tcell#1107</a></li>
<li>fix: cells should be marked dirty even if they have no content
(fixes… by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1108">gdamore/tcell#1108</a></li>
<li>fix: lock SetSize screen mutations by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1109">gdamore/tcell#1109</a></li>
<li>tscreen: prevent terminal mutation after Fini by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1110">gdamore/tcell#1110</a></li>
<li>Avoid extra keyboard protocols on Windows by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1111">gdamore/tcell#1111</a></li>
<li>[codex] Fix OSC 8 hyperlink state transitions by <a
href="https://github.com/gdamore"><code>@​gdamore</code></a> in <a
href="https://redirect.github.com/gdamore/tcell/pull/1112">gdamore/tcell#1112</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/ImGajeed76"><code>@​ImGajeed76</code></a> made
their first contribution in <a
href="https://redirect.github.com/gdamore/tcell/pull/1077">gdamore/tcell#1077</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/gdamore/tcell/compare/v3.3.0...v3.4.0">https://github.com/gdamore/tcell/compare/v3.3.0...v3.4.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c67165c6c2"><code>c67165c</code></a>
[codex] Fix OSC 8 hyperlink state transitions (<a
href="https://redirect.github.com/gdamore/tcell/issues/1112">#1112</a>)</li>
<li><a
href="3f24a1a195"><code>3f24a1a</code></a>
test: Include test case for Apple Terminal</li>
<li><a
href="0af1f67667"><code>0af1f67</code></a>
feat: add terminal override controls</li>
<li><a
href="d3371c05d8"><code>d3371c0</code></a>
fix: remove the 25ms startup delay for primary DA</li>
<li><a
href="7da1880519"><code>7da1880</code></a>
feat: report WezTerm and Terminal.app when using env var detection</li>
<li><a
href="defbc72dec"><code>defbc72</code></a>
fix: avoid extra keyboard protocols on windows and hard code WezTerm
capabili...</li>
<li><a
href="a8373181b0"><code>a837318</code></a>
tscreen: prevent terminal mutation after Fini (<a
href="https://redirect.github.com/gdamore/tcell/issues/1110">#1110</a>)</li>
<li><a
href="d7fff268b3"><code>d7fff26</code></a>
fix: lock SetSize screen mutations (fixes <a
href="https://redirect.github.com/gdamore/tcell/issues/1098">#1098</a>)
(<a
href="https://redirect.github.com/gdamore/tcell/issues/1109">#1109</a>)</li>
<li><a
href="b91ae6def9"><code>b91ae6d</code></a>
fix: cells should be marked dirty even if they have no content (fixes <a
href="https://redirect.github.com/gdamore/tcell/issues/1089">#1089</a>)
...</li>
<li><a
href="c01e1075d5"><code>c01e107</code></a>
fix: limit inbound control strings (<a
href="https://redirect.github.com/gdamore/tcell/issues/1107">#1107</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/gdamore/tcell/compare/v3.3.0...v3.4.0">compare
view</a></li>
</ul>
</details>
<br />
2026-05-26 10:03:03 +02:00
dependabot[bot] 5d08537ea4
Bump github.com/gdamore/tcell/v3 from 3.3.0 to 3.4.0
Bumps [github.com/gdamore/tcell/v3](https://github.com/gdamore/tcell) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/gdamore/tcell/releases)
- [Changelog](https://github.com/gdamore/tcell/blob/main/CHANGESv3.md)
- [Commits](https://github.com/gdamore/tcell/compare/v3.3.0...v3.4.0)

---
updated-dependencies:
- dependency-name: github.com/gdamore/tcell/v3
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 08:00:07 +00:00
Stefan Haller 323fb469d3
Bump golang.org/x/sys from 0.43.0 to 0.45.0 (#5607)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.43.0 to
0.45.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="397d5f8092"><code>397d5f8</code></a>
unix: update to Linux kernel 7.0</li>
<li><a
href="0a387f7a07"><code>0a387f7</code></a>
cpu: detect zbc extension on riscv64</li>
<li><a
href="758f71cb83"><code>758f71c</code></a>
cpu: add LLACQ_SCREL, SCQ, DBAR_HINTS detection for loong64</li>
<li><a
href="99666ae32e"><code>99666ae</code></a>
unix: merge Linux readv/writev implementation with Darwin/OpenBSD</li>
<li><a
href="e4444cbaaa"><code>e4444cb</code></a>
windows: add NtSetEaFile, NtQueryEaFile and NtQueryInformationFile</li>
<li><a
href="04396e85d4"><code>04396e8</code></a>
unix: add Readv, Writev, Preadv, Pwritev for OpenBSD</li>
<li><a
href="fb1facd76f"><code>fb1facd</code></a>
windows: avoid uint16 overflow in NewNTUnicodeString</li>
<li><a
href="94ad893e1e"><code>94ad893</code></a>
windows: add GetIfTable2Ex, GetIpInterface{Entry,Table},
GetUnicastIpAddressT...</li>
<li><a
href="54fe89f841"><code>54fe89f</code></a>
cpu: use IsProcessorFeaturePresent to calculate ARM64 on windows</li>
<li><a
href="df7d5d7b60"><code>df7d5d7</code></a>
unix: automatically remove container created by mkall.sh</li>
<li>Additional commits viewable in <a
href="https://github.com/golang/sys/compare/v0.43.0...v0.45.0">compare
view</a></li>
</ul>
</details>
<br />
2026-05-26 09:58:12 +02:00
dependabot[bot] dfcd195fb8
Bump golang.org/x/sys from 0.43.0 to 0.45.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.43.0 to 0.45.0.
- [Commits](https://github.com/golang/sys/compare/v0.43.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 07:55:25 +00:00
Stefan Haller 32f8a601e3
Bump github.com/sahilm/fuzzy from 0.1.1 to 0.1.2 (#5606)
Bumps [github.com/sahilm/fuzzy](https://github.com/sahilm/fuzzy) from
0.1.1 to 0.1.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sahilm/fuzzy/releases">github.com/sahilm/fuzzy's
releases</a>.</em></p>
<blockquote>
<h2>v0.1.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Dust off the repo by <a
href="https://github.com/sahilm"><code>@​sahilm</code></a> in <a
href="https://redirect.github.com/sahilm/fuzzy/pull/25">sahilm/fuzzy#25</a></li>
<li>Ignore match strings past the first NUL rune by <a
href="https://github.com/nfreya"><code>@​nfreya</code></a> in <a
href="https://redirect.github.com/sahilm/fuzzy/pull/24">sahilm/fuzzy#24</a></li>
<li><code>FindFrom</code> respects original ordering by <a
href="https://github.com/SayYoungMan"><code>@​SayYoungMan</code></a> in
<a
href="https://redirect.github.com/sahilm/fuzzy/pull/28">sahilm/fuzzy#28</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/sahilm/fuzzy/compare/v0.1.1...v0.1.2">https://github.com/sahilm/fuzzy/compare/v0.1.1...v0.1.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2cea772ce2"><code>2cea772</code></a>
Upgrade golangci-lint to fix the build</li>
<li><a
href="76e61c374b"><code>76e61c3</code></a>
<code>FindFrom</code> respects original ordering (<a
href="https://redirect.github.com/sahilm/fuzzy/issues/28">#28</a>)</li>
<li><a
href="5ed613fa11"><code>5ed613f</code></a>
Merge pull request <a
href="https://redirect.github.com/sahilm/fuzzy/issues/24">#24</a> from
nfreya/bugfix/panic-on-nuls-in-data</li>
<li><a
href="3e298b8b9b"><code>3e298b8</code></a>
Merge branch 'master' into bugfix/panic-on-nuls-in-data</li>
<li><a
href="4546989695"><code>4546989</code></a>
So long travis. Thank you.</li>
<li><a
href="f98d2a036a"><code>f98d2a0</code></a>
switch to tools dujour; old ones deprecatd</li>
<li><a
href="45c5e49a0f"><code>45c5e49</code></a>
Use go.mod now. Gopkg is deprecated.</li>
<li><a
href="12ea3fbc39"><code>12ea3fb</code></a>
Add test for NULs in search data</li>
<li><a
href="7e3799a599"><code>7e3799a</code></a>
Ignore match strings past the first NUL rune</li>
<li>See full diff in <a
href="https://github.com/sahilm/fuzzy/compare/v0.1.1...v0.1.2">compare
view</a></li>
</ul>
</details>
<br />
2026-05-26 09:53:50 +02:00
dependabot[bot] 62b38ff78a
Bump github.com/sahilm/fuzzy from 0.1.1 to 0.1.2
Bumps [github.com/sahilm/fuzzy](https://github.com/sahilm/fuzzy) from 0.1.1 to 0.1.2.
- [Release notes](https://github.com/sahilm/fuzzy/releases)
- [Commits](https://github.com/sahilm/fuzzy/compare/v0.1.1...v0.1.2)

---
updated-dependencies:
- dependency-name: github.com/sahilm/fuzzy
  dependency-version: 0.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 07:51:24 +00:00
Stefan Haller 21b59f9e33
Fix undo shortcut in Undoing.md (#5640)
We fixed this recently in the Readme (see 7a3bae4de1), but forgot to
update this.

Fixes #5630.
2026-05-26 09:49:16 +02:00
Stefan Haller 9ae76d7eec Fix undo shortcut in Undoing.md
We fixed this recently in the Readme (see 7a3bae4de1), but forgot to update
this.
2026-05-26 09:45:41 +02:00
Stefan Haller 87e6959fca
Bump github.com/gookit/color from 1.6.0 to 1.6.1 (#5586)
Bumps [github.com/gookit/color](https://github.com/gookit/color) from
1.6.0 to 1.6.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/gookit/color/releases">github.com/gookit/color's
releases</a>.</em></p>
<blockquote>
<h2>v1.6.1</h2>
<h2>Change Log</h2>
<h3>Fixed</h3>
<ul>
<li>fix: re-apply color after nested reset in RenderString (<a
href="https://redirect.github.com/gookit/color/issues/119">#119</a>) <a
href="e58a89993a</a></li>
<li>fix(detect): should enable VTP on windows CMD,PWSH <a
href="2bb27a593f</a></li>
<li>fix(convert): incorrect conversion between integer types <a
href="1245572809</a></li>
</ul>
<h3>Other</h3>
<ul>
<li>build(deps): bump github/codeql-action from 3 to 4 (<a
href="https://redirect.github.com/gookit/color/issues/113">#113</a>) <a
href="2e1842657d</a></li>
<li>build(deps): bump actions/checkout from 5 to 6 (<a
href="https://redirect.github.com/gookit/color/issues/115">#115</a>) <a
href="ed1b9cc478</a></li>
<li>Add 'stable' to Go version matrix and update action <a
href="de1e24367e</a></li>
<li>ci(release): remove Go version matrix and simplify build steps in
release action <a
href="d232e114aa</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d232e114aa"><code>d232e11</code></a>
ci(release): remove Go version matrix and simplify build steps in
release action</li>
<li><a
href="1245572809"><code>1245572</code></a>
fix(convert): incorrect conversion between integer types</li>
<li><a
href="2bb27a593f"><code>2bb27a5</code></a>
fix(detect): should enable VTP on windows CMD,PWSH</li>
<li><a
href="e58a89993a"><code>e58a899</code></a>
fix: re-apply color after nested reset in RenderString (<a
href="https://redirect.github.com/gookit/color/issues/119">#119</a>)</li>
<li><a
href="de1e24367e"><code>de1e243</code></a>
Add 'stable' to Go version matrix and update action</li>
<li><a
href="ed1b9cc478"><code>ed1b9cc</code></a>
build(deps): bump actions/checkout from 5 to 6 (<a
href="https://redirect.github.com/gookit/color/issues/115">#115</a>)</li>
<li><a
href="2e1842657d"><code>2e18426</code></a>
build(deps): bump github/codeql-action from 3 to 4 (<a
href="https://redirect.github.com/gookit/color/issues/113">#113</a>)</li>
<li>See full diff in <a
href="https://github.com/gookit/color/compare/v1.6.0...v1.6.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/gookit/color&package-manager=go_modules&previous-version=1.6.0&new-version=1.6.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2026-05-26 09:42:13 +02:00
dependabot[bot] af041092d5
Bump github.com/gookit/color from 1.6.0 to 1.6.1
Bumps [github.com/gookit/color](https://github.com/gookit/color) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/gookit/color/releases)
- [Commits](https://github.com/gookit/color/compare/v1.6.0...v1.6.1)

---
updated-dependencies:
- dependency-name: github.com/gookit/color
  dependency-version: 1.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 07:39:34 +00:00
Stefan Haller 822807ce48
Fix cycling pagers when main view is focused (#5639)
Fixes #5638.
2026-05-26 08:03:21 +02:00
Stefan Haller e6a8415162 Refresh main view when cycling pagers with main view focused
The previous logic only re-rendered the main view when the side panel itself was
focused. When the user pressed `0` to focus the main view, the
Normal/NormalSecondary context becomes Current and the equality check failed, so
cycling pagers had no visible effect. Mirror the pattern from postRefreshUpdate:
when the main view is focused, call HandleRenderToMain on the side panel below
it on the stack (which CurrentSide already returns).
2026-05-26 07:58:50 +02:00
Stefan Haller 137831630a Do less work to update the main view when cycling pagers
The call to HandleFocus worked fine too, but it was doing too much; all we
really need here is rerender the main view.
2026-05-26 07:54:29 +02:00
Stefan Haller 273e340490
Add <alt+up>/<alt+down> as alternate keybindings for moving commits up/down (#5637)
I like these because they are the same as moving a line of code up or
down in Visual Studio Code.
2026-05-25 19:21:11 +02:00
Stefan Haller 2537995067 Add <alt+up>/<alt+down> as alternate keybindings for moving commits up/down
I like these because they are the same as moving a line of code up or down in
Visual Studio Code.
2026-05-25 19:15:54 +02:00
Stefan Haller c826811eaf
Allow keybindings to configure more than one key (#5634)
Keybindings in the user config file can now either be a single string as
before, or a list of strings, in which case the action can be triggered
by any of them.

This has two benefits:
- users can add alternatives that they want to use occasionally. One
example is the `<esc>` key: some users are used to typing it as `ctrl+[`
because this used to be possible in the legacy terminal protocol. With
recent changes to lazygit's keybinding system this no longer works out
of the box, since `<esc>` and `ctrl+[` are now distinct keys that can be
bound separately. But users who want the two to behave the same (as in
the old days) can now do
  ```yml
  keybinding:
    universal:
      return: [<esc>, "ctrl+["]
  ```
- we can get rid of all those `XyzAlt` bindings that we used to have,
for cases where we already wanted to have alternate keybindings by
default (for example `<up>`/`<down>` and `j`/`k` for going up and down
in a list). These can now be expressed a lot more elegantly, and require
less code.

The `XyzAlt` bindings are marked as deprecated but they are still
supported. We could instead have added a
migrator that changes users' config files and gets rid of the alt
configs for good already; I decided not to do that, because this would
render the config file invalid for older versions of lazygit, which
would then refuse to start; and that's annoying when bisecting bugs.
We'll keep the deprecated configs in the code for a year or so, and then
add the migrator.
2026-05-25 15:49:46 +02:00
Stefan Haller d0d58233ff If a menu entry has multiple keybindings, list them in a tooltip
We append them with a blank line to an existing tooltip if the item already has
one, or create a new tooltip if not.
2026-05-25 15:32:47 +02:00
Stefan Haller 3a3625d855 Fold remaining alt bindings into their main fields
Convert the remaining *Alt/*Alt[12] sibling fields (PrevItem/NextItem,
GotoTop/GotoBottom, PrevBlock/NextBlock, ScrollUpMain/ScrollDownMain,
OptionMenu, ConfirmInEditor, DiffingMenu) so the merge mechanism folds
their values into the corresponding main multi-key binding at config
load. The redundant alt-only Binding registrations across the various
controllers and the global keybindings file are gone: the merged main
field already carries every key, so the for-loop in SetKeybinding
registers them all.
2026-05-25 15:32:47 +02:00
Stefan Haller 2ba401909d Use a dedicated keybinding for hunk navigation in the main view
Previously the patch_explorer and merge_conflicts controllers reused
Universal.PrevBlock/NextBlock for moving between hunks (or conflicts) in the
main view, sharing keys with the global side-window cycle. The two operations
are conceptually distinct: cycling side windows is a global navigation gesture,
while next/prev hunk acts on the diff in the main view. Tying them together also
blocks adding <tab>/<backtab> as side- window-cycle keys, because <tab> already
means "toggle panel" in the staging view.

Add Main.PrevHunk/NextHunk to the existing KeybindingMainConfig (which already
groups bindings for the main view across staging, patch building, and merge
conflicts) and switch both controllers to it. The defaults match the active key
set those controllers had before (<left>/<right>/h/l), so the user-visible
behavior is unchanged.
2026-05-25 15:32:47 +02:00
Stefan Haller 022d24cb79 Fold legacy quit-alt1 into the multi-key quit binding
Now that quit accepts multiple keys, the historical quit-alt1 field is
redundant: existing configs that set it should keep working without the user
having to migrate, but the lazygit code shouldn't have to register the alt
binding separately.

Add a merge step that runs after the user config is loaded (and from
NewDummyAppConfig, which the cheatsheet generator and integration tests go
through) folding the alt value into the main key list. Mark QuitAlt1 deprecated
so it disappears from the generated Config.md example, while staying in the JSON
schema with a description so editors can still steer users toward the new form.
Note that instead of marking the alt config as deprecated, we could have added a
migrator that changes users' config files and gets rid of the alt config for
good. I decided not to do that, because this would render the config file
invalid for older versions of lazygit, which would then refuse to start; and
that's annoying when bisecting bugs. We'll keep the deprecated configs in the
code for a year or so, and then add the migrator.

The next commit will fold the remaining ~15 -alt-style fields the same way; the
helper is shaped to keep that mechanical.
2026-05-25 15:32:47 +02:00
Stefan Haller fbcf562e29 Convert custom command Key fields to Keybinding
CustomCommand.Key and CustomCommandMenuOption.Key are user-configured
keybindings just like the built-in ones. Converting them to the Keybinding type
lets a user assign multiple keys to the same custom command, e.g. `key: [a, b]`,
the same way they would for any other keybinding.

The validator iterates over the elements rather than checking a single string,
the binding registration goes through GetValidatedKeyBindingKeys to register
every alternate, and the existing error messages use .String() so a multi-key
binding renders sensibly.

CustomCommandPrompt.Key (a form field name, not a keybinding) stays a plain
string.
2026-05-25 15:32:47 +02:00
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 06b8d5a1e4 Add Keybinding type that accepts a string or a sequence of strings
Each user-configurable keybinding is currently a single string in the YAML
config. To let users assign alternate keys to a command, introduce a Keybinding
type that decodes from either a scalar (the existing single-key form, kept for
backward compatibility and for a simpler config file) or a sequence of strings.
Marshalling collapses single-element slices back to a scalar so configs and
generated docs round-trip cleanly.

JSONSchema describes the type as a oneOf union so editors validate either form;
subsequent commits will inline the union into the generated schema and start
using Keybinding as the field type.
2026-05-25 15:18:18 +02:00