Skip to content

Conversation

@jstrot
Copy link
Contributor

@jstrot jstrot commented Jul 22, 2024

If the GIT_DIR environment variable is set, then running git checkout can fail to install plugins but also corupt the Git repository GIT_DIR is pointing to.


Here's a script to reproduce the issue.

#!/bin/bash

set -eu

cd "$(dirname "$0")"

rm -Rf tmp-repro-dir

export XDG_CONFIG_HOME=$(pwd)/tmp-repro-dir/config
export XDG_DATA_HOME=$(pwd)/tmp-repro-dir/share
export GIT_EDITOR=nvim

mkdir -p tmp-repro-dir/config/nvim
cat > tmp-repro-dir/config/nvim/init.lua <<EOF

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
local uv = vim.uv or vim.loop
if not uv.fs_stat(lazypath) then
  -- bootstrap lazy.nvim
  -- stylua: ignore
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath })
end
vim.opt.rtp:prepend(lazypath)

require('lazy').setup({
  {
    "nvim-treesitter/nvim-treesitter",
    opts = {
      auto_install = true,
    },
    config = function(_, opts)
      require('nvim-treesitter.install').prefer_git = true
      require('nvim-treesitter.configs').setup(opts)
    end,
  }
})

EOF

mkdir tmp-repro-dir/git-repo
cd tmp-repro-dir/git-repo
git init
export GIT_DIR=$(pwd)/.git

echo
echo "First nvim run to install plugins. Please :qa it."
echo -e "Press enter to continue." ; read
nvim

echo
echo "Next, performing a fake git commit to force treesitter to install the gitcommit parser."
echo "It is expected to fail."
echo -e "Press enter to continue." ; read
git commit --allow-empty

Save the above as "repro.sh", for example, and run it.


It creates a minimal Neovim configuration and an empty git repo. While doing a fake git commit, Treesitter will fail to install the gitcommit parser with the following message:

nvim-treesitter[gitcommit]: Error while checking out revision
fatal: reference is not a tree: aa5c279287f0895a7ebc76a06e55ac3e4b2df7c7

It can also corrupt the repo that GIT_DIR is pointing to, e.g.:

$ git status
error: invalid object 100644 8b79819533e4274f7b787580aa31461ba2aa67b7 for '.github/workflows/ci.yml'
fatal: unable to read ffb52abeccb5891893f58abc2f87944fc9760d00

This PR attempts to mitigate the issue by flat out refusing to install parsers while running within a Git session. The list of Git environments being used for detection is very broad: In my testing, setting GIT_DIR see ms to be a prerequisite to cause the issue but just unsetting it within Treesitter is not enough (although parser can install successfully) as it causes Git to set other variables such as GIT_INDEX_FILE and I suspect t hat may be the one doing the damage (corruption of the git repository).

@clason
Copy link
Contributor

clason commented Jul 22, 2024

Duplicate of #6745. The actual resolution is deprecating prefer_git (which is no longer needed).

@clason clason closed this Jul 22, 2024
@clason
Copy link
Contributor

clason commented Jul 22, 2024

(Although this is a cleaner fix than the closed PR.)

@clason clason linked an issue Jul 22, 2024 that may be closed by this pull request
@clason clason reopened this Jul 22, 2024
"GIT_PREFIX",
"GIT_WORK_TREE",
}) do
if luv.os_getenv(k) then
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if luv.os_getenv(k) then
if vim.uv.os_getenv(k) then

-- Git repository.
-- The check below will refuse to perform any risky action until a safe way
-- is implemented.
local luv = vim.loop
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
local luv = vim.loop

Comment on lines +292 to +297
-- Running `git clone` or `git checkout` while running under Git (such as
-- editing a `git commit` message) will likely fail to install parsers
-- (such as 'gitcommit') and can also corrupt the index file of the current
-- Git repository.
-- The check below will refuse to perform any risky action until a safe way
-- is implemented.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
-- Running `git clone` or `git checkout` while running under Git (such as
-- editing a `git commit` message) will likely fail to install parsers
-- (such as 'gitcommit') and can also corrupt the index file of the current
-- Git repository.
-- The check below will refuse to perform any risky action until a safe way
-- is implemented.
-- Running `git clone` or `git checkout` while running under Git (such as
-- editing a `git commit` message) will likely fail to install parsers
-- (such as 'gitcommit') and can also corrupt the index file of the current
-- Git repository. Check for typical Git environment variables and abort.

"GIT_WORK_TREE",
}) do
if luv.os_getenv(k) then
return vim.api.nvim_err_writeln("Refusing to install while embedded in a git session. Run ':TSInstall " .. project_name .. "' manually")
Copy link
Contributor

Choose a reason for hiding this comment

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

Please run stylua (from the repository root) on this file.

@clason
Copy link
Contributor

clason commented Jul 22, 2024

(and please allow maintainers to push to your PR; you should always open PRs from your personal fork, not some other org.)

@clason
Copy link
Contributor

clason commented Jul 22, 2024

superseded by #6960

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

:TSInstall while committing may break current git repo

2 participants