sindrets / diffview.nvim

Single tabpage interface for easily cycling through diffs for all modified files for any git rev.
Other
3.6k stars 101 forks source link

Saving in the index buffer after picking hunks stages the entire file #411

Closed devansh08 closed 11 months ago

devansh08 commented 11 months ago

Description

I'm trying to stage specific hunks in a file by following the steps in this section. But on using diffput on some hunks in the unstaged changes buffer and then saving with :w on the index buffer, the entire file's changes get staged. Recording of this behavior: https://asciinema.org/a/ZfJxCwsiLdl1m4k3GnzluX3t2 asciicast

I'm assuming what I'm doing should only stage the hunks I picked. Am I missing or misunderstanding anything here ?

For the config, I'm using the default example one given in the README. I'm still exploring this plugin and so I'm not fully sure yet if some part of the config is messing things for me. Do let me know if something needs to be checked there.

Thanks!

Expected behavior

Stage only the hunks picked using diffput

Actual behavior

Stages the entire file

Steps to reproduce

Recording of the behavior: https://asciinema.org/a/ZfJxCwsiLdl1m4k3GnzluX3t2

Health check

Output of :checkhealth diffview ``` ============================================================================== diffview: require("diffview.health").check() Checking plugin dependencies ~ - OK nvim-web-devicons installed. Checking VCS tools ~ - The plugin requires at least one of the supported VCS tools to be valid. - OK Git found. - OK Git is up-to-date. (2.41.0) - WARNING Configured `hg_cmd` is not executable: 'hg' ```

Log info

Relevant info from :DiffviewLog ``` [ERROR 2023-08-13 23:62:42.960 +0530] ...lazy/diffview.nvim/lua/diffview/vcs/adapters/hg/init.lua:50: [HgAdapter] Configured `hg_cmd` is not executable: 'hg' [INFO 2023-08-13 23:66:09.082 +0530] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-08-13 23:66:09.197 +0530] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 38 files successfully (72.390 ms) [INFO 2023-08-13 23:66:54.756 +0530] ...local/share/nvim/lazy/diffview.nvim/lua/diffview/lib.lua:24: [command call] :DiffviewOpen [INFO 2023-08-13 23:66:54.856 +0530] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 38 files successfully (63.150 ms) [INFO 2023-08-13 23:67:28.318 +0530] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 39 files successfully (55.339 ms) [INFO 2023-08-13 23:67:28.850 +0530] ...iffview.nvim/lua/diffview/scene/views/diff/diff_view.lua:483: [DiffView] Completed update for 39 files successfully (48.407 ms) ```

Neovim version

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

Operating system and version

Linux 6.4.10-arch1-1 x86_64 GNU/Linux

Minimal config

{
  "sindrets/diffview.nvim",
  branch = "main",
  opts = {
    diff_binaries = false, -- Show diffs for binaries
    enhanced_diff_hl = false, -- See ':h diffview-config-enhanced_diff_hl'
    git_cmd = { "git" },   -- The git executable followed by default args.
    use_icons = true,      -- Requires nvim-web-devicons
    show_help_hints = true, -- Show hints for how to open the help panel
    watch_index = true,    -- Update views and index buffers when the git index changes.
    icons = {              -- Only applies when use_icons is true.
      folder_closed = "",
      folder_open = "",
    },
    signs = {
      fold_closed = "",
      fold_open = "",
      done = "✓",
    },
    view = {
      -- Configure the layout and behavior of different types of views.
      -- Available layouts:
      --  'diff1_plain'
      --    |'diff2_horizontal'
      --    |'diff2_vertical'
      --    |'diff3_horizontal'
      --    |'diff3_vertical'
      --    |'diff3_mixed'
      --    |'diff4_mixed'
      -- For more info, see ':h diffview-config-view.x.layout'.
      default = {
        -- Config for changed files, and staged files in diff views.
        layout = "diff2_horizontal",
        winbar_info = false, -- See ':h diffview-config-view.x.winbar_info'
      },
      merge_tool = {
        -- Config for conflicted files in diff views during a merge or rebase.
        layout = "diff3_horizontal",
        disable_diagnostics = true, -- Temporarily disable diagnostics for conflict buffers while in the view.
        winbar_info = true,    -- See ':h diffview-config-view.x.winbar_info'
      },
      file_history = {
        -- Config for changed files in file history views.
        layout = "diff2_horizontal",
        winbar_info = false, -- See ':h diffview-config-view.x.winbar_info'
      },
    },
    file_panel = {
      listing_style = "tree",       -- One of 'list' or 'tree'
      tree_options = {              -- Only applies when listing_style is 'tree'
        flatten_dirs = true,        -- Flatten dirs that only contain one single dir
        folder_statuses = "only_folded", -- One of 'never', 'only_folded' or 'always'.
      },
      win_config = {                -- See ':h diffview-config-win_config'
        position = "left",
        width = 35,
        win_opts = {},
      },
    },
    file_history_panel = {
      log_options = { -- See ':h diffview-config-log_options'
        git = {
          single_file = {
            diff_merges = "combined",
          },
          multi_file = {
            diff_merges = "first-parent",
          },
        },
        hg = {
          single_file = {},
          multi_file = {},
        },
      },
      win_config = { -- See ':h diffview-config-win_config'
        position = "bottom",
        height = 16,
        win_opts = {},
      },
    },
    commit_log_panel = {
      win_config = { -- See ':h diffview-config-win_config'
        win_opts = {},
      },
    },
    default_args = { -- Default args prepended to the arg-list for the listed commands
      DiffviewOpen = {},
      DiffviewFileHistory = {},
    },
    hooks = {},             -- See ':h diffview-config-hooks'
    keymaps = {
      disable_defaults = false, -- Disable the default keymaps
    },
  },
}
sindrets commented 11 months ago

I'm assuming what I'm doing should only stage the hunks I picked. Am I missing or misunderstanding anything here ?

Yes, you've understood the process correctly. But I can't reproduce this. Please use the minimal config from the report template properly. It's there to help both you and me figure out whether your problem is related to your setup or to the plugin. You use the minimal config by saving it anywhere on your disk and then calling nvim with:

$ nvim --clean -n -u path/to/diffview_mini.lua
devansh08 commented 11 months ago

Hey, seems like I misunderstood the purpose of the minimal config in the template :sweat_smile: It does work perfectly with the minimal config. Adding the diffview config I shared above also does work. Seems like some other plugin or my own config is breaking this.

I'll try and incrementally check what might be breaking this. But any pointers or better approach to check this are welcome :)

Thanks!

devansh08 commented 11 months ago

Aaaand I've found the issue in my config :) I've an autocmd that runs jdtls.organize_imports() on filetype java that's triggered on BufWritePre. So I guess that's interfering with diffview telling what to write to index.

I'll probably look for ways to check how to identify if I'm in a DiffView type of buffer. Pls let me know if you have any suggestions for that :)

Thanks!

Edit: In case anyone lands in this situation, you can use hooks like view_opened, view_enter, view_closed and view_leave to figure out when you are in diffview mode.

sindrets commented 11 months ago

I'm glad you figured it out.

I'll probably look for ways to check how to identify if I'm in a DiffView type of buffer. Pls let me know if you have any suggestions for that :)

Thanks!

Edit: In case anyone lands in this situation, you can use hooks like view_opened, view_enter, view_closed and view_leave to figure out when you are in diffview mode.

You don't need to use hooks for this. As far as I can tell, what you actually want to assert is that the file path you're writing to could be a real path on your file system. In that case I assume that in most cases it would be enough to check that the file's parent directory exists:

vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = "*.java",
  callback = function(e)
    -- Ensure that the parent dir is a real path
    if vim.fn.isdirectory(vim.fn.fnamemodify(e.file, ":h")) == 1 then
      jdtls.organize_imports()
    end
  end,
})