telescope.nvim
telescope.nvim copied to clipboard
fix(actions): detached worktrees not detected for git actions
Description
- Fixes an issue where git actions (checkout, switch branch, etc.) do not work when within a custom detached working tree (first introduced in https://github.com/nvim-telescope/telescope.nvim/pull/2597).
- Moves helper functions for setting git command options in __git.lua to lua/telescope/utils.lua so that they can be set directly in
utils.__git_command.
Type of change
- Bug fix (non-breaking change which fixes an issue)
How Has This Been Tested?
Tested the following pickers with detached/attached working trees and git worktrees.
- git_files
- git_status
- git_stash
- git_commits
- git_bcommits
- git_branches
Configuration:
- Neovim version (nvim --version): NVIM v0.10.0-dev-d70667a
- Operating system and version: MacOS 13.4
Checklist:
- [x] My code follows the style guidelines of this project (stylua)
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation (lua annotations)
@jamestrew Since you originally created the PR for the detached git_worktrees feature, do you mind reviewing these changes?
Now that I think about it, none of the git actions are inheriting the use_file_path, and use_git_root options passed into the builtin git pickers.
https://github.com/nvim-telescope/telescope.nvim/blob/b543aaa2c9cf8123ed2fe7dbb6c211a9cd415124/doc/telescope.txt#L1018-L1027
From what I can tell, it doesn't seem like the cwd used by any of the actions is even guaranteed to match the cwd that was passed into the picker — currently it's being retrieved from Telescope's internal state:
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
While I'm not yet entirely sure how telescope manages its internal state for pickers, it seems like it might be possible to store the options passed into any of the builtin get pickers via: https://github.com/nvim-telescope/telescope.nvim/blob/b543aaa2c9cf8123ed2fe7dbb6c211a9cd415124/lua/telescope/state.lua#L6-L9
If this is true, then they can retrieved with something like:
local opts = action_state.get_current_picker(prompt_bufnr).opts
local get_git_command_output = function(args, opts)
return utils.get_os_command_output(utils.__git_command(args, opts), opts.cwd)
end
get_git_command_output({ "checkout", "-b", new_branch }, opts))
Instead of how it's done currently:
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
utils.get_os_command_output(git_command { "checkout", "-b", new_branch }, cwd)
Hmm... yeah I see the issue and honestly it was a bit of an oversight on my part not handling the actions before merging that previous PR.
As far as getting access to the gitdir and toplevel fields inside actions, I have a couple of alternative solutions:
- inherit and extend the base picker and just add
gitdir/toplevel(and any other necessary fields) to it and use that for all git related pickers -- then I think we can just do like
local gitdir = action_state.get_current_picker(prompt_bufnr).gitdir
- bind the necessary fields to the finder but this might not work since some actions cause a refresh of the picker so the binding would get lost
- wrap all git actions, passing in necessary fields so the actions have access to them as part of the closure eg.
actions.git_create_branch = function(opts)
return function(prompt_bufnr)
-- has access to opts.gitdir, etc
end
end
-- then map like this
map({ "i", "n" }, "<c-a>", actions.git_create_branch(opts))
This way we can avoid resolving gitdir & toplevel each time want to call a git command I think.
Option 1 might be easiest but I don't think it's something we do.
@Conni2461 Is there an idiomatic way of passing arbitrary option fields for pickers to actions?
I dont like this solution at all. I think there is a good reason to just store the original passed opts inside the picker and then use these later in actions. That would simplify a lot.
But i also dont like the original solution for detached worktrees (with a default config option) and i think ill have to redo them as well
I've been working through setting up a bare git repository for managing my dotfiles. Been using the work around mentioned in the last comment of this issue.
https://github.com/nvim-telescope/telescope.nvim/issues/435
Works reasonably well but it got me digging into why git_files wasn't working out of the box and I found #2597 which links to this issue.
What's a little confusing is where along the line git_worktrees was dropped and why.
EDIT: Ah I see that's it's in master and not the 1.x branch.
I've been working through setting up a bare git repository for managing my dotfiles. Been using the work around mentioned in the last comment of this issue.
Some of the git pickers support a git_command option where you can pass these git env variables. But not all do. The aim of #2597 was to enable passing these git env vars to all git pickers (for multiple git worktrees if desired) at the top level telescope settings.
Problem with both these methods is that the actions related to the pickers still won't know about the env vars.
I think there is a good reason to just store the original passed opts inside the picker and then use these later in actions.
Yeah that's what I'd like to do if I'm interpreting this correctly. Like do something like this inside each of the git actions:
local current_picker = action_state.get_current_picker(prompt_bufnr)
local gitdir = current_picker.gitdir
local toplevel = current_picker.toplevel
Is this currently possible? I don't think I've seen example of something like this in the code base.