Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add worktrees view #2147

Merged
merged 74 commits into from
Jul 30, 2023
Merged

Conversation

kadaan
Copy link

@kadaan kadaan commented Sep 1, 2022

(Jesse speaking)

Adds a worktree view and operations for worktrees
If you don't use worktrees, you shouldn't notice any change other than the new worktrees tab appearing next to the files tab.

This is a first-cut. We will refine the UX as we go

@jesseduffield
Copy link
Owner

Wow! Didn't expect that you'd pick up on all the current patterns. Code looks pretty good so far, I'll try to find time on the weekend to give it a more thorough review

@kadaan
Copy link
Author

kadaan commented Sep 1, 2022

Thanks! I have a few thoughts regarding worktree support

  1. Does it make sense for worktrees to be a separate tab in branches panel? It feels like it should, but I am unsure.
  2. In the branches list, I have filtered out branches that are checked out in a worktree that is not the current worktree.
  3. What other operations from https://git-scm.com/docs/git-worktree would we want to support? I'm thinking about add and remove, in addition to list and switch, being a good first step.
  4. We still need to handle worktrees which have been deleted from the filesystem, but not from git.
  5. How do we want to handle worktree which are on removable devices (see git worktree lock ...)?
  6. What information do we want to show on the right panel when a worktree is selected in the worktree list?
  7. How do we want to display the current repo/worktree in the status panel? Currently it displays worktree_support -> worktree_support for the linked worktree. It would be better if it showed the repo, indicated we are in a worktree, and the branch.

@mark2185
Copy link
Collaborator

mark2185 commented Sep 2, 2022

I'll add my two cents.

  1. Does it make sense for worktrees to be a separate tab in branches panel? It feels like it should, but I am unsure.

It does, IMO it's at the same level as submodules, as far as functionality and options go.

  1. In the branches list, I have filtered out branches that are checked out in a worktree that is not the current worktree.

Maybe it would also be good to have them in the branches panel, but denote somehow that that branch is from a different worktree.

  1. What other operations from https://git-scm.com/docs/git-worktree would we want to support? I'm thinking about add and remove, in addition to list and switch, being a good first step.

Sounds like a big step forward having just those few commands. We could always add more later.

  1. We still need to handle worktrees which have been deleted from the filesystem, but not from git.

Just denote them somehow special and give the user an error when they try to switch to it?

  1. How do we want to handle worktree which are on removable devices (see git worktree lock ...)?

Uhhh... how often is that used?

  1. What information do we want to show on the right panel when a worktree is selected in the worktree list?

I guess we could do the same as the recent repositores popup does: folder-name current-branch-name path/to/repo ? Seems reasonable.

Sorta kinda related question, since it looks like you've used worktrees before - should we warn users that it will not work with git-lfs?

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

  1. That was my thought as well
  2. I like the idea of using the branches panel. If we supported that, switching between branches that were checked out in different worktrees could etc worktree. Though, because linked worktrees can switch branches, we would need to support some way to checkout a branch into a worktree in addition to the current check out command. Lastly, we still would need the worktree panel, which means we would have multiple panels for managing worktrees. Sounds confusing…
  3. Agreed
  4. Another option is to just not show worktrees in the list if their target path does not exist
  5. No idea, I never do
  6. Good idea
  7. Looks like LFS has linked worktree support: https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-install.adoc. Am I missing something?

@mark2185
Copy link
Collaborator

mark2185 commented Sep 2, 2022

  1. I like the idea of using the branches panel. If we supported that, switching between branches that were checked out in different worktrees could etc worktree. Though, because linked worktrees can switch branches, we would need to support some way to checkout a branch into a worktree in addition to the current check out command. Lastly, we still would need the worktree panel, which means we would have multiple panels for managing worktrees. Sounds confusing…

Well we can have both. Have the worktree panel for adding or removing worktrees, but still show all branches.

  1. Another option is to just not show worktrees in the list if their target path does not exist

Or that, yeah.

  1. Looks like LFS has linked worktree support: https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-install.adoc. Am I missing something?

Huh, maybe it was a messup on my side. I tried using an additional worktree with several gigabytes of data in git-lfs and it didn't work out, I'll take a second look, thanks!

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

@mark2185 There are a few things I'd like feedback on in this image
2022-09-02 at 08 30 54@2x

  1. In the top left status panel, that is my quick attempt to differentiate being in a linked worktree vs the main work tree. Any other thoughts on how to do it?
  2. In the worktrees panel, what should we call the main worktree. Initially, I chose "main", but the problem is I can create a worktree via git worktree add .worktrees/main which will then also be called "main". 2022-09-02 at 08 53 18@2xAlso, I can create a worktree via git worktree add -b worktree_tests2 .worktrees2/worktree_tests which will be pointed at a new branch (two worktrees cannot check out the same branch), but will have the same final segment in the path. As you can see in the following gif, there are two worktrees and they have the same "name" in the worktrees panel because their final path segment is the same.
    2022-09-02 at 08 51 01 When icons are enabled, it helps differentiate the main and linked worktrees if they share a "name", but it can still get pretty confusing.
  3. When icons are enabled I think it would be good to include a "link" icon for the linked worktrees in the worktree panel. 2022-09-02 at 08 43 45@2x
  4. On the right status panel, I'm currently showing what we have decided it the "name" of the worktree and the path. Seems like the only things missing are the current branch name and maybe some indication that selected item is a main or linked worktree.

@mark2185
Copy link
Collaborator

mark2185 commented Sep 2, 2022

  1. In the top left status panel, that is my quick attempt to differentiate being in a linked worktree vs the main work tree. Any other thoughts on how to do it?

That seems good enough, I've used that panel exactly 0 times so I'm fine either way.

  1. In the worktrees panel, what should we call the main worktree. Initially, I chose "main", but the problem is I can create a worktree via git worktree add .worktrees/main which will then also be called "main".

Could we use the current working directory as it's name? As in, if the user just clones a repo, it'll be called e.g. lazygit?

Also, I can create a worktree via git worktree add -b worktree_tests2 .worktrees2/worktree_tests which will be pointed at a new branch (two worktrees cannot check out the same branch), but will have the same final segment in the path. As you can see in the following gif, there are two worktrees and they have the same "name" in the worktrees panel because their final path segment is the same.

That doesn't seem like a big issue. I don't know many people who use multiple worktrees so I don't have anyone to ask, but if I were creating multiple trees, I'd make sure they are not in folders of the same name.

  1. When icons are enabled I think it would be good to include a "link" icon for the linked worktrees in the worktree panel.

Seems reasonable.

  1. On the right status panel, I'm currently showing what we have decided it the "name" of the worktree and the path. Seems like the only things missing are the current branch name and maybe some indication that selected item is a main or linked worktree.

* is okay for the current worktree, the link icon is okay for the linked one, maybe we could use something tree-like for the main tree?

Also, I wouldn't hide invalid worktrees, I'd just mark them red or something. That way, the user can still delete them from within lazygit.

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

Good points.

I have already added filtering out of the worktree, but I can add them back, style them red, and then check on enter to ensure the target location exists.

Also, I had to add back the check you called out in the Branches loader as it is needed to not filter out branches which are not checked out.

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

2022-09-02 at 09 33 35

@mark2185
Copy link
Collaborator

mark2185 commented Sep 2, 2022

Looks good! Does it also handle out-of-source worktrees just as well?

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

What do you mean by "out of source"?

@mark2185
Copy link
Collaborator

mark2185 commented Sep 2, 2022

What do you mean by "out of source"?

All of these worktrees were created within your lazygit clone, right? What if you create one outside of it? I.e. git worktree add -b stable ../otherfolder or something similar.

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

Yup, that works
2022-09-02 at 10 46 03@2x

Also, added a call out for missing worktrees on the right status panel
2022-09-02 at 10 46 45@2x

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

I think the look of the top left status is a lot better like this
2022-09-02 at 10 57 09

@kadaan
Copy link
Author

kadaan commented Sep 2, 2022

Things remaining:

  • Support add worktree where branch name is worktree name
  • Support add worktree where branch name is different than worktree name
  • Add branch to worktree main panel display
  • Add option when deleting the worktree to delete the branch
  • Tests, tests, tests

@kadaan
Copy link
Author

kadaan commented Sep 3, 2022

2022-09-02 at 20 59 21@2x

2022-09-02 at 20 59 31@2x

@kadaan
Copy link
Author

kadaan commented Sep 3, 2022

Basic add support is in:
2022-09-02 at 21 35 59

Copy link
Owner

@jesseduffield jesseduffield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great so far. Left some feedback

pkg/commands/loaders/branches.go Outdated Show resolved Hide resolved
pkg/commands/loaders/branches_test.go Outdated Show resolved Hide resolved
pkg/commands/models/worktree.go Outdated Show resolved Hide resolved
pkg/commands/models/worktree.go Outdated Show resolved Hide resolved
pkg/gui/refresh.go Outdated Show resolved Hide resolved
@kadaan
Copy link
Author

kadaan commented Sep 11, 2022

@jesseduffield Addressed all open comments

}

func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
worktreesOutput, err := self.cmd.New(`git worktree list --porcelain -z`).DontLog().RunWithOutput()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

I'm running git 2.33 and looks like that doesn't support the -z flag, so I'd remove that and use newlines instead (assuming that doesn't present any major problems).

Speaking of compatibility, we have a compatibility requirement with git v2.0+, and it's worth considering if any of this PR doesn't work with git v2.0. I know magit supports as early as 2.4, so I'm happy to bump up the minimum required version to 2.4 if necessary for anything in this PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on 2 google searches, worktrees were introduced in v2.5, so...

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shiiieeet haha

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case I reckon we just need to only run our worktree code if we're on at least 2.5, otherwise we hide the worktree tab

@jesseduffield
Copy link
Owner

@kadaan thanks for waiting, I'm gonna give this another review this weekend

Copy link
Owner

@jesseduffield jesseduffield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm midway through a review but I need to submit it to respond to @mark2185 's comments

return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.NewWorktreePath,
HandleConfirm: func(response string) error {
self.c.LogAction(self.c.Tr.Actions.CreateWorktree)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we wrap this in a loader, given it takes a couple seconds for me. Have a look at WithWaitingStatus

func (self *WorktreeHelper) IsCurrentWorktree(w *models.Worktree) bool {
pwd, err := os.Getwd()
if err != nil {
log.Fatalln(err.Error())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add context to this error e.g. 'failed to determine a given worktree is the current worktree'. Given we're not panicking here, it's good to have something that's easy to search for within the codebase to see where it's failing.

}

func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
worktreesOutput, err := self.cmd.New(`git worktree list --porcelain -z`).DontLog().RunWithOutput()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shiiieeet haha

}

func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
worktreesOutput, err := self.cmd.New(`git worktree list --porcelain -z`).DontLog().RunWithOutput()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case I reckon we just need to only run our worktree code if we're on at least 2.5, otherwise we hide the worktree tab

@jesseduffield
Copy link
Owner

Some more things I noted from locally testing:

  • interestingly, a worktree named 'foo' will appear in git status --short as 'foo/'. Lazygit expects all status changes to be files, meaning it renders the workspace in the files view as a folder that has a file with no name. It would be good if we could actually signify that it's a worktree in the files panel, similar to what we do with submodules. Both when staged and unstaged it should appear as a single 'file' (right now it shows as a folder + file when unstaged and as a file when staged)
  • deleting a file that contains a worktree should refresh the worktree panel
  • When hiting space on a worktree, things get a bit weird: initially I'm taken to the files window, and then upon switching to the branches window again I'm kicked out of the Worktrees tab and put in the Local Branches tab. Then if I go back to the Worktrees and hit space on other worktrees some more, eventually it keeps me in the Worktrees tab but moves my cursor down by one item. We should be consistent in what happens. I think we should stay in the Worktrees tab and the cursor should remain on the item we just hit space on.
  • deleting worktree should also use a loader
  • hitting enter on a worktree should also make you enter it (not just space)

})
},
nil,
gui.withDiffModeCheck(gui.worktreesRenderToMain),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the diff mode check: that's more applicable to things like branches/commits

@@ -59,3 +61,13 @@ func IconForRemote(remote *models.Remote) string {
}
return DEFAULT_REMOTE_ICON
}

func IconForWorktree(worktree *models.Worktree, missing bool) string {
if worktree.Main() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would show LINKED_WORKTREE_ICON even for the main worktree, so long as we also show the green asterisk

"github.com/jesseduffield/lazygit/pkg/theme"
)

func GetWorktreeDisplayString(isCurrent bool, isPathMissing bool, worktree *models.Worktree) []string {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func GetWorktreeDisplayString(isCurrent bool, isPathMissing bool, worktree *models.Worktree) []string {
func GetWorktreeDisplayStrings(isCurrent bool, isPathMissing bool, worktree *models.Worktree) []string {

@@ -554,6 +571,10 @@ func (gui *Gui) refreshStatus() {

name := presentation.GetBranchTextStyle(currentBranch.Name).Sprint(currentBranch.Name)
repoName := utils.GetCurrentRepoName()
mainWorktreeName := gui.helpers.Worktree.GetMainWorktreeName()
if repoName != mainWorktreeName {
repoName = fmt.Sprintf("%s(%s)", mainWorktreeName, style.FgBlue.Sprint(repoName))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use something other than blue given it can be hard to see on some screens (we typically use blue for unimportant stuff but I think it's important to show what worktree the user is in). How bout magenta?

Our min required git version is 2.20 so there's no need to add guards
for worktrees because they were added in 2.5
We now always re-use the state of the repo if we're returning to it, and we always reset the windows to their default tabs.

We reset to default tabs because it's easy to implement. If people want to:
* have tab states be retained when switching
* have tab states specific to the current repo retained when switching back

Then we'll need to revisit this
This fixes pkg/integration/tests/worktree/rebase.go which was failing on old git versions due to a difference in
order of branches that don't have recency values
We're doing all the IO in our workers loader method so that we don't need to do any
in our presentation code
There are quite a few paths you might want to get e.g. the repo's path, the worktree's path,
the repo's git dir path, the worktree's git dir path. I want these all obtained once and
then used when needed rather than having to have IO whenever we need them. This is not so
much about reducing time spent on IO as it is about not having to care about errors every time
we want a path.
I would prefer to use methods to keep things immutable but I'd rather be consistent with the other
models and update them all at once
We want to be using forward slashes everywhere internally, so if we get a path from windows
we should immediately convert it to use forward slashes.

I'm leaving out the recent repos list because that would require a migration
…nches

When switching worktrees (which we can now do via the branch view) we re-layout the windows and their views.
We had the worktree view ahead of the file view based on the Flatten() method in context.go, because it used
to be associated with the branches panel.
Afero is a package that lets you mock out a filesystem with an in-memory filesystem.
It allows us to easily create the files required for a given test without worrying about
a cleanup step or different tests tripping on eachother when run in parallel.

Later on I'll standardise on using afero over the vanilla os package
In the presentation layer, when showing branches, we'll show worktrees against branches if they're
associated. But there was a race condition: if the worktree model was refreshed after the branches model,
it wouldn't be used in the presentation layer when it came time to render the branches.

A better solution would be to have some way of signalling that a particular context needs to be refreshed
and after all the models are done being refreshed, we then refresh the contexts. This will prevent
double-renders
@jesseduffield jesseduffield merged commit 08f0e28 into jesseduffield:master Jul 30, 2023
renovate bot referenced this pull request in scottames/dots Aug 5, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
|
[GoogleContainerTools/skaffold](https://github.com/GoogleContainerTools/skaffold)
| patch | `v2.6.2` -> `v2.6.3` |
| [ajeetdsouza/zoxide](https://github.com/ajeetdsouza/zoxide) | patch
| `v0.9.1` -> `v0.9.2` |
| [aquaproj/aqua-registry](https://github.com/aquaproj/aqua-registry)
| patch | `v4.32.0` -> `v4.32.2` |
| [jesseduffield/lazygit](https://github.com/jesseduffield/lazygit) |
minor | `v0.39.4` -> `v0.40.0` |
| [weaveworks/eksctl](https://github.com/weaveworks/eksctl) | minor |
`v0.150.0` -> `v0.151.0` |

---

### Release Notes

<details>
<summary>GoogleContainerTools/skaffold
(GoogleContainerTools/skaffold)</summary>

###
[`v2.6.3`](https://github.com/GoogleContainerTools/skaffold/releases/tag/v2.6.3):
Release

[Compare
Source](https://github.com/GoogleContainerTools/skaffold/compare/v2.6.2...v2.6.3)

##### v2.6.3 Release - 2023-08-04

**Linux amd64**
`curl -Lo skaffold
https://storage.googleapis.com/skaffold/releases/v2.6.3/skaffold-linux-amd64
&& chmod +x skaffold && sudo mv skaffold /usr/local/bin`

**Linux arm64**
`curl -Lo skaffold
https://storage.googleapis.com/skaffold/releases/v2.6.3/skaffold-linux-arm64
&& chmod +x skaffold && sudo mv skaffold /usr/local/bin`

**macOS amd64**
`curl -Lo skaffold
https://storage.googleapis.com/skaffold/releases/v2.6.3/skaffold-darwin-amd64
&& chmod +x skaffold && sudo mv skaffold /usr/local/bin`

**macOS arm64**
`curl -Lo skaffold
https://storage.googleapis.com/skaffold/releases/v2.6.3/skaffold-darwin-arm64
&& chmod +x skaffold && sudo mv skaffold /usr/local/bin`

**Windows**

https://storage.googleapis.com/skaffold/releases/v2.6.3/skaffold-windows-amd64.exe

**Docker image**
`gcr.io/k8s-skaffold/skaffold:v2.6.3`

**Full Changelog**:
GoogleContainerTools/skaffold@v2.6.2...v2.6.3

</details>

<details>
<summary>ajeetdsouza/zoxide (ajeetdsouza/zoxide)</summary>

###
[`v0.9.2`](https://github.com/ajeetdsouza/zoxide/releases/tag/v0.9.2):
0.9.2

[Compare
Source](https://github.com/ajeetdsouza/zoxide/compare/v0.9.1...v0.9.2)

##### Added

-   Short option `-a` for `zoxide query --all`.

##### Fixed

-   PowerShell: use `global` scope for variables / functions.

</details>

<details>
<summary>aquaproj/aqua-registry (aquaproj/aqua-registry)</summary>

###
[`v4.32.2`](https://github.com/aquaproj/aqua-registry/releases/tag/v4.32.2)

[Compare
Source](https://github.com/aquaproj/aqua-registry/compare/v4.32.1...v4.32.2)


[Issues](https://github.com/aquaproj/aqua-registry/issues?q=is%3Aissue+milestone%3Av4.32.2)
| [Pull
Requests](https://github.com/aquaproj/aqua-registry/pulls?q=is%3Apr+milestone%3Av4.32.2)
| aquaproj/aqua-registry@v4.32.1...v4.32.2

##### Fixes


[#&#8203;14327](https://github.com/aquaproj/aqua-registry/issues/14327)
Rename kyleconroy/sqlc to sqlc-dev/sqlc as of repository migration
[@&#8203;ichizero](https://github.com/ichizero)

[#&#8203;14339](https://github.com/aquaproj/aqua-registry/issues/14339)
sqlc-dev/sqlc: Support old versions

###
[`v4.32.1`](https://github.com/aquaproj/aqua-registry/releases/tag/v4.32.1)

[Compare
Source](https://github.com/aquaproj/aqua-registry/compare/v4.32.0...v4.32.1)


[Issues](https://github.com/aquaproj/aqua-registry/issues?q=is%3Aissue+milestone%3Av4.32.1)
| [Pull
Requests](https://github.com/aquaproj/aqua-registry/pulls?q=is%3Apr+milestone%3Av4.32.1)
| aquaproj/aqua-registry@v4.32.0...v4.32.1

#### Fixes


[#&#8203;14275](https://github.com/aquaproj/aqua-registry/issues/14275)
[#&#8203;14276](https://github.com/aquaproj/aqua-registry/issues/14276)
[#&#8203;14277](https://github.com/aquaproj/aqua-registry/issues/14277)
[#&#8203;14278](https://github.com/aquaproj/aqua-registry/issues/14278)
[domoritz/arrow-tools/{csv2arrow,csv2parquet,json2arrow,json2parquet}](https://github.com/domoritz/arrow-tools):
Follow up changes of asset names

</details>

<details>
<summary>jesseduffield/lazygit (jesseduffield/lazygit)</summary>

###
[`v0.40.0`](https://github.com/jesseduffield/lazygit/releases/tag/v0.40.0)

[Compare
Source](https://github.com/jesseduffield/lazygit/compare/v0.39.4...v0.40.0)

<!-- Release notes generated using configuration in .github/release.yml
at v0.40.0 -->

### 🎉  LAZYGIT FIVE YEAR ANNIVERSARY EDITION 🎉

Holy moly, has it really been 5 years since Lazygit's birth? Time flies
when you're having fun.

I've written a post celebrating the anniversary
[here](https://jesseduffield.com/Lazygit-5-Years-On).

As for this release, we've got some great features here.

##### Worktrees

We now have a worktrees view so you can easily create worktrees and
switch to them and so on. I'm not a big worktrees user myself so please
raise an issue if you can think of places to improve the UX.


![worktree_create_from_branches-compressed](https://github.com/jesseduffield/lazygit/assets/8456633/3ef0b085-e9d0-42de-af58-16cbae581d34)

##### Rebase --onto

Rebasing onto a marked base commit is a very useful feature that we've
been sorely lacking for a while
(demo coming soon)

##### Auto-refresh on window focus

Auto-refresh on window activation is a complete game-changer. No more
having to manually press shift+R when you come back from your editor.

##### Nuking the worktree

We also have a fun enhancement in this release: showing an explosion
animation when you nuke the working tree.


![nuke-gif](https://github.com/jesseduffield/lazygit/assets/8456633/32b3f91c-fea3-474d-8997-1de2f5e4f5d4)

You'll also notice in the readme we've got some updated demo gifs to
showoff Lazygit's features. More of those to come.

#### What's Changed

##### Features ✨

- Add worktrees view by
[@&#8203;jesseduffield](https://github.com/jesseduffield) (with help
from [@&#8203;kadaan](https://github.com/kadaan)) in
[https://github.com/jesseduffield/lazygit/pull/2147](https://github.com/jesseduffield/lazygit/pull/2147)
- Rebase onto branch from a marked base commit by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2835](https://github.com/jesseduffield/lazygit/pull/2835)
- Auto-refresh on window activation by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2854](https://github.com/jesseduffield/lazygit/pull/2854)

##### Enhancements 🔥

- Faster refresh by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2841](https://github.com/jesseduffield/lazygit/pull/2841)
- feat: add os.copyToClipboardCmd to allow for a custom command
[#&#8203;1055](https://github.com/jesseduffield/lazygit/issues/1055)
by [@&#8203;redstreet](https://github.com/redstreet) in
[https://github.com/jesseduffield/lazygit/pull/2784](https://github.com/jesseduffield/lazygit/pull/2784)
- Add bisect menu entry that lets you choose bisect terms by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2838](https://github.com/jesseduffield/lazygit/pull/2838)
- When bisecting, always mark the current commit as good/bad, not the
selected by [@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2837](https://github.com/jesseduffield/lazygit/pull/2837)
- Visualize local branch heads in commits panel, 2nd approach by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2775](https://github.com/jesseduffield/lazygit/pull/2775)
- Allow force-tagging if tag exists by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2827](https://github.com/jesseduffield/lazygit/pull/2827)
- Save IgnoreWhitespaceInDiffView in state.yml by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2830](https://github.com/jesseduffield/lazygit/pull/2830)
- Show loader when rebasing by
[@&#8203;KarlHeitmann](https://github.com/KarlHeitmann) in
[https://github.com/jesseduffield/lazygit/pull/2851](https://github.com/jesseduffield/lazygit/pull/2851)
- Internationalise logging of commands by
[@&#8203;KarlHeitmann](https://github.com/KarlHeitmann) in
[https://github.com/jesseduffield/lazygit/pull/2852](https://github.com/jesseduffield/lazygit/pull/2852)
- Show visual explosion effect when nuking worktree by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2861](https://github.com/jesseduffield/lazygit/pull/2861)

##### Fixes 🔧

- Fix issue where using `null` to un-map a keybinding was ignored by
[@&#8203;hatredholder](https://github.com/hatredholder) in
[https://github.com/jesseduffield/lazygit/pull/2832](https://github.com/jesseduffield/lazygit/pull/2832)
- Show error when trying to open patch menu with an empty patch by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2829](https://github.com/jesseduffield/lazygit/pull/2829)
- Fix merge status for update-ref command by
[@&#8203;stefanhaller](https://github.com/stefanhaller) in
[https://github.com/jesseduffield/lazygit/pull/2845](https://github.com/jesseduffield/lazygit/pull/2845)
- Stop worktrees view from stealing the window by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2863](https://github.com/jesseduffield/lazygit/pull/2863)
- Fix confirmation view sizing by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2879](https://github.com/jesseduffield/lazygit/pull/2879)

##### Maintenance ⚙️

- Standardise on using lo for slice functions by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2846](https://github.com/jesseduffield/lazygit/pull/2846)
- Remove redundant secureexec package by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2847](https://github.com/jesseduffield/lazygit/pull/2847)
- Add automated demo recordings by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2853](https://github.com/jesseduffield/lazygit/pull/2853)
- Remove file watcher code by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2865](https://github.com/jesseduffield/lazygit/pull/2865)
- Add more demos to the README by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2866](https://github.com/jesseduffield/lazygit/pull/2866)
- Move features to top of readme by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2867](https://github.com/jesseduffield/lazygit/pull/2867)
- Add more demos by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2874](https://github.com/jesseduffield/lazygit/pull/2874)

##### Other Changes

- Create demo output dir if it doesn't already exist by
[@&#8203;jesseduffield](https://github.com/jesseduffield) in
[https://github.com/jesseduffield/lazygit/pull/2857](https://github.com/jesseduffield/lazygit/pull/2857)

#### New Contributors

- [@&#8203;hatredholder](https://github.com/hatredholder) made their
first contribution in
[https://github.com/jesseduffield/lazygit/pull/2832](https://github.com/jesseduffield/lazygit/pull/2832)
- [@&#8203;redstreet](https://github.com/redstreet) made their first
contribution in
[https://github.com/jesseduffield/lazygit/pull/2784](https://github.com/jesseduffield/lazygit/pull/2784)
- [@&#8203;kadaan](https://github.com/kadaan) made their first
contribution in
[https://github.com/jesseduffield/lazygit/pull/2147](https://github.com/jesseduffield/lazygit/pull/2147)
- [@&#8203;KarlHeitmann](https://github.com/KarlHeitmann) made their
first contribution in
[https://github.com/jesseduffield/lazygit/pull/2851](https://github.com/jesseduffield/lazygit/pull/2851)

**Full Changelog**:
jesseduffield/lazygit@v0.39.4...v0.40.0

</details>

<details>
<summary>weaveworks/eksctl (weaveworks/eksctl)</summary>

###
[`v0.151.0`](https://github.com/eksctl-io/eksctl/releases/tag/v0.151.0):
eksctl 0.151.0 (permalink)

[Compare
Source](https://github.com/weaveworks/eksctl/compare/0.150.0...0.151.0)

### Release v0.151.0

#### 🚀 Features

- Support custom AMIs for self-managed Windows nodegroups
([#&#8203;6804](https://github.com/weaveworks/eksctl/issues/6804))
- Support custom Ubuntu AMIs for EKS-managed nodegroups
([#&#8203;6850](https://github.com/weaveworks/eksctl/issues/6850))

#### 🎯 Improvements

- Remove support for EKS 1.22
([#&#8203;6704](https://github.com/weaveworks/eksctl/issues/6704))

#### 🐛 Bug Fixes

- Fix error with tar in `Post Cache go-build and mod` step
([#&#8203;6840](https://github.com/weaveworks/eksctl/issues/6840))
- Fix setting link-time variables for release version
([#&#8203;6841](https://github.com/weaveworks/eksctl/issues/6841))
- Select one subnet for AZs where multiple are present and no VPC config
provided
([#&#8203;6814](https://github.com/weaveworks/eksctl/issues/6814))
- Paginate instance type offerings response
([#&#8203;6832](https://github.com/weaveworks/eksctl/issues/6832))

#### 🧰 Maintenance

- Bump dependencies
([#&#8203;6852](https://github.com/weaveworks/eksctl/issues/6852),
[#&#8203;6859](https://github.com/weaveworks/eksctl/issues/6859))
- Cleanup Flux Integration
([#&#8203;6836](https://github.com/weaveworks/eksctl/issues/6836))

#### Acknowledgments

Weaveworks would like to sincerely thank:
[@&#8203;watany-dev](https://github.com/watany-dev)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 4pm on thursday" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/scottames/dots).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4yNy4xIiwidXBkYXRlZEluVmVyIjoiMzYuMjcuMSIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@stefanhaller stefanhaller mentioned this pull request Dec 17, 2023
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature For large enhancements that add a new chunk of functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants