lewis6991 / gitsigns.nvim

Git integration for buffers
MIT License
5.22k stars 191 forks source link

Support staging partial hunks #338

Closed ahmadov closed 2 years ago

ahmadov commented 3 years ago

Description

Staging the changes in the selected range (lines) does not work as expected. Instead, it stages the whole hunk.

Neovim version

NVIM v0.5.0 (Build type: Release LuaJIT 2.0.5)

Operating system and version

ArchLinux

Steps to reproduce

  1. git init
  2. touch test.txt
  3. git add -am "initial"
  4. echo 'foo\nbar' > test.txt
  5. nvim -nu minimal.lua test.txt
  6. Enter visual mode and select only the first line
  7. Press <space>hs

Expected behavior

Stage the changes only in the selected range.

Actual behavior

Do not stage the changes in the selected range but stage the whole hunk.

Gitsigns debug messages

setup_highlight: Deriving GitSignsDelete from DiffDelete
setup_highlight: Highlight GitSignsDelete is already defined setup_highlight: Deriving GitSignsAdd from DiffAdd setup_highlight: Deriving GitSignsChange from DiffChange setup_highlight: Highlight GitSignsChange is already defined run_job: git --no-pager --version attach(1): Attaching (trigger=BufRead) run_job: git --no-pager config user.name run_job: git --no-pager rev-parse --show-toplevel --absolute-git-dir --abbrev-ref HEAD run_job: git --no-pager --git-dir=/tmp/gitsigns/.git ls-files --stage --others --exclude-standard /tmp/gitsigns/test.txt watch_index(1): Watching index run_job: git --no-pager --git-dir=/tmp/gitsigns/.git show :0:test.txt update(1): updates: 1, jobs: 5 run_job: git --no-pager --git-dir=/tmp/gitsigns/.git apply --whitespace=nowarn --cached --unidiff-zero - run_job: git --no-pager --git-dir=/tmp/gitsigns/.git show :0:test.txt update(1): updates: 2, jobs: 7 watcher_cb(1): Index update run_job: git --no-pager rev-parse --show-toplevel --absolute-git-dir --abbrev-ref HEAD run_job: git --no-pager --git-dir=/tmp/gitsigns/.git ls-files --stage --others --exclude-standard /tmp/gitsigns/test.txt run_job: git --no-pager --git-dir=/tmp/gitsigns/.git show :0:test.txt update(1): updates: 3, jobs: 10

Minimal config

vim.cmd [[set runtimepath=$VIMRUNTIME]]
vim.cmd [[set packpath=/tmp/nvim/site]]
local package_root = '/tmp/nvim/site/pack'
local install_path = package_root .. '/packer/start/packer.nvim'

if vim.fn.isdirectory(install_path) == 0 then
  print("Installing Gitsigns and dependencies.")
  vim.fn.system { 'git', 'clone', '--depth=1', 'https://github.com/wbthomason/packer.nvim', install_path }
end

-- Load plugins
require('packer').startup {
  {
    'wbthomason/packer.nvim',
    {
      'lewis6991/gitsigns.nvim',
      requires = { 'nvim-lua/plenary.nvim' },
    },
    -- ADD PLUGINS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
  },
  config = {
    package_root = package_root,
    compile_path = install_path .. '/plugin/packer_compiled.lua',
    display = { non_interactive = true },
  },
}

_G.load_config = function()
  require('gitsigns').setup{
    debug_mode = true, -- You must add this to enable debug messages
    signs = {
      ...
    },
    numhl = false,
    linehl = false,
    word_diff  = false,
    keymaps = {
      noremap = true,
      buffer = true,
      ['n <leader>hs'] = "<cmd>lua require('gitsigns').stage_hunk()<CR>",
      ['v <leader>hs'] = "<cmd>lua require('gitsigns').stage_hunk({vim.fn.line('.'), vim.fn.line('v')})<CR>",
    },
    ...
  }

  -- ADD INIT.LUA SETTINGS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE

  -- ALSO INCLUDE GITSIGNS DEBUG MESSAGES
  vim.cmd('Gitsigns debug_messages')
end

require('packer').sync()

vim.cmd [[autocmd User PackerComplete ++once echo "Ready!" | lua load_config()]]
lewis6991 commented 3 years ago

Partial staging is not yet supported, it is listed as a to-do in the README

RaafatTurki commented 3 years ago

This is highly needed, I sometimes find it difficult to stage my changes without playing the silly game of "lets delete that addition, stage the hunk and paste it back in".

zapling commented 3 years ago

How would you solve this in a normal git flow?

lewis6991 commented 3 years ago

I guess you wouldn't, which is why this feature would be really useful.

zapling commented 3 years ago

Right, just trying to get a understanding of how one would implement this. I read in the table that Gitgutter have this, so I might take a look at how they solved it there.

gegoune commented 3 years ago

Neogit also has such functionality. Allows for staging line by line.

lewis6991 commented 3 years ago

This looks like the code: https://github.com/TimUntersberger/neogit/blob/60832ae311f98eacd9245e72fe333cfd6b5de584/lua/neogit/status.lua#L449