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

Undo deprecated? #1180

Closed
h0adp0re opened this issue Jan 21, 2025 · 14 comments
Closed

Undo deprecated? #1180

h0adp0re opened this issue Jan 21, 2025 · 14 comments

Comments

@h0adp0re
Copy link

Hello! First, thank you for maintaining this plugin, it's part of my daily Git interface.

A feature I frequently rely on is undo_stage_hunk. Recently, it was deprecated with the note "use gitsigns.stage_hunk() on staged signs". I tried to do that but I'm only getting the message "No hunk to stage" in my work buffer. These are my current keymaps:

map({ "n", "v" }, "<leader>hs", gs.stage_hunk, "Stage hunk")
map("n", "<leader>hu", gs.undo_stage_hunk, "Undo stage hunk")

Is the replacement feature not implemented yet? Or is this feature (as-is) going away?

@lewis6991
Copy link
Owner

It is implemented and those keymaps should work. I use it all the time.

@h0adp0re
Copy link
Author

How do you use them? After mistakenly staging a hunk, what do you do? Running stage_hunk again does nothing on my side.

@lewis6991
Copy link
Owner

You need to have staged signs enabled and you need to run stage_hunk with your cursor on lines with staged signs.

@spreiter
Copy link

I also just stumbled over an issue here, but only in visual mode. In normal mode it works as expected.

However in visual mode it does not. Only if the upmost line has a change, it works.

I also found adjusted config in the README:

    map('v', '<leader>hs', function()
      gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') })
    end)

But this only works to stage an area, not for un-staging.

@cjumel
Copy link

cjumel commented Jan 30, 2025

Hi, I'm also using gitsigns daily and I find it amazing, thanks a lot!
I also really like undo_stage_hunk, and I work without staged signs enabled, so not having to have the cursor on staged lines to unstage them is quite important for me. Is there a way to keep the undo_stage_hunk behavior after the deprecation?

@h0adp0re
Copy link
Author

Thanks @lewis6991, I just tried the signs_staged_enable feature, I didn't know it existed. I will have to keep it enabled now but since it's reliant on cursor position it's more cumbersome than the previous implementation. But it's more verbose, which I like again. But then again, now I have the visual noise of staged hunks which I didn't have before.

@spreiter Do you want to unstage just a part of a hunk?

@spreiter
Copy link

No, I was actually trying to unstage 2 hunks at once. I tested now the following in visual mode:

  • ✅ stage part of a hunk
  • ✅ stage entire hunk
  • ✅ stage one plus part of another hunk
  • ❌ unstage part of a hunk
  • ❌ unstage entire hunk
  • ❌ unstage more than one hunk

All done with the keybinding from the README file:

        '<leader>gs',
        function()
          require('gitsigns').stage_hunk { vim.fn.line '.', vim.fn.line 'v' }
        end,
        mode = 'v',

@lewis6991
Copy link
Owner

@h0adp0re It's hard to make everyone happy, but I don't want to be maintaining features that roughly achieve the same thing.

@lewis6991
Copy link
Owner

@spreiter the logic for how staging works is fairly straightforward. So straightforward, I can just paste the code.

  local hunk = get_hunk(bufnr, range, opts.greedy ~= false, false)

  local invert = false
  if not hunk then
    invert = true
    hunk = get_hunk(bufnr, range, opts.greedy ~= false, true)
  end

  if not hunk then
    api.nvim_echo({ { 'No hunk to stage', 'WarningMsg' } }, false, {})
    return
  end

  local err = bcache.git_obj:stage_hunks({ hunk }, invert)
  if err then
    message.error(err)
    return
  end

Gitsigns will first attempt to find a hunk (using range is supplied) by looking at unstaged signs. If no hunk can be found/created, it will try looking at staged signs.

@spreiter
Copy link

Yes, I checked it out. On the first glance it looked fine to me. I am not sure, what exactly is going wrong. Also in the get_hunk() function the range is sorted.

I added some vim.notify() calls for debugging. I selected lines 311 to 315 (all of them are stage already) and vim.inspect() of the the first call of get_hunk() returned the following:

{
  added = {
    count = 5,
    lines = { "    # 1", "    # 2", "    # 3", "    # 4", "    # 5" },
    start = 311
  },
  head = "@@ -308,5 +311,5 @@",
  removed = {
    count = 5,
    lines = { "    # 1", "    # 2", "    # 3", "    # 4", "    # 5" },
    start = 308
  },
  type = "change",
  vend = 315
}

I would need more time to fully understand, how it works..

@lewis6991
Copy link
Owner

lewis6991 commented Jan 30, 2025

I think I understand the issue. The problem is in get_hunk() the fields added.lines and removed.lines are being populated incorrectly.

To do this correctly:

  • for added.lines: top and bot need to be adjusted to equivalent range in the index file and the lines need to be pulled from bcache.compare_text (instead of the buffer).
  • for removed.lines: the lines need to be pulled from bcache.compare_text_head (instead of bcache.compare_text).

@lewis6991
Copy link
Owner

@spreiter 31d2dcd should fix staging staged signs in visual mode. It might have some bugs but appeared to work well enough when I tried it.

@spreiter
Copy link

Only when a hunk is partly staged and I try to un-stage in normal mode on a staged line, nothing happens, not even a message. If I stage the not staged line, it gets staged correctly. But I think this is a quite rare occasion 😉

Thanks for the update and sorry for injection into this issue.

@lewis6991
Copy link
Owner

If anything doesn't work, and you want it to, then please raise an issue report with precise information.

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

No branches or pull requests

4 participants