@@ -91,39 +91,61 @@ local function git_preview(opts, file)
9191 return opts .preview
9292end
9393
94+ --- @param opts fzf-lua.config.GitBase |{}?
95+ --- @param ref string
96+ --- @return boolean
97+ local git_validate_ref = function (opts , ref )
98+ local cmd = path .git_cwd ({ " git" , " rev-parse" , " --verify" , ref }, opts --[[ @as table]] )
99+ local _ , exit_code = utils .io_systemlist (cmd --[[ @as string[] ]] )
100+ if exit_code ~= 0 then
101+ utils .warn (" Invalid git ref %s" , ref )
102+ return false
103+ end
104+ return true
105+ end
106+
94107--- @param opts fzf-lua.config.GitDiff |{}?
95108--- @return thread ?, string ?, table ?
96109M .diff = function (opts )
97110 --- @type fzf-lua.config.GitDiff
98111 opts = config .normalize_opts (opts , " git.diff" )
99112 if not opts then return end
100- -- Ensure that ref is a commit hash in this git repository.
101- local validation_ref = path . git_cwd ({ " git " , " rev-parse " , " --verify " , opts . ref }, opts )
102- local _ , exit_status_code_ref = utils . io_systemlist ( validation_ref )
103- if exit_status_code_ref ~= 0 then
104- utils . warn ( " Invalid git ref %s " , opts .ref )
105- return
113+ -- Backward compat `compare_against` -> `ref1`
114+ --- @diagnostic disable-next-line : undefined-field
115+ opts . ref1 = opts . compare_against or opts . ref1
116+ -- Convinience: ref as string array
117+ if type ( opts .ref ) == " table " then
118+ opts . ref , opts . ref1 = opts . ref [ 1 ], ( opts . ref [ 2 ] or opts . ref1 )
106119 end
107- -- If compare_against is given, ensure that it is a commit hash in this git repository.
108- if type (opts .compare_against ) == " string" and # opts .compare_against > 0 then
109- local validation_comp = path .git_cwd ({ " git" , " rev-parse" , " --verify" , opts .compare_against },
110- opts )
111- local _ , exit_code_status_comp = utils .io_systemlist (validation_comp )
112- if exit_code_status_comp ~= 0 then
113- utils .warn (" Invalid git ref %s" , opts .compare_against )
120+ -- Ensure supplied refs are valid in this git repository.
121+ for _ , r in ipairs ({ " ref" , " ref1" }) do
122+ if type (opts [r ]) == " string" and # opts [r ] > 0 and not git_validate_ref (opts , opts [r ]) then
114123 return
115124 end
116- else
117- -- Default to diffing against ref and its direct parent commit.
118- opts .compare_against = opts .ref .. " ^"
119125 end
120- opts .cmd = opts .cmd :gsub (" [<{]ref[}>]" , opts .ref )
121- opts .cmd = opts .cmd :gsub (" [<{]compare_against[}>]" , opts .compare_against )
122- opts .preview = opts .preview :gsub (" [<{]ref[}>]" , opts .ref )
123- opts .preview = opts .preview :gsub (" [<{]compare_against[}>]" , opts .compare_against )
126+ -- If no ref was supplied default to last commit, otherwise compare against the index
127+ if not opts .ref and not opts .ref1 then
128+ local cmd = path .git_cwd (
129+ { " git" , " -c" , " color.status=false" , " --no-optional-locks" , " status" , " --porcelain=v1" },
130+ opts --[[ @as table]] )
131+ local out , exit_code = utils .io_systemlist (cmd --[[ @as string[] ]] )
132+ if exit_code == 0 and # out == 0 then
133+ opts .ref = " HEAD^"
134+ else
135+ opts .ref = " HEAD"
136+ end
137+ end
138+ opts .cmd = opts .cmd :gsub (" [<{]ref[}>]" , opts .ref or " " )
139+ opts .cmd = opts .cmd :gsub (" [<{]ref1[}>]" , opts .ref1 or " " )
140+ opts .preview = opts .preview :gsub (" [<{]ref[}>]" , opts .ref or " " )
141+ opts .preview = opts .preview :gsub (" [<{]ref1[}>]" , opts .ref1 or " " )
124142 opts = set_git_cwd_args (opts )
125143 if not opts .cwd then return end
126144 opts .preview = git_preview (opts , " {-1}" )
145+ if type (opts ._headers ) == " table" then
146+ table.insert (opts ._headers , " ref" )
147+ table.insert (opts ._headers , " ref1" )
148+ end
127149 return core .fzf_exec (opts .cmd , opts )
128150end
129151
@@ -301,13 +323,10 @@ M.hunks = function(opts)
301323 --- @type fzf-lua.config.GitHunks
302324 opts = config .normalize_opts (opts , " git.hunks" )
303325 if not opts then return end
304- local cmd = path .git_cwd ({ " git" , " rev-parse" , " --verify" , opts .ref }, opts )
305- local _ , err = utils .io_systemlist (cmd )
306- if err ~= 0 then
307- utils .warn (" Invalid git ref %s" , opts .ref )
326+ if type (opts .ref ) == " string" and # opts .ref > 0 and not git_validate_ref (opts , opts .ref ) then
308327 return
309328 end
310- opts .cmd = opts .cmd :gsub (" [<{]ref[}>]" , opts .ref )
329+ opts .cmd = opts .cmd :gsub (" [<{]ref[}>]" , opts .ref or " " )
311330 opts = set_git_cwd_args (opts )
312331 if not opts .cwd then return end
313332
0 commit comments