Show fake trees when editing directory in index

This commit is contained in:
Tim Pope 2018-07-29 14:22:33 -04:00
parent 004da420e5
commit 8a0a448f56
2 changed files with 53 additions and 33 deletions

View File

@ -1126,16 +1126,30 @@ function! fugitive#BufReadCmd(...) abort
if empty(dir) if empty(dir)
return 'echo "Invalid Fugitive URL"' return 'echo "Invalid Fugitive URL"'
endif endif
if rev =~# '^:\d$'
let b:fugitive_type = 'stage'
else
let b:fugitive_type = system(s:Prepare(dir, 'cat-file', '-t', rev))[0:-2] let b:fugitive_type = system(s:Prepare(dir, 'cat-file', '-t', rev))[0:-2]
if v:shell_error && rev =~# '^:0'
let sha = system(s:Prepare(dir, 'write-tree', '--prefix=' . rev[3:-1]))[0:-2]
let b:fugitive_type = 'tree'
endif
if v:shell_error if v:shell_error
unlet b:fugitive_type unlet b:fugitive_type
if rev =~# '^:\d:'
let &readonly = !filewritable(dir . '/index')
return 'silent doautocmd BufNewFile '.s:fnameescape(amatch) return 'silent doautocmd BufNewFile '.s:fnameescape(amatch)
else
setlocal readonly nomodifiable
return ''
endif
elseif b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$' elseif b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
return "echoerr ".string("fugitive: unrecognized git type '".b:fugitive_type."'") return "echoerr ".string("fugitive: unrecognized git type '".b:fugitive_type."'")
endif endif
if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob' if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
let b:fugitive_display_format = +getbufvar('#','fugitive_display_format') let b:fugitive_display_format = +getbufvar('#','fugitive_display_format')
endif endif
endif
if b:fugitive_type !=# 'blob' if b:fugitive_type !=# 'blob'
setlocal nomodeline setlocal nomodeline
@ -1150,9 +1164,11 @@ function! fugitive#BufReadCmd(...) abort
if b:fugitive_type ==# 'tree' if b:fugitive_type ==# 'tree'
let b:fugitive_display_format = b:fugitive_display_format % 2 let b:fugitive_display_format = b:fugitive_display_format % 2
if b:fugitive_display_format if b:fugitive_display_format
call s:ReplaceCmd([dir, 'ls-tree', rev]) call s:ReplaceCmd([dir, 'ls-tree', exists('sha') ? sha : rev])
else else
if !exists('sha')
let sha = system(s:Prepare(dir, 'rev-parse', '--verify', rev))[0:-2] let sha = system(s:Prepare(dir, 'rev-parse', '--verify', rev))[0:-2]
endif
call s:ReplaceCmd([dir, 'show', '--no-color', sha]) call s:ReplaceCmd([dir, 'show', '--no-color', sha])
endif endif
elseif b:fugitive_type ==# 'tag' elseif b:fugitive_type ==# 'tag'
@ -1181,6 +1197,8 @@ function! fugitive#BufReadCmd(...) abort
silent keepjumps 1,/^diff --git\|\%$/g/\r$/s/// silent keepjumps 1,/^diff --git\|\%$/g/\r$/s///
keepjumps 1 keepjumps 1
endif endif
elseif b:fugitive_type ==# 'stage'
call s:ReplaceCmd([dir, 'ls-files', '--stage'])
elseif b:fugitive_type ==# 'blob' elseif b:fugitive_type ==# 'blob'
call s:ReplaceCmd([dir, 'cat-file', b:fugitive_type, rev]) call s:ReplaceCmd([dir, 'cat-file', b:fugitive_type, rev])
setlocal nomodeline setlocal nomodeline
@ -1188,9 +1206,12 @@ function! fugitive#BufReadCmd(...) abort
finally finally
keepjumps call setpos('.',pos) keepjumps call setpos('.',pos)
setlocal nomodified noswapfile setlocal nomodified noswapfile
if rev !~# '^:.' if rev !~# '^:.:'
setlocal readonly nomodifiable setlocal nomodifiable
else
let &modifiable = b:fugitive_type !=# 'tree'
endif endif
let &readonly = !&modifiable || !filewritable(dir . '/index')
if &bufhidden ==# '' if &bufhidden ==# ''
setlocal bufhidden=delete setlocal bufhidden=delete
endif endif
@ -3064,16 +3085,12 @@ function! s:NavigateUp(count) abort
let rev = s:buffer().rev() let rev = s:buffer().rev()
let c = a:count let c = a:count
while c while c
if rev =~# '^[/:]$' if rev =~# ':.*/.'
let rev = 'HEAD' let rev = matchstr(rev, '.*\ze/.\+', '')
elseif rev =~# '.:.'
let rev = matchstr(rev, '^.[^:]*:')
elseif rev =~# '^:' elseif rev =~# '^:'
let rev = ':' let rev = 'HEAD^{}'
elseif rev =~# '^refs/[^^~:]*$\|^[^^~:]*HEAD$'
let rev .= '^{}'
elseif rev =~# '^/\|:.*/'
let rev = s:sub(rev, '.*\zs/.*', '')
elseif rev =~# ':.'
let rev = matchstr(rev, '^[^:]*:')
elseif rev =~# ':$' elseif rev =~# ':$'
let rev = rev[0:-2] let rev = rev[0:-2]
else else
@ -3155,10 +3172,14 @@ function! s:cfile() abort
let myhash = matchstr(getline(1),'^\w\+ \zs\S\+') let myhash = matchstr(getline(1),'^\w\+ \zs\S\+')
endif endif
let treebase = s:DirCommitFile(@%)[1].':'.s:Relative('').(s:Relative('') =~# '^$\|/$' ? '' : '/') let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
if treebase !~# '^\d\=:' && getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
let treebase = substitute(s:DirCommitFile(@%)[1], '^\d$', ':&', '') . ':' .
\ s:Relative('') . (s:Relative('') =~# '^$\|/$' ? '' : '/')
if getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
return [treebase . s:sub(matchstr(getline('.'),'\t\zs.*'),'/$','')] return [treebase . s:sub(matchstr(getline('.'),'\t\zs.*'),'/$','')]
elseif treebase !~# '^\d\=:' && getline(1) =~# '^tree ' && empty(getline(2)) && line('.') >= 2 elseif showtree
return [treebase . s:sub(getline('.'),'/$','')] return [treebase . s:sub(getline('.'),'/$','')]
else else
@ -3172,8 +3193,6 @@ function! s:cfile() abort
return [file] return [file]
endif endif
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
if getline('.') =~# '^ref: ' if getline('.') =~# '^ref: '
let ref = strpart(getline('.'),5) let ref = strpart(getline('.'),5)
@ -3191,9 +3210,9 @@ function! s:cfile() abort
endwhile endwhile
return [ref] return [ref]
elseif getline('.') =~ '^tree \x\{40\}$' elseif getline('.') =~# '^tree \x\{40\}$'
let ref = matchstr(getline('.'),'\x\{40\}') let ref = matchstr(getline('.'),'\x\{40\}')
if s:repo().rev_parse(myhash.':') == ref if len(myhash) && s:repo().rev_parse(myhash.':') ==# ref
let ref = myhash.':' let ref = myhash.':'
endif endif
return [ref] return [ref]

View File

@ -327,14 +327,15 @@ master: The tree referenced by master
Makefile The file named Makefile in the work tree Makefile The file named Makefile in the work tree
@^:Makefile The file named Makefile in the parent of HEAD @^:Makefile The file named Makefile in the parent of HEAD
:Makefile The file named Makefile in the index (writable) :Makefile The file named Makefile in the index (writable)
@:% The current file in HEAD
- The current file in HEAD - The current file in HEAD
^ The current file in the previous commit ^ The current file in the previous commit
~3 The current file 3 commits ago ~3 The current file 3 commits ago
: .git/index (Same as |:Gstatus|) : .git/index (Same as |:Gstatus|)
:0 The current file in the index :% The current file in the index
:1 The current file's common ancestor during a conflict :1:% The current file's common ancestor during a conflict
:2 The current file in the target branch during a conflict :2:% The current file in the target branch during a conflict
:3 The current file in the merged branch during a conflict :3:% The current file in the merged branch during a conflict
STATUSLINE *fugitive-statusline* STATUSLINE *fugitive-statusline*