v0.41.0
Hold on tight because this is a HUGE release! This release includes a whopping 595 commits from a period of over 7 months, from 40 different contributors. Thanks to everybody who made this possible, and apologies for taking so long to actually release it: we'll be more frequent in future!
Special thanks to Stefan Haller who is behind many of this release's changes and who has been critical in getting this release across the line.
I've made a video running through the big changes here:
What's Changed
Here's some highlighted features:
Range select
You can now press 'v' to toggle range select in any list view, just like you already could in the staging view. You can also press shift+up/down to select a range. You can use range select to:
- stage/discard a range of files
- select multiple commits to fixup/squash/move outside an interactive rebase
- select multiple commits to mark as fixup/squash/etc within an interactive rebase
- select multiple commit files to discard or add to a custom patch (courtesy of @afhoffman)
- select multiple commits to cherry-pick
I have been waiting for this feature for a very long time and it's already made me way more productive. If I need to squash a range of commits I can now easily do it directly rather than needing to squash them one-by-one, or needing to manually start an interactive rebase first. Likewise, it's much easier to select a range of files and stage them than stage them one-by-one.
This is a Breaking change: Unfortunately, the 'v' key clashes with the existing key for pasting commits (cherry-pick), so we've replaced that with shift+V and changed the commit copy key to shift+C. If you want the old keybindings back, you can do that like so:
keybinding:
universal:
toggleRangeSelect: <something other than v>
commits:
cherryPickCopy: 'c'
pasteCommits: 'v'
Auto-wrap in commit editor
The commit editor now automatically hard-wraps your content by default, so you no longer need to hit the enter key yourself when you approach the margin. You can disable/configure this in your config:
git:
commit:
autoWrapCommitMessage: true
autoWrapWidth: 72
Thanks to @stefanhaller for this feature.
Easier remote branch checkout
Now when you go to checkout a remote branch, either via the c
keybinding in the branches view or by pressing space
on a remote branch, you'll be given the choice to checkout as a local branch or as a detached head (previously it would just check it out as a detached head which typically isn't what you want). This is a Breaking change in terms of muscle memory.
Thanks to @stefanhaller for this feature.
Easier start interactive rebase
Previously, to start an interactive rebase, you would need to navigate to a base commit and press e
on it. Now you can simply press i
and regardless of which commit is selected, an interactive rebase will begin that includes all the commits on your branch (or if there are merge commits: all the commits up to first merge commit).
The above demo for range select showcases this.
Easier squashing of fixup!
commits
In a similar vein to the above section, now when you press shift+S
, you're given the choice of squashing all commits above the selected commit and squashing all commits on the branch, which is what you typically want. This is a Breaking change in terms of muscle memory.
Thanks to @stefanhaller for this feature.
View divergence from upstream branch
If you press u
on a local branch a menu appears which shows options relating to the branch's upstream. Now, the first option in that menu allows you to view the divergence from the upstream which shows commits to pull and commits to push
Thanks to @stefanhaller for this feature.
Find appropriate commit for fixup/amend
This one is some serious voodoo: if somebody suggests changes in a PR review, you'll often apply the changes, then go hunting for the appropriate commit to fixup/amend. Now, from the files view you can press ctrl+f
and if Lazygit can identify an appropriate commit with certainty, it will select that commit for you. Pretty cool!
We've made the algorithm very strict so that you can always trust the result, but this means in circumstances where we can't know for sure which commit is appropriate (such as when your changes only include added lines), it's left to you to manually find the commit. We're keen to get lots of feedback on this feature to see where the sweet spot is.
For more info see the docs
Thanks to @stefanhaller for this feature.
Delete remote branches/tags
Now when you press d
on a local branch, remote branch, or tag, you're given the option to delete that branch/tag in the remote.
Thanks to @AzraelSec for this feature.
Add co-author to commit
When you press a
on a commit an option now appears to add a co-author (something GitHub can read).
Thanks to @omaussa for this feature.
Filter commits by author
You can now filter commits by author via pressing ctrl+s
in the commits view and selecting the option to filter by author.
Thanks to @part22 for this feature.
Change branch sort order
You can now change branch sort order by pressing s
in the branches view (and remote branches view). By default local branches are sorted by 'recency' meaning how recently they were checked out, but you can now sort by head commit date and alphabetically.
Thanks to @hosaka for this feature.
Better bare repo support
We have fixed a bunch of bugs relating to bare repos so if you had issues with them in the past it should work fine now.
Thanks to @jwhitley for this feature.
Miscelleneous UI changes
- Unstaged files are now shown in white, not red, which is easier on the eyes
- Scrollbars are thinner (and, thus, cooler)
- Keybindings menu now has section headers (@stefanhaller)
- Error toasts now appear for some errors (less intrusive than popups) (@stefanhaller)
- Search history is now retained (@karimkhaleel)
- Git log is shown by default (@stefanhaller)
More Breaking Changes π₯
- When you press 'g' to bring up the git reset menu, the 'mixed' option is now the first and default, rather than 'soft'. This is because 'mixed' is the most commonly used option.
- Push/pull/fetch loading statuses are now shown against the branch rather than in a popup. This allows you to e.g. fetch multiple branches in parallel and see the status for each branch.
- The git log graph in the commits view is now always shown by default (previously it was only shown when the view was maximised). If you find this too noisy, you can change it back via
ctrl+L
-> 'Show git graph' -> 'when maximised' - Filtering (e.g. when pressing '/') is less fuzzy by default; it only matches substrings now. Multiple substrings can be matched by separating them with spaces. If you want to revert to the old behavior, set the following in your config:
gui:
filterMode: 'fuzzy'
What's Changed
All Enhancements π₯
- Add range selection ability on list contexts by @jesseduffield in #3207
- Allow deleting remote tags/branches from local tag/branch views by @AzraelSec in #2738
- Add command to show divergence from upstream by @stefanhaller in #2871
- Add 'Quick start interactive rebase' action by @jesseduffield in #3213
- Add command to open git difftool by @stefanhaller in #3156
- Support editing files in existing neovim instance by @jesseduffield in #2916
- Show commit mark before showing extra info by @jesseduffield in #2928
- Jump to middle of the view when selection leaves the visible area by @stefanhaller in #2915
- Add emacs-keybinds for word navigation by @horriblename in #2935
- Add
gui.scrollOffBehavior
config for scrolling list views by half-pages by @stefanhaller in #2939 - Switch to editor from commit message panel by @stefanhaller in #2881
- Select same commit again after pressing "e" to edit a commit by @stefanhaller in #2954
- Support custom keybindings for confirm discard by @mskelton in #2960
- Allow adding a port to webDomain part of services config by @raidora in #2908
- Add icons for files with .mdx and .svelte file extensions by @hrstmr in #2889
- Section headers in keybindings menu by @stefanhaller in #2911
- Check for staged files for "Amend commit" and "Create fixup commit" by @stefanhaller in #2970
- Add support for external diff commands (e.g. difftastic) by @stefanhaller in #2868
- Save diff context size in state.yml instead of config.yml by @stefanhaller in #2969
- Support to reset the current branch to a selected branch upstream by @AzraelSec in #2940
- Replace whitespace with '-' when renaming a branch by @calthejuggler in #2990
- Add jump-to-panel label config setting by @MariaSolOs in #2993
- Add co-author to commits by @omaussa in #2912
- Change the default of the "gui.borders" config to "rounded" by @stefanhaller in #2998
- Add a DisabledReason mechanism for menu items and keybindings by @stefanhaller in #2992
- Allow cherry-picking commits during a rebase by @stefanhaller in #3013
- Add history for search view by @karimkhaleel in #2877
- Replace loader panels with waiting status (pull/push/fetch) by @stefanhaller in #2973
- Add menu to rebase onto selected branch remote upstream by @AzraelSec in #3020
- Add ability to force portrait mode by @ldelossa in #3037
- Add Micro editor preset by @kytta in #3049
- Show sync status in branches list by @stefanhaller in #3021
- Add 'lvim' editor preset for lunarvim by @zottelsheep in #3074
- Truncate branch names to make branch status always visible by @stefanhaller in #3075
- Color file icons by @jesseduffield in #3080
- Add UserConfig jsonschema generation script by @karimkhaleel in #3039
- Add a copy-to-clipboard menu to the file view (with
diff
copy options) by @AzraelSec in #3104 - Fix bottom line alignment by @stefanhaller in #3076
- Make move up/down blocking by @stefanhaller in #2966
- Add remote branch sorting menu by @hosaka in #3171
- Add age to stash entries by @AzraelSec in #3174
- Add local branch sorting menu by @hosaka in #3182
- Show a friendly error message when starting lazygit from a non-existent cwd by @simonwhitaker in #3192
- Replace copy commit SHA with copy commit subject on the y s keybind in the commits view by @karimkhaleel in #3188
- Add config setting for splitting window vertically in half screen mode by @stefanhaller in #3133
- Add command to find base commit for creating a fixup by @stefanhaller in #3105
- Show Toast instead of error panel when invoking a disabled command by @stefanhaller in #3180
- Show file names in default colour by @jesseduffield in #3081
- Add config setting to suppress showing file icons by @stefanhaller in #3216
- Support range select for rebase actions by @jesseduffield in #3232
- Make range selections created with the mouse non-sticky by @stefanhaller in #3234
- Support range select for staging/discarding files by @jesseduffield in #3248
- Inline status for fetching remotes by @stefanhaller in #3238
- Add shortcuts for filtering files by status by @mark2185 in #3137
- Keep same selection range when quick-starting an interactive rebase by @stefanhaller in #3247
- Add loads of tooltips by @jesseduffield in #3269
- Show better keybinding suggestions by @jesseduffield in #3203
- Support selecting file range in patch builder by @afhoffman in #3259
- Add command to squash all fixups in the current branch by @stefanhaller in #3274
- Use slimmer scrollbars by @jesseduffield in #3283
- Clear cherry-picked commits after pasting by @molejnik88 in #3240
- Change default of git.log.showGraph to 'always' by @stefanhaller in #3314
- Support range select removing files from a commit by @afhoffman in #3276
- Migrate git.log.showGraph and git.log.order to app state by @hosaka in #3197
- Change "git reset" default to --mixed by @stefanhaller in #3264
- Add author filtering to commit view by @part22 in #3302
- Provide two helix presets, one for "helix" and one for "hx" by @stefanhaller in #3346
- Don't show branch head on rebase todos if the rebase.updateRefs config is on by @stefanhaller in #3340
- Show all submodules recursively by @stefanhaller in #3341
- Support setting a range of commits to "edit" outside of a rebase by @stefanhaller in #3370
- Adjust selection after squashing fixups by @stefanhaller in #3338
- Auto-wrap commit message while typing by @stefanhaller in #3173
- Add Co-Author support to new commits by @2KAbhishek in #3097
- Show "breaking changes" message at startup by @stefanhaller in #3377
- Allow moving and deleting update-ref todos by @stefanhaller in #3391
- When checking out a remote branch by name, ask the user how by @stefanhaller in #3388
- Use substring filtering instead of fuzzy filtering by default by @stefanhaller in #3376
- Always prompt to return from subprocess if there was an error by @stefanhaller in #3410
- When adding a new remote, select it and fetch it by @stefanhaller in #3401
- Support editing multiple files at once using range selection by @stefanhaller in #3407
- Make it easy to create "amend!" commits by @stefanhaller in #3409
- Add config to truncate commit hashes when copying them to the clipboard by @stefanhaller in #3402
Fixes π§
- Fix issue where explosion effect was out-of-view by @jesseduffield in #2909
- Show dialogue when attempting to open info link fails by @simonwhitaker in #2899
- Fix jumping to the correct line from the staging view by @stefanhaller in #2919
- Fix sha colors when rebasing by @stefanhaller in #2946
- Fix the commit graph display after selection jumps in commits view by @stefanhaller in #2943
- Handle trailing slash in worktree path by @Krismix1 in #2947
- Fix escape not cancelling filter mode, but closing the menu instead by @stefanhaller in #2977
- Use
Error
method to handle commits url copy from unknown service by @AzraelSec in #3007 - Hide waiting status during credentials prompt by @stefanhaller in #3016
- Use upstream branch when opening pull requests by @mark2185 in #2693
- Fix issue where active search inappropriately changed selected line by @jesseduffield in #3022
- Respect $GIT_WORK_TREE and $GIT_DIR env vars (fix #3010). by @intrntbrn in #3024
- Fix crash when trying to filter the list of remotes by @stefanhaller in #3059
- Re-apply filter when model changes by @stefanhaller in #3058
- Use a PTY when calling external diff command by @AFutureD in #3120
- Re-enable 'Unset upstream' option when upstream branch is missing by @mark2185 in #3086
- Fall back to WithWaitingStatus if item is not visible by @stefanhaller in #3083
- Fix checking out a tag when there is a branch with the same name by @stefanhaller in #3179
- Fix preserving the commit message when description contains blank lines by @stefanhaller in #3170
- Allow multiple fetch commands (or fetch and pull) to run concurrently by @stefanhaller in #3202
- Support insteadOf URL rewriting when opening URLs in browser by @stefanhaller in #3177
- Fix keybindings for characters involving AltGr on Windows by @stefanhaller in #3194
- Do not include keybindings from another view in keybindings menu by @jesseduffield in #3220
- Fix crash with short branch names by @stefanhaller in #3219
- Keep same branch selected when fetching a branch while sorted by date by @stefanhaller in #3186
- Use git rev-parse to obtain repository and worktree paths by @jwhitley in #3183
- Pass absolute file paths to all editor commands by @stefanhaller in #3255
- Disallow cherry-picking merge commits by @stefanhaller in #3316
- Fix two problems related to update-ref rebase todo items by @stefanhaller in #3290
- Fix order of custom commands history by @stefanhaller in #3286
- Fix some problems with patches if
git diff
was customized with config (e.g.external
ornoprefix
). by @mricherzhagen in #3222 - Use $XDG_STATE_HOME for state.yml by @horriblename in #2936
- Fix display of Chinese characters on Windows by @stefanhaller in #3352
- Allow more than one argument in git.merging.args config by @stefanhaller in #3336
- Don't strike out reserved keys in menus by @stefanhaller in #3365
- Don't ask to force-push if the remote rejected updates by @stefanhaller in #3387
- Fix container detection by @aritmos in #3412
Maintenance βοΈ
- Add Click() to GuiDriver by @simonwhitaker in #2898
- Add Makefile by @kyu08 in #2937
- fix GitHub Actions warnings by @kyu08 in #2950
- Add instruction in PR template to start PRs with an imperative by @jesseduffield in #2967
- Don't show toasts when running integration tests by @stefanhaller in #2975
- Various debugging improvements by @stefanhaller in #3000
- Rename
test/results
totest/_results
by @stefanhaller in #3012 - Support passing -race flag to integration tests by @stefanhaller in #3019
- Improve debugging of integration tests by @stefanhaller in #3029
- Use go:generate for cheatsheet by @stefanhaller in #3035
- Change Makefile to build non-optimized by @stefanhaller in #3028
- Update PR template to use go generate command by @jesseduffield in #3041
- Band-aid fix for submodule/reset.go test failure by @stefanhaller in #3047
- Remove redundant
len
check by @Juneezee in #3051 - Add disabled compat for user config (#2833) by @karimkhaleel in #3060
- Fix go.mod file by @stefanhaller in #3118
- Capture test code coverage stats by @jesseduffield in #3135
- fixed typo in test description by @schuebel in #3101
- Update cheatsheets by @stefanhaller in #3143
- fix(config): add
yaml:"options"
struct tag toCustomCommandPrompt
.[]Options
by @lexor in #3163 - Set working directory in lazygit test command by @jesseduffield in #3215
- Fix CI erroneously marking failed tests as successful by @jesseduffield in #3221
- Fix cherrypick demo by @afhoffman in #3287
- Fix linter warnings by @stefanhaller in #3351
- Remove support for old style non-interactive rebase by @stefanhaller in #3348
Docs π
- Mention JSON schema by @EmilyGraceSeville7cf in #2893
- Add more demos by @jesseduffield in #2927
- Add compare-commits demo by @jesseduffield in #2929
- Feature add git flow instructions by @barthr in #2785
- Fix: Update 'zh' to 'zh-CN' in lazygit Language Configuration by @try-to-fly in #2842
- Add termux installation instructions to README by @jothi-prasath in #2892
- Add installation guide using winget CLI by @ErickRock in #2963
- Add install instructions for openSUSE by @pdostal in #2727
- Add comments in user config struct by @jesseduffield in #3040
- commmit - enhance docs for keybinding 'c' for local branch by @smangels in #3046
- Updated installation instruction for Gentoo by @hbenazha in #3113
- fix: MacOS default path misspelling by @zeromask1337 in #3148
- Add codebase guide by @jesseduffield in #3206
- Add NixOs installation instructions to README.md by @rsniezek in #3249
- Make the links in the status panel point to the current version rather than master by @stefanhaller in #3397
I18n π
- Update translations for polish language by @undg in #3389
- Fixed translations for zh_TW by @olivertzeng in #3393
Other Changes
- Improve prompts when amending commits by @stefanhaller in #2980
- Update Stacked_Branches.md by @apotterri in #3090
New Contributors
- @EmilyGraceSeville7cf made their first contribution in #2893
- @simonwhitaker made their first contribution in #2898
- @horriblename made their first contribution in #2935
- @kyu08 made their first contribution in #2937
- @barthr made their first contribution in #2785
- @try-to-fly made their first contribution in #2842
- @jothi-prasath made their first contribution in #2892
- @ErickRock made their first contribution in #2963
- @mskelton made their first contribution in #2960
- @raidora made their first contribution in #2908
- @pdostal made their first contribution in #2727
- @hrstmr made their first contribution in #2889
- @calthejuggler made their first contribution in #2990
- @MariaSolOs made their first contribution in #2993
- @omaussa made their first contribution in #2912
- @karimkhaleel made their first contribution in #2877
- @intrntbrn made their first contribution in #3024
- @ldelossa made their first contribution in #3037
- @kytta made their first contribution in #3049
- @Juneezee made their first contribution in #3051
- @zottelsheep made their first contribution in #3074
- @apotterri made their first contribution in #3090
- @AFutureD made their first contribution in #3120
- @smangels made their first contribution in #3046
- @schuebel made their first contribution in #3101
- @hbenazha made their first contribution in #3113
- @zeromask1337 made their first contribution in #3148
- @lexor made their first contribution in #3163
- @hosaka made their first contribution in #3171
- @jwhitley made their first contribution in #3183
- @afhoffman made their first contribution in #3259
- @molejnik88 made their first contribution in #3240
- @mricherzhagen made their first contribution in #3222
- @part22 made their first contribution in #3302
- @2KAbhishek made their first contribution in #3097
- @undg made their first contribution in #3389
- @olivertzeng made their first contribution in #3393
- @rsniezek made their first contribution in #3249
- @aritmos made their first contribution in #3412
Shameless Plug
I (Jesse) quit my day job and co-founded Subble, a startup that helps your company manage its SaaS subscriptions (discovery of subscriptions, onboarding/offboarding etc) to save you time and money. Check it out! https://www.subble.com/