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

Encountered an error when using git_command in git_bcommits #2517

Open
keaising opened this issue May 22, 2023 · 5 comments · May be fixed by #2846
Open

Encountered an error when using git_command in git_bcommits #2517

keaising opened this issue May 22, 2023 · 5 comments · May be fixed by #2846
Labels
bug Something isn't working

Comments

@keaising
Copy link

keaising commented May 22, 2023

Description

In my use case, I use customized git_command in git_bcommits, and meet error

Error executing luv callback:
...repro/plugins/plenary.nvim/lua/plenary/async/control.lua:122: Oneshot channel can only send once
stack traceback:
        [C]: in function 'assert'
        ...repro/plugins/plenary.nvim/lua/plenary/async/control.lua:122: in function 'eof_tx'
        ...otfile/.repro/plugins/telescope.nvim/lua/telescope/_.lua:142: in function <...otfile/.repro/plugins/telescope.nvim/lua/telescope/_.lua:136>

But if I use default command, it's ok

My customized command:

git log --date="format:%y/%m/%d" --pretty="format:%C(auto) %h %ad %s"

Default command in Telescope

git log --pretty=oneline --abbrev-commit

I think maybe my customized command missed something needed, but I can not find the difference between the results of these two command

PS. This issue can be reliably reproduced only on some files. If you cannot reproduce it in your projects or files, please try this file https://github.com/keaising/dotfile/blob/master/nvim/.config/nvim/lua/plugins/telescope.lua , the issue can be reliably reproduced on it.

Neovim version

NVIM v0.9.0
Build type: Release
LuaJIT 2.1.0-beta3

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/share/nvim"

Run :checkhealth for more info

Operating system and version

ArchLinux, latest

Telescope version / branch / rev

master branch

checkhealth telescope

telescope: require("telescope.health").check()

Checking for required plugins ~
- OK plenary installed.
- OK nvim-treesitter installed.

Checking external dependencies ~
- OK rg: found ripgrep 13.0.0
- OK fd: found fd 8.7.0

===== Installed extensions ===== ~

Steps to reproduce

  1. git clone git@github.com:keaising/dotfile.git
  2. copy and paste minimal.lua content into minimal.lua in dotfile folder
  3. nvim -u minimal.lua nvim/.config/nvim/lua/plugins/telescope.lua
  4. Wait lazy install all plugins needed
  5. press gb can meet the error
  6. press gj will not meet the error

Expected behavior

No error

Actual behavior

Error executing luv callback:
...repro/plugins/plenary.nvim/lua/plenary/async/control.lua:122: Oneshot channel can only send once
stack traceback:
        [C]: in function 'assert'
        ...repro/plugins/plenary.nvim/lua/plenary/async/control.lua:122: in function 'eof_tx'
        ...otfile/.repro/plugins/telescope.nvim/lua/telescope/_.lua:142: in function <...otfile/.repro/plugins/telescope.nvim/lua/telescope/_.lua:136>

Minimal config

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
    vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({
        "git",
        "clone",
        "--filter=blob:none",
        "--single-branch",
        "https://github.com/folke/lazy.nvim.git",
        lazypath,
    })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
vim.keymap.set("n", "<Leader>e", "<Plug>(x-file-explorer)", { silent = true })
local M = {
    "nvim-telescope/telescope.nvim",
    dependencies = {
        "nvim-lua/plenary.nvim",
        "nvim-treesitter/nvim-treesitter",
    },
    config = function()
        local bufopts = { noremap = true, silent = true }
        local builtin = require("telescope.builtin")
        vim.keymap.set("n", "gb", function()
            builtin.git_bcommits({
                git_command = {
                    "git",
                    "log",
                    -- "--pretty=oneline",
                    -- "--abbrev-commit",
                    "--date=format:%y/%m/%d",
                    "--pretty=format:%C(auto) %h %ad %s",
                    "--follow",
                },
            })
        end, bufopts)
        vim.keymap.set("n", "gj", builtin.git_bcommits, bufopts)

        require("telescope").setup({})
    end,
}
local plugins = {
    M,
}
require("lazy").setup(plugins, {
    root = root .. "/plugins",
})
@keaising keaising added the bug Something isn't working label May 22, 2023
@jamestrew
Copy link
Contributor

I can reproduce this.

I dug around a little bit while I don't really have a solution, my instinct is telling me that that command is not very well suited for passing the output through pipes. At least not with how telescope currently works.

I played around with this bit of code. If you do as well, you should see that, for you command, after the first stdout chunk, each subsequent chunk appears to start with a new line. The telescope code doesn't handle that well. Try it with the original command, the new line comes after the chunk is done. Maybe the telescope code should handle this better, but also maybe git is being weird.

the code
local uv = vim.loop
local stdin = uv.new_pipe()
local stdout = uv.new_pipe()
local stderr = uv.new_pipe()

local handle, pid = uv.spawn("git", {
	args = {
		"log",
    -- "--pretty=oneline",
    -- "--abbrev-commit",
		"--date=format:%y/%m/%d",
		"--pretty=format:%h %ad %s",
		"--follow",
		"/tmp/testing/dotfile/nvim/.config/nvim/lua/plugins/telescope.lua",
	},
	stdio = {
		stdin,
		stdout,
		stderr,
	},
}, function(code, signal) -- on exit
	print("exit code", code)
	print("exit signal", signal)
end)

print("process opened", handle, pid)

stdout:read_start(function(err, data)
	assert(not err, err)
	if data then
		vim.print("stdout chunk", data)
	else
		vim.print("stdout end")
	end
end)

@keaising
Copy link
Author

Thanks for your instinct, I find a workround to solve this issue.

I create a bash script named gitlog.sh to output all content of git log in one time, so the content passed to Telescope will be processed only once, it works as my wish!

This is my script:

#!/usr/bin/env bash

# $1 is the file path from Telescope
git log --date="format:%y/%m/%d" --pretty="format:%C(auto) %h %ad %s" --follow $1 >/tmp/gitlog && cat /tmp/gitlog

And this is my Telescope config

    config = function()
        local bufopts = { noremap = true, silent = true }
        local builtin = require("telescope.builtin")
        vim.keymap.set("n", "gb", function()
            builtin.git_bcommits({
                git_command = { "/location/of/gitlog.sh" },
            })
        end, bufopts)
        vim.keymap.set("n", "gj", builtin.git_bcommits, bufopts)

        require("telescope").setup({})
    end,

@keaising
Copy link
Author

@jamestrew Do you think it's necessary to keep this issue open and let's work through it to solve the problem once and for all, or do we just stop here, there's already a workround anyway, after all not all bugs have to be fixed and it's not necessarily a Telescope's bug

@jamestrew
Copy link
Contributor

I think it's ok to leave it open. This might be something worth looking into deeper.

@nicos68
Copy link

nicos68 commented Apr 30, 2024

Thanks for your instinct, I find a workround to solve this issue.

I create a bash script named gitlog.sh to output all content of git log in one time, so the content passed to Telescope will be processed only once, it works as my wish!

This is my script:

#!/usr/bin/env bash

# $1 is the file path from Telescope
git log --date="format:%y/%m/%d" --pretty="format:%C(auto) %h %ad %s" --follow $1 >/tmp/gitlog && cat /tmp/gitlog

And this is my Telescope config

    config = function()
        local bufopts = { noremap = true, silent = true }
        local builtin = require("telescope.builtin")
        vim.keymap.set("n", "gb", function()
            builtin.git_bcommits({
                git_command = { "/location/of/gitlog.sh" },
            })
        end, bufopts)
        vim.keymap.set("n", "gj", builtin.git_bcommits, bufopts)

        require("telescope").setup({})
    end,

I tried your workaound, but I still get an empty window. However if I replace what’s inside of the gitlog.sh file with

git log --follow $1 >/tmp/gitlog && cat /tmp/gitlog

then I do get the result of git log in my telescope popup …

EDIT: If I just add an echo "" >> /tmp/gitlog command in the end it works

¯\_(ツ)_/¯

So the workaround becomes

git log --date="format:%y/%m/%d" --pretty="format:%C(auto) %h %ad %s" --follow $1 \
  >/tmp/gitlog \
  && echo "" >> /tmp/gitlog \
  && cat /tmp/gitlog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants