Commit Graph
100 Commits
Author SHA1 Message Date
Stefan HallerandGitHub 8beec9aacc Add a user config for using git's external diff command for paging (#4832)
### PR Description

This is similar to using lazygit's `Git.Paging.ExternalDiffCommand`
config, except that the command is configured in git. This can be done
either with git's `diff.external` config, or through `.gitattributes`,
so it gives a bit more flexibility.

We could consider removing the `Git.Paging.ExternalDiffCommand` config
now, because its functionality is covered by the new config. I decided
to keep it though, because I don't want to make this a breaking change,
and also because some users might want to have the external diff command
only in lazygit but not on the command line.
2025-08-20 10:42:37 +02:00
Stefan Haller 40e989467f Add a user config for using git's external diff command for paging
This is similar to using lazygit's Git.Paging.ExternalDiffCommand config, except
that the command is configured in git. This can be done either with git's
`diff.external` config, or through .gitattributes, so it gives a bit more
flexibility.
2025-08-20 10:39:55 +02:00
Stefan HallerandGitHub 86934ce1af Remove the git.paging.useConfig option (#4837)
### PR Description

Many people don't understand what this means, which is apparent from the
amount of issues that got filed because of this. Let's get rid of it to
avoid this confusion. People will have to configure their pager twice if
they want to use it both on the command line and in lazygit, which I
think is not a big deal.

See
[here](https://github.com/jesseduffield/lazygit/issues/3704#issuecomment-2330772344)
for more rationale.

Closes #3704.
2025-08-20 10:39:21 +02:00
Stefan Haller 548244c0b7 Add breaking changes notice about git.paging.useConfig option 2025-08-19 11:54:54 +02:00
Stefan Haller 9657b4346f Remove the git.paging.useConfig option
Many people don't understand what this means, which is apparent from the amount
of issues that got filed because of this. Let's get rid of it to avoid this
confusion. People will have to configure their pager twice if they want to use
it both on the command line and in lazygit, which I think is not a big deal.
2025-08-19 10:43:28 +02:00
Stefan HallerandGitHub 13f97fb259 Use external diff command in stashes panel (#4836)
### PR Description

When we added support for using external diff commands as pagers (mainly
to support difftastic as a pager) in #2868, we only supported this in
the files and commits panels, but not in the stashes panel. This was
forgotten in 6266e19623.
2025-08-19 09:53:50 +02:00
Stefan Haller 89d50fa229 Use external diff command in stashes panel
This was forgotten in 6266e19623.
2025-08-19 09:48:11 +02:00
Stefan HallerandGitHub 0f785c434a Run label check workflow only on label events and open pr event (#4830)
## **PR Description**
- Currently, `check-required-label` only runs when commits are added to
a PR, even if a maintainer has added labels, so the CI status remains
red until a commit is pushed after labels are added by a maintainer.
- I updated the workflows to run `check-required-label` only on label
events(add/remove) or open PR event.
- This will make PR status updates more accurate, so authors will be
able to see that tests and lint are passing by just checking the PR
status, and maintainers will easily know if the PR is ready for review.
2025-08-18 07:44:43 +02:00
Stefan HallerandGitHub 1639e17d4e Enhance PR/Issue templates readability (#4829) 2025-08-18 07:39:53 +02:00
Stefan HallerandGitHub 011ff853b8 Add "CopyToClipboard" command to ConfirmationController (#4810)
## **PR Description**

Sometimes, I want to copy the error message to clipboard to search
google or ask to LLM about the error message.

So I added CopyToClipboard command to `ConfirmationController` and I
have confirmed that this command copies the content of the window to the
clipboard.
2025-08-15 17:20:16 +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 HallerandGitHub deaa701d41 Update donation wording so that it's clear there's no strings attached (#4827) 2025-08-15 12:05:40 +02:00
Stefan HallerandGitHub 82daedb96d Add support for suspending LazyGit with Ctrl+Z on Unix systems (#4757)
##  Add Ctrl+Z suspend support for LazyGit on Unix-like systems

### 📝 Summary

This PR adds support for suspending LazyGit when the user presses
`Ctrl+Z`, making it behave like common CLI tools (e.g., Vim, less,
htop):

* Pressing `Ctrl+Z` sends a `SIGTSTP` signal to suspend LazyGit.
* After resuming with `fg`, LazyGit redraws and continues working
without hanging.
* During suspension, background routines are paused to avoid running
while LazyGit is stopped.

###  Motivation

Make LazyGit feel more native on Unix-like systems by supporting
standard terminal suspend/resume (Ctrl+Z / fg) behavior.

Closes #3906
2025-08-14 20:47:19 +02:00
Stefan Haller 4bc1ba22c1 Add a breaking changes notice for the changed keybinding 2025-08-14 20:42:21 +02:00
Stefan Haller 6322359392 Update cheatsheets, config docs, and schema 2025-08-14 20:42:20 +02:00
Stefan Haller af190ad280 Extract methods suspend/resume on Gui struct
These suspend/resume the gocui layer and pause/unpause background refreshes.
2025-08-14 20:40:44 +02:00
Stefan Haller 5490e559a3 Cleanup: remove stale comment
This should have been removed in 8c574f888c, where I renamed it back to 'gui'
to fix a linter warning.
2025-08-14 20:40:44 +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 HallerandGitHub 5b86716446 Improve display of "esc" keybinding in the keybindings status bar (#4819)
### PR Description

- For popup windows, the status bar would show `Confirm: <enter> |
Close/Cancel: <esc> | Cancel: <esc>`. Omit the second `<esc>`.
- Don't show the `<esc>` binding in other views when it doesn't do
anything.
- Change the text of the `<esc>` label to show what it does, based on
context. This is very helpful because esc can cancel all sorts of
things, and if several of these things are active at once, it is not
obvious which one will be cancelled first.

Supersedes #4808.
2025-08-14 18:02:07 +02:00
Stefan Haller da7121fa87 Don't append "Disabled: " to menu tooltip if disabled reason is empty
In some cases we set a disabled reason but leave the text empty, so that we
don't get an error toast when the item is invoked. In such a case it looks
awkward if there is a tooltip showing "Disabled: " with no following text.
2025-08-14 17:59:38 +02:00
Stefan Haller 0c0c32aec4 Show "Close/Cancel: <esc>" for menus like we do for confirmations
For many menus, just "Close" is fine, but some menus act more like confirmations
(e.g. the menu that appears when you cherry-pick and get conflicts); in this
case, it's good to make it more obvious that hitting esc cancels the whole
thing.
2025-08-14 17:59:38 +02:00
Stefan Haller aeff986450 Show context-specific labels for <esc> in staging and patch building view
Dismissing a range selection is handled by the global escape handler for all
list views, but not for the staging and patch building views, so we need to make
the esc description dynamic for these, too.
2025-08-14 17:59:38 +02:00
Stefan Haller 51066b14b1 Show escape binding for staging and patch building in the status bar 2025-08-14 17:59:38 +02:00
Stefan Haller 5f91b1b48e Move global escape handler to before the keybindings menu handler
The main reason for this is that sometimes the escape key is handled by a local
binding, in which case it appears before the '?' binding in the options status
bar, and other times it is handled by the global controller, in which case it
appeared after. Moving it to before the keybindings menu handler makes it appear
before '?' in both cases.

Also, if the window is too narrow to show all keybindings, the ones that don't
fit will be truncated, and in this case it is more important to show the esc
binding because of its context sensitivity.

This also moves the esc entry up a few positions in the keybindings menu, but I
don't think this matters much.
2025-08-14 17:59:38 +02:00
Stefan Haller a8e44dcea6 Show context-specific labels for the global <esc> binding
WHen several modes are active at the same time, it isn't totally obvious which
one will be cancelled first, so show this in the status bar.
2025-08-14 17:59:38 +02:00
Stefan Haller d8ea83704f Rename ModeStatus.Description to InfoLabel
It is styled and includes a "(Reset)" button, so it's really not a
general-purpose description, but very specific to the Information view.
2025-08-14 17:59:38 +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 0af439ddf5 Cleanup: remove dead code
Cancelling searching (as opposed to filtering) is handled by gocui.
2025-08-14 17:59:38 +02:00
Stefan Haller 4961c4b678 Avoid duplicate key bindings in options map
Sometimes there is a local and a global keybinding for the same key; if both are
configured to be shown in the options map, we should only show the local one
because it takes precedence. This happens for example for <esc> in a popup, or
for <esc> in the focused main view.

Note that this is also a problem in the keybindings menu, and we don't solve
that here.
2025-08-14 17:59:38 +02:00
Stefan Haller f2c2e80a5c Show "Exit back to side panel" in options status bar for focused main view
It's maybe not totally obvious, so let's show it.

Esc now appears twice in the status bar, because the global controller also
appends its generic "Cancel". We'll fix this in the next commit.
2025-08-14 17:59:38 +02:00
Stefan HallerandGitHub d50e58559e Support Azure DevOps vs-ssh.visualstudio.com SSH remotes as hosting provider (#4822)
**PR Description**  
This PR adds support for parsing **legacy Azure DevOps SSH remotes**
that use the
`vs-ssh.visualstudio.com` host, which is still common in older
repositories or corporate setups.

This PR fixes issue #2667.

Previously, even if users mapped this host to the Azure DevOps provider
via
`configServiceDomains`, URL generation failed with:
```
Failed to parse repo information from url
```
because the Azure DevOps `ServiceDefinition` regex set did not include
this SSH format.

### Changes
- Added a new regex to `azdoServiceDef.regexStrings` to match:
  ```
  git@vs-ssh.visualstudio.com:v3/<org>/<project>/<repo>
  ```
- This allows `getRepoURLFromRemoteURL` to correctly extract `org`,
`project`, and `repo`
  for these remotes.
- Added a test case to `TestGetPullRequestURL` verifying that mapping  
`vs-ssh.visualstudio.com` → `azuredevops:dev.azure.com` produces the
correct PR URL.

### Example
With this config:
```yaml
services:
  'vs-ssh.visualstudio.com': 'azuredevops:dev.azure.com'
```
and remote:
```
git@vs-ssh.visualstudio.com:v3/myorg/myproject/myrepo
```
`GetPullRequestURL("feature/new", "")` now returns:
```
https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature%2Fnew
```

### Why
- Many users still have remotes in this legacy format.
- This change is **backward-compatible** and does not affect existing
supported remotes.
- It unblocks URL generation for PRs and commits without requiring users
to change their remotes.
- Fixes #2667
2025-08-14 15:23:38 +02:00
Stefan HallerandGitHub 0c0f53fa31 Allow filtering the keybindings menu by keybinding (#4821)
- **PR Description**

When filtering the keybindings menu using `/`, typing `@` filters by
keybinding.

Closes #4739.
2025-08-14 15:04:56 +02:00
Stefan Haller a08799ac15 Allow filterable contexts to customize the filter label 2025-08-14 15:02:48 +02:00
Stefan Haller 2ed11336b5 Allow filtering for keybindings by prepending filter string with '@' 2025-08-14 15:02:48 +02:00
Stefan Haller d52d5e6a9e Allow filtered lists to preprocess the filter string
An example for this can be seen in the next commit.

We make this a setter rather than an added constructor argument so that we don't
have to change all those contexts that don't want to make use of this.
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 HallerandGitHub 389ff29871 Fix right-alignment of divergence from base branch for branch checked out in a worktree (#4824)
- **PR Description**

We didn't take the worktree icon into account properly, so the
divergence indication was offset to the left by two characters in this
case.

I haven't used worktrees myself so far, so I didn't notice this before.
2025-08-14 14:30:51 +02:00
Stefan Haller e54a8b2ee7 Fix right-alignment of divergence from base branch for branch checked out in a worktree
We didn't take the worktree icon into account properly, so the divergence
indication was offset to the left by two characters in this case.
2025-08-14 14:28:11 +02:00
Stefan HallerandGitHub 1e75aee37e Add installation with gah (#4820)
- **PR Description**

This PR adds to the documentation a way of installation using
[gah](https://github.com/marverix/gah/).

> gah is an GitHub Releases app installer, that does not require sudo.
It is a simple bash script that downloads the latest release of an app
from GitHub and installs it in `~/.local/bin`. It is designed to be used
with apps that are distributed as a single binary file.
2025-08-13 18:30:47 +02:00
Stefan HallerandGitHub 28ef4a13d2 Pass only Git-tracked Go files to gofumpt (#4809)
## **PR Description**
The below error message is shown when executing `make format` when
`test/_results/demo/worktree_create_from_branches/actual/repo/src/shims.go`
exists (maybe executing integration test produces this file?).

```sh
$ make format
gofumpt -l -w .
test/_results/demo/worktree_create_from_branches/actual/repo/src/shims.go:1:20: expected 'package', found 'EOF'
make: *** [format] Error 2
```

I have confirmed it works without above error when I run `make format`
on this PR's branch.
2025-08-12 11:46:02 +02:00
Stefan HallerandGitHub b1382da9ec Fix delay with flicking through files or commits when git diff is very slow (#4803)
One reason why git diff can be very slow is when "diff.algorithm =
histogram" is being used. In this case, showing a very long single-file
diff can take seconds to load, and you'll see the "loading..." message
in the main view until we got the first lines of the diff to show.
There's nothing really we can do about this delay; however, when
switching to another, shorter file (or commit) while the "loading..."
message is still showing, this switch should be instantaneous. And it
was before 0.54.0, but we broke this in 0.54.0 with 8d7740a5ac
(#4782); now users have to wait for the slow git diff command to output
more text before the switch occurs. To fix this, don't block waiting for
the process to terminate if we just stopped it.

In addition, improve CPU usage by terminating git processes gracefully
(by sending them a TERM signal); this helps keep CPU usage low when
flicking through several of these huge diffs with "diff.algorithm =
histogram", because it avoids having several git processes running in
the background, calculating expensive diffs that we are never going to
show. Unfortunately this is only possible on Linux and Mac, so Windows
users will have to live with the higher CPU usage. The recommended
workaround is to not use "diff.algorithm = histogram".

Fixes #4798.
2025-08-11 18:13:42 +02:00
Stefan Haller e056e33da5 Improve CPU usage when flicking through large diffs
The previous commit already fixed the user-visible lag, but there's still a
problem with multiple background git processes consuming resources calculating
diffs that we are never going to show. Improve this by terminating those
processes (by sending them a TERM signal).

Unfortunately this is only possible on Linux and Mac, so Windows users will have
to live with the higher CPU usage. The recommended workaround is to not use
"diff.algorithm = histogram".
2025-08-11 18:07:21 +02:00
Stefan Haller 898f565116 Fix delay with flicking through files or commits when git diff is very slow
One reason why git diff can be very slow is when "diff.algorithm = histogram" is
being used. In this case, showing a very long single-file diff can take seconds
to load, and you'll see the "loading..." message in the main view until we got
the first lines of the diff to show. There's nothing really we can do about this
delay; however, when switching to another, shorter file (or commit) while the
"loading..." message is still showing, this switch should be instantaneous. And
it was before 0.54.0, but we broke this in 0.54.0 with 8d7740a5ac (#4782); now
users have to wait for the slow git diff command to output more text before the
switch occurs.

To fix this, don't block waiting for the process to terminate if we just stopped
it.
2025-08-11 18:07:21 +02:00
Stefan Haller e5acbed848 Cleanup: move UpdateWindowTitle to platform-specific source files
No need to do a runtime check if we already have the platform-specific files.
2025-08-11 18:07:21 +02:00
Stefan HallerandGitHub 77a9207f9e Update the badges of golangci-lint and homebrew in README.md (#4807) 2025-08-11 13:56:20 +02:00
Stefan Haller 985013718d Change color of github tag and homebrew badges to blue
Both of these badges have the coloring logic to show stable releases in blue,
and prereleases in orange. The criterion for a prerelease is that the major
version is 0. Now it is debatable whether we consider lazygit "stable", but I
don't feel we are in a preliminary state of the project, working towards the
first final 1.0 release, so I feel blue expresses the state of the project
better.
2025-08-11 13:42:19 +02:00
Stefan Haller 39b4f16e1a Update github tag badge
It doesn't really seem to make a difference, but this is what I get from
shields.io's builder (no idea where the previous .svg extension came from).
2025-08-11 13:37:53 +02:00
Stefan Haller 2864eecd37 Update homebrew link
The old link was broken, it would have to be "Formula/l/lazygit.rb" instead of
"Formula/lazygit.rb".

However, I don't find it very useful to link to the raw formula file, so I
decided to change the link to point to the homebrew web page for lazygit.
2025-08-11 13:36:05 +02:00
Stefan HallerandGitHub 0da27604e4 Update CONTRIBUTING.md to clarify translation contribution process (#4806) 2025-08-10 10:01:43 +02:00
Stefan HallerandGitHub 26db25be34 Fix scrollbar in certain popup panels (e.g. the intro message for new users) (#4804)
When showing a confirmation whose text ends with a line feed, we would
make the popup panel one line less tall than it needs to be, so it would
show a scroll bar. One example where this occurred is the very first
popup that users ever see (the "seriously you rock" message for new
users); that's a pretty bad first impression.

This happens because our code to suppress trailing newlines in views
doesn't work for styled text, and the text in confirmations is bold.
This code checks if the last character of the text is a line feed, and
in this case it isn't; the escape sequence for turning bold off comes
after it.

We should really fix this by improving that mechanism, but this would
require some tricky logic, so as a quick fix, trim trailing (and
leading) linefeeds from the text that we display in a confirmation,
before making it bold.
2025-08-09 11:52:04 +02:00
Stefan Haller 09e2bfaf99 Trim trailing newlines when showing confirmations
When showing a confirmation whose text ended with a line feed, we would make the
popup panel one line less tall than it needs to be, so it would show a scroll
bar. One example where this occurred is the very first popup that users ever see
(the "seriously you rock" message for new users); that's a pretty bad first
impression.

This happens because our code to suppress trailing newlines in views doesn't
work for styled text, and the text in confirmations is bold. This code checks if
the last character of the text is a line feed, and in this case it isn't; the
escape sequence for turning bold off comes after it.

We should really fix this by improving that mechanism, but this would require
some tricky logic, so as a quick fix, trim trailing (and leading) linefeeds from
the text that we display in a confirmation, before making it bold.
2025-08-08 20:37:44 +02:00
Stefan Haller a364ee53a8 Cleanup: remove duplicate test case
This is identical to the one right before.
2025-08-08 11:24:43 +02:00
Stefan HallerandGitHub c0dcf7d0ad Fix the useHunkModeInStagingView hint in the breaking changes message (#4800)
`useHunkSelectionMode` must have been a left-over from an earlier
iteration of the branch where the config had a different name.
2025-08-06 19:31:18 +02:00
Stefan Haller d869c23c1a Fix the useHunkModeInStagingView hint in the breaking changes message 2025-08-06 19:26:00 +02:00
Stefan HallerandGitHub 0262a8de69 Stop bumping our homebrew formula (#4799)
It is being auto-bumped by homebrew, like most formulae these days, so
no reason for us to do that explicitly; and it actually fails with an
error message, so stop trying.
2025-08-06 19:24:46 +02:00
Stefan Haller 04c2be826b Stop bumping our homebrew formula
It is being auto-bumped by homebrew, like most formulae these days, so no reason
for us to do that explicitly; and it actually fails with an error message, so
stop trying.
2025-08-06 14:02:23 +02:00
Stefan HallerandGitHub c08903e3ad Stop updating Jesse's homebrew tap (#4797)
The tap is being retired, see
https://github.com/jesseduffield/homebrew-lazygit/pull/3.
2025-08-06 13:30:43 +02:00
Stefan Haller 5a654b1d56 Stop updating Jesse's homebrew tap
The tap is being retired, see
https://github.com/jesseduffield/homebrew-lazygit/pull/3.
2025-08-06 13:28:07 +02:00
Stefan HallerandGitHub 525edfbc4d Fix temp dir permission problem on multi-user machines (#4796)
In 3a9dbf7341 we created a global /tmp/lazygit/ folder that contains
the temp directories of each running instance, to avoid polluting /tmp
with multiple folders. The problem with that approach was that the
folder was created with 700 permissions, so if multiple users were using
lazygit on the same machine (e.g. a server), all users except the first
one would get fatal errors on startup.

Fix this by creating temp folders containing the user's uid.

Fixes #4793.
2025-08-06 09:48:14 +02:00
Stefan Haller 71813fdda5 Create a user-specific temp dir to avoid permission problems on multi-user machines
In 3a9dbf7341 we created a global /tmp/lazygit/ folder that contains the temp
directories of each running instance, to avoid polluting /tmp with multiple
folders. The problem with that approach was that the folder was created with 700
permissions, so if multiple users were using lazygit on the same machine (e.g. a
server), all users except the first one would get fatal errors on startup.

Fix this by creating temp folders containing the user's uid.
2025-08-05 22:50:22 +02:00
Stefan HallerandGitHub bcb95bd211 Update Fedora section of the README.md file (#4792)
After discussion from the following PR (
https://github.com/jesseduffield/lazygit/pull/4362 ) I have finally
found time to make a PR to update the Fedora section of the README.md
file. I actually use those instructions myself from few different Fedora
and Amazon Linux 2023 machines.

Here is an example of installing lazygit from the Copr:

```
» sudo dnf install lazygit
Updating and loading repositories:
Repositories loaded.
Package                                                              Arch        Version                                                              Repository                                                  Size
Installing:
 lazygit                                                             x86_64      0.48.0-1.fc41                                                        copr:copr.fedorainfracloud.org:dejan:lazygit            21.5 MiB

Transaction Summary:
 Installing:         1 package

Total size of inbound packages is 6 MiB. Need to download 6 MiB.
After this operation, 22 MiB extra will be used (install 22 MiB, remove 0 B).
Is this ok [y/N]: y
[1/1] lazygit-0:0.48.0-1.fc41.x86_64                                                                                                                                          100% |   3.7 MiB/s |   5.7 MiB |  00m02s
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[1/1] Total                                                                                                                                                                   100% |   3.7 MiB/s |   5.7 MiB |  00m02s
Running transaction
[1/3] Verify package files                                                                                                                                                    100% |  52.0   B/s |   1.0   B |  00m00s
[2/3] Prepare transaction                                                                                                                                                     100% |   3.0   B/s |   1.0   B |  00m00s
[3/3] Installing lazygit-0:0.48.0-1.fc41.x86_64                                                                                                                               100% |  44.9 MiB/s |  21.5 MiB |  00m00s
Complete!
```
2025-08-05 12:39:03 +02:00
Stefan HallerandGitHub 5175798cb1 README.md: Update Sponsors (#4710)
Automated changes by
[create-pull-request](https://github.com/peter-evans/create-pull-request)
GitHub action
2025-08-02 10:34:01 +02:00
Stefan HallerandGitHub e732833d7d Update translations from Crowdin (#4791) 2025-08-01 11:10:01 +02:00
Stefan Haller 8bf58f9a6b Update translations from Crowdin 2025-08-01 11:07:35 +02:00
Stefan HallerandGitHub 3541b090af Enable hunk staging mode by default (#4780)
- **PR Description**

In #4684 we improved the hunk selection behavior to work on blocks of
changes instead of actual hunks, and I find this so useful that I wanted
to use it by default. In #4685 I added a user config to make hunk
selection the default, but I made it an opt-in config because I was
worried that users might not find out how to switch back to line
selection if needed.

To address this concern, in this PR I add a popup that explains this the
first time the user enters staging; there is also a breaking changes
notice at startup, and we improve the options display at the bottom of
the screen to be clearer about this. Hopefully these measures are enough
to not confuse people.

Closes #4759.
2025-08-01 10:38:06 +02:00
Stefan Haller c216388b5c Add breaking changes notice about hunk mode being the default now 2025-08-01 10:35:17 +02:00
Stefan Haller 117bb3f829 Cleanup: whitespace 2025-08-01 10:35:17 +02:00
Stefan Haller 3d703bc9b9 Show hint about hunk staging mode being the default now, and how to switch to line mode
It is shown the first time the user enters either staging or patch building.
2025-08-01 10:35:17 +02:00
Stefan Haller 37724e9d14 Cleanup: rely on zero values for initialization 2025-08-01 10:35:17 +02:00
Stefan Haller 4d51234ee2 Enable hunk staging mode by default 2025-08-01 10:35:16 +02:00
Stefan Haller eb41bd2af2 Change the "toggle hunk selection" binding description to be dynamic
When the useHunkModeInStagingView config is on and you enter the staging view
with hunk selection enabled, it is confusing to see "a: Select hunk" in the
options view at the bottom.
2025-08-01 10:35:16 +02:00
Stefan Haller 75afa099e9 Add support for dynamic binding descriptions 2025-08-01 10:35:16 +02:00
Stefan Haller 9eb1e3a729 Add a GetShortDescription() method to Binding 2025-08-01 10:35:16 +02:00
Stefan Haller d0438b7d33 Cleanup: better receiver name
No need for this to be uppercase.
2025-08-01 10:35:16 +02:00
Stefan HallerandGitHub 98801da106 Terminate git processes more gracefully to avoid the stale index.lock problem (#4782)
- **PR Description**

Instead of killing git processes when we no longer need them, close
their ptys or output pipes; this makes them terminate more gracefully,
and it avoids the problem of left-over index.lock files that the next
git command chokes on.

To fix the index.lock problem, only the first two commits of the branch
are needed. I decided to go a bit further and add more commits to make
similar changes to other places in the code; these might be considered
more risky than necessary, and we might decide to drop or revert them if
they cause problems. But it does allow us to remove the kill package
dependency altogether.

Fixes #2050.
2025-08-01 10:35:03 +02:00
Stefan Haller 1a72561b15 Remove the kill package dependency 2025-08-01 10:32:47 +02:00
Stefan Haller 7d9eaead54 Close the pty instead of killing the process for runAndDetectCredentialRequest
As with the previous commit, this is not strictly necessary for anything, just
cleaner.
2025-08-01 10:32:47 +02:00
Stefan Haller 83046a05d4 Don't kill processes in RunAndProcessLines
As we just did for tasks, close their stdout pipe instead. This makes the called
process terminate more gracefully.

This isn't a change that we *need* to make, it's just a bit nicer.
2025-08-01 10:32:47 +02:00
Stefan Haller 8d7740a5ac Don't kill tasks when we no longer need them
Now that we close a task's stdout pipe when we are done with it, it should
terminate by itself at that point, so there's no longer a need to kill it. This
way, called processes get a chance to terminate gracefully rather than being
killed with SIGKILL; in particular, this allows git to clean up its index.lock
file if it created one.
2025-08-01 10:32:46 +02:00
Stefan Haller d0a10bafbd Close a task's stdout pipe when we are done with it
This is similar to what we do when running tasks in a pty (we close the pty
there), and it should cause the called command to terminate.
2025-08-01 10:32:46 +02:00
Stefan HallerandGitHub 47afa7eb95 Improve temp dir handling (#4784)
- Lazygit creates a temp dir at startup, and is supposed to clean it up
after itself; however, this only worked for the main executable, not
when lazygit was spawned as a helper daemon for interactive rebases, so
we would leak a temp dir every time the user pressed `e` or `ctrl-j` or
other similar commands.
- All these temp dirs were created at top level in `/tmp` and thus
pollute it; now we create them inside a `/tmp/lazygit/` folder. This is
no longer quite as important now that the first bug is fixed, but might
still be useful when lazygit crashes, or when running many instances at
once in different terminal tabs.

Resolves #4781.
2025-08-01 10:32:32 +02:00
Stefan Haller 3a9dbf7341 Create temp directories inside a "lazygit" folder rather than top-level in /tmp
This is no longer as important now that we fixed the stale, left-over temp dirs
caused by daemon mode, but it could still be helpful in case lazygit crashes, or
if you have many instances of lazygit running.
2025-08-01 10:30:28 +02:00
Stefan Haller 6a17144ef4 Don't exit after handling daemon mode
The function that called us has just created a temp dir, and scheduled a defer
to remove it again; by calling os.Exit we short-cut this defer, and don't clean
up the temp dir. There is no reason to exit here, the calling function will
return after having called us.
2025-08-01 10:30:28 +02:00
Stefan Haller f4afeed9ff Improve .gitignoring debug executables 2025-08-01 10:30:28 +02:00
Stefan HallerandGitHub 05c30b8344 Fix commit hash colors when filtering by path or aythor (#4789)
- **PR Description**

Previously we would call git merge-base with the upstream branch to
determine where unpushed commits end and pushed commits start, and also
git merge-base with the main branch(es) to see where the merged commits
start. This worked ok in normal cases, but it had two problems:
- when filtering by path or by author, those merge-base commits would
usually not be part of the commit list, so we would miss the point where
we should switch from unpushed to pushed, or from pushed to merged. The
consequence was that in filtering mode, all commit hashes were always
yellow.
- when main was merged into a feature branch, we would color all commits
from that merge on down in green, even ones that are only part of the
feature branch but not main. (See #3796)

To fix these problems, we switch our approach to one where we call git
rev-list with the branch in question, with negative refspecs for the
upstream branch and the main branches, respectively; this gives us the
complete picture of which commits are pushed/unpushed/merged, so it also
works in the cases described above.

And funnily, even though intuitively it feels more expensive, it
actually performs better than the merge-base calls (for normal usage
scenarios at least), so the commit-loading part of refresh is faster now
in general. We are talking about differences like 300ms before, 140ms
after, in some unscientific measurements I took (depends a lot on repo
sizes, branch length, etc.). An exception are degenerate cases like
feature branches with hundreds of thousands of commits, which are slower
now; but I don't think we need to worry about those too much.

Fixes #3796.
2025-08-01 10:29:16 +02:00
Stefan Haller e46dc1ead6 Use a better approach for determining pushed and merge statuses
Previously we would call git merge-base with the upstream branch to determine
where unpushed commits end and pushed commits start, and also git merge-base
with the main branch(es) to see where the merged commits start. This worked ok
in normal cases, but it had two problems:
- when filtering by path or by author, those merge-base commits would usually
not be part of the commit list, so we would miss the point where we should
switch from unpushed to pushed, or from pushed to merged. The consequence was
that in filtering mode, all commit hashes were always yellow.
- when main was merged into a feature branch, we would color all commits from
that merge on down in green, even ones that are only part of the feature branch
but not main.

To fix these problems, we switch our approach to one where we call git rev-list
with the branch in question, with negative refspecs for the upstream branch and
the main branches, respectively; this gives us the complete picture of which
commits are pushed/unpushed/merged, so it also works in the cases described
above.

And funnily, even though intuitively it feels more expensive, it actually
performs better than the merge-base calls (for normal usage scenarios at least),
so the commit-loading part of refresh is faster now in general. We are talking
about differences like 300ms before, 140ms after, in some unscientific
measurements I took (depends a lot on repo sizes, branch length, etc.). An
exception are degenerate cases like feature branches with hundreds of thousands
of commits, which are slower now; but I don't think we need to worry about those
too much.
2025-07-31 15:50:53 +02:00
Stefan Haller 20517330b4 Change GetCommitsOptions.RefForPushedStatus to a models.Ref
This makes it easier to use the full ref in the git merge-base call, which
avoids ambiguities when there's a tag with the same name as the current branch.

This fixes a hash coloring bug in the local commits panel when there's a tag
with the same name as the checked out branch; in this case all commit hashes
that should be yellow were painted as red.
2025-07-31 15:26:19 +02:00
Stefan Haller 4b9921d0a4 Move the Ref interface from gui/types to models
This is a type that can be useful for model/backend stuff, so move it there. We
are going to use it in the API of the commit loader.
2025-07-31 15:21:34 +02:00
Stefan Haller cc0b5a2f7f Cleanup: remove the ignoringWarnings hack from GetMergeBase
GetMergeBase is always called with a full ref, so it shouldn't need the
ignoringWarnings hack (which is about ignoring warnings coming from ambiguous
refs).

Also, separate stdout and stderr, which would also have solved the problem. We
no longer really need it now, but it's still cleaner.
2025-07-31 15:21:34 +02:00
Stefan HallerandGitHub a02f1e8655 Draw divergence from base branch right-aligned in branches view (#4785)
- **PR Description**

I didn't enable the `showDivergenceFromBaseBranch` config by default yet
(even though I find it very useful) because I'm worried that people
might find the display too noisy. Drawing the divergence information
right-aligned helps reduce that noise a little bit.
2025-07-30 14:26:00 +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 HallerandGitHub d7626d4ccf refactor: use slices.Equal to simplify code (#4764)
- **PR Description**

In the Go 1.21 standard library, a new function has been introduced that
enhances code conciseness and readability. It can be find
[here](https://pkg.go.dev/slices@go1.21.1#Equal).
2025-07-29 11:23:17 +02:00
Stefan HallerandGitHub 8e04349828 When pressing a to stage all files, don't include untracked files when showing only tracked files (#4779)
- **PR Description**

This is very similar to what we did for pressing space in #4386; we
forgot that the "stage all" command has the same issue.

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 18:01:56 +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 HallerandGitHub 79da2ca3af Make the minimum required git version a placeholder in the error text (#4778)
- **PR Description**

This way we don't have to update the text and all translations every
time we bump the version.

Remove the year from the error text, it's cumbersome to update and I
don't find it very important to have in the message.

Also remove the invitation to file an issue; I don't find it very likely
that we are going to relax the minimum git requirement again.
2025-07-28 13:13:41 +02:00
Stefan Haller 05b27c390d Make the minimum required git version a placeholder in the error text
This way we don't have to update the text and all translations every time we
bump the version.

Remove the year from the error text, it's cumbersome to update and I don't find
it very important to have in the message.

Also remove the invitation to file an issue; I don't find it very likely that we
are going to relax the minimum git requirement again.
2025-07-28 13:10:25 +02:00
Stefan HallerandGitHub a52d953789 Fix performance regression on startup in repos with many tags (#4777)
- **PR Description**

In #4663 we added information in the tags panel about the selected tag
(whether it's annotated etc). Unfortunately this introduced a
performance regression in repositories with many tags, so revert this
and implement the feature in a slightly different way to avoid the
performance hit.

Fixes #4770.
2025-07-28 12:26:53 +02:00
Stefan Haller 1c533dcd55 Revert "Add IsAnnotated field to models.Tag struct"
It seems that `git for-each-ref` is a lot slower than `git tag --list` when
there are thousands of tags, so revert back to the previous method, now that we
no longer use the IsAnnotated field.

This reverts commit b12b1040c3.
2025-07-28 10:53:51 +02:00
Stefan Haller 151e80902e Use a different way to check if a tag is annotated
Storing it in the Tag struct makes loading tags a lot slower when there is a
very large number of tags; so determine it on the fly instead. On my machine,
the additional call takes under 5ms, so it seems we can afford it.
2025-07-28 10:53:51 +02:00