Harmonize Git in vim; If <cword> is hash, use it
dblume

dblume commited on 2023-04-26 10:28:31
Showing 1 changed files, with 29 additions and 7 deletions.


Now Blame, Show, Diff and Log all work together a little better.

If the current word is a git hash then:
  * Blame: Will "git blame <hash>^ -- filename"
  * Diff: Will diff that commit with the previous one.

This works even if running on a Log or Show window.
... ...
@@ -1,4 +1,4 @@
1
-" Version 2022-03-10.1 - Use Quickfix for cscope, add OpenCurrentAsNewTab
1
+" Version 2023-04-26.1 - Harmonize the git commands for common recipes
2 2
 set nocompatible    " Use Vim defaults, forget compatibility with vi.
3 3
 set bs=2            " allow backspacing over everything in insert mode
4 4
 set wildmenu        " Allows command-line completion with tab
... ...
@@ -149,7 +149,7 @@ function! GitBlame()
149 149
     let l:hash = expand('<cword>')
150 150
     let l:currentView = winsaveview()
151 151
     " If in a Blame window already, do blame for previous commit
152
-    if l:hash =~ '^[0-9a-f]\{8,40}$' && stridx(expand('%'), ' -- ') != -1
152
+    if l:hash =~ '^[0-9a-f]\{7,40}$' && stridx(expand('%'), ' -- ') != -1
153 153
         let l:fname = split(expand('%'), ' -- ')[-1]
154 154
         exec 'tabnew | r! git blame ' . l:hash . '^ -- ' . shellescape(l:fname)
155 155
         exec 'silent :file git blame ' . l:hash . '^ -- ' . l:fname
... ...
@@ -165,12 +165,19 @@ endfunction
165 165
 command Blame :call GitBlame()
166 166
 
167 167
 function! GitShow()
168
+    let l:fname = expand('%')
168 169
     let l:hash = expand('<cword>')
169
-    if l:hash =~ '^[0-9a-f]\{8,40}$'
170
+    if l:hash =~ '^[0-9a-f]\{7,40}$'
171
+        if stridx(l:fname, ' -- ') != -1
172
+            let l:fname = split(l:fname, ' -- ')[-1]
173
+	endif
174
+	" Have Show show all the affected files, so don't actually use  "--"
175
+        " exec 'tabnew | r! git show ' . l:hash . ' -- ' . shellescape(l:fname)
170 176
         exec 'tabnew | r! git show ' . l:hash
171 177
         setl buftype=nofile
172 178
         0d_
173
-        exec 'silent :file git show ' . l:hash
179
+	" We lie here (' -- ') to have a filename the other git commands can use.
180
+        exec 'silent :file git show ' . l:hash . ' -- ' . l:fname
174 181
     else
175 182
         echo l:hash . ' is not a git hash.'
176 183
     endif
... ...
@@ -181,7 +188,21 @@ function! GitDiff()
181 188
     let l:fname = expand('%:.')
182 189
     let l:buf = winbufnr(0)
183 190
     let l:commit = 'HEAD'
191
+    let l:hash = expand('<cword>')
192
+
193
+    " If the current word is a hash, then diff that vs. previous
194
+    if l:hash =~ '^[0-9a-f]\{7,40}$' && stridx(expand('%'), ' -- ') != -1
195
+        let l:fname = split(expand('%'), ' -- ')[-1]
196
+        exec ':tabnew | silent r! git show ' . l:hash . '^:$(git rev-parse --show-prefix)' . shellescape(l:fname)
197
+        setl buftype=nofile
198
+        0d_
199
+        exec 'silent :file git show '.l:hash .'^:' . l:fname
184 200
 
201
+        exec 'vne | silent r! git show ' . l:hash . ':$(git rev-parse --show-prefix)' . shellescape(l:fname)
202
+        setl buftype=nofile
203
+        exec 'silent :file git show '.l:hash.':' . l:fname
204
+        0d_
205
+    else
185 206
         " If the buffer is not different then repo, then diff HEAD vs file's previous commit
186 207
         let l:o = system("git status --porcelain | grep " . l:fname)
187 208
         if v:shell_error != 0
... ...
@@ -194,6 +215,7 @@ function! GitDiff()
194 215
         0d_
195 216
         exec 'silent :file git show '.l:commit.':' . l:fname
196 217
         exec 'vert sb '.l:buf
218
+    endif
197 219
     windo diffthis
198 220
     setl buftype=nofile
199 221
     wincmd r
... ...
@@ -202,11 +224,11 @@ endfunction
202 224
 command Diff :call GitDiff()
203 225
 
204 226
 function! GitLog()
205
-    let l:fname = expand('%:t')
206
-    exec 'tabnew | r! git log1 -- ' . shellescape(expand('%'))
227
+    let l:fname = expand('%')
228
+    exec 'tabnew | r! git log1 -- ' . shellescape(l:fname)
207 229
     setl buftype=nofile
208 230
     0d_
209
-    exec 'silent :file git log1 ' . l:fname
231
+    exec 'silent :file git log1 -- ' . l:fname
210 232
 endfunction
211 233
 command Log :call GitLog()
212 234
 
213 235