vim.pack.add({ 'https://github.com/esmuellert/codediff.nvim' }) require('codediff').setup({ keymaps = { -- q closes the diff tab from inside it; gc is here too so the -- same key that opened things from the g/diff group also shuts them. view = { quit = { 'q', 'gc' } }, }, }) local function map(lhs, rhs, desc) vim.keymap.set('n', lhs, rhs, { desc = desc }) end map('gd', 'CodeDiff', 'Diff working tree') map('gh', 'CodeDiff history %', 'File history') map('gH', 'CodeDiff history', 'Branch history') -- A remote's cached HEAD, or nil if it has none. Kept current by -- remote.origin.followRemoteHEAD in the gitconfig and by `git sync`; without -- those this is whatever the default branch was at clone time. local function remote_head(remote) local prefix = 'refs/remotes/' .. remote .. '/' -- --quiet so a remote with no cached HEAD stays silent rather than having its -- error text come back as the branch name. local ref = vim.fn.systemlist('git symbolic-ref --quiet ' .. prefix .. 'HEAD')[1] if not ref or ref:sub(1, #prefix) ~= prefix then return nil end return ref:sub(#prefix + 1) end -- The base branch name varies per repo (main, master, totara-20, ...), so ask a -- remote rather than hardcoding one. origin first: in the fork workflow that is -- my fork, and `git sync` keeps its default branch level with upstream's. Only -- then upstream, then whatever remotes exist - `git remote` sorts them -- alphabetically, so first-available on its own can hand back a colleague's fork. local function default_branch() local candidates = { 'origin', 'upstream' } vim.list_extend(candidates, vim.fn.systemlist('git remote')) for _, remote in ipairs(candidates) do local branch = remote_head(remote) if branch then return branch end end return '' end map('gm', function() vim.ui.input({ prompt = 'Diff against: ', default = default_branch() }, function(rev) if rev and rev ~= '' then -- rev...HEAD is merge-base semantics: what this branch added, not what -- the base branch has moved on to since. vim.cmd('CodeDiff ' .. rev .. '...HEAD') end end) end, 'Diff against branch')