diff --git a/lua/gitsigns/diff_int.lua b/lua/gitsigns/diff_int.lua index f9445273c..658cc0b84 100644 --- a/lua/gitsigns/diff_int.lua +++ b/lua/gitsigns/diff_int.lua @@ -102,11 +102,17 @@ function M.run_diff(fa, fb, linematch) for i = rs, rs + rc - 1 do hunk.removed.lines[#hunk.removed.lines + 1] = fa[i] or '' end + if rs + rc >= #fa and fa[#fa] ~= '' then + hunk.removed.no_nl_at_eof = true + end end if ac > 0 then for i = as, as + ac - 1 do hunk.added.lines[#hunk.added.lines + 1] = fb[i] or '' end + if as + ac >= #fb and fb[#fb] ~= '' then + hunk.added.no_nl_at_eof = true + end end hunks[#hunks + 1] = hunk end diff --git a/lua/gitsigns/hunks.lua b/lua/gitsigns/hunks.lua index 3b79dccaa..32938730e 100644 --- a/lua/gitsigns/hunks.lua +++ b/lua/gitsigns/hunks.lua @@ -11,6 +11,7 @@ local min, max = math.min, math.max --- @field start integer --- @field count integer --- @field lines string[] +--- @field no_nl_at_eof? true --- @class (exact) Gitsigns.Hunk.Hunk --- @field type Gitsigns.Hunk.Type @@ -265,10 +266,19 @@ function M.create_patch(relpath, hunks, mode_bits, invert) for _, l in ipairs(pre_lines) do results[#results + 1] = '-' .. l end + + if process_hunk.removed.no_nl_at_eof then + results[#results + 1] = '\\ No newline at end of file' + end + for _, l in ipairs(now_lines) do results[#results + 1] = '+' .. l end + if process_hunk.added.no_nl_at_eof then + results[#results + 1] = '\\ No newline at end of file' + end + process_hunk.removed.start = start + offset offset = offset + (now_count - pre_count) end diff --git a/test/actions_spec.lua b/test/actions_spec.lua index 24295a018..8eab693f1 100644 --- a/test/actions_spec.lua +++ b/test/actions_spec.lua @@ -302,4 +302,23 @@ describe('actions', function() command('Gitsigns prev_hunk') check_cursor({ 4, 0 }) end) + + it('can stage hunks with no NL at EOF', function() + setup_test_repo() + local newfile = helpers.newfile + exec_lua([[vim.g.editorconfig = false]]) + system("printf 'This is a file with no nl at eof' > "..newfile) + helpers.gitm({ + { 'add', newfile }, + { 'commit', '-m', 'commit on main' }, + }) + + edit(newfile) + check({ status = { head = 'master', added = 0, changed = 0, removed = 0 } }) + feed('x') + check({ status = { head = 'master', added = 0, changed = 1, removed = 0 } }) + command('Gitsigns stage_hunk') + check({ status = { head = 'master', added = 0, changed = 0, removed = 0 } }) + end) + end)