Refactor diff code

- Simplify external diff code and make it's api consistent with FFI diff.
- Move diff code into separate modules diff_ext and diff_ffi.
This commit is contained in:
Lewis Russell 2021-07-21 15:42:13 +01:00
parent b685aa405f
commit 0180dfd7ae
13 changed files with 474 additions and 222 deletions

View File

@ -593,6 +593,7 @@ word_diff *gitsigns-config-word_diff*
Type: `boolean`, Default: `false`
Highlight intra-line word differences in the buffer.
Requires `config.use_internal_diff = true` .
Uses the highlights:
• GitSignsAddLn

2
lua/gitsigns.lua generated
View File

@ -408,7 +408,7 @@ M.setup = void(function(cfg)
manager.apply_win_signs(bufnr, bcache.pending_signs, top + 1, bot + 1)
return config.word_diff
return config.word_diff and config.use_internal_diff
end,
on_line = function(_, _, bufnr, row)
manager.apply_word_diff(bufnr, row)

View File

@ -352,14 +352,16 @@ M.preview_hunk = function()
api.nvim_buf_set_var(cbuf, '_gitsigns_preview_open', true)
vim.cmd([[autocmd CursorMoved,CursorMovedI <buffer> ++once silent! unlet b:_gitsigns_preview_open]])
local regions = require('gitsigns.diff').run_word_diff(hunk.lines)
local offset = #lines - #hunk.lines
for _, region in ipairs(regions) do
local line, scol, ecol = region[1], region[3], region[4]
api.nvim_buf_set_extmark(bufnr, ns, line + offset - 1, scol, {
end_col = ecol,
hl_group = 'TermCursor',
})
if config.use_internal_diff then
local regions = require('gitsigns.diff_ffi').run_word_diff(hunk.lines)
local offset = #lines - #hunk.lines
for _, region in ipairs(regions) do
local line, scol, ecol = region[1], region[3], region[4]
api.nvim_buf_set_extmark(bufnr, ns, line + offset - 1, scol, {
end_col = ecol,
hl_group = 'TermCursor',
})
end
end
end

82
lua/gitsigns/diff_ext.lua generated Normal file
View File

@ -0,0 +1,82 @@
local git = require('gitsigns.git')
local gs_hunks = require("gitsigns.hunks")
local Hunk = gs_hunks.Hunk
local util = require('gitsigns.util')
local a = require('plenary.async')
local M = {}
local function write_to_file(path, text)
local f, err = io.open(path, 'wb')
if f == nil then
error(err)
end
for _, l in ipairs(text) do
f:write(l)
f:write('\n')
end
f:close()
end
M.run_diff = function(
text_cmp,
text_buf,
diff_algo)
local results = {}
if not util.is_unix then
a.util.scheduler()
end
local file_buf = util.tmpname() .. '_buf'
local file_cmp = util.tmpname() .. '_cmp'
write_to_file(file_buf, text_buf)
write_to_file(file_cmp, text_cmp)
git.command({
'-c', 'core.safecrlf=false',
'diff',
'--color=never',
'--diff-algorithm=' .. diff_algo,
'--patch-with-raw',
'--unified=0',
file_cmp,
file_buf,
}, {
on_stdout = function(_, line)
if vim.startswith(line, '@@') then
table.insert(results, gs_hunks.parse_diff_line(line))
elseif #results > 0 then
table.insert(results[#results].lines, line)
end
end,
})
os.remove(file_buf)
os.remove(file_cmp)
return results
end
return M

245
lua/gitsigns/diff_ffi.lua generated Normal file
View File

@ -0,0 +1,245 @@
local create_hunk = require("gitsigns.hunks").create_hunk
local Hunk = require('gitsigns.hunks').Hunk
local ffi = require("ffi")
ffi.cdef([[
typedef struct s_mmbuffer { const char *ptr; long size; } mmbuffer_t;
typedef struct s_xpparam {
unsigned long flags;
// See Documentation/diff-options.txt.
char **anchors;
size_t anchors_nr;
} xpparam_t;
typedef long (__stdcall *find_func_t)(
const char *line,
long line_len,
char *buffer,
long buffer_size,
void *priv
);
typedef int (__stdcall *xdl_emit_hunk_consume_func_t)(
long start_a, long count_a, long start_b, long count_b,
void *cb_data
);
typedef struct s_xdemitconf {
long ctxlen;
long interhunkctxlen;
unsigned long flags;
find_func_t find_func;
void *find_func_priv;
xdl_emit_hunk_consume_func_t hunk_func;
} xdemitconf_t;
typedef struct s_xdemitcb {
void *priv;
int (__stdcall *outf)(void *, mmbuffer_t *, int);
} xdemitcb_t;
int xdl_diff(
mmbuffer_t *mf1,
mmbuffer_t *mf2,
xpparam_t const *xpp,
xdemitconf_t const *xecfg,
xdemitcb_t *ecb
);
]])
local MMBuffer = {}
local function setup_mmbuffer(lines)
local text = vim.tbl_isempty(lines) and '' or table.concat(lines, '\n') .. '\n'
return text, #text
end
local XPParam = {}
local function get_xpparam_flag(diff_algo)
local daflag = 0
if diff_algo == 'minimal' then daflag = 1
elseif diff_algo == 'patience' then daflag = math.floor(2 ^ 14)
elseif diff_algo == 'histogram' then daflag = math.floor(2 ^ 15)
end
return daflag
end
local Long = {}
local XDEmitConf = {}
local M = {}
local DiffResult = {}
local mmba = ffi.new('mmbuffer_t')
local mmbb = ffi.new('mmbuffer_t')
local xpparam = ffi.new('xpparam_t')
local emitcb = ffi.new('xdemitcb_t')
local function run_diff_xdl(fa, fb, diff_algo)
mmba.ptr, mmba.size = setup_mmbuffer(fa)
mmbb.ptr, mmbb.size = setup_mmbuffer(fb)
xpparam.flags = get_xpparam_flag(diff_algo)
local results = {}
local hunk_func = ffi.cast('xdl_emit_hunk_consume_func_t', function(
start_a, count_a, start_b, count_b)
local ca = tonumber(count_a)
local cb = tonumber(count_b)
local sa = tonumber(start_a)
local sb = tonumber(start_b)
if ca > 0 then sa = sa + 1 end
if cb > 0 then sb = sb + 1 end
results[#results + 1] = { sa, ca, sb, cb }
return 0
end)
local emitconf = ffi.new('xdemitconf_t')
emitconf.hunk_func = hunk_func
local ok = ffi.C.xdl_diff(mmba, mmbb, xpparam, emitconf, emitcb)
hunk_func:free()
return ok == 0 and results
end
jit.off(run_diff_xdl)
function M.run_diff(fa, fb, diff_algo)
local results = run_diff_xdl(fa, fb, diff_algo)
local hunks = {}
for _, r in ipairs(results) do
local rs, rc, as, ac = unpack(r)
local hunk = create_hunk(rs, rc, as, ac)
hunk.head = ('@@ -%d%s +%d%s @@'):format(
rs, rc > 0 and ',' .. rc or '',
as, ac > 0 and ',' .. ac or '')
if rc > 0 then
for i = rs, rs + rc - 1 do
table.insert(hunk.lines, '-' .. (fa[i] or ''))
end
end
if ac > 0 then
for i = as, as + ac - 1 do
table.insert(hunk.lines, '+' .. (fb[i] or ''))
end
end
table.insert(hunks, hunk)
end
return hunks
end
local Region = {}
local gaps_between_regions = 5
function M.run_word_diff(hunk_body)
local removed, added = 0, 0
for _, line in ipairs(hunk_body) do
if line:sub(1, 1) == '-' then
removed = removed + 1
elseif line:sub(1, 1) == '+' then
added = added + 1
end
end
if removed ~= added then
return {}
end
local ret = {}
for i = 1, removed do
local rline = hunk_body[i]:sub(2)
local aline = hunk_body[i + removed]:sub(2)
local a, b = vim.split(rline, ''), vim.split(aline, '')
local hunks0 = {}
for _, r in ipairs(run_diff_xdl(a, b)) do
local rs, rc, as, ac = unpack(r)
if rc == 0 then rs = rs + 1 end
if ac == 0 then as = as + 1 end
hunks0[#hunks0 + 1] = create_hunk(rs, rc, as, ac)
end
local hunks = { hunks0[1] }
for i = 2, #hunks0 do
local h, n = hunks[#hunks], hunks0[i]
if not h or not n then break end
if n.added.start - h.added.start - h.added.count < gaps_between_regions then
h.added.count = n.added.start + n.added.count - h.added.start
h.removed.count = n.removed.start + n.removed.count - h.removed.start
if h.added.count > 0 or h.removed.count > 0 then
h.type = 'change'
end
else
hunks[#hunks + 1] = n
end
end
for _, h in ipairs(hunks) do
local rem = { i, h.type, h.removed.start, h.removed.start + h.removed.count }
local add = { i + removed, h.type, h.added.start, h.added.start + h.added.count }
ret[#ret + 1] = rem
ret[#ret + 1] = add
end
end
return ret
end
return M

96
lua/gitsigns/git.lua generated
View File

@ -82,7 +82,6 @@ local M = {BlameInfo = {}, Version = {}, Obj = {}, }
local Obj = M.Obj
@ -117,7 +116,7 @@ local function check_version(version)
return true
end
local command = a.wrap(function(args, spec, callback)
M.command = a.wrap(function(args, spec, callback)
local result = {}
local reserr
spec = spec or {}
@ -176,7 +175,7 @@ local get_repo_info = function(path, cmd)
a.util.scheduler()
local results = command({
local results = M.command({
'rev-parse', '--show-toplevel', git_dir_opt, '--abbrev-ref', 'HEAD',
}, {
command = cmd or 'git',
@ -193,77 +192,12 @@ local get_repo_info = function(path, cmd)
return toplevel, gitdir, abbrev_head
end
local function write_to_file(path, text)
local f, err = io.open(path, 'wb')
if f == nil then
error(err)
end
for _, l in ipairs(text) do
f:write(l)
f:write('\n')
end
f:close()
end
M.run_diff = function(
staged,
text,
diff_algo)
local results = {}
if not util.is_unix then
a.util.scheduler()
end
local buffile = util.tmpname() .. '_buf'
write_to_file(buffile, text)
command({
'-c', 'core.safecrlf=false',
'diff',
'--color=never',
'--diff-algorithm=' .. diff_algo,
'--patch-with-raw',
'--unified=0',
staged,
buffile,
}, {
on_stdout = function(_, line)
if startswith(line, '@@') then
table.insert(results, gs_hunks.parse_diff_line(line))
elseif #results > 0 then
table.insert(results[#results].lines, line)
end
end,
})
os.remove(buffile)
return results
end
M.set_version = function(version)
if version ~= 'auto' then
M.version = parse_version(version)
return
end
local results = command({ '--version' })
local results = M.command({ '--version' })
local line = results[1]
assert(startswith(line, 'git version'), 'Unexpected output: ' .. line)
local parts = vim.split(line, '%s+')
@ -278,7 +212,7 @@ end
Obj.command = function(self, args, spec)
spec = spec or {}
spec.cwd = self.toplevel
return command({ '--git-dir=' .. self.gitdir, unpack(args) }, spec)
return M.command({ '--git-dir=' .. self.gitdir, unpack(args) }, spec)
end
Obj.update_abbrev_head = function(self)
@ -336,24 +270,6 @@ Obj.get_show_text = function(self, object)
})
end
Obj.get_show = function(self, object, output_file)
local outf, err = io.open(output_file, 'wb')
if outf == nil then
error(err)
end
self:command({ 'show', object }, {
supress_stderr = true,
on_stdout = function(_, line)
outf:write(line)
outf:write('\n')
end,
})
outf:close()
end
Obj.run_blame = function(self, lines, lnum)
local results = self:command({
'blame',
@ -431,14 +347,14 @@ Obj.new = function(file)
local self = setmetatable({}, { __index = Obj })
self.file = file
self.username = command({ 'config', 'user.name' })[1]
self.username = M.command({ 'config', 'user.name' })[1]
self.toplevel, self.gitdir, self.abbrev_head =
get_repo_info(util.dirname(file))
if M.enable_yadm and not self.gitdir then
if vim.startswith(file, os.getenv('HOME')) and
#command({ 'ls-files', file }, { command = 'yadm' }) ~= 0 then
#M.command({ 'ls-files', file }, { command = 'yadm' }) ~= 0 then
self.toplevel, self.gitdir, self.abbrev_head =
get_repo_info(util.dirname(file), 'yadm')
end

View File

@ -17,8 +17,10 @@ local gs_debug = require("gitsigns.debug")
local dprint = gs_debug.dprint
local eprint = gs_debug.eprint
local util = require('gitsigns.util')
local git = require('gitsigns.git')
local gs_hunks = require("gitsigns.hunks")
local Hunk = gs_hunks.Hunk
local setup_highlight = require('gitsigns.highlight').setup_highlight
local config = require('gitsigns.config').config
@ -148,7 +150,7 @@ M.apply_word_diff = function(bufnr, row)
for _, hunk in ipairs(cache[bufnr].hunks) do
if lnum >= hunk.start and lnum <= hunk.vend then
local size = #hunk.lines / 2
local regions = require('gitsigns.diff').run_word_diff(hunk.lines)
local regions = require('gitsigns.diff_ffi').run_word_diff(hunk.lines)
for _, region in ipairs(regions) do
local line = region[1]
if lnum == hunk.start + line - size - 1 and
@ -192,16 +194,17 @@ local update0 = function(bufnr, bcache)
local compare_object = bcache.get_compare_obj(bcache)
if config.use_internal_diff then
local diff = require('gitsigns.diff')
if not bcache.compare_text or config._refresh_staged_on_update then
bcache.compare_text = git_obj:get_show_text(compare_object)
end
bcache.hunks = diff.run_diff(bcache.compare_text, buftext, config.diff_algorithm)
else
git_obj:get_show(compare_object, bcache.compare_file)
bcache.hunks = git.run_diff(bcache.compare_file, buftext, config.diff_algorithm)
if not bcache.compare_text or config._refresh_staged_on_update then
bcache.compare_text = git_obj:get_show_text(compare_object)
end
local run_diff
if config.use_internal_diff then
run_diff = require('gitsigns.diff_ffi').run_diff
else
run_diff = require('gitsigns.diff_ext').run_diff
end
bcache.hunks = run_diff(bcache.compare_text, buftext, config.diff_algorithm)
bcache.pending_signs = gs_hunks.process_hunks(bcache.hunks)
scheduler()

View File

@ -408,7 +408,7 @@ M.setup = void(function(cfg: Config)
manager.apply_win_signs(bufnr, bcache.pending_signs, top+1, bot+1)
-- Returning false prevents the on_line callbacks
return config.word_diff
return config.word_diff and config.use_internal_diff
end,
on_line = function(_, _, bufnr: integer, row: integer)
manager.apply_word_diff(bufnr, row)

View File

@ -352,14 +352,16 @@ M.preview_hunk = function()
api.nvim_buf_set_var(cbuf, '_gitsigns_preview_open', true)
vim.cmd[[autocmd CursorMoved,CursorMovedI <buffer> ++once silent! unlet b:_gitsigns_preview_open]]
local regions = require('gitsigns.diff').run_word_diff(hunk.lines)
local offset = #lines - #hunk.lines
for _, region in ipairs(regions) do
local line, scol, ecol = region[1], region[3], region[4]
api.nvim_buf_set_extmark(bufnr as integer, ns, line + offset - 1, scol, {
end_col = ecol,
hl_group = 'TermCursor'
})
if config.use_internal_diff then
local regions = require('gitsigns.diff_ffi').run_word_diff(hunk.lines)
local offset = #lines - #hunk.lines
for _, region in ipairs(regions) do
local line, scol, ecol = region[1], region[3], region[4]
api.nvim_buf_set_extmark(bufnr as integer, ns, line + offset - 1, scol, {
end_col = ecol,
hl_group = 'TermCursor'
})
end
end
end

82
teal/gitsigns/diff_ext.tl Normal file
View File

@ -0,0 +1,82 @@
local git = require('gitsigns.git')
local gs_hunks = require("gitsigns.hunks")
local Hunk = gs_hunks.Hunk
local util = require('gitsigns.util')
local a = require('plenary.async')
local record M
-- Async function
run_diff: function({string}, {string}, string): {Hunk}
end
local function write_to_file(path: string, text: {string})
local f, err = io.open(path, 'wb')
if f == nil then
error(err)
end
for _, l in ipairs(text) do
f:write(l)
f:write('\n')
end
f:close()
end
M.run_diff = function(
text_cmp: {string},
text_buf: {string},
diff_algo: string
): {Hunk}
local results: {Hunk} = {}
if not util.is_unix then
-- tmpname must not be called in a callback on windows
a.util.scheduler()
end
local file_buf = util.tmpname()..'_buf'
local file_cmp = util.tmpname()..'_cmp'
write_to_file(file_buf, text_buf)
write_to_file(file_cmp, text_cmp)
-- Taken from gitgutter, diff.vim:
--
-- If a file has CRLF line endings and git's core.autocrlf is true, the file
-- in git's object store will have LF line endings. Writing it out via
-- git-show will produce a file with LF line endings.
--
-- If this last file is one of the files passed to git-diff, git-diff will
-- convert its line endings to CRLF before diffing -- which is what we want
-- but also by default outputs a warning on stderr.
--
-- warning: LF will be replace by CRLF in <temp file>.
-- The file will have its original line endings in your working directory.
--
-- We can safely ignore the warning, we turn it off by passing the '-c
-- "core.safecrlf=false"' argument to git-diff.
git.command({
'-c', 'core.safecrlf=false',
'diff',
'--color=never',
'--diff-algorithm='..diff_algo,
'--patch-with-raw',
'--unified=0',
file_cmp,
file_buf,
}, {
on_stdout = function(_, line: string)
if vim.startswith(line, '@@') then
table.insert(results, gs_hunks.parse_diff_line(line))
elseif #results > 0 then
table.insert(results[#results].lines, line)
end
end
})
os.remove(file_buf)
os.remove(file_cmp)
return results
end
return M

View File

@ -55,7 +55,7 @@ local record M
enable_yadm: boolean
set_version: function(string)
run_diff : function(string, {string}, string): {Hunk}
command : function(args: {string}, spec: GJobSpec): {string}, string
record Obj
toplevel : string
@ -73,7 +73,6 @@ local record M
update_abbrev_head : function(Obj)
update_file_info : function(Obj): boolean
unstage_file : function(Obj, string, string)
get_show : function(Obj, string, string)
get_show_text : function(Obj, string): {string}, string
run_blame : function(Obj, {string}, number): M.BlameInfo
file_info : function(Obj, string): string, string, string, boolean
@ -117,7 +116,7 @@ local function check_version(version: {number,number,number}): boolean
return true
end
local command = a.wrap(function(args: {string}, spec: GJobSpec, callback: function({string}, string))
M.command = a.wrap(function(args: {string}, spec: GJobSpec, callback: function({string}, string))
local result: {string} = {}
local reserr: string
spec = spec or {}
@ -176,7 +175,7 @@ local get_repo_info = function(path: string, cmd: string): string,string,string
-- https://github.com/lewis6991/gitsigns.nvim/pull/215
a.util.scheduler()
local results = command({
local results = M.command({
'rev-parse', '--show-toplevel', git_dir_opt, '--abbrev-ref', 'HEAD',
}, {
command = cmd or 'git',
@ -193,77 +192,12 @@ local get_repo_info = function(path: string, cmd: string): string,string,string
return toplevel, gitdir, abbrev_head
end
local function write_to_file(path: string, text: {string})
local f, err = io.open(path, 'wb')
if f == nil then
error(err)
end
for _, l in ipairs(text) do
f:write(l)
f:write('\n')
end
f:close()
end
M.run_diff = function(
staged: string,
text: {string},
diff_algo: string
): {Hunk}
local results: {Hunk} = {}
if not util.is_unix then
-- tmpname must not be called in a callback on windows
a.util.scheduler()
end
local buffile = util.tmpname()..'_buf'
write_to_file(buffile, text)
-- Taken from gitgutter, diff.vim:
--
-- If a file has CRLF line endings and git's core.autocrlf is true, the file
-- in git's object store will have LF line endings. Writing it out via
-- git-show will produce a file with LF line endings.
--
-- If this last file is one of the files passed to git-diff, git-diff will
-- convert its line endings to CRLF before diffing -- which is what we want
-- but also by default outputs a warning on stderr.
--
-- warning: LF will be replace by CRLF in <temp file>.
-- The file will have its original line endings in your working directory.
--
-- We can safely ignore the warning, we turn it off by passing the '-c
-- "core.safecrlf=false"' argument to git-diff.
command({
'-c', 'core.safecrlf=false',
'diff',
'--color=never',
'--diff-algorithm='..diff_algo,
'--patch-with-raw',
'--unified=0',
staged,
buffile,
}, {
on_stdout = function(_, line: string)
if startswith(line, '@@') then
table.insert(results, gs_hunks.parse_diff_line(line))
elseif #results > 0 then
table.insert(results[#results].lines, line)
end
end
})
os.remove(buffile)
return results
end
M.set_version = function(version: string)
if version ~= 'auto' then
M.version = parse_version(version)
return
end
local results = command{'--version'}
local results = M.command{'--version'}
local line = results[1]
assert(startswith(line, 'git version'), 'Unexpected output: '..line)
local parts = vim.split(line, '%s+')
@ -278,7 +212,7 @@ end
Obj.command = function(self: Obj, args: {string}, spec: GJobSpec): {string}, string
spec = spec or {}
spec.cwd = self.toplevel
return command({'--git-dir='..self.gitdir, unpack(args)}, spec)
return M.command({'--git-dir='..self.gitdir, unpack(args)}, spec)
end
Obj.update_abbrev_head = function(self: Obj)
@ -326,7 +260,7 @@ Obj.file_info = function(self: Obj, file: string): string, string, string, boole
end
Obj.unstage_file = function(self: Obj)
self:command{'reset', self.file }
self:command{'reset', self.file }
end
--- Get version of file in the index, return array lines
@ -336,24 +270,6 @@ Obj.get_show_text = function(self: Obj, object: string): {string}, string
})
end
--- Get version of file in the index, write lines to file
Obj.get_show = function(self: Obj, object: string, output_file: string)
-- On windows 'w' mode use \r\n instead of \n, see:
-- https://stackoverflow.com/a/43967013
local outf, err = io.open(output_file, 'wb')
if outf == nil then
error(err)
end
self:command({'show', object}, {
supress_stderr = true,
on_stdout = function(_, line: string)
outf:write(line)
outf:write('\n')
end
})
outf:close()
end
Obj.run_blame = function(self: Obj, lines: {string}, lnum: number): M.BlameInfo
local results = self:command({
'blame',
@ -431,14 +347,14 @@ Obj.new = function(file: string): Obj
local self = setmetatable({} as Obj, {__index = Obj})
self.file = file
self.username = command({'config', 'user.name'})[1]
self.username = M.command({'config', 'user.name'})[1]
self.toplevel, self.gitdir, self.abbrev_head =
get_repo_info(util.dirname(file))
-- Try yadm
if M.enable_yadm and not self.gitdir then
if vim.startswith(file, os.getenv('HOME'))
and #command({'ls-files', file}, {command = 'yadm'}) ~= 0 then
and #M.command({'ls-files', file}, {command = 'yadm'}) ~= 0 then
self.toplevel, self.gitdir, self.abbrev_head =
get_repo_info(util.dirname(file), 'yadm')
end

View File

@ -17,8 +17,10 @@ local gs_debug = require("gitsigns.debug")
local dprint = gs_debug.dprint
local eprint = gs_debug.eprint
local util = require('gitsigns.util')
local git = require('gitsigns.git')
local gs_hunks = require("gitsigns.hunks")
local Hunk = gs_hunks.Hunk
local setup_highlight = require('gitsigns.highlight').setup_highlight
local config = require('gitsigns.config').config
@ -148,7 +150,7 @@ M.apply_word_diff = function(bufnr: integer, row: integer)
for _, hunk in ipairs(cache[bufnr].hunks) do
if lnum >= hunk.start and lnum <= hunk.vend then
local size = #hunk.lines / 2
local regions = require('gitsigns.diff').run_word_diff(hunk.lines)
local regions = require('gitsigns.diff_ffi').run_word_diff(hunk.lines)
for _, region in ipairs(regions) do
local line = region[1]
if lnum == hunk.start + line - size - 1
@ -192,16 +194,17 @@ local update0 = function(bufnr: integer, bcache: CacheEntry)
local compare_object = bcache.get_compare_obj(bcache)
if config.use_internal_diff then
local diff = require('gitsigns.diff')
if not bcache.compare_text or config._refresh_staged_on_update then
bcache.compare_text = git_obj:get_show_text(compare_object)
end
bcache.hunks = diff.run_diff(bcache.compare_text, buftext, config.diff_algorithm)
else
git_obj:get_show(compare_object, bcache.compare_file)
bcache.hunks = git.run_diff(bcache.compare_file, buftext, config.diff_algorithm)
if not bcache.compare_text or config._refresh_staged_on_update then
bcache.compare_text = git_obj:get_show_text(compare_object)
end
local run_diff: function({string}, {string}, string): {Hunk}
if config.use_internal_diff then
run_diff = require('gitsigns.diff_ffi').run_diff
else
run_diff = require('gitsigns.diff_ext').run_diff
end
bcache.hunks = run_diff(bcache.compare_text, buftext, config.diff_algorithm)
bcache.pending_signs = gs_hunks.process_hunks(bcache.hunks)
scheduler()