@@ -188,44 +188,84 @@ M.git_log_grepper_on_file = function(bufnr)
188
188
end , git_log_entry_maker )
189
189
end
190
190
191
+ local previous_commit_hash = function (commit_hash )
192
+ local command = " git rev-parse " .. commit_hash .. " ~"
193
+ local handle = io.popen (command )
194
+ local output = handle :read (" *a" )
195
+ handle :close ()
196
+
197
+ output = string.gsub (output , " \n " , " " )
198
+ return output
199
+ end
200
+
201
+ --- Determine the historic file name for a given commit hash and buffer number
202
+ --- @param commit_hash string
203
+ --- @param bufnr number
204
+ --- @return string | nil file_path historic file name relative to git root
191
205
local determine_historic_file_name = function (commit_hash , bufnr )
192
- local current_file_name = file .relative_path (bufnr )
206
+ local current_file_name = file .git_relative_path (bufnr )
193
207
194
- local command = " git log -M --diff-filter=R --follow --name-status --summary "
208
+ local command = " cd "
209
+ .. file .git_dir ()
210
+ .. " && "
211
+ .. " git --no-pager log -M --follow --name-status --oneline "
195
212
.. commit_hash
196
- .. " .. -- "
213
+ .. " ~ .. -- "
197
214
.. current_file_name
198
- .. " | grep ^R | tail -1 | cut -f2, 2"
215
+ .. " | tail -2"
199
216
200
217
local handle = io.popen (command )
201
218
local output = handle :read (" *a" )
202
219
handle :close ()
203
220
204
- output = string.gsub (output , " \n " , " " )
205
- if output == " " then
206
- output = file .git_relative_path (bufnr )
221
+ -- first line contains the commit_hash and message
222
+ -- second line contains the file status and file name (when rename, 2 filenames are present)
223
+ output = utils .split_string (output , " \n " )
224
+
225
+ if output [1 ] == nil or output [2 ] == nil then
226
+ return nil
207
227
end
208
228
209
- -- output is relative to git root
210
- return output
229
+ local returned_hash = utils .split_string (output [1 ])[1 ]
230
+
231
+ -- only return the file name if the commit hash matches, otherwise return nil
232
+ if string.sub (returned_hash , 1 , 7 ) == string.sub (commit_hash , 1 , 7 ) then
233
+ local split_output = utils .split_string (output [2 ])
234
+ return split_output [# split_output ]
235
+ else
236
+ return nil
237
+ end
211
238
end
212
239
213
240
M .git_diff_previewer_file = function (bufnr )
214
241
return previewers .new_termopen_previewer ({
215
242
get_command = function (entry )
216
243
local commit_hash = entry .opts .commit_hash
217
244
218
- local prev_commit = string.format (" %s~" , commit_hash )
219
- return git_diff_command ({
220
- " git" ,
221
- " diff" ,
222
- prev_commit
223
- .. " :"
224
- .. determine_historic_file_name (prev_commit , bufnr ),
225
- commit_hash
226
- .. " :"
227
- .. determine_historic_file_name (commit_hash , bufnr ),
228
- })
245
+ local prev_commit = previous_commit_hash (commit_hash )
246
+ if determine_historic_file_name (prev_commit , bufnr ) == nil then
247
+ return git_diff_command ({
248
+ " git" ,
249
+ " diff" ,
250
+ prev_commit ,
251
+ commit_hash ,
252
+ " --" ,
253
+ file .git_dir ()
254
+ .. " /"
255
+ .. determine_historic_file_name (commit_hash , bufnr ),
256
+ })
257
+ else
258
+ return git_diff_command ({
259
+ " git" ,
260
+ " diff" ,
261
+ prev_commit
262
+ .. " :"
263
+ .. determine_historic_file_name (prev_commit , bufnr ),
264
+ commit_hash
265
+ .. " :"
266
+ .. determine_historic_file_name (commit_hash , bufnr ),
267
+ })
268
+ end
229
269
end ,
230
270
})
231
271
end
0 commit comments