diffs.nvim/lua/diffs/git.lua
Barrett Ruth bf2c91f79f feat: add :Gdiff command for unified diff against git revision
Compares current buffer against any git revision (default HEAD), opens result
in vsplit with full diffs.nvim syntax highlighting.
2026-02-04 18:14:18 -05:00

66 lines
1.7 KiB
Lua

local M = {}
---@param filepath string
---@return string?
function M.get_git_dir(filepath)
local dir = vim.fn.fnamemodify(filepath, ':h')
local result = vim.fn.systemlist({ 'git', '-C', dir, 'rev-parse', '--git-dir' })
if vim.v.shell_error ~= 0 then
return nil
end
local git_dir = result[1]
if not git_dir then
return nil
end
if vim.startswith(git_dir, '/') then
return git_dir
end
return vim.fn.fnamemodify(dir .. '/' .. git_dir, ':p'):gsub('/+$', '')
end
---@param filepath string
---@return string?
function M.get_repo_root(filepath)
local dir = vim.fn.fnamemodify(filepath, ':h')
local result = vim.fn.systemlist({ 'git', '-C', dir, 'rev-parse', '--show-toplevel' })
if vim.v.shell_error ~= 0 then
return nil
end
return result[1]
end
---@param revision string
---@param filepath string
---@return string[]?, string?
function M.get_file_content(revision, filepath)
local repo_root = M.get_repo_root(filepath)
if not repo_root then
return nil, 'not in a git repository'
end
local rel_path = vim.fn.fnamemodify(filepath, ':.')
if vim.startswith(filepath, repo_root) then
rel_path = filepath:sub(#repo_root + 2)
end
local result = vim.fn.systemlist({ 'git', '-C', repo_root, 'show', revision .. ':' .. rel_path })
if vim.v.shell_error ~= 0 then
return nil, 'failed to get file at revision: ' .. revision
end
return result, nil
end
---@param filepath string
---@return string?
function M.get_relative_path(filepath)
local repo_root = M.get_repo_root(filepath)
if not repo_root then
return nil
end
if vim.startswith(filepath, repo_root) then
return filepath:sub(#repo_root + 2)
end
return vim.fn.fnamemodify(filepath, ':.')
end
return M