-
-
Notifications
You must be signed in to change notification settings - Fork 194
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
Staging part of hunk causes signs for entire hunk to change to staged #929
Labels
bug
Something isn't working
Comments
Priority of this should probably be bumped up since #1039 is now merged. |
I can confirm that using |
ambroisie
added a commit
to ambroisie/nix-config
that referenced
this issue
Jul 12, 2024
ambroisie
added a commit
to ambroisie/nix-config
that referenced
this issue
Jul 19, 2024
ambroisie
added a commit
to ambroisie/nix-config
that referenced
this issue
Jul 19, 2024
I don't think this issue is fully correct. See #1102 (comment) |
I think the following patch (PR #1152) may fix the issue: diff --git a/lua/gitsigns/manager.lua b/lua/gitsigns/manager.lua
index 4a5c07a..1f5edfc 100644
--- a/lua/gitsigns/manager.lua
+++ b/lua/gitsigns/manager.lua
@@ -26,30 +26,49 @@ local M = {}
--- @param bot integer
--- @param clear? boolean
--- @param untracked boolean
-local function apply_win_signs0(bufnr, signs, hunks, top, bot, clear, untracked)
+--- @return Gitsigns.Sign[]
+local function calc_win_signs(bufnr, signs, hunks, top, bot, clear, untracked)
if clear then
+ -- WARN: Stateful/impure action.
signs:remove(bufnr) -- Remove all signs
end
- for i, hunk in ipairs(hunks or {}) do
+ --- @type Gitsigns.Sign[]
+ local win_signs = {}
+
+ if clear and not hunks then
+ --- @type Gitsigns.Hunk.Hunk
+ local hunk = hunks[1]
+
--- @type Gitsigns.Hunk.Hunk?
- local next = hunks[i + 1]
+ local next = hunks[2]
-- To stop the sign column width changing too much, if there are signs to be
-- added but none of them are visible in the window, then make sure to add at
-- least one sign. Only do this on the first call after an update when we all
-- the signs have been cleared.
- if clear and i == 1 then
- signs:add(bufnr, Hunks.calc_signs(hunk, next, hunk.added.start, hunk.added.start, untracked))
+ for _, s in ipairs(Hunks.calc_signs(hunk, next, hunk.added.start, hunk.added.start, untracked)) do
+ win_signs[#win_signs + 1] = s
end
+ end
+
+ -- Calculate signs for the visible hunks.
+ for i, hunk in ipairs(hunks or {}) do
+ --- @type Gitsigns.Hunk.Hunk?
+ local next = hunks[i + 1]
if top <= hunk.vend and bot >= hunk.added.start then
- signs:add(bufnr, Hunks.calc_signs(hunk, next, top, bot, untracked))
+ for _, s in ipairs(Hunks.calc_signs(hunk, next, top, bot, untracked)) do
+ win_signs[#win_signs + 1] = s
+ end
end
+
if hunk.added.start > bot then
break
end
end
+
+ return win_signs
end
--- @param bufnr integer
@@ -59,9 +78,45 @@ end
local function apply_win_signs(bufnr, top, bot, clear)
local bcache = assert(cache[bufnr])
local untracked = bcache.git_obj.object_name == nil
- apply_win_signs0(bufnr, signs_normal, bcache.hunks, top, bot, clear, untracked)
+
+ -- Collect all normal signs (by line number).
+ --- @type table<integer, Gitsigns.Sign[]>
+ local normal_signs_by_lnum = {}
+ local normal_signs = calc_win_signs(bufnr, signs_normal, bcache.hunks, top, bot, clear, untracked)
+ for _, s in ipairs(normal_signs) do
+ normal_signs_by_lnum[s.lnum] = normal_signs_by_lnum[s.lnum] or {}
+ table.insert(normal_signs_by_lnum[s.lnum], s)
+ end
+
+ -- Collect all staged signs (by line number).
+ --- @type table<integer, Gitsigns.Sign[]>
+ local staged_signs_by_lnum = {}
+ if signs_staged then
+ local staged_signs =
+ calc_win_signs(bufnr, signs_staged, bcache.hunks_staged, top, bot, clear, false)
+ for _, s in ipairs(staged_signs) do
+ if not normal_signs_by_lnum[s.lnum] then
+ staged_signs_by_lnum[s.lnum] = staged_signs_by_lnum[s.lnum] or {}
+ table.insert(staged_signs_by_lnum[s.lnum], s)
+ end
+ end
+ end
+
+ -- Flatten and sort staged signs by line number.
+ --- @type Gitsigns.Sign[]
+ local staged_signs = {}
+ --- @type integer[]
+ local staged_signs_lnums = vim.tbl_keys(staged_signs_by_lnum)
+ table.sort(staged_signs_lnums)
+ for _, lnum in ipairs(staged_signs_lnums) do
+ for _, s in ipairs(staged_signs_by_lnum[lnum]) do
+ table.insert(staged_signs, s)
+ end
+ end
+
+ signs_normal:add(bufnr, normal_signs)
if signs_staged then
- apply_win_signs0(bufnr, signs_staged, bcache.hunks_staged, top, bot, clear, false)
+ signs_staged:add(bufnr, staged_signs)
end
end
Not a lua programmer, so it's not particularly pretty. |
YodaEmbedding
added a commit
to YodaEmbedding/gitsigns.nvim
that referenced
this issue
Dec 5, 2024
YodaEmbedding
added a commit
to YodaEmbedding/gitsigns.nvim
that referenced
this issue
Dec 5, 2024
YodaEmbedding
added a commit
to YodaEmbedding/gitsigns.nvim
that referenced
this issue
Dec 5, 2024
YodaEmbedding
added a commit
to YodaEmbedding/gitsigns.nvim
that referenced
this issue
Dec 5, 2024
YodaEmbedding
added a commit
to YodaEmbedding/gitsigns.nvim
that referenced
this issue
Dec 5, 2024
YodaEmbedding
added a commit
to YodaEmbedding/gitsigns.nvim
that referenced
this issue
Dec 5, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
Using experimental
_signs_staged_enable = true
is very helpful and worked pretty well for a long time until I noticed that staging part of hunk causes signs for entire hunk to change to staged. Entire hunk does not get staged though, only status column signs are incorrect.Neovim version
Operating system and version
MacOS 14.2.1
Expected behavior
Only signs for staged lines within larger hunk to change to staged while remaining signs stay at changed.
Actual behavior
Signs for entire hunk change to as if entire hunk was staged.
Minimal config
Steps to reproduce
mkdir temp; cd temp; git init
echo "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" > file
git add file
git commit -m initial
nvim --clean -u minimal.lua file
vip>
# mark entire file as edited, marks should show and stateu
for each line3jV3j
# select lines for staging:'<,'>Gitsigns stage_hunk
# attempt to stage selection onlyStep 8. causes signs for entire hunk (buffer in our case) to change to
s
. But that's not correct, as per git'a diff of stage area:Gitsigns debug messages
The text was updated successfully, but these errors were encountered: