8720 Commits
Author SHA1 Message Date
Stefan Haller bbca3df2cd Avoid conflicts and duplicate lines when moving a patch to an earlier commit (#6167)
When moving a custom patch to an earlier commit, or into a new commit
before the original one, lazygit applies the patch to the earlier commit
and then replayed the original commit unchanged. It relied on git
noticing during the replay that the patch's changes are already there.
This doesn't always work:

- If the patch contains only some of several adjacent added lines,
replaying the original commit stops with a conflict.
- If git can place the patch's added lines in two positions because they
repeat the line after them, the replay may put them in the other
position than the patch did. Git then keeps both copies, and the file
ends up containing the patch's lines twice. There's no conflict, so this
goes unnoticed.

Fix this by making the rebase pick a copy of the source commit instead.
The copy has the same tree, author and message, but its parent is the
original parent with the patch applied. Picking it only replays the
source commit's changes minus the patch, so git no longer has to
recognize the patch as already applied.
2026-11-06 17:28:57 +01:00
Stefan HallerandClaude Opus 5.5 fabc14d7e5 Keep the conflicts popup open after moving a patch into a new commit
If moving a custom patch into a new commit stops at a conflict,
CheckMergeOrRebase shows the "Conflicts!" popup. The handler then
focused the commits view anyway, and this closed the popup.

Only focus the commits view if the operation finished.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan HallerandClaude Opus 5.5 3864ddc52c Unify the handlers for moving a patch into a new commit
The handlers for moving the patch into a new commit before or after the
original one differ only in the git command they call. The next commit
fixes a bug that both have.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan HallerandClaude Opus 5.5 16f51df6e3 Avoid conflicts and duplicate lines when moving a patch into a new commit before
Moving a custom patch into a new commit before the original one has the
same problem as moving it to an earlier commit. After committing the
patch, the rebase picks the original commit unchanged and relies on git
noticing that the patch is already there.

Make the rebase pick a copy of the original commit whose parent already
contains the patch, as we do when moving to an earlier commit. Here,
the copy's parent normally has the same tree as the new commit, so
picking the copy doesn't conflict. Only a commit hook that changes the
new commit's files could make it conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan HallerandClaude Opus 5.5 507b65065f Avoid conflicts and duplicate lines when moving a patch to an earlier commit
When moving a custom patch to an earlier commit, we apply the patch to
the earlier commit and then let the rebase pick the commit that the
patch came from, unchanged. This relies on git noticing during the pick
that the patch's changes are already there. If the patch contains only
some of several adjacent added lines, git doesn't notice, and the pick
stops with a conflict. If git can place the patch's added lines in more
than one position, it may place them differently for the pick than for
the patch. It then adds them a second time, without any conflict.

Make the rebase pick a copy of the source commit instead. The copy has
the same tree, author and message, but its parent is the original
parent with the patch applied. Picking it only replays the source
commit's changes minus the patch, so git no longer has to recognize
the patch as already applied. Create the copy with plumbing commands
and a temporary index; this doesn't touch the working tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan HallerandClaude Opus 5.5 09068b0360 Add a function to change which commit a rebase todo picks
The next commit uses this to replay a modified copy of a commit in
place of the original one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan HallerandClaude Opus 5.5 e8261e06d1 Disable moving a patch between a merge commit and another commit
If the patch comes from a merge commit, moving it to a later commit
leaves the user in a rebase that is stuck before its first todo.
Moving it to an earlier commit, or into a new commit before the merge,
finishes, but with surprising results. The rebase doesn't replay a
merge commit; it recreates it from its parents. If the patch contains
changes from the merged branch, the commits on that branch that made
them become empty. And a new commit "before" the merge ends up at the
tip of the merged branch.

Moving a patch to a later merge commit gets stuck in the same way.
Moving a patch to a merge commit isn't useful in either direction, so
disable both.

The other patch commands amend the merge commit itself and work fine,
so they stay enabled. They are useful for removing changes that were
added to a merge commit by accident.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan HallerandClaude Opus 5.5 9383172a6c Add a test demonstrating that the conflicts popup disappears
If moving a custom patch into a new commit before the original one
results in a conflict, lazygit shows the "Conflicts!" popup, but then
immediately focuses the commits view. This closes the popup, and the
user is left in a rebase that is stopped at a conflict without being
told about it.

The test uses a pre-commit hook that changes a file of the new commit;
this makes picking the original commit conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan HallerandClaude Opus 5.5 7bf398db1d Add tests demonstrating bugs when moving a patch to an earlier commit
When moving a custom patch to an earlier commit, or into a new commit
before the original one, lazygit applies the patch to the earlier
commit and then replays the original commit unchanged. It relies on
git noticing during the replay that the patch's changes are already
there. This doesn't always work:

- If the patch contains only some of several adjacent added lines,
  replaying the original commit stops with a conflict.
- If git can place the patch's added lines in two positions because
  they repeat the line after them, the replay may put them in the
  other position than the patch did. Git then keeps both copies, and
  the file ends up containing the patch's lines twice. There's no
  conflict, so this goes unnoticed.

When moving into a new commit before the original one, the conflict of
the first case doesn't show the usual "Conflicts!" popup; lazygit
focuses the commits panel instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:25:48 +01:00
Stefan Haller 0002c03547 Don't offer to push or pull branches merged into a local main branch (#6169)
When pushing master, lazygit offers to push other branches along with it
if they were merged into master locally and have unpushed commits.
Pulling master offers to update such branches in the same way. These
branches aren't part of a stack, so the menu only adds an extra step to
an ordinary push or pull.

This happens because a branch counts as stacked below the current one if
its tip is one of the current branch's commits that aren't merged into a
main branch yet. A commit's merged status only looks at the remote
branch of each main branch. So until master is pushed, the commits that
were merged into it locally count as unmerged. The same goes for pushing
or pulling a feature branch on top of such a master.

Treat the commits that a local main branch contains as merged too, so
that the search for stacked branches stops at a main branch.

Fixes #6144.
2026-11-03 19:24:53 +01:00
Stefan HallerandClaude Opus 5.5 fb1b6ed1c1 Don't offer to push or pull branches merged into a local main branch
When pushing master, lazygit offers to push other branches along with
it if they were merged into master locally and have unpushed commits.
Pulling master offers to update such branches in the same way. These
branches aren't part of a stack, so the menu only adds an extra step to
an ordinary push or pull.

This happens because a branch counts as stacked below the current one
if its tip is one of the current branch's commits that aren't merged
into a main branch yet. A commit's merged status only looks at the
remote branch of each main branch. So until master is pushed, the
commits that were merged into it locally count as unmerged. The same
goes for pushing or pulling a feature branch on top of such a master.

Treat the commits that a local main branch contains as merged too, so
that the search for stacked branches stops at a main branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 15:12:36 +01:00
Stefan Haller c9c0db40bd Improve bisecting (#6168)
This PR makes bisecting easier in several ways:

- **Start a bisect from more views.** The bisect menu (`b`) is now also
available in the local branches, remote branches, tags, sub-commits and
reflog views. This makes it possible to mark a branch or tag as good or
bad without checking it out first. Once git knows both a good and a bad
commit, lazygit focuses the commits panel, where the bisect continues.
- **Select the commit to test.** Whenever git picks a new commit to
test, lazygit selects it. Before, this happened only when you marked the
commit to test in lazygit while it was selected. Now it also happens
when lazygit starts during a bisect, when you run `git bisect` commands
in a terminal, and when the commit is further down than the commits that
lazygit loads at first.
- **Select the result.** When the bisect is done, lazygit selects the
first bad commit, so that you can look at it right away. Pressing `b`
afterwards shows the result again and offers to reset the bisect.
Before, the menu offered to mark the commit that you had just marked.
- **Show the log of HEAD until both a good and a bad commit are known.**
If you check out another branch to find a commit to mark, the commits
panel shows that branch.
- **Focus the commits panel at startup** if a bisect is in progress.
- **Mark the remaining commits correctly.** The "?" marks for the
commits that git still has to consider now come from git. They were
missing while git tests the merge base of a good and a bad commit on
different branches, and early in a long bisect.
- **Fix labels.** Before git has picked a commit to test, the bisect
menu names the selected commit instead of calling it the "current
commit". Once the bisect is done, the last tested commit shows its mark
instead of "current".

Closes #2346.
Closes #2941.
Closes #5530.
Closes #6103.
2026-10-31 15:12:18 +01:00
Stefan HallerandClaude Opus 5.5 0b87c9e610 Ask git which commits a bisect hasn't ruled out yet
The commits view marks the commits that a bisect hasn't ruled out yet
with a "?". To find them, it looks for the bad commit and the first good
commit in the list, and marks the commits between them. If there's no
good commit in the list, it marks none. This is the case while git
tests the merge base of a good and a bad commit on different branches.
It's also the case early in a long bisect, when the good commit is
further down than the commits that we load. With merges, the commits
between the two can also include some that the bisect has ruled out.

Ask git instead, with "git rev-list <bad> --not <good>...", when
refreshing the commits while git knows both a good and a bad commit.
This takes about as long as the git log that loads the commits, or
less, and it gets faster as the bisect goes on. Keep only the commits
that the commits view has loaded, because git may list many more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 12:17:43 +01:00
Stefan HallerandClaude Opus 5.5 fd7178a3a9 Add tests showing that some commits to bisect lack the "?" mark
The commits view marks the commits between the bad commit and the first
good commit in the list with a "?". If there's no good commit in the
list, it doesn't mark any. This is the case while git tests the merge
base of a good and a bad commit on different branches. It's also the
case early in a long bisect, when the good commit is further down than
the commits that we load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 12:15:16 +01:00
Stefan HallerandClaude Opus 5.5 368633f69c Show the result of a finished bisect instead of the bisect menu
Once git has nothing left to test, the bisect menu offers marking or
skipping the current commit, although the user has marked it already. If
git found the first bad commit without checking out anything to test,
the menu acts on the selected commit instead, as if git didn't know both
a good and a bad commit yet. At this point, the user wants to see the
result and reset the bisect.

Show the "Bisect complete" dialog again instead of the menu. It names
the first bad commit and asks whether to reset the bisect. This also
lets the user see the result again after declining the reset when the
bisect finished.

If git stopped without finding the first bad commit, because the merge
base of the good and the bad commit is bad, show the confirmation for
resetting the bisect. Git said why it stopped when it did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 5284818424 Add tests showing that the bisect menu offers marks once a bisect is done
Once git has nothing left to test, the bisect menu still offers marking
or skipping the current commit, although the user has marked it
already. This also happens if git stopped because the merge base of the
good and the bad commit is bad. If git found the first bad commit
without checking out anything to test, the menu acts on the selected
commit, as if git didn't know both a good and a bad commit yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 ba05949879 Show the mark of the last tested commit once a bisect is done
Once git has nothing left to test, the commit that the user marked last
stays the current commit. The commits view labels it "<-- current",
although git doesn't want the user to test it any more. Show its mark
instead, like for the other marked commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 21569fa96f Add a test showing that a finished bisect labels the last commit "current"
Once git has nothing left to test, the commit that the user marked last
stays the current commit. The commits view labels it "<-- current",
although it is marked good or bad now, and git doesn't want the user to
test it any more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 32d07f2b38 Select the first bad commit once a bisect is done
When the user marks the last commit to test, the commits view keeps it
selected, and the user has to look for the result. The same happens
when lazygit starts after a bisect has finished.

After a mark, git checks out the next commit to test, unless there's
nothing left to test. In that case, the commit that the user marked
last is still the current commit, and the commit marked bad is the
first bad commit. So once the current commit is marked, select the
commit marked bad instead. Do the same if git never checked out a
commit to test, because the good commit is a parent of the bad one.

If only skipped commits are left to test, the first bad commit is
either one of them or the commit marked bad. Select the commit marked
bad then too; it's the newest of the candidates.

The commits view loads the commits down to the commit that it selects,
so this one is always loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 e080c08b90 Add tests showing that a finished bisect doesn't select the first bad commit
When the user marks the last commit to test as good, git reports the
commit that is marked bad as the first bad commit. The commits view
keeps the commit that the user just marked selected, though, so the
user has to look for the result. The same happens when lazygit starts
after a bisect has finished.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 350c061081 Focus the commits panel at startup when a bisect is in progress
Lazygit starts in the files panel. During a bisect, this is rarely what
the user needs. The commits panel shows how far the bisect has got, and
the user marks the commits to test there. So start in the commits panel
if a bisect is in progress, even if git doesn't know both a good and a
bad commit yet. The same applies the first time the user switches to
such a repo during a session.

A filter path or a "status", "branch", "log" or "stash" argument still
decides which panel to focus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 e1336f03dd Offer the bisect menu in more views than the commits panel
To start a bisect, users often know that one branch or tag is good and
another one is bad. The bisect menu was available in the commits panel
only, though. To mark the head of another branch, the user had to check
it out first, or find its head commit in the commits panel. The commits
panel shows only the checked-out branch.

Offer the menu in the local branches, remote branches, tags, sub-commits
and reflog views too. There it marks the selected item as good or bad,
and its entries name the item ("branch 'dev'", "tag 'v1.0'"), so that
it's clear what they act on. Once git knows both a good and a bad
commit, the bisect continues in the commits panel. It shows the good and
bad commits and the one to test next, and its menu acts on that one. So
focus the commits panel when a mark in another view gives git the second
of the two, and disable the key in the other views from then on. They
don't offer skipping either.

Name the selected commit "commit <hash>" in the commits panel's menu
too, so that it reads the same in all views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 308a11f84d Let the bisect controller work with any context that has a selected ref
It worked with the commits of the local commits context only. The next
commit offers the bisect menu in other views too, such as branches and
tags, so let it take any context and act on its selected ref.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 eef08f04ec Don't call the selected commit "current" before bisecting starts
After marking the first commit as good or bad, the bisect menu's
entries act on the selected commit until git knows both a good and a
bad commit. They called it the "current commit" though, as if it was
the commit that git wants the user to test.

Call it "commit <hash>" instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 9761cec61a Split the bisect menu for before and while bisecting
One function built the menu both for when git still waits for a good or
a bad commit, and for while bisecting. Its entries act on the selected
commit in the first case, and on the commit that git wants the user to
test in the second case. Several conditions in the function picked
between the two.

The next commits change the first menu only, so make it a function of
its own. Extract the menu entries that both menus have, so that they
don't get duplicated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 027a5babeb Add a test showing that the bisect menu mislabels the selected commit
After marking the first commit as good or bad, the bisect menu acts on
the selected commit until git knows both a good and a bad commit. Its
entries call that commit the "current commit" though, as if it was the
commit that git wants the user to test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 08065f0294 Load the commits down to the current bisect commit
The commits view loads the first 300 commits only. If the range to
bisect is longer than about 600 commits, the commit that git wants the
user to test is further down than that, so it isn't shown, and we can't
select it.

While bisecting, count the commits in the log above the current commit,
and load that many more than usual.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 990913dd63 Add a test showing that a current bisect commit far down isn't selected
The commits view loads the first 300 commits only. If the range to
bisect is longer than about 600 commits, the commit that git wants the
user to test is further down than that. It isn't loaded, so we can't
select it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 ee07abe508 Load all commits when the selection is near the end of the loaded ones
The commits and sub-commits views load the first 300 commits, and load
all of them once the user selects a commit beyond the 200th. A later
commit loads more than 300 commits while bisecting, so that the commit
to test is among them. If it is beyond the 200th, it would cause all
commits to be loaded as soon as it gets selected.

Remember how many commits the views were loaded with, and load all of
them only when the selection gets within 100 commits of that number.
For the views loaded with 300 commits, nothing changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 0d41e696ac Pass the number of commits to load to the commit loader
The commit loader took a flag for whether to limit the number of
commits it loads, and the limit of 300 was hard-coded in it. A later
commit needs to load more than that while bisecting, so let the caller
pass the number.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 b2e9d2a348 Unify the code that loads all commits when scrolling near the end
The commits and the sub-commits views had identical copies of it. A
later commit changes when it loads all commits, so make it one function
first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 8055f5c139 Show the log of HEAD until both a good and a bad commit are known
Once a bisect had started, the commits view showed the log of the
branch that was checked out when it started, even while git was still
waiting for a good or a bad commit. If the user checked out a different
branch to mark its head as bad, its commits weren't shown.

Keep showing the log of HEAD until git starts checking out commits to
test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 4725e80b34 Add a test showing that a checkout before bisecting doesn't update the log
Once a bisect has started, the commits view shows the log of the branch
that was checked out when it started. This happens even while we don't
know both a good and a bad commit yet, and git hasn't checked out
anything for the user to test. If the user checks out a different
branch to mark its head as bad, the commits view keeps showing the old
branch, so the new branch's head isn't there to be marked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 208bbce33f Select the current bisect commit whenever it changes
If lazygit starts while a bisect is in progress, the commits view
selects the top commit, and the user has to look for the commit that
git wants them to test. The same happens when a git bisect command run
outside of lazygit moves the bisect on.

The bisect menu selected the new current commit after a good, bad or
skip, but only if the selected commit was the current one. It also
needed extra logic to wait for the refresh in case the log was going to
start from a different ref.

Remove that, and let the commits refresh select the current commit
whenever it differs from the one at the previous refresh, like it does
for a newly conflicted commit. A refresh that doesn't change it leaves
the selection alone. This way a background fetch doesn't move the
selection back to the current commit after the user navigated away from
it.

Marking the current commit as good or bad while a different commit is
selected now selects the new current commit too.

Skipping the selected commit when it isn't the current one is an
exception. Git often picks a different commit to test after that, but
we keep the skipped commit selected, so that the user can go on
skipping commits near it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:27:58 +01:00
Stefan HallerandClaude Opus 5.5 550a6d88a7 Scroll a newly conflicted commit into view in background refreshes
When a refresh finds a new conflicted commit, it selects it so that the
user sees where the rebase stopped. A background refresh keeps the
scroll position of the views it updates though. If the conflicted
commit is outside the visible part of the commits view, the selection
moves to a commit that the user can't see.

Scroll the selection into view whenever the refresh moves it to a newly
conflicted commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 20:37:56 +01:00
Stefan HallerandClaude Opus 5.5 30744324f8 Add a test showing that a background refresh doesn't scroll to a conflict
If a rebase started outside of lazygit stops with a conflict, the next
background refresh selects the conflicted commit. It keeps the scroll
position though, so if there are enough pending todos above the
conflicted commit, the selection is off-screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 20:37:44 +01:00
Stefan HallerandClaude Opus 5.5 cd23678775 Re-render the commits view in the same UI-thread hop as its model update
The commits refresh updated the model and the selection in one hop to
the UI thread, and re-rendered the view in a second one. The scroll
behavior of the re-render was fixed when the refresh started.

The next commit makes the scroll behavior depend on how the refresh
changed the selection. Do both in one hop, so that the re-render can
see that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 20:35:41 +01:00
Stefan HallerandClaude Opus 5.5 d924a26737 Fix the parameter names of Shell.StartBisect
`git bisect start` takes the bad commit first and the good one second.
The parameters were named the other way round. The only caller already
passes the bad commit first, so only the names were wrong.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 20:34:47 +01:00
Stefan Haller 4e1eebe278 Stop uploading test coverage to Codacy (#6141)
Codacy hasn't analysed this repository since April 2026, because status
checks are disabled for it in Codacy's settings. The uploads from CI
still succeed, but the commits never show up in Codacy, and the coverage
badge in the README shows 0%.

We decided not to revive the integration. Remove the upload job and the
two Codacy badges.
2026-10-17 13:06:23 +02:00
Stefan HallerandClaude Opus 5.5 cb5c127b55 Write all integration test coverage to LAZYGIT_GOCOVERDIR
If LAZYGIT_GOCOVERDIR is set, run_integration_tests.sh collects the
coverage of the integration tests. Only the lazygit binary writes its
data to that directory, though. The test runner always writes to
/tmp/code_coverage, so the data ends up in two places unless the
variable points there. On CI it always did.

Also, the run fails if the directory doesn't exist yet. With a relative
path, the binary's data goes missing, because the binary runs in the
directory of the test's repo.

Pass the directory to the test runner too, create it if needed, and turn
it into an absolute path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 12:50:31 +02:00
Stefan HallerandClaude Opus 5.5 232b3c5e08 Fix a typo in a comment in run_integration_tests.sh
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 12:50:31 +02:00
Stefan HallerandClaude Opus 5.5 5b212e184b Remove the Go Report Card badge
Go Report Card has shut down. The badge now reads "go report: retired",
and the report page only shows a farewell note. That note recommends
golangci-lint as the replacement, and we already show a badge for it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 12:50:31 +02:00
Stefan HallerandClaude Opus 5.5 6d46f2c0f4 Stop collecting test coverage on CI
CI collected coverage data from the unit and integration tests only for
the Codacy upload. Nothing else reads it.

Remove the coverage flags, the LAZYGIT_GOCOVERDIR env var and the
artifact uploads from the CI workflow. Keep the support for
LAZYGIT_GOCOVERDIR in run_integration_tests.sh and in the integration
test runner, so that we can still measure the coverage of the
integration tests locally.

Remove the step in run_integration_tests.sh that merges the coverage
files, though. It only existed to reduce the number of artifacts to
upload.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 12:50:31 +02:00
Stefan HallerandClaude Opus 5.5 a181c3ec3a Stop uploading test coverage to Codacy
Codacy hasn't analysed this repository since April 2026, because status
checks are disabled for it in Codacy's settings. The uploads from CI
still succeed, but the commits never show up in Codacy, and the coverage
badge in the README shows 0%. On Dependabot PRs the upload fails
outright. These runs don't get the CODACY_PROJECT_TOKEN secret.

We decided not to revive the integration. Remove the upload job and the
two Codacy badges.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 12:50:31 +02:00
Stefan Haller a5343678ec Bump golangci-lint to 2.15.0 (#6140)
This is needed so that linting works with go 1.27.
2026-10-17 12:49:07 +02:00
Stefan HallerandClaude Opus 5.5 9b52fad152 Bump golangci-lint to 2.15.0
With Go 1.27 installed, `just lint` fails with typecheck errors like
"export data version 5 is greater than maximum supported version 4".
The shim builds golangci-lint with the local Go, but v2.12.2 can't read
the export data of Go 1.27's standard library. Support for Go 1.27 came
in v2.13.0.

v2.15.0 still builds with Go 1.26, so linting keeps working there too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 12:14:56 +02:00
Stefan HallerandClaude Opus 5.5 0a11e1289a Discard the error of Pipeline.Wait explicitly in a test
TestClosingAPipelinesOutputBringsItDown receives the error of
Pipeline.Wait from a channel and ignores it. errcheck v1.30.0 reports
such a receive as an unchecked error. golangci-lint 2.15.0 comes with
this errcheck version, and the next commit bumps to it.

The test ignores the error on purpose. It only checks that Wait returns,
and the error depends on the platform. Make that explicit by discarding
the error in the goroutine, and use the channel only to signal that
Wait has returned.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 12:14:56 +02:00
Stefan Haller 4b38f6f8b7 Guard against mistakes when running the release action (#6138)
Releases are run from stefanhaller's fork, but if that fork is not up to
date with jesseduffield's, bad things can happen. Guard against this by
checking that the release.yml file in both is identical.

Also take the go version to build with from the go.mod file in the
branch that is being released from, rather than hard-code it in
release.yml; this could be relevant when making a release from a 0.66.3
branch when the go version has already been bumped on master.
2026-10-16 14:58:11 +02:00
Stefan HallerandClaude Opus 5.5 5858bb7193 Take the Go version for releases from go.mod
release.yml installs a fixed Go version for building a release, and it
must match the release.yml on master. A patch release from a branch off
an older tag is therefore built with master's Go version, not with the
one that branch uses. For example, once master moves to Go 1.27, a
v0.66.3 built from a branch off v0.66.2 would no longer run on macOS
12, although v0.66.2 does.

Read the version from the go line of the checked-out go.mod instead,
and add ".x" so that setup-go installs the latest patch release.
setup-go's go-version-file input can't do this; for "go 1.26.0" it
installs exactly 1.26.0. Read the version before pushing the tag, so
that a go.mod without a go line stops the release early.

This also removes release.yml from the files to edit when updating Go.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 14:23:10 +02:00
Stefan HallerandClaude Opus 5.5 e718b4b63e Check that the fork's release.yml matches upstream's
Releases run the release workflow of the stefanhaller/lazygit fork, but
build the code of jesseduffield/lazygit. If the fork's master is behind,
its copy of release.yml can differ from upstream's, and the release
runs with outdated steps. This may only show up after the new tag has
already been pushed.

Stop the release right after checking out the code if the running
release.yml differs from the one on jesseduffield/lazygit's master.
Compare with master rather than with the branch being released. A
patch release from a branch off an older tag carries an older
release.yml, and it should still be released with the current workflow.

This means that changes to release.yml can no longer be tried out in
the fork before they land upstream.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 14:22:57 +02:00