Commit graph

770 commits

Author SHA1 Message Date
Chris McDonnell 737a99b1c8 Add integration tests showing resetting to duplicate named tags and branches 2025-06-04 20:43:01 +02:00
Elias Assaf fdf9726c37 Use branchPrefix on moving commits to a new branch
Signed-off-by: Elias Assaf <elyas51000@gmail.com>
2025-05-29 22:39:26 +02:00
Stefan Haller 3cff48437e Add user config gui.addRootItemInFileTree 2025-05-24 18:17:25 +02:00
Chris McDonnell e67bc45d48 Split behavior of rendering allBranchesLogCmd and switching to next cmd
This now allows for leaving the status panel and returning back to the
same log command. Previously any return to the status panel would result
in the next command in the list being shown. Now, you need to press `a`,
with a log command being rendered, to rotate to the next
allBranchesLogCmd.
2025-05-21 08:17:09 +02:00
Stefan Haller f6d13330dd Add custom patch command "Move patch into new commit before the original commit"
This is often useful to extract preparatory refactoring commits from a bigger
one.
2025-05-10 18:57:28 +02:00
Stefan Haller 5321101276 Use 'break' instead of 'edit' for BeginInteractiveRebaseForCommit with merge commit
BeginInteractiveRebaseForCommit is used for all the patch commands, and for
rewording. It works by setting the commit we want to stop at to 'edit'; this
doesn't work for merge commits. This wasn't a problem for the patch commands so
far, because you typically don't use custom patches with merge commits (although
we don't prevent this; maybe we should?).

However, it was a problem when you tried to reword a merge commit; this
previously failed with an error, as the test added in the previous commit
demonstrated.

Also, we want to add a new patch command that has to stop *before* the selected
commit (pull patch to new commit before the original one), and this wouldn't
work for the first commit in a feature branch, because it would have to set the
last commit before that to 'edit', which isn't possible if that's a merge (which
is likely).

To fix all this, use a 'break' before the selected commit if the commit is a
merge. It is important that we only do it in that case and not always, otherwise
we would break the new regression tests that were added a few commits ago.
2025-05-10 18:44:31 +02:00
Stefan Haller 50b2aa5843 Add test for rewording a merge commit
This currently fails with an error.
2025-05-10 18:19:35 +02:00
Stefan Haller b02441cdca Regression test for moving custom patch to new commit from last commit of a stacked branch
I almost broke this during the development of this branch, so add a test to
guard against that. The point here is that the stack remains intact, i.e. the
newly created commit is the last commit of the lower branch, and thus shows the
"*".
2025-05-10 18:19:35 +02:00
Stefan Haller 0c0f95168c Regression test for renaming the last commit of a stacked branch
I almost broke this during the development of this branch, so add a test to
guard against that. The point here is that the stack remains intact, i.e. the
renamed commit is the head of the lower branch, and thus shows the "*".
2025-05-10 18:19:09 +02:00
Stefan Haller 144565ee03 Cleanup: remove unnecessary setup steps 2025-05-10 18:15:42 +02:00
Chris McDonnell 1028f8efb8 Migrate deprecated AllBranchesLogCmd to AllBranchesLogCmds
This solves https://github.com/jesseduffield/lazygit/issues/3961 because
we no longer have a combination of the default and the user defined
list. We just have the user defined list.
2025-05-06 23:33:17 -04:00
Stefan Haller a9f9dee30d Combine customCommand's subprocess, stream, and showOutput fields into a single output enum 2025-05-01 15:46:06 +02:00
Stefan Haller 6402c830d5 Remove space after rebase todo
This is very old; I can only guess that this was added at a time where today's
list column handling wasn't in place yet, so the space was needed to separate
columns. This now causes a gap of two spaces between the rebase todo column and
the author column, which I'm sure wasn't intended. Funny that I never noticed.
2025-04-29 11:30:37 +02:00
Stefan Haller da24deb881 Allow changing diff context size and rename threshold when main view is focused 2025-04-23 08:38:46 +02:00
Stefan Haller 30868eead8 Add new command "Move commits to new branch" 2025-04-21 18:12:50 +02:00
Stefan Haller eaaa937315 Add config for auto-forwarding branches after fetching 2025-04-21 18:06:09 +02:00
Stefan Haller acfa024915 Allow clicking in main view to focus it 2025-04-21 18:03:24 +02:00
Stefan Haller 2a2705dcc3 Always render diffs to the main/secondary context pair, even for files
Previously we would render the diff for a directory to the main/secondary pair,
but a diff for a file to the staging/stagingSecondary pair. (And similar for
commit files: main/secondary for directories, but
patchBuilding/patchBuildingSecondary for files.)

I always found this confusing and couldn't really understand why we are doing
this; but now it gets in my way because I want to attach a controller to
main/secondary so that they can be focused. So change it to always use the main
context pair for everything we render from a side panel.
2025-04-21 18:03:18 +02:00
Stefan Haller 74054c9d70 Remove the "YOU ARE HERE" marker
Now that we have sections, it is no longer needed.

Keep the "<-- CONFLICTS" marker though.
2025-04-20 16:06:15 +02:00
Stefan Haller 6cbc1e0ace Add section headers for rebase todos, cherry-picks, reverts, and actual commits 2025-04-20 16:06:15 +02:00
Stefan Haller e90a3dc666 Fix view selection running out of sync with list selection when view isn't focused
When rerendering a view at the end of a refresh, we call HandleFocus only if the
view has the focus. This is so that we rerender the main view for the new
selection.

What was missing here is to update the view selection from the list selection if
the view doesn't have the focus, so that the selection is painted properly.
Normally this is not relevant because you don't see the selection if another
side panel has the focus; however, you do see it as an inactive selection when
e.g. a popup is shown, in which case it does matter.

This will become more important when we introduce section headers for commits,
because in that case the view selection needs to change when the working copy
state changes from normal to rebasing or vice versa, even if the list selection
stays the same.

The changed test submodule/reset.go shows how this was wrong before: when
entering the submodule again after resetting, there is a refresh which keeps the
same branch selected as before (master); however, since the branches panel is
not focused, the view didn't notice and kept thinking that the detached head is
selected (which it isn't, you can tell by running the test in sandbox mode and
focusing the branches panel at the end: you'll see that master is selected). So
the change in this commit fixes that.
2025-04-20 16:06:15 +02:00
Stefan Haller 945b023eb5 Support range selection for reverting commits 2025-04-20 16:03:06 +02:00
Stefan Haller f14a3cdd46 Remove the "Select parent commit" prompt when reverting a merge commit
In pretty much 100% of the cases, you want to use -m1, so spare users the
complexity of a confusing prompt.

See
https://public-inbox.org/git/e60a8b1a-98c8-4ac7-b966-ff9635bb781d@haller-berlin.de/
for some discussion.
2025-04-20 16:03:06 +02:00
Stefan Haller 108054efc6 Allow cherry-picking merge commits
Now that we use git cherry-pick to implement it, there's no reason not to.
2025-04-20 15:59:48 +02:00
Stefan Haller 4b35434eba Use "git cherry-pick" for implementing copy/paste of commits
We do this because
- it's closer to what you would do on the command line
- it simplifies the code a bit
- it will allow us to support cherry-picking merge commits.
2025-04-20 15:59:48 +02:00
Stefan Haller b350876f84 Disallow any changes to commits or todos when cherry-picking or reverting
We treat the .git/sequencer/todo file as read-only. Technically it seems it
would be possible to treat it as modifiable in the same way as
.git/rebase-merge/git-rebase-todo, effectively turning a cherry-pick or revert
that stops at a conflict into an interactive rebase; however, git itself doesn't
allow this (there is no "git cherry-pick --edit-todo"), so it seems safer not to
rely on it.

Theoretically it would be possible to allow modifying the rebase todos when a
cherry-pick or revert conflicts in the middle of a rebase. However, it would
introduce a bit of complexity to support this, as we would have to be able to
distinguish between rebasing todos and cherry-picking/reverting todos, which we
currently can't; it could also be a bit error-prone as far as edge cases are
concerned. And it's really a pretty uncommon situation, so it doesn't seem worth
it, and we just forbid all modifications to todos whenever we are cherry-picking
or reverting.
2025-04-20 15:55:44 +02:00
Stefan Haller 5ba8d42c80 Fix the bug described in the previous commit
What happens here is that when stopping on an "edit" todo entry, we rely on the
assumption that if the .git/rebase-merge/amend file exists, the command was
successful, and if it doesn't, there was a conflict. The problem is that when
you stop on an edit command, and then run a multi-commit cherry-pick or rebase,
this will delete the amend file. You may or may not consider this a bug in git;
to work around it, we also check the existence of the rebase-merge/message file,
which will be deleted as well by the cherry-pick or revert.
2025-04-20 15:55:44 +02:00
Stefan Haller 9b88052a4e Add test demonstrating problem with revert (or cherry-pick) during a rebase
This problem can't happen inside of lazygit itself right now, but this will
change in the future. It will only happen when you stopped in an interactive
rebase on an "edit" entry, and then you perform a revert or cherry-pick
consisting of more than one commit; in this situation lazygit will show a
conflict although there is none.

This is not possible with lazygit yet, as we don't support range-select for
reverting, and we don't use `git cherry-pick` for cherry-picking. Both will
change in the future, so it's good to fix this bug.
2025-04-20 15:55:44 +02:00
Stefan Haller 6b6d881624 Add test to check that an "edit" entry correctly shows a conflict
This works correctly, we are only adding this as a regression test to verify
that the change later in this branch doesn't break it.
2025-04-20 15:55:44 +02:00
Stefan Haller bb4d03db1f Show todos (and conflicting commit) for cherry-pick and revert 2025-04-20 15:55:44 +02:00
Stefan Haller ff465e2581 Show original todo action instead of "conflict", and show <-- CONFLICT instead
It is useful to see if the conflicted commit was a "pick" or an "edit". What's
more, we're about to add support for showing cherry-picks and reverts, and
seeing that a conflicted commit was a revert is important because its diff is
backwards compared to the diff of the conflicting files in the Files panel.
2025-04-20 15:55:44 +02:00
Stefan Haller 3e5024480d Check for conflicts after reverting a commit
This way we get the usual menu for viewing the conflicts or aborting, like for
rebases.
2025-04-20 15:53:17 +02:00
Stefan Haller 4b3262ab3e Add test for reverting a commit that conflicts
This works already (except that the "you are here" marker is not right yet, but
that's an issue for another PR), just add a test that verifies it.
2025-04-20 15:53:17 +02:00
Stefan Haller 362678e2ef Mention which command is continued in PromptToContinueRebase
When you are in the middle of a rebase, and you cherry-pick a commit which
conflicts, it helps to be clear on whether you are prompted to continue the
cherry-pick or the rebase.
2025-04-20 15:53:17 +02:00
Stefan Haller e1eb95b2b3 Add test for a special situation in rebases involving empty commits
The situation is that you perform a rebase, and one of the commits becomes empty
during the rebase, in a way that couldn't be predicted before the rebase
started. To explain: git rebase has some logic where it immediately discards
commits if it can tell that they already exist in the branch being rebased onto;
it does this by looking at the patch ids of the commits to work out which
commits already exist upstream. But for those commits that become empty even
though there isn't a corresponding commit upstream, git stops with an error, and
lazygit detects this (in CheckMergeOrRebaseWithRefreshOptions) and automatically
continues the rebase.

This all works fine; I'm adding this test because I almost broke this during
development of this branch, so I'm adding it to guard against regressions.
2025-04-20 15:53:17 +02:00
Stefan Haller b0ab6529c1 Escape special characters when git-ignoring files 2025-04-13 18:25:24 +10:00
Stefan Haller 41f89d86f0 Add test that shows problems with git-ignoring files with special characters
For #, !, [, and ], the problem is that it doesn't ignore the file because the
special characters need to be quoted. For *, the problem is that it ignores too
much (it also hides the abc_def file because the * is treated as a glob).
2025-04-13 18:25:24 +10:00
Stefan Haller 80b5e21bd5 Add a command to select all commits of the current branch
This is useful for seeing the combined diff of all commits of a branch.
2025-04-10 09:02:09 +02:00
Stefan Haller ced70903ec Prefill the commit subject with the skipHook prefix when pressing w
We removed prefilling the skipHook prefix in b102646b20 with the intention of
making it clearer that using the prefix in normal commits and typing `w` to skip
hooks are now two independent features.

It turns out that some people liked it with prefilling the prefix and perceive
it as a regression, so put it back in.

But only if we don't have a preserved message; this is an important use case,
when you try to make a normal commit, the hook fails, and then you want to make
the same commit with skipping the hook, but with the same message that you
already typed.
2025-04-10 08:53:11 +02:00
Ruud Kamphuis 12820481e6 Add runCommand function to Go template syntax
This makes it possible to use date and time in initial values like this:

```yaml
initialValue: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'
```

I want to use this to configure my BranchPrefix like this:

```yaml
git:
  branchPrefix: 'ruudk/{{ runCommand "date +\"%Y/%-m\"" }}/'
```
2025-04-09 10:44:36 +02:00
Ruud Kamphuis c7feba9bb1 Move test from commit to branch 2025-04-09 10:44:36 +02:00
Stefan Haller 82e1caa166 Remove conditional code related to git earlier than 2.22 2025-04-09 10:40:52 +02:00
Stefan Haller ebb576feac Provide conflict resolution dialogs for non-textual conflicts 2025-04-09 10:27:57 +02:00
Stefan Haller b09251e27b
Merge branch 'master' into fix-display-of-renamed-files-in-tree-view 2025-04-08 16:17:33 +02:00
Stefan Haller 59af407eb1 Fix the bug described in the previous commit 2025-04-08 16:14:31 +02:00
Stefan Haller f20b7ea593 Add test demonstrating problem with main view display when pressing e in a stack of branches
We keep the same commit selected (even though its index changed because of the
added update-ref todo), which is nice; however, the main view shows the diff of
the wrong commit, which is very confusing. I'm suprised that this hasn't been
noticed yet.

The reason why this happens is that we first do the refresh, which includes
re-rendering the main view diff (with the same commit index as before, so the
wrong one), and then we restore the correct commit index but don't render the
main view again.
2025-04-08 16:14:31 +02:00
Brandon f75c0af6e0 Update disabled message 2025-04-07 09:42:19 +02:00
Brandon 2db0a024bc Add integration test 2025-04-07 09:42:19 +02:00
Stefan Haller b0b8ef9cf6 Fix display of renamed files
This broke with #4346 (Add root node in file tree).
2025-04-02 18:15:44 +02:00
Stefan Haller 267ef70de6 Add test showing problem with the display of renamed files
Renaming a file inside the same directory shows it with its full path in the
tree view, which isn't what we want. We'll fix this in the next commit.

Also adding a few other test cases for moving files; they show that the display
of moved files in tree view isn't ideal. For example, moving file1 from top
level into dir shows it as "R file1 → file1", which isn't distinguishable from
renaming file1 inside dir. I suppose what we would like to have here is
"R ../file1 → file1" or something, but I'll leave that for the future; here I
only want to fix the regression that was introduced with the root item PR.
2025-04-02 18:15:27 +02:00
gaogao-qwq 3a03aebd89
feat: Implement range stash drop
Signed-off-by: gaogao-qwq <gaogaoqwq@gmail.com>
2025-04-02 17:34:35 +08:00
Stefan Haller a8f6b04ff3 Add "Absolute path" item to the file view's copy menu
Rename the existing item to "Relative path".
2025-03-25 10:00:56 +01:00
Stefan Haller d2059df543 Fix the bug mentioned in the previous commit 2025-03-25 09:56:01 +01:00
Stefan Haller 61c56c7822 Add test for checking out a file from a range selection of commits
The test shows a misbehavior: even though the diff shows "-one" and "+three",
meaning that "three" is the state we want to check out, we get "one". The reason
is that the checkout file command doesn't pay attention to range selections, it
only looks at the "moving end" of the range. Had we created the range by
selecting "two" and then pressed shift-up to "three", we would have gotten the
expected result.
2025-03-25 09:56:01 +01:00
Stefan Haller ac7d8ad025 Add test for checking out a file from a commit
This works, we just didn't have a test for it.
2025-03-25 09:56:01 +01:00
Korbinian Schweiger b102646b20 Commit without pre-commit hooks is independent on prefix
Add verify flag

Add and update integration tests

Rename verify to forceSkipHooks

Adapt CommitSkipHooks integration test to actually use a hook

Remove forceSkipHooks param from OnConfirm et al

Simplify tests
2025-03-22 11:04:28 +01:00
Stefan Haller 26459523f5 Add a root item ("/") if files at top level have changed 2025-03-21 08:04:58 +01:00
Stefan Haller 0b5504aa98 Cleanup: make integration test assertions for files panel more specific
Assert the entire lines using Equals instead of Contains. This makes the tests a
bit easier to read, and it makes it much easier to decide how they need to be
changed when we change the layout (like we do in the last commit of this
branch).

It is true that this requires changing all these tests for any future UI
changes, but I think this is a good price to pay; those adaptions are trivial
and can be done without thinking.
2025-03-20 11:58:50 +01:00
Stefan Haller 030c2e5aef Fix postFilterTest to actually do what it says
I'm pretty sure that the check for the main view was meant to be done with the
commit selected in the commits panel, not with the first file of the commit
files view selected, so it was pressing enter too early. It's pure coincidence
that the test worked.
2025-03-20 11:58:50 +01:00
Stefan Haller f7295a97c0 Add a "Content of selected file" entry to the copy menu for commit files
This is useful for copying the entire content of the selected file as it was at
the selected commit.

We only add it to the commit files panel; it is not needed in the files panel,
because there you can simply press "e" to edit the file.
2025-03-20 11:52:53 +01:00
Partho Kunda 7a1b63182d Commit only tracked files in tracked only filter view 2025-03-17 19:51:27 +01:00
Partho Kunda 220f06052a Show staged but untracked files in tracked only filter view 2025-03-17 19:50:58 +01:00
Kevin Radloff b76b73943a Add an integration test for a config with a negative refspec 2025-03-11 08:33:41 +01:00
Stefan Haller 22512d55a8 Add commandMenu property to custom commands 2025-02-28 10:11:30 +01:00
Stefan Haller f93948cb23 Change customCommand fields to pointers
This allows us to tell whether they appear in the user's config file, which we
will need later in this branch.
2025-02-28 10:00:59 +01:00
Stefan Haller 0df5e08828 Don't set showOutput explicitly
It is false by default. This way there's one less change to make in the next
commit.
2025-02-28 10:00:59 +01:00
Chris McDonnell b766ff9c83 Disable global keybinds while popups are active 2025-02-23 08:44:48 +01:00
Stefan Haller c9196812a2 Add a "Copy to clipboard" menu to the Commit Files panel
This is very similar to the same menu in the Files panel, except that it works
on whatever diff is currently shown in the main view, including range diffs
either in diffing mode (shift-W), or from a range selection of commits.
2025-02-19 18:50:12 +01:00
Stefan Haller caca62b89e Cleanup: simplify and tighten test expectations related to clipboard
Change our fake clipboard command to not append a linefeed; that's closer to
what the production code does.

This allows us to use Equals instead of Contains for checking the clipboard
contents.

Finally, use FileSystem().FileContent() to assert the clipboard contents,
instead of selecting the clipboard file and then checking the diff view.
2025-02-19 18:50:12 +01:00
Chris McDonnell 2fa4ee2cac feat: Support multiple commit prefixes
This implementation, unlike that proposed in https://github.com/jesseduffield/lazygit/pull/4253
keeps the yaml schema easy, and does a migration from the single
elements to a sequence of elements.
2025-02-17 19:58:31 +01:00
Chris McDonnell ab23539c0c Add option to copy commit message body 2025-02-17 18:43:39 +01:00
Stefan Haller e987d4b519 Swap position of checkout-commit and checkout-branch menu items
Jesse's comment from https://github.com/jesseduffield/lazygit/issues/4237:

We recently added a new option to check out a commit's branch from within the
commits, reflog, and sub-commits panels:

https://github.com/user-attachments/assets/0a5cf3f2-6803-4709-ae5a-e4addc061012

After using it for some time, I find it annoying that the default option has
changed. I rarely find myself wanting to check out a branch from the commits
panel, and it's rarer still to want to check out a branch from the reflog and
sub-commits panel. Although there may be use cases for this, it is jarring that
something you can always do (checkout the commit) is harder to do than something
that you can sometimes do (checkout the branch).

We've also had a user complain (see
https://github.com/jesseduffield/lazygit/pull/4117) about their muscle-memory
being broken by the recent change, and I have also fallen victim to this. I
don't think that the new branch checkout option is sufficiently useful to
dislodge the existing keybinding, so let's swap them.
2025-02-10 13:35:01 +01:00
Stefan Haller ff4ae4a544 Fix possible crash when deleting a branch while filtering is active
The code that tries to reselect the same branch again uses GetItems, which in
case of filtering is the filtered list. After replacing the branches slice with
a new one, the filtered list is no longer up to date, so we must reapply the
filter before working with it. It so happens that refreshView does that, so
simply call that before setting the selection again; I don't think the order
matters in this case. Otherwise we'd have to insert another call to
ReApplyFilter before the call to GetItems, which we can avoid this way.

Note that this doesn't actually make anything work better in the case of
deleting a branch, since we can't reselect the deleted branch anyway of course.
But it avoids a possible crash if the branch that was deleted was the last one
in the unfiltered list.
2025-02-07 09:34:25 +01:00
AzraelSec 6065908b0d Improve and adapt commit persistence test-cases 2025-02-07 09:28:27 +01:00
Stefan Haller 2f4cedd025 Show current files filter as radio buttons
I renamed the "Reset filter" item to "No filter" to make it look more like a
state than an action, so that it fits the radio button concept better.

When there are conflicts and we set the filter to show only conflicting files,
then none of the radio buttons light up, which is slightly strange. I guess it's
ok though.
2025-02-07 09:24:24 +01:00
Jesse Duffield 7e85cdd027 Allow user to filter the files view to only show untracked files
This handles the situation where the user's own config says to not show
untracked files, as is often the case with bare repos managing a user's
dotfiles.
2025-02-07 09:04:55 +11:00
Brandon 02ca07a9be Fix incorrect stash diff after rename 2025-02-06 09:55:26 +01:00
Bruno Jesus 4856c96521 Fix tag truncated when copying to clipboard
Copy the whole tag to clipboard instead of truncating to the value of
TruncateCopiedCommitHashesTo.
2025-02-03 21:25:34 +00:00
Stefan Haller 0a78d0016e Show confirmation menu when trying to amend changes while there are conflicts 2025-01-30 08:53:34 +01:00
Anvar Umuraliev 7db8fb8e9c Add option to delete local and remote tag 2025-01-30 09:05:17 +11:00
Bruno Jesus 632695f71c Integration tests for copy tags to clipboard
Adds integration test in order to confirm if tags are being properly
sent to the clipboard
2025-01-28 00:34:57 +00:00
Stefan Haller 4baf008ac7 Expose {{.SelectedCommitRange}} to custom commands
It has fields .To and .From (the hashes of the last and the first selected
commits, respectively), and it is useful for creating git commands that act on a
range of commits.
2025-01-27 08:53:50 +01:00
Gabriel Lanata 4065175a58 Improve undo action to restore files upon undoing a commit 2025-01-18 00:07:15 +11:00
Mauricio Trajano 7bea41534b Collapse/expand all files in tree
Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
2025-01-13 21:13:11 +01:00
Brandon c44231a7d7 Add number of commits to cherry-pick confirmation prompt 2025-01-08 21:08:42 -08:00
Stefan Haller 64cd7cd9f6 Adjust line number for working copy when editing a line
There are two ways to jump to the editor on a specific line: pressing `e` in the
staging or patch building panels, or clicking on a hyperlink in a delta diff. In
both cases, this works perfectly in the unstaged changes view, but in other
views (either staged changes, or an older commit) it can often jump to the wrong
line; this happens when there are further changes to the file being viewed in
later commits or in unstaged changes.

This commit fixes this so that you end up on the right line in these cases.
2025-01-07 17:46:51 +01:00
Stefan Haller 1c5fe8ff17 Add a test demonstrating the problem
When pressing `e` on line 5 in a diff of an older commit, we expect it to take
us to line 5 in that file. But we end up on line 2, because the file had further
changes both in newer commits, and in the unstaged changes of the working copy.
2025-01-07 17:46:51 +01:00
Stefan Haller ae53059ed2 Bump gocui
This updates gocui to include https://github.com/jesseduffield/gocui/pull/68 and
https://github.com/jesseduffield/gocui/pull/69, which changes views to not have
an extra blank line at the end when content ending in a newline character is
written to them. This makes text views more consistent with list views, which
don't have a blank line after the last list entry either.
2025-01-07 17:34:30 +01:00
Stefan Haller 009062534e Fix resetting or rebasing a branch to its upstream when the upstream branch name is different 2025-01-04 15:48:26 +01:00
Stefan Haller 33e81f717d Extend reset/rebase test to use upstream branch name that is different from local one
The easiest way to do that is to rename the local branch after pushing.

This shows various levels of brokenness for the reset and rebase to upstream
commands: both menu entries display the wrong upstream branch name in the menu
(the local one rather than the remote one); executing the rebase command works
correctly though, the rebase command uses the right branch name. Resetting
fails, though.

We'll fix this in the next commit.
2025-01-04 15:46:14 +01:00
Nathan Baulch 508cdb40a8 Fix typos 2025-01-03 10:50:36 +11:00
John Mutuma e1c18226bf Add worktree option to fast forwarding operation 2025-01-02 16:52:24 +11:00
Jesse Duffield 621229bb09 Default to half-screen mode when filtering files or using the git-arg CLI arg
It should have been half-screen from the get-go. I think I just used
full-screen to make demos look nicer. Now that we have a CLI arg for the
screen mode we can make use of that in the demos.
2025-01-02 16:10:58 +11:00
Sebastian Flügge f4c8287143 Allow to switch branches in Commit View
When the user checks out a commit which has a local branch ref attached
to it, they can select between checking out the branch or checking out
the commit as detached head.
2025-01-01 14:55:12 +01:00
Stefan Haller 3a30211099 Don't preserve commit message when it's unchanged from initial message
Sometimes we populate the commit message panel with a pre-created commit
message. The two cases where this happens is:
- you type `w` to commit, in which case we put the skipHookPrefix in the subject
- you have a commitPrefix pattern, in which case we match it against the branch
  name and populate the subject with the replacement string if it matches

In either case, if you have a preserved commit message, we use that.

Now, when you use either of these and then cancel, we preserve that initial,
unchanged message and reuse it the next time you commit. This has two problems:
it strips spaces, which is a problem for the commitPrefix patterns, which often
end with a space. And also, when you change your config to experiment with
commitPrefix patterns, the change seemingly doesn't take effect, which can be
very confusing.

To fix both of these problems, only preserve the commit message when it is not
identical to the initial message.
2024-12-23 12:28:52 +01:00
Stefan Haller ec92d92bf4 Extend commitPrefix test to cancel without changing the commmit message
The test shows that we lose a space when cancelling and committing again.
2024-12-23 12:28:52 +01:00
Stefan Haller 87d5da511e Cleanup: reformat to make the test setup code easier to read
- break it to separate lines
- use backticks for pattern so we need less quoting
- don't unnecessarily quote forward slash in pattern
2024-12-23 12:28:52 +01:00
Stefan Haller a9ef69b9c7 Fix moving a commit across a branch boundary in a stack
See the previous commit for a detailed explanation.
2024-12-23 12:18:48 +01:00
Stefan Haller cf27974ea3 Add test for moving a commit across a branch boundary in a stack
The test demonstrates that the behavior is undesirable right now: we move the
commit only past the update-ref todo of branch1, which means the order of
commits stays the same and only the branch head icon moves up by one. However,
we move the selection down by one, so the wrong commit is selected now. This is
especially bad if you type a bunch of ctrl-j quickly in a row, because now you
are moving the wrong commit.

There are two possible ways to fix this:
1) keep the moving behavior the same, but don't change the selection
2) change the behavior so that we move the commit not only past the update-ref,
   but also past the next real commit.

You could argue that 1) is the more desirable fix, as it gives you more control
over where exactly the moved commit goes; however, it is much trickier to
implement, so we go with 2) for now (and that's what the commented-out
"EXPECTED" section documents here). If users need more fine-grained control,
they can always enter an interactive rebase first.
2024-12-23 12:18:48 +01:00
Stefan Haller 078445db63 Allow deleting a merge commit
For non-merge commits we change "pick" to "drop" when we delete them. We do this
so that we can use the same code for dropping a commit no matter whether we are
in an interactive rebase or not. (If we aren't, we could just as well delete the
pick line from the todo list instead of setting it to "drop", but if we are, it
is better to keep the line around so that the user can change it back to "pick"
if they change their mind.)

However, merge commits can't be changed to "drop", so we have to delete them
from the todo file. We add a new daemon instruction that does this.

We still don't allow deleting a merge commit from within an interactive rebase.
The reason is that we don't show the "label" and "reset" todos in lazygit, so
deleting a merge commit would leave the commits from the branch that is being
merged in the list as "pick" commits, with no indication that they are going to
be dropped because they are on a different branch, and the merge commit that
would have brought them in is gone. This could be very confusing.
2024-12-23 12:12:45 +01:00
Stefan Haller debfe1a21f Improve editing a commit
In 67b8ef449c we changed the "edit" command to insert a "break" after the
selected commit, rather than setting the selected todo to "edit". The reason for
doing this was that it now works for merge commits too.

Back then, I claimed "In most cases the behavior is exactly the same as before."
Unfortunately that's not true, there are two reasons why the previous behavior
was better (both are demonstrated by tests earlier in this branch):
- when editing the last commit of a branch in the middle of a stack of branches,
  we are now missing the update-ref todo after it, which means that amending the
  commit breaks the stack
- it breaks auto-amending (see the added test earlier in this branch for an
  explanation)

For these reasons, we are going back to the previous approach of setting the
selected commit to "edit" whenever possible, i.e. unless it's a merge commit.

The only scenario where this could still be a problem is when you have a stack
of branches, and the last commit of one of the branches in the stack is a merge
commit, and you try to edit that. In my experience with stacked branches this is
very unlikely, in almost all cases my stacked branches are linear.
2024-12-01 11:05:45 +01:00
Stefan Haller 016d46526c Add test for editing several commits right after a merge commit
This is very similar to edit_range_select_outside_rebase.go, except that it
selects commits right after, and including, a merge commit.

This test already works correctly. The reason we add it is that we are going to
have two different implementations of the `e` command depending on whether the
last selected commit is a merge commit, and we want to make sure they both work
with a range selection.
2024-12-01 11:05:45 +01:00
Stefan Haller 0766b14afd Add test to auto-amend a commit after pressing e on it
Auto-amending is a little-known feature of git that is very convenient once you
know it: whenever you stop at a commit marked with `edit` in an interactive
rebase, you can make changes and stage them, and when you continue the rebase
they automatically get amended to the commit you had stopped at. This is so
convenient because making changes to a commit is one of the main reasons why you
edit a commit.

Unfortunately this currently doesn't work in lazygit because we don't actually
use `edit` to stop at the first commit (instead, we add a `break` todo after it,
which doesn't have the auto-amend functionality).

We'll improve this later in this branch.
2024-12-01 11:05:45 +01:00
Stefan Haller 4624d496a2 Add test for editing the last commit of a branch in a stack
The test demonstrates that the "update-ref" todo after the selected commit is
missing, which means when we amend the commit it'll break the stack.
2024-12-01 11:05:45 +01:00
Stefan Haller ea03ae5ee3 Cleanup: remove a no-op Focus() call 2024-12-01 11:05:45 +01:00
Stefan Haller c1b4201726 Allow deleting a range selection of branches
We allow deleting remote branches (or local and remote branches) only if *all*
selected branches have one.

We show the a warning about force-deleting as soon as at least one of the
selected branches is not fully merged.

The added test only tests a few of the most interesting cases; I didn't try to
cover the whole space of possible combinations, that would have been too much.
2024-12-01 10:59:54 +01:00
Stefan Haller 0b0910573b Extract test helper function checkRemoteBranches
We'll need it a few more times in the next test we add.
2024-12-01 10:59:54 +01:00
Moritz Haase 949e131ebe pkg/gui: Allow user to select remote and branch when creating a PR
When creating a PR against a selected branch (via O = "create pull request
options"), the user will first be asked to select a remote (if there is more
than one). After that, the suggestion area is populated with all remote branches
at that origin - instead of all local ones. After all, creating a PR against a
branch that doesn't exist on the remote won't work.

Please note that for the "PR is not filed against 'origin' remote" use case
(e.g. when contributing via a fork that is 'origin' to a GitHub project that is
'upstream'), the opened URL will not be correct. This is not a regression and
will be fixed in an upcoming PR.

Fixes #1826.
2024-11-23 11:52:21 +11:00
LU Jialin dd765801db add test case for decreasing Diff Context length to zero 2024-11-19 08:21:19 +11:00
Harris Greenstein 8da43af924 Add config option to disable tab switching with jump keys 2024-11-09 17:19:14 +11:00
Stefan Haller a58770ee1b Fix pressing shift-down after clicking in diff view
When clicking in a single-file diff view to enter staging (or custom patch
editing, when coming from the commit files panel), and then pressing shift-down
or shift-up to select a range, it would move the selected line rather than
creating a range. Only on the next press would it start to select a range from
there.

This is very similar to the fix we made for pressing escape in 0e4d266a52.
2024-10-18 10:08:27 +02:00
Stefan Haller 7655f6864e Add test demonstrating a bug with clicking in the staging view
When clicking in the main view to enter staging, and then pressing shift-down to
select a range, it moves the selection rather than selecting a two-line range.
We'll fix this in the next commit.
2024-10-18 10:08:27 +02:00
Stefan Haller 85523402d6 Allow pasting commits more than once
After pasting commits once, we hide the cherry-picking status (as if it had been
reset), and no longer paint the copied commits with blue hashes; however, we
still allow pasting them again. This can be useful e.g. to backport a bugfix to
multiple major version release branches.
2024-10-13 16:55:54 +02:00
Stefan Haller 696e78fcc8 Fix ForEachLineInFile to not lose the last line if it doesn't end with a LF 2024-10-09 15:37:08 +02:00
Stefan Haller b71aa5e23b Add regression test for resolving conflicts in a file without a trailing LF
The test shows that the last line of the file is lost.
2024-10-09 15:36:02 +02:00
Stefan Haller 1ab70ec645 Add a menu item to delete both local and remote branch at once 2024-09-28 11:23:21 +02:00
Stefan Haller c712b1d0fe Better local branch delete confirmation
Currently we try to delete a branch normally, and if git returns an error and
its output contains the text "branch -D", then we prompt the user to force
delete, and try again using -D. Besides just being ugly, this has the
disadvantage that git's logic to decide whether a branch is merged is not very
good; it only considers a branch merged if it is either reachable from the
current head, or from its own upstream. In many cases I want to delete a branch
that has been merged to master, but I don't have master checked out, so the
current branch is really irrelevant, and it should rather (or in addition) check
whether the branch is reachable from one of the main branches. The problem is
that git doesn't know what those are.

But lazygit does, so make the check on our side, prompt the user if necessary,
and always use -D. This is both cleaner, and works better.

See this mailing list discussion for more:
https://lore.kernel.org/git/bf6308ce-3914-4b85-a04b-4a9716bac538@haller-berlin.de/
2024-09-28 11:19:32 +02:00
Stefan Haller c4e5995cb9 Fix bug with deleting remote branch whose name doesn't match local branch 2024-09-28 11:19:32 +02:00
Stefan Haller be3683ccc8 Add test that demonstrates bug with deleting remote branch with different name
It's maybe not very common, but it's totally possible for a remote branch to
have a different name than the local branch. This test shows that we don't
support this properly when deleting the remote branch.
2024-09-28 11:19:32 +02:00
Stefan Haller 3d56357294 Fix copying commit author to clipboard
This was a regression introduced with the GitCommandBuilder in 25f8b0337.
2024-09-23 09:47:14 +02:00
Stefan Haller 9b2a0c4538 Add test for copying a commit author to the clipboard
The test shows that we are including single quotes in strange places.
2024-09-23 09:45:03 +02:00
Stefan Haller f8073c7188 Fix crash when viewing the divergence of a branch which is up to date with its upstream
This was introduced by #3838, specifically by commit e675025411.

Add a regression test that would have crashed without the fix.
2024-09-18 09:24:10 +02:00
Stefan Haller b22149d832 Create fixup commit at end of its branch when there's a stack of branches 2024-09-15 11:19:39 +02:00
Stefan Haller f5b8619ded Switch to Files panel after popping a stash 2024-09-06 13:15:37 +02:00
Brandon 4e880e56c4 Add integration tests for checkout/new branch with autostash 2024-09-03 09:05:53 +02:00
Stefan Haller ba21d4e651 Ask to auto-stage unstaged files when continuing a rebase after resolving conflicts 2024-09-02 18:24:36 +02:00
Stefan Haller 90b8fd242d Add config git.autoStageResolvedConflicts 2024-09-02 18:12:47 +02:00
Stefan Haller 32fef9aadb Add a simple integration test for non-sticky range diff 2024-08-28 19:51:15 +02:00
Stefan Haller b07ce19b9a Add --stat -p to diff args in diffing mode
This is consistent with what we do for showing single commits (with git show),
and I find it very useful.
2024-08-28 18:27:52 +02:00
Yaroslav Halchenko 4bbfe7b3cc [DATALAD RUNCMD] run codespell throughout fixing typos automagically
=== Do not change lines below ===
{
 "chain": [],
 "cmd": "codespell -w",
 "exit": 0,
 "extra_inputs": [],
 "inputs": [],
 "outputs": [],
 "pwd": "."
}
^^^ Do not change lines above ^^^

Signed-off-by: Yaroslav Halchenko <debian@onerussian.com>
2024-08-27 18:03:00 +02:00
Yaroslav Halchenko 00530477c9 [DATALAD RUNCMD] Do interactive fixing of some ambigous typos
=== Do not change lines below ===
{
 "chain": [],
 "cmd": "codespell -w -i 3 -C 2 ./pkg/commands/oscommands/cmd_obj_runner.go ./pkg/integration/tests/branch/rebase_and_drop.go",
 "exit": 0,
 "extra_inputs": [],
 "inputs": [],
 "outputs": [],
 "pwd": "."
}
^^^ Do not change lines above ^^^

Signed-off-by: Yaroslav Halchenko <debian@onerussian.com>
2024-08-27 18:03:00 +02:00
Yaroslav Halchenko 83ef031922 [DATALAD RUNCMD] Do interactive fixing of some ambigous typos
=== Do not change lines below ===
{
 "chain": [],
 "cmd": "codespell -w -i 3 -C 2",
 "exit": 0,
 "extra_inputs": [],
 "inputs": [],
 "outputs": [],
 "pwd": "."
}
^^^ Do not change lines above ^^^

Signed-off-by: Yaroslav Halchenko <debian@onerussian.com>
2024-08-27 18:03:00 +02:00
Stefan Haller 30f43a245b Fix loading customCommands from per-repo config file
Any newly loaded custom command coming from the per-repo config file should add
to the global ones (or override an existing one in the global one), rather than
replace all global ones.

We can achieve this by simply prepending the newly loaded commands to the
existing ones. We don't have to take care of removing duplicate key assignments;
it is already possible to add two custom commands with the same key to the
global config file, the first one wins.
2024-08-24 11:01:25 +02:00
Stefan Haller 283ed29f10 Add a test that shows how per-repo config file replaces customCommands
We want to add to the global customCommands instead of replacing them.
2024-08-24 11:01:25 +02:00
Stefan Haller d3940729eb Allow using </> and ,/. in sticky range select mode in patch explorer
They still cancel hunk selection mode, setting it to line selection mode, but if
range selection mode is on, we keep it on.
2024-08-24 10:56:20 +02:00
Stefan Haller bbd779b437 Use our new hyperlink support in the information view 2024-08-24 10:36:01 +02:00
Brandon 387bdb1b84 Don't stage already staged deleted items 2024-08-24 09:36:44 +10:00
Stefan Haller 55d8e801f1 Use getters for AppState and UserConfig instead of accessing the fields directly
This will allow us to make them private.
2024-08-18 10:24:52 +02:00
Stefan Haller 7fb758cc1d Set SelectedPath to SelectedCommitFilePath in CommitFiles context 2024-08-17 11:26:31 +02:00
Stefan Haller 22f0d9cdd3 Expose SelectedCommit to custom commands, deprecate Selected{Local,Reflog,Sub}Commit
SelectedCommit is context-dependent and points to SelectedLocalCommit,
SelectedReflogCommit, or SelectedSubCommit depending on which panel is active.

If none of these panels is active, it returns the selected local commit, which
is probably the most useful default (e.g. when defining custom commands for the
Files panel).
2024-08-17 11:26:31 +02:00
Stefan Haller dbca9306de Rename "Custom Command" to "Shell Command"
The double use of the term "Custom Command" for both shell commands and
user-configured keybindings was confusing.
2024-08-17 10:56:03 +02:00
Stefan Haller 0cbe08b105 Add new integration tests folder "shell_commands"
The folder custom_commands contained tests for both custom commands (the ones
you configure in config.yml) and shell commands (the ones you execute at the ":"
prompt). I always found this confusing, so separate these into two different
folders.
2024-08-17 10:56:03 +02:00
Stefan Haller b37d6dcd1c When using the panel jump keys and the target panel is already active, switch tabs 2024-08-17 10:37:00 +02:00
Yam Liu 542030f190 Support multiple contexts within one command, add tests, update doc 2024-08-02 11:55:29 +02:00
Yam Liu 206b2c6f0b Add a unit test case for global context 2024-08-02 11:55:29 +02:00
István Donkó b9107d5fc8 Support setting the similarity threshold for detecting renames 2024-07-13 14:24:26 +10:00
Luke Swan 968060a5ec Ensure branch name matches pattern before replace
Amend test for non-matching branch name
2024-07-10 09:05:41 +02:00
Luke Swan 07fe828f60 Add initial test for non-matching branch name 2024-07-10 09:05:33 +02:00
Martin Kock be21328c69 Allow cycling between multiple log commands
- Introduced a new optional user config command, allBranchesLogCmds
- When pressing 'a' in the Status view, cycle between non-empty, non-identical log commands
- There will always be at least one command to run, since allBranhesLogCmd has a default
- Update documentation & write an integration test
- Update translation string
2024-07-06 22:02:47 +10:00
Brandon 38aa5b89ab Simplify integration test 2024-07-06 21:22:04 +10:00
Brandon 2e5b570bb6 Add integration test 2024-07-06 21:22:04 +10:00
Elliot Cubit 5959f7bc8e Allow setting a default name when creating new branches 2024-07-06 21:06:28 +10:00
T. b26ff43d9e Update tracking behaviour for branches created from remote branches
The current behaviour when creating a new branch off of a remote branch
is to always track the branch it was created from.

For example, if a branch 'my_branch' is created off of the remote branch
'fix_crash_13', then 'my_branch' will be tracking the remote
'fix_crash_13' branch.

It is common practice to have both the local and remote branches named
the same when the local is tracking the remote one. Therefore, it is
reasonable to expect that 'my_branch' should not track the remote
'fix_crash_13' branch.

The new behaviour when creating a new branch off of a remote branch is
to track the branch it was created from only if the branch names match.
If the branch names DO NOT match then the newly created branch will not
track the remote branch it was created from.

For example, if a user creates a new branch 'fix_crash_13' off of the
remote branch 'fix_crash_13', then the local 'fix_crash_13' branch will
track the remote 'fix_crash_13' branch.
However, if the user creates a new branch called 'other_branch_name' off
of the remote branch 'fix_crash_13', then the local 'other_branch_name'
branch will NOT track the remote 'fix_crash_13' branch.
2024-07-04 22:34:36 +02:00
Noah 232be05785 feat: squash merge 2024-06-30 11:01:03 +10:00
Stefan Haller e205c6ba7f Always reapply filters on filtered views, even inactive ones 2024-06-28 08:23:27 +02:00
Stefan Haller c6df856079 Add test demonstrating a problem with updating the filter when the model changes
We only update the filter when the filtered view has the focus.
2024-06-28 08:23:27 +02:00
WaterLemons2k d146d834c2 Add command to paste commit message from clipboard
Resolves #3672
2024-06-26 22:20:54 +02:00
Stefan Haller 68c966567c Show radio buttons in the sort order menu for branches 2024-06-23 12:53:15 +02:00
Stefan Haller 4cd15a36e3 Fix custom patch operations on added files
Several custom patch commands on parts of an added file would fail with the
confusing error message "error: new file XXX depends on old contents". These
were dropping the custom patch from the original commit, moving the patch to a
new commit, moving it to a later commit, or moving it to the index.

We fix this by converting the patch header from an added file to a diff against
an empty file. We do this not just for the purpose of applying the patch, but
also for rendering it and copying it to the clip board. I'm not sure it matters
much in these cases, but it does feel more correct for a filtered patch to be
presented this way.
2024-06-23 12:40:31 +02:00
Stefan Haller 1a76a7da09 Add test for moving a patch from an added file to an earlier commit
This currently works (albeit with a bit of manual work, as the user needs to
resolve conflicts), and we add this test just to make sure that we don't break
it with the following change.
2024-06-23 12:40:31 +02:00
Stefan Haller 8a16f24ecb Add test for moving a patch from a deleted file to a new commit
This currently works, we add it as a regression test to make sure we don't break
it. It is an interesting test because it turns the deletion of the file in the
moved-from commit into a modification.
2024-06-23 12:40:31 +02:00
Stefan Haller e2b4d9cff3 Remove unneccesary test actions
Pressing enter in the patch building view does nothing.
2024-06-23 12:40:31 +02:00
Stefan Haller cf27fd827b Clear keybinding functions in resetHelpersAndControllers
When switching to a repo that was open before, the context tree is reused, so
before adding keybinding functions to those contexts again, we need to clear the
old ones.
2024-06-23 12:28:42 +02:00
Stefan Haller a7c97400c6 Add a test demonstrating the bug
After switching to another repo and then back to the original one, all
keybinding suggestions in the status bar are shown twice.
2024-06-23 12:28:42 +02:00
Stefan Haller 779e6f95a3 Assert that the search status view is visible
Just to be really sure that it not only contains the expected status text, but
also actually shows it.
2024-06-23 11:43:12 +02:00
Stefan Haller 92dd80c3e3 Suspend lazygit when continuing a rebase with exec todos
It's likely that the exec todos are some kind of lengthy build task whose output
the user will want to see in the terminal.
2024-06-12 12:45:00 +02:00
Stefan Haller 899e25b208 Show "exec" todos in the list of rebase todos
Unfortunately it isn't possible to delete them. This would often be useful, but
our todo rewriting mechanisms rely on being able to find todos by some
identifier (hash for pick, ref for update-ref), and exec todos don't have a
unique identifier.
2024-06-12 12:44:33 +02:00
Stefan Haller 7780f1264a Disregard master commits when finding base commit for fixup
If exactly one candidate from inside the current branch is found, we return that
one even if there are also hunks belonging to master commits; we disregard those
in this case.
2024-06-10 12:00:24 +02:00
Stefan Haller f9ba2dac9d Add test demonstrating the desired behavior
It has two modified hunks, one for a master commit and one for a branch commit.
Currently we get an error mentioning those two commits, but we would like to
silently select the branch commit.
2024-06-10 12:00:24 +02:00
AzraelSec 6b9cf72e79 feat: support range selection for commit attributes amend 2024-06-07 23:09:52 +02:00
AzraelSec 06496ccd17 feat: let the staging secondary panel change view mode 2024-06-07 22:51:16 +02:00
AzraelSec f6457c4def fix: update rebase_onto demo test to match new rebase menu title 2024-06-05 01:38:08 +02:00
Stefan Haller a8921a13cb Add command "Rebase onto base branch" to rebase menu 2024-06-03 14:06:11 +02:00
Stefan Haller 837f7456ab Remove target branch from title of rebase menu
Put it into the individual menu items instead.

Again, this is necessary because we are going to add another entry to the menu
that is independent of the selected branch.
2024-06-03 14:06:11 +02:00
Stefan Haller 343db7b3f1 Add command "View divergence from base branch" 2024-06-03 14:02:07 +02:00
Stefan Haller 373b1970ca Show divergence from base branch in branches list 2024-06-03 13:59:43 +02:00
Stefan Haller 5b613f5bc7 Remove ColoredBranchStatus and branchStatusColor
Previously the entire status was colored in a single color, so the API made
sense. This is going to change in the next commit, so now we must include the
color in the string returned from BranchStatus(), which means that callers who
need to do hit detection or measure the length need to decolorize it.

While we're at it, switch the order of ↑3↓7 to ↓7↑3. For some reason that I
can't really explain I find it more logical this way. The software out there is
pretty undecided about it, it seems: VS Code puts ↓7 first, and so does the
shell prompt that comes with git; git status and git branch -v put "ahead" first
though. Shrug.
2024-06-03 13:02:46 +02:00
Stefan Haller 19d0048cc4 More explicit test of status panel content
Use Equals instead of Contains for asserting the status view content. This
solves the problem that we might assert Contains("↓2 repo"), but what it really
shows is "↑1↓2 repo", and the test still succeeds. At best this is confusing.

Also, this way we don't have to use the awkward DoesNotContain to check that it
really doesn't show a checkmark.

To do this, we need to fix two whitespace problems:
- there was always a space at the end for no reason. Simply remove it. It was
  added in efb51eee96, but from looking at that diff it seems it was added
  accidentally.
- there was a space at the beginning if the branch status was empty. This is
  actually a cosmetic problem, for branches without a status the text was
  indented by once space. Change this so that the space is added conditionally.
  It's a bit awkward that we have to use Decolorise here, but this will go away
  again later in this branch.
2024-06-03 13:02:46 +02:00
Stefan Haller dbdabb34f3 Make "Find base commit for fixup" work with hunks with only added lines
To understand what this does and why, read the design document that I'm about to
add in the next commit.
2024-06-01 08:31:18 +02:00
Stefan Haller 3284d69886 Add integration test for pushing when the remote is not stored locally
The test needs all three fixes from this branch to succeed.
2024-06-01 08:12:45 +02:00
Stefan Haller 22a38c9f50 Add property outputTitle to CustomCommand
It can optionally be used to set the title of the panel that shows the output of
a command (when showOutput is true). If left unset, the command string is used
as the title.
2024-05-20 21:02:49 +02:00
AzraelSec 5af0ea85fc feat: focus on local commits view after moving code into new commit 2024-05-20 19:12:38 +02:00
Stefan Haller c5cf1b2428 Correctly request force-pushing in triangular workflows
To determine whether we need to ask for force pushing, we need to query the push
branch rather than the upstream branch, in case they are not the same.
2024-05-19 09:44:38 +02:00
Stefan Haller b91b40ba4d Add test demonstrating the problem with force-pushing in a triangular workflow
Our code doesn't realize that we need to prompt the user to force push, when the
branch is up-to-date with its upstream but not with the branch that we're
pushing to.
2024-05-19 09:44:38 +02:00
Stefan Haller c4927e21c5 Rename PushBranch to PushBranchAndSetUpstream
It is unexpected that a function called PushBranch also sets the upstream
branch; also, we want to add a PushBranch function in the next commit that
doesn't.
2024-05-19 09:44:38 +02:00
Stefan Haller a7041cf492 Allow editing a custom command from the suggestions list by pressing 'e'
For custom commands it is useful to select an earlier command and have it copied
to the prompt for further editing. This can be done by hitting 'e' now.

For other types of suggestion panels we don't enable this behavior, as you can't
create arbitrary new items there that don't already exist as a suggestion.
2024-05-19 07:06:18 +02:00
Stefan Haller da3e0f7147 Support deleting items from the custom commands history
In the custom commands panel you can now tab to the suggestions and hit 'd' to
delete items from there. Useful if you mistyped a command and don't want it to
appear in your history any more.
2024-05-19 07:06:18 +02:00
dsolerhww 5b80c0c792 Fix stashing partialy staged files for git version >= 2.35.0
Use `git stash push --staged` git feature available on git version >
2.35.0.
2024-05-18 09:59:00 +02:00
Stefan Haller 380855d4e8 Add tests for clicking in status side panel
To prevent this from breaking again. All three tests would fail without the fix
from the previous commit.
2024-05-15 13:21:17 +02:00
Jonathan Duck 01ff18dd92 Add commitPrefix for defining a prefix for any project 2024-05-01 19:03:12 +02:00
Stefan Haller 8b99a3c949 Drop update-ref commands at the top of the rebase-todo file
The rebase.updateRefs feature of git is very useful to rebase a stack of
branches and keep everything nicely stacked; however, it is usually in the way
when you make a copy of a branch and want to rebase it "away" from the original
branch in some way or other. For example, the original branch might sit on main,
and you want to rebase the copy onto devel to see if things still compile there.
Or you want to do some heavy history rewriting experiments on the copy, but keep
the original branch in case the experiments fail. Or you want to split a branch
in two because it contains two unrelated sets of changes; so you make a copy,
and drop half of the commits from the copy, then check out the original branch
and drop the other half of the commits from it.

In all these cases, git's updateRefs feature insists on moving the original
branch along with the copy in the first rebase that you make on the copy. I
think this is a bug in git, it should create update-ref todos only for branches
that point into the middle of your branch (because only then do they form a
stack), not when they point at the head (because then it's a copy). I had a long
discussion about this on the git mailing list [1], but people either don't agree
or don't care enough.

So we fix this on our side: whenever we start a rebase for whatever reason, be
it interactive, non-interactive, or behind-the-scenes, we drop any update-ref
todos that are at the very top of the todo list, which fixes all the
above-mentioned scenarios nicely.

I will admit that there's one scenario where git's behavior is the desired one,
and the fix in this PR makes it worse: when you create a new branch off of an
existing one, with the intention of creating a stack of branches, but before you
make the first commit on the new branch you realize some problem with the first
branch (e.g. a commit that needs to be reworded or dropped). It this case you do
want both branches to be affected by the change. In my experience this scenario
is much rarer than the other ones that I described above, and it's also much
easier to recover from: just check out the other branch again and hard-reset it
to the rebased one.

[1]
https://public-inbox.org/git/354f9fed-567f-42c8-9da9-148a5e223022@haller-berlin.de/
2024-04-22 20:59:15 +02:00
Stefan Haller af6d072cc6 Add tests demonstrating undesired behavior with update-ref todos for copied branches
These tests succeed here, but have comments explaining which bits are undesired.
See next commit for a more detailed explanation why.
2024-04-22 20:59:15 +02:00
thirdkeyword 1c098ff82a pkg: fix some typos
Signed-off-by: thirdkeyword <fliterdashen@gmail.com>
2024-04-20 13:47:39 +02:00
Stefan Haller 7e14d88dc9 Support both Sha and Hash on commits in custom commands
We achieve this by wrapping the model Commit in a custom struct that provides
both.
2024-04-12 08:33:47 +02:00
Stefan Haller e6a07b3f03 Add integration test that accesses commit properties in a custom command
Useful as a regression test to check that the following commit doesn't break it.
2024-04-12 08:33:47 +02:00
Stefan Haller 93251db67e Fix the "Add to .git/info/exclude" command in submodules or worktrees 2024-03-28 13:11:08 +01:00
Stefan Haller de52a68b53 Add a test that demonstrates the problem
Using the "Add to .git/info/exclude" in a worktree results in an error message,
as the test shows. The same would happen in a submodule, but I'm not adding an
extra test for that, as the circumstances are the same.
2024-03-28 13:11:08 +01:00
Stefan Haller bd8518355e Keep the same commit selected when exiting filtering mode
When exiting filtering mode, we currently keep the selection index the same in
the commits panel. This doesn't make sense at all, since the index in the
filtered view has no relation to the index in the unfiltered view.

I often use filtering mode (either by path or by author) to find a given commit
faster than I would otherwise be able to. When exiting filtering mode, it's
useful to keep the same commit selected, so that I can look at the surrounding
commits, see which branch it was a part of, etc. So reselect the commit again
after exiting filtering mode.

Sometimes this is not possible, most likely when the commit is so long ago that
it's outside of the initial 300 range. In that case, at least select the commit
again that was selected before I entered filtering; this is still better than
arbitrarily keeping the same selection index.
2024-03-28 12:23:46 +01:00
Stefan Haller 0b70dfbf46 Fix crash when filtering the keybindings menu
It would crash when some keybindings are set to null, and the filter string is
such that only those keybindings remain visible.

The reason for the crash is that when inserting non-model items (menu section
headers in this case) you specify a column to align them to. This works on the
assumption that the number of columns is always the same. It can cope with the
case that columns are removed because they are empty for all items; but it can't
cope with the case that the getDisplayStrings function returns a lower number of
columns.

And this is what happened here: MenuViewModel.GetDisplayStrings would omit the
keybinding column when none of the entries have a keybinding. This logic is
unnecessary, the generic list rendering mechanism takes care of this, so
removing this logic fixes the crash.

We do have to make sure though that the column is really empty when there's no
keybinding, so change the logic to use FgCyan only when there's a keybinding.
2024-03-28 09:58:45 +01:00
Stefan Haller 1fdcc29277 Fix deleting update-ref todos
It is a bad idea to read a git-rebase-todo file, remove some update-ref todos,
and write it back out behind git's back. This will cause git to actually remove
the branches referenced by those update-ref todos when the rebase is continued.

The reason is that git remembers the refs affected by update-ref todos at the
beginning of the rebase, and remembers information about them in the file
.git/rebase-merge/update-refs. Then, whenever the user performs a "git rebase
--edit-todo" command, it updates that file based on whether update-ref todos
were added or removed by that edit. If we rewrite the git-rebase-todo file
behind git's back, this updating doesn't happen.

Fix this by not updating the git-rebase-todo file directly in this case, but
performing a "git rebase --edit-todo" command where we set ourselves as the
editor and change the file in there. This makes git update the bookkeeping
information properly.

Ideally we would use this method for all cases where we change the
git-rebase-todo file (e.g. moving todos up/down, or changing the type of a
todo); this would be cleaner because we wouldn't mess with git's private
implementation details. I tried this, but unfortunately it isn't fast enough.
Right now, moving a todo up or down takes between 1 and 2ms on my machine;
changing it to do a "git rebase --edit-todo" slows it down to over 100ms, which
is unacceptable.
2024-03-26 22:29:56 +01:00
Stefan Haller ba85f93fb3 Extend delete_update_ref_todo test to actually test what it was supposed to
In the test we simply removed the update-ref todo but didn't make any other
changes to the todos. This should really have kept everything the way it was,
including the other branch head. The fact that the star was gone was really
because of the bug that we are going to fix later in the branch.

Change the test so that it also makes a change before the update-ref todo; this
way we test that the star is gone because we deleted the update-ref, not because
of the bug.

To guard against the bug, we add another assertion for the branches view to test
that both branches are still there. This currently fails.
2024-03-26 22:23:50 +01:00
Stefan Haller cdbec3997d Cleanup: fix typo in test comment 2024-03-26 22:23:50 +01:00
Jesse Duffield c3f0b5cb4a Update interactive rebase demo
I'm adding an explicit delay between moving the commits and selecting
the next items because otherwise it happens too fast
2024-03-23 20:45:51 +11:00
Stefan Haller 96c5cbe34e Change CopiedToClipboard text to start lower-case
It is used in the context "'xyz' copied to clipboard", so it looks weird when it
start uppercase.
2024-03-22 09:59:46 +01:00
Stefan Haller 150cc70698 Make it easy to create "amend!" commits
To support this, we turn the confirmation prompt of the "Create fixup commit"
command into a menu; creating a fixup commit is the first entry, so that
"shift-F, enter" behaves the same as before. But there are additional entries
for creating "amend!" commits, either with or without file changes. These make
it easy to reword commit messages of existing commits.
2024-03-22 08:27:45 +01:00
Stefan Haller a8797c7261 Default to substring filtering, add option to go back to fuzzy filtering
By default we now search for substrings; you can search for multiple substrings
by separating them with spaces. Add a config option gui.filterMode that can be
set to 'fuzzy' to switch back to the previous behavior.
2024-03-17 11:55:09 +01:00
Stefan Haller 0608fc6471 Allow deleting update-ref todos 2024-03-16 22:01:13 +01:00
Stefan Haller bd975a8dcb Allow moving update-ref todos up/down 2024-03-16 22:01:03 +01:00
Stefan Haller 1ec87364fe Add integration test 2024-03-11 09:19:11 +01:00
Stefan Haller b8f4cd0ef6 Extract functions AddCoAuthorToMessage and AddCoAuthorToDescription
In this commit we only need the former; the latter will be reused later in this
branch.
2024-03-11 09:18:40 +01:00
Stefan Haller 287195b5b2 Make test assertion more specific
It's safe to rely on git padding the log messages with exactly four spaces (I
think). This makes the diff of the following commit slightly clearer.
2024-03-11 09:18:40 +01:00
Stefan Haller d1f8c45099 Add integration test 2024-03-09 10:00:44 +01:00
Stefan Haller bb26979420 Keep the same line selected after squashing fixup commits
This uses a bit of a heuristic that is hopefully correct most of the time.
2024-03-09 07:55:22 +01:00
Stefan Haller 3e3b902228 Move selection down by one after creating a fixup commit 2024-03-09 07:55:22 +01:00
Stefan Haller dfb45ba893 Extend squash_fixups_in_current_branch test to check the selection
This shows a problem with the wrong commit being selected after squashing.
2024-03-09 07:55:22 +01:00
Stefan Haller 314efe2539 Add test for creating a fixup commit and squashing fixups
We have such a test already (squash_fixups_above_first_commit.go), but it can't
be used for what we want to check here, because it uses the first commit, and we
can't move down from there. So create a new one that basically does the same
thing, but for a commit in the middle. The focus of this new test is to check
how the selection behaves; as you can see, there is a problem both when creating
a fixup and when squashing fixups. We'll address these separately in the next
commits.
2024-03-09 07:55:22 +01:00
Stefan Haller 40232440b7 Support setting a range of commits to "edit" outside of a rebase
It starts a rebase on the bottom-most commit of the range, and sets all the
selected commits to "edit" (skipping merge commits, because they can't be
edited).
2024-03-09 07:43:48 +01:00
Stefan Haller 3b723282cb Show all submodules recursively 2024-03-07 20:16:28 +01:00
Stefan Haller ea87912a74 Fix deleting submodule where name and path are different 2024-03-07 20:16:28 +01:00
Stefan Haller ddcd916301 Add test to check that the git dir for a deleted submodule was removed
The test shows that it actually doesn't work when the submodule name is
different from its path. We'll fix this in the next commit.
2024-03-07 20:16:28 +01:00
Stefan Haller 85a6a42bff Extend submodule tests to use a submodule where name and path are different
In most real-world scenarios, name and path are usually the same. They don't
have to be though, and it's important to make sure we use the right one when
passing arguments to git commands, so change the tests to have different name
and path.
2024-03-07 20:16:28 +01:00
Stefan Haller 416a40b0e6 Don't show branch head on rebase todos if the rebase.updateRefs config is on
The additional branch head icon is more confusing than useful in this situation.
The update-ref entries show very clearly where the branch heads will go when
continuing the rebase; the information where the branch heads used to be before
the rebase is not really needed here, and just makes the display more confusing.

I'm not adding more tests here because the changes to the existing tests
demonstrate the change clearly enough.
2024-03-02 10:17:58 +01:00
Stefan Haller fd8ce7d779 Add test demonstrating the current (undesired) behavior 2024-03-02 10:17:58 +01:00
Tristan Déplantes 503422a72e Add author filtering to commit view
This commit introduces a new feature to the commit view, allowing users
to filter commits based on the author's name or email address. Similar
to the existing path filtering functionality, accessible through <c-s>,
this feature allows users to filter the commit history by the currently
selected commit's author if the commit view is focused, or by typing in
the author's name or email address.

This feature adds an entry to the filtering menu, to provide users with
a familiar and intuitive experience
2024-02-21 09:58:09 +01:00
Stefan Haller 236f42879c Add integration test
The test would fail without the fixes in the previous commits; even if
only one of the configs is set.
2024-02-18 15:24:09 +01:00
Stefan Haller 9f0b4d0000 Don't omit section headers when filtering the keybindings menu 2024-02-16 13:51:15 +01:00
Stefan Haller 649048c336 Optionally keep sort order stable when filtering lists
For some lists it is useful to keep the same sort order when filtering (rather
than sorting by best match like we usually do). Add an optional function to
FilteredList to make this possible, and use it whenever we show lists of things
sorted by date (branches, stashes, reflog entries), as well as menu items
because this allows us to keep the section headers in the keybindings menu,
which is useful for understanding what you are looking at when filtering.
2024-02-16 13:51:15 +01:00
Stefan Haller 6c6201ab04 Fix order problems when saving custom commands history
This fixes two problems:
- each time the custom commands panel was opened, the history of commands would
  be shown in reversed order compared to last time. (The reason is that
  lo.Reverse modifies the slice in place rather than just returning a new,
  reversed slice.)
- when executing a previous command again (either by typing it in again, or by
  picking it from the history), it should move to the beginning of the history,
  but didn't.

We fix this by storing the history in reversed order (as the user sees it in
the panel), this makes the logic simpler. We just have to prepend rather
than append newly added commands now.

While this is theoretically a breaking change, it's not worth bothering because
the order was wrong for existing users in 50% of the cases anyway.
2024-02-16 13:31:37 +01:00
Alex March e354a9bb48 Deprecate git.log.showGraph and git.log.order config
Added identical properties to AppState that should eventually have their defaults set.
2024-02-16 13:23:35 +01:00
Stefan Haller 3b7f32db95 Avoid crash when hitting enter on an update-ref todo 2024-02-16 13:06:24 +01:00
Aaron Hoffman c431698dba Fix range select bug
After discarding file changes from the commit, the was still referencing
these indexes as being part of the range select. The consequence was
needing to hit escape twice to exit commit files in some situations.
Canceling the range select after discarding changes fixes that.
2024-02-13 09:10:15 -06:00
Aaron Hoffman d138f7ce86 Clean up test case
I'm combining the delete single file case from `discard_old_file_change`
with the content of `discard_range_select` and calling that
`discard_old_file_changes`. Hopefully that cleans things up a little
bit.

This also adds a check that the custom patch is getting reset properly.
2024-02-13 09:10:15 -06:00
Aaron Hoffman 15d5261933 Support range select removing files from a commit 2024-02-13 09:10:15 -06:00
Stefan Haller b1d05b6371 Change default of git.log.showGraph to 'always'
Most people seem to prefer it to be on.
2024-02-13 14:34:40 +01:00
Aaron Hoffman fdc54b7455 Fix cherrypick demo
Cherrypick selections are now cleared after pasting (#3240), so the demo
needs a tiny change to reflect that.
2024-01-30 09:27:44 -06:00
molejnik88 ee173ff7c9 Clear cherry-picked commits after pasting
It can be tedious after each cherry-pick opearation to clear the
selection by pressing escape in order for lazygit to stop displaying
info about copied commits. Also, it seems to be a rare case to
cherry-pick commits to more than one destination.

The simplest solution to address this issue is to clear the selection
upon paste.

The only exception is a merge conflict. Initially, I wanted to clear
selected commits in this scenario too. During a discussion we found out
that it may be convenient to have the copied commits still around.
Aborting the rebase and pasting the commits in the middle of a branch
can be a valid use case.
2024-01-30 09:21:12 +11:00
Stefan Haller b133318b40 Add command to squash all fixups in the current branch
To do that, change the "Apply fixup commits" command to show a menu with the two
choices "in current branch" and "above the selected commit"; we make "in current
branch" the default, as it's the more useful one most of the time, even though
it is a breaking change for those who are used to "shift-S enter" meaning
"squash above selected".
2024-01-29 09:37:47 +01:00
Stefan Haller e8e7ddea45 Fix typo 2024-01-28 09:49:56 +01:00
Aaron Hoffman 510f9a1ae1 Support selecting file range in patch builder
test: add move_range_to_index

test: add toggle_range
2024-01-28 12:00:47 +11:00
Jesse Duffield 0f9d9e13d1 Show mode-specific keybinding suggestions
As part of making lazygit more discoverable, there are certain keys which you almost certainly
need to press when you're in a given mode e.g. 'v' to paste commits when cherry-picking. This
commit prominently shows these keybinding suggestions alongside the others in the option view.

I'm using the same colours for these keybindings as is associated with the mode elsewhere e.g.
yellow for rebasing and cyan for cherry-picking. The cherry-picking one is a bit weird because
we also use cyan text to show loaders and app status at the bottom left so it may be confusing,
but I haven't personally found it awkward from having tested it out myself.

Previously we would render these options whenever a new context was activated, but now that we
need to re-render options whenever a mode changes, I'm instead rendering them on each screen
re-render (i.e. in the layout function). Given how cheap it is to render this text, I think
it's fine performance-wise.
2024-01-28 08:33:13 +11:00
Jesse Duffield 7bddf53223 Improve keybinding descriptions
This adds a bunch of tooltips to keybindings and updates some keybinding descriptions (i.e. labels).

It's in preparation for displaying more keybindings on-screen (in the bottom right of the screen),
and so due in part to laziness it shortens some descriptions so that we don't need to manage both
a short and long description (for on-screen vs in-menu). Nonetheless I've added a ShortDescription
field for when we do want to have both a short and long description.

You'll notice that some keybindings I deemed unworthy of the options view have longer descriptions,
because I could get away with it.
2024-01-28 08:12:01 +11:00
Stefan Haller f9876c9742 Keep same selection range when quick-starting an interactive rebase
This is useful if you want to move a range of commits, so you select them, and
then realize it's better to do it in an interactive rebase. Pressing 'i'
preserves the range now.
2024-01-26 11:18:13 +01:00
Stefan Haller d28a2ec059 Add tests for preserving the selection when pressing 'i'
Preserving the selection for a non-range selection already works as expected;
however, the test for a selection range shows an undesired behavior.
2024-01-26 11:18:06 +01:00
Jesse Duffield 269ef7f250 Support range select for staging/discarding files
As part of this, you must now press enter on a merge conflict file
to focus the merge view; you can no longer press space and if you do
it will raise an error.
2024-01-25 11:34:59 +11:00
John Whitley 3d9f1e02e5 Refactor repo_paths.go to use git rev-parse
This changes GetRepoPaths() to pull information from `git rev-parse`
instead of effectively reimplementing git's logic for pathfinding. This
change fixes issues with bare repos, esp. versioned homedir use cases,
by aligning lazygit's path handling to what git itself does.

This change also enables lazygit to run from arbitrary subdirectories of
a repository, including correct handling of symlinks, including "deep"
symlinks into a repo, worktree, a repo's submodules, etc.

Integration tests are now resilient against unintended side effects from
the host's environment variables. Of necessity, $PATH and $TERM are the
only env vars allowed through now.
2024-01-24 08:40:01 +01:00
Jesse Duffield f0de880136 Support range select in rebase actions 2024-01-23 17:23:56 +11:00
Jesse Duffield 44e2542e4a Better assertion logic for line selection
Previously if we marked a line with IsSelected() we would check if it was selected, but
we would not check if other lines were unexpectedly selected. Now, if you use IsSelected(),
we ensure that _only_ the lines you marked as such are the selected lines.
2024-01-23 13:43:39 +11:00
Stefan Haller 2c9b4770bc Keep same branch selected when refreshing branches
This wasn't necessary before, because the only available branch sorting option
was by recency, so the sort order couldn't change except by checking out
branches. Now, you can sort by committer date, so the branch order can change by
fetching; in this case it's important to keep the same branch selected. One
important use case is to rebase the checked-out branch onto master; you select
master, press "f" to fetch it (this can now change its position in the list),
and then press "r" to rebase. To make this work smoothly it's important to keep
master selected after pressing "f".
2024-01-19 09:25:07 +01:00
Stefan Haller 9867180202 Add test showing how branch should stay selected after fetching (but doesn't yet) 2024-01-19 09:23:55 +01:00
Jesse Duffield 51fb82d6bf Enforce single-item selection in various actions
We want to show an error when the user tries to invoke an action that expects only
a single item to be selected.

We're using the GetDisabledReason field to enforce this (as well as DisabledReason
on menu items).

I've created a ListControllerTrait to store some shared convenience functions for this.
2024-01-19 10:50:49 +11:00