Commit Graph
8797 Commits
Author SHA1 Message Date
Stefan HallerandClaude Opus 5.5 2a39f2b564 Rename bufferedKeyEvents to bufferedInputEvents
The next commit buffers paste events in it too.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This is just one of many examples of what can go wrong when retrying
rebase, cherry-pick, or revert commands that fail with an index.lock
error; this PR tries to handle as many situations as reasonable
automatically (e.g. by issuing `git rebase --continue` when a pick
failed and lazygit can confirm that the pick was rescheduled by git).
See the individual commits for details.
2026-11-08 15:16:49 +01:00
Stefan HallerandClaude Opus 5.5 4d56db828c Recognize a rebase that couldn't commit a pick, and continue it
If git can't take the index lock to commit the changes of a pick during
a rebase, it exits without writing rebase-merge/stopped-sha. Lazygit
then showed the rebase as a cherry-pick, because it only recognized
CHERRY_PICK_HEAD as part of a rebase if stopped-sha matched it.

Also accept CHERRY_PICK_HEAD as part of the rebase if it matches the
last todo in rebase-merge/done, the pick that git was executing.

With this, continuing runs "git rebase --continue". In this state it
refuses to commit the staged changes of the pick, because git didn't
write the message file that it writes when a pick conflicts. So commit
them first with "git cherry-pick --continue". This uses the author and
message of the pick, like the rebase would have.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 de10b170c9 Add a test for a stopped rebase being shown as a cherry-pick
If git can't take the index lock to commit the changes of a pick during
a rebase, it exits without recording that the rebase stopped. It leaves
CHERRY_PICK_HEAD behind, but no rebase-merge/stopped-sha. Lazygit only
recognizes CHERRY_PICK_HEAD as part of a rebase if stopped-sha matches
it, so it shows the rebase as a cherry-pick.

Its "Cherry-pick options" then run cherry-pick commands during the
rebase. Continuing happens to work, but takes two steps. Skipping or
aborting discards the changes of the pick, and continuing the rebase
afterwards loses that commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 fcfe2e309f Don't repeat a continue or skip that a lock error stopped partway
If a lock stops "git rebase --skip" after git has applied the changes
of the next commit but before it has committed them, running it again
discards those staged changes, and the commit is lost. Something
similar happens with "git cherry-pick --continue" and "--skip" (and
the same for revert). If the lock stops them at the next commit, git
doesn't reschedule that commit, and running them again skips it.

For a rebase, handle continue and skip like the commands that start a
rebase. Run the command again if the lock stopped it before it changed
the state of the rebase, continue if git rescheduled the todo that
failed, and give up otherwise. For a cherry-pick or revert, run the
command again if it didn't change the todos in .git/sequencer, and
give up otherwise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 4c18daf933 Add a test for a lock error partway through skipping in a rebase
If a lock stops "git rebase --skip" after git has applied the changes
of the next commit but before it has committed them, git doesn't
reschedule that commit. The changes stay staged. The git command runner
then runs "git rebase --skip" again, and this discards the staged
changes, so the commit is silently lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 d4b11b8cfd Abort and redo a cherry-pick or revert that a lock error stopped
If a lock stops a cherry-pick or revert of several commits partway
through, the git command runner ran the same command again. This failed
with "cherry-pick is already in progress", and the user was left with
an operation that stopped halfway. Continuing it would skip the commit
that failed, because git doesn't reschedule it the way a rebase does.

Abort the operation instead, and then run the command again. Also
abort when the runner gives up, so that the user doesn't end up with
the stopped operation.

Only do this for several commits. For a single commit, git doesn't use
.git/sequencer, and a cherry-pick of one commit may even run while a
cherry-pick of several commits is in progress. If .git/sequencer exists
after a single cherry-pick failed, it belongs to that other operation,
and we must not abort it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 3ecf3ae4cb Add a test for a lock error partway through a cherry-pick
If a lock stops a cherry-pick of several commits partway through, the
git command runner runs the same "git cherry-pick" command again. This
fails with "cherry-pick is already in progress", and the user is left
with a cherry-pick that stopped halfway. Unlike a rebase, git doesn't
reschedule the commit that failed, so continuing the cherry-pick would
skip that commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 4e24ef025b Show a cherry-pick or revert as in progress if only .git/sequencer exists
If a cherry-pick or revert of several commits stops before git starts
to apply one of them, git doesn't write CHERRY_PICK_HEAD or REVERT_HEAD.
It only leaves the todos behind in .git/sequencer.

Look at the first todo there, like git status does. If it is a "pick"
or "revert", consider a cherry-pick or revert to be in progress.

Once we show such an operation, two more things need care. The same
state occurs if the user resolves a conflict and commits the result
themselves. Git tells the two cases apart by whether HEAD has moved
since it last tried to apply a commit, so do the same. Mark the commit
that git stopped at as conflicted only if CHERRY_PICK_HEAD or
REVERT_HEAD exists, and don't show it as pending if the user has
committed it.

Also, "git cherry-pick --continue" skips the commit that git stopped
at, even if git never applied it. Before continuing in that case, put a
copy of its todo in front of it, so that git skips the copy instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 6614d4d8f8 Add a test for a cherry-pick that stops before it applies a commit
If a cherry-pick of several commits stops before git starts to apply
one of them, for example because the commit would overwrite an
untracked file, lazygit doesn't show the cherry-pick as in progress.
Git doesn't write CHERRY_PICK_HEAD in that case, and this is the only
thing we look at. The user has no way to continue or abort the
cherry-pick from lazygit, and the next cherry-pick fails with
"cherry-pick is already in progress".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 6dc34a62d2 Resume a pull whose rebase a lock error stopped partway through
If pull.rebase is set and a lock stops the rebase partway through, the
git command runner ran "git pull" again. This failed with "You are not
currently on a branch", and the rebase was left stopped halfway.

Handle this the same way as for an interactive rebase. Continue the
rebase if git rescheduled the todo that failed, give up if it didn't,
and run the pull again if the lock stopped it before the rebase
started.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 3fb06d9095 Add a test for a lock error partway through a pull with rebase
This has the same problem as an interactive rebase. If pull.rebase is
set and a lock stops the rebase partway through, the git command runner
runs "git pull" again. This fails with "You are not currently on a
branch" because HEAD is detached during the rebase, and the rebase is
left stopped halfway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 fc5ac8fc63 Resume a rebase that a lock error stopped partway through
If another git process takes index.lock while a rebase is replaying
commits, git stops the rebase and reschedules the todo that failed. The
git command runner then ran the whole "git rebase --interactive" command
again. This failed because the rebase was already in progress, and the
user was left with a rebase that stopped halfway.

Continue the rebase with "git rebase --continue" instead; this runs the
rescheduled todo again. Only do this if the todo files show that git
rescheduled it. In some cases git doesn't, for example if the lock stops
a pick after it has applied the changes but before it has committed
them. Continuing is not safe in that case, so give up and show the
error.

If the lock stops the command before the rebase starts, git cleans up
after itself, and we run the command again as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 21bbcc957a Add a test for a lock error partway through a rebase
If another git process takes index.lock while a rebase is replaying
commits (for example an IDE running "git status" in the background),
git stops the rebase and reschedules the command that failed. Lazygit
then runs the whole "git rebase --interactive" command again. This
fails with "It seems that there is already a rebase-merge directory",
and the user is left with a rebase that stopped halfway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 3dcad25058 Turn runSkipEditorCommand into a function that only sets up the editor
The next commit needs a "git rebase --continue" command with this setup
that the git command runner runs, rather than one that we run directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 3a538fc2a8 Let a git command decide how to recover from a lock error
The git command runner runs a command again if it failed because
another git process held a lock. This is wrong for a command that starts
an operation of several steps, such as a rebase or a cherry-pick of
several commits, if the lock stopped it partway through. Running it
again then fails because the operation is already in progress.

Add a hook that such a command can use to tell the runner what to do
instead. The following commits use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan HallerandClaude Opus 5.5 4486e8d149 Extract the check for a rescheduled rebase command into a helper
We are going to need it for recovering from lock errors during a rebase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:54:41 +01:00
Stefan Haller ed60806c04 Add a security policy (#6194)
The repository doesn't say how to report a vulnerability privately, and
#6185 was reported in a public issue. Point reporters to GitHub's
private vulnerability reporting.
2026-11-08 14:31:49 +01:00
Stefan HallerandClaude Opus 5.5 6bae77f1ce Add a security policy
The repository doesn't say how to report a vulnerability privately,
and #6185 was reported in a public issue. Point reporters to GitHub's
private vulnerability reporting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:28:32 +01:00
Stefan Haller 8e7c837c1d Make "go to bottom" stop at the beginning of each branch of a stack (#6193)
In the Commits panel, the "go to bottom" command (`>`) already has a
special case where it jumps to the beginning of the checked-out branch
first, and only then to the end of the list.

In this PR we take this one step further and also make it stop at the
beginning of each individual branch in a stack. This makes it easier to
navigate stacks of long branches.

Also, we make it stop at the beginning of the rebase todos in an
interactive rebase, and at the bad, current and good commits of a
bisect.
2026-11-08 14:27:21 +01:00
Stefan HallerandClaude Opus 5.5 af0e6ab7f2 Make "go to bottom" in a divergence view stop at the last remote commit
The divergence view shows the remote commits in a section above the
local ones. Pressing '>' now goes to the beginning of the remote section
before it goes on to the bottom of the local one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:08:51 +01:00
Stefan HallerandClaude Opus 5.5 280c67ff98 Make "go to bottom" stop at the bad, current and good commits of a bisect
During a bisect, the commits panel shows the commits known to be bad at
the top, the known good ones at the bottom, and the ones that the bisect
hasn't ruled out yet between them. Pressing '>' now stops at the
bottommost bad commit, then at the commit to test, and then at the
topmost good commit.

It doesn't stop at each commit marked good. The commits between two of
them are all good, and they don't form a section of their own.

During a bisect, it also doesn't stop at the beginnings of the other
sections, such as the beginning of a branch. The commits panel doesn't
color the commits by whether they are merged while bisecting, so these
would look like arbitrary commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 14:08:51 +01:00
Stefan HallerandClaude Opus 5.5 462a168d87 Make "go to bottom" stop at the beginning of each branch of a stack
In a stack of branches, pressing '>' in the commits panel went to the
beginning of the bottommost branch right away. Make it go to the
beginning of the branch that the selection is in first, and then to the
beginning of each branch below it. During a rebase, the update-ref todos
separate the branches among the todos, so stop above each of them too.

The branches of the stack are the ones that the commits list marks, and
that pushing and pulling a stack include.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:46:15 +01:00
Stefan HallerandClaude Opus 5.5 633bedf4fd Pass only the branch name to BranchesBelow
The commits panel will need to call it. All it knows is the name of the
checked-out branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:43:36 +01:00
Stefan HallerandClaude Opus 5.5 33f52279c4 Make "go to bottom" in the commits panel stop at the first todo
During a rebase, cherry-pick or revert, the todos are a section of their
own at the top of the commits panel. Pressing '>' now goes to the first
of them, the bottommost one, before it goes on to the beginning of the
branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:42:48 +01:00
Stefan HallerandClaude Opus 5.5 7426d7f934 Don't let "go to bottom" in the commits panel go up
The command went to the commit above the first merged one whenever the
commit below the selection wasn't merged. It did this even if the
selection was below that commit already.

Collect the places where the command can stop, and go to the closest one
below the selection, or to the bottom if there is none. This also makes
it easy to add more places to stop at.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:41:57 +01:00
Stefan HallerandClaude Opus 5.5 381c532b14 Add a test showing that "go to bottom" in the commits panel can go up
If the history of a branch interleaves merged and unmerged commits, for
example because master was merged into the branch, pressing '>' on a
merged commit that an unmerged one follows selects a commit above it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:41:25 +01:00
Stefan HallerandClaude Opus 5.5 97aeaf77a5 Unify the "go to bottom" logic of the two commit list contexts
The local commits and the sub-commits contexts had identical copies of
it. We are going to make it smarter, so make sure the copies don't
drift apart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:40:28 +01:00
Stefan HallerandClaude Opus 5.5 89c6f0ce5a Don't mark branches merged into a local main branch in the commits list
If a branch was merged into a local main branch, but the main branch
wasn't pushed yet, the commits list still marks the head of the branch
as part of a stack. For example, after merging wip into master locally,
the commits of master show a marker at the head of wip.

Pushing and pulling a stack leave such branches out since #6169, and the
markers disappear as soon as the main branch is pushed. Leave them out
of the markers too, so that the markers show the same stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:40:06 +01:00
Stefan HallerandClaude Opus 5.5 c84a181de9 Extract finding the commits merged into a local main branch
The commits list will need this to decide which branches to mark. It
renders the list again whenever the selection changes, so stop the walk
at merged commits. Their parents are merged too, and a local main branch
is usually merged itself, so there is mostly nothing left to walk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:38:05 +01:00
Stefan HallerandClaude Opus 5.5 4ba8f7c175 Move BranchesBelowInStack to a new branchstack package
The commits list will need it to mark the branches of a stack, and so
will the "go to bottom" command of the commits panel to find their
beginnings. Neither the presentation nor the context package can import
helpers.

Rename it to BranchesBelow, since the name of the package says that it
is about stacks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 12:36:41 +01:00
Stefan Haller d3c0ca6ecf Merge v0.66.3 to master (#6190) 2026-11-08 08:45:02 +01:00
Stefan Haller 5a8adefd53 Merge v0.66.3 into master 2026-11-08 08:30:13 +01:00