|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
" fugitive.vim - A Git wrapper so awesome, it should be illegal
|
|
|
|
|
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
|
|
|
|
|
" Version: 1.1
|
|
|
|
|
" Version: 1.2
|
|
|
|
|
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
|
|
|
|
|
|
|
|
|
|
if exists('g:loaded_fugitive') || &cp
|
|
|
|
|
@@ -108,7 +108,7 @@ function! s:ExtractGitDir(path) abort
|
|
|
|
|
let ofn = ""
|
|
|
|
|
let nfn = fn
|
|
|
|
|
while fn != ofn
|
|
|
|
|
if isdirectory(fn . '/.git')
|
|
|
|
|
if filereadable(fn . '/.git/HEAD')
|
|
|
|
|
return s:sub(simplify(fnamemodify(fn . '/.git',':p')),'\W$','')
|
|
|
|
|
elseif fn =~ '\.git$' && filereadable(fn . '/HEAD')
|
|
|
|
|
return s:sub(simplify(fnamemodify(fn,':p')),'\W$','')
|
|
|
|
|
@@ -132,19 +132,25 @@ function! s:Detect(path)
|
|
|
|
|
if exists('b:git_dir')
|
|
|
|
|
silent doautocmd User Fugitive
|
|
|
|
|
cnoremap <expr> <buffer> <C-R><C-G> fugitive#buffer().rev()
|
|
|
|
|
let buffer = fugitive#buffer()
|
|
|
|
|
if expand('%:p') =~# '//'
|
|
|
|
|
let buffer = fugitive#buffer()
|
|
|
|
|
call buffer.setvar('&path',s:sub(buffer.getvar('&path'),'^\.%(,|$)',''))
|
|
|
|
|
endif
|
|
|
|
|
if b:git_dir !~# ',' && stridx(buffer.getvar('&tags'),b:git_dir.'/tags') == -1
|
|
|
|
|
if &filetype != ''
|
|
|
|
|
call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/'.&filetype.'.tags')
|
|
|
|
|
endif
|
|
|
|
|
call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/tags')
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
augroup fugitive
|
|
|
|
|
autocmd!
|
|
|
|
|
autocmd BufNewFile,BufReadPost * call s:Detect(expand('<amatch>:p'))
|
|
|
|
|
autocmd FileType netrw call s:Detect(expand('<amatch>:p'))
|
|
|
|
|
autocmd FileType netrw call s:Detect(expand('<afile>:p'))
|
|
|
|
|
autocmd VimEnter * if expand('<amatch>')==''|call s:Detect(getcwd())|endif
|
|
|
|
|
autocmd BufWinLeave * execute getbufvar(+expand('<abuf>'), 'fugitive_restore')
|
|
|
|
|
autocmd BufWinLeave * execute getwinvar(+winnr(), 'fugitive_restore')
|
|
|
|
|
augroup END
|
|
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
|
@@ -248,8 +254,8 @@ endfunction
|
|
|
|
|
|
|
|
|
|
function! s:repo_rev_parse(rev) dict abort
|
|
|
|
|
let hash = self.git_chomp('rev-parse','--verify',a:rev)
|
|
|
|
|
if hash =~ '^\x\{40\}$'
|
|
|
|
|
return hash
|
|
|
|
|
if hash =~ '\<\x\{40\}$'
|
|
|
|
|
return matchstr(hash,'\<\x\{40\}$')
|
|
|
|
|
endif
|
|
|
|
|
call s:throw('rev-parse '.a:rev.': '.hash)
|
|
|
|
|
endfunction
|
|
|
|
|
@@ -351,7 +357,7 @@ endfunction
|
|
|
|
|
function! s:buffer_type(...) dict abort
|
|
|
|
|
if self.getvar('fugitive_type') != ''
|
|
|
|
|
let type = self.getvar('fugitive_type')
|
|
|
|
|
elseif fnamemodify(self.name(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$'
|
|
|
|
|
elseif fnamemodify(self.spec(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$'
|
|
|
|
|
let type = 'head'
|
|
|
|
|
elseif self.getline(1) =~ '^tree \x\{40\}$' && self.getline(2) == ''
|
|
|
|
|
let type = 'tree'
|
|
|
|
|
@@ -359,11 +365,11 @@ function! s:buffer_type(...) dict abort
|
|
|
|
|
let type = 'tree'
|
|
|
|
|
elseif self.getline(1) =~ '^\d\{6\} \x\{40\}\> \d\t'
|
|
|
|
|
let type = 'index'
|
|
|
|
|
elseif isdirectory(self.name())
|
|
|
|
|
elseif isdirectory(self.spec())
|
|
|
|
|
let type = 'directory'
|
|
|
|
|
elseif self.name() == ''
|
|
|
|
|
elseif self.spec() == ''
|
|
|
|
|
let type = 'null'
|
|
|
|
|
elseif filereadable(self.name())
|
|
|
|
|
elseif filereadable(self.spec())
|
|
|
|
|
let type = 'file'
|
|
|
|
|
else
|
|
|
|
|
let type = ''
|
|
|
|
|
@@ -375,42 +381,61 @@ function! s:buffer_type(...) dict abort
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
if has('win32')
|
|
|
|
|
|
|
|
|
|
function! s:buffer_spec() dict abort
|
|
|
|
|
let bufname = bufname(self['#'])
|
|
|
|
|
let retval = ''
|
|
|
|
|
for i in split(bufname,'[^:]\zs\\')
|
|
|
|
|
let retval = fnamemodify((retval==''?'':retval.'\').i,':.')
|
|
|
|
|
endfor
|
|
|
|
|
return s:shellslash(fnamemodify(retval,':p'))
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
function! s:buffer_spec() dict abort
|
|
|
|
|
let bufname = bufname(self['#'])
|
|
|
|
|
return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
function! s:buffer_name() dict abort
|
|
|
|
|
let bufname = bufname(self['#'])
|
|
|
|
|
return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
|
|
|
|
|
return self.spec()
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:buffer_commit() dict abort
|
|
|
|
|
return matchstr(self.name(),'^fugitive://.\{-\}//\zs\w*')
|
|
|
|
|
return matchstr(self.spec(),'^fugitive://.\{-\}//\zs\w*')
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:buffer_path(...) dict abort
|
|
|
|
|
let rev = matchstr(self.name(),'^fugitive://.\{-\}//\zs.*')
|
|
|
|
|
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
|
|
|
|
if rev != ''
|
|
|
|
|
let rev = s:sub(rev,'\w*','')
|
|
|
|
|
else
|
|
|
|
|
let rev = self.name()[strlen(self.repo().tree()) : -1]
|
|
|
|
|
let rev = self.spec()[strlen(self.repo().tree()) : -1]
|
|
|
|
|
endif
|
|
|
|
|
return s:sub(rev,'^/',a:0 ? a:1 : '')
|
|
|
|
|
return s:sub(s:sub(rev,'.\zs/$',''),'^/',a:0 ? a:1 : '')
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:buffer_rev() dict abort
|
|
|
|
|
let rev = matchstr(self.name(),'^fugitive://.\{-\}//\zs.*')
|
|
|
|
|
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
|
|
|
|
if rev =~ '^\x/'
|
|
|
|
|
return ':'.rev[0].':'.rev[2:-1]
|
|
|
|
|
elseif rev =~ '.'
|
|
|
|
|
return s:sub(rev,'/',':')
|
|
|
|
|
elseif self.name() =~ '\.git/index$'
|
|
|
|
|
elseif self.spec() =~ '\.git/index$'
|
|
|
|
|
return ':'
|
|
|
|
|
elseif self.name() =~ '\.git/refs/\|\.git/.*HEAD$'
|
|
|
|
|
return self.name()[strlen(self.repo().dir())+1 : -1]
|
|
|
|
|
elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
|
|
|
|
return self.spec()[strlen(self.repo().dir())+1 : -1]
|
|
|
|
|
else
|
|
|
|
|
return self.path()
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:buffer_sha1() dict abort
|
|
|
|
|
if self.name() =~ '^fugitive://' || self.name() =~ '\.git/refs/\|\.git/.*HEAD$'
|
|
|
|
|
if self.spec() =~ '^fugitive://' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
|
|
|
|
return self.repo().rev_parse(self.rev())
|
|
|
|
|
else
|
|
|
|
|
return ''
|
|
|
|
|
@@ -420,6 +445,8 @@ endfunction
|
|
|
|
|
function! s:buffer_expand(rev) dict abort
|
|
|
|
|
if a:rev =~# '^:[0-3]$'
|
|
|
|
|
let file = a:rev.self.path(':')
|
|
|
|
|
elseif a:rev =~# '^[-:]/$'
|
|
|
|
|
let file = '/'.self.path()
|
|
|
|
|
elseif a:rev =~# '^-'
|
|
|
|
|
let file = 'HEAD^{}'.a:rev[1:-1].self.path(':')
|
|
|
|
|
elseif a:rev =~# '^@{'
|
|
|
|
|
@@ -430,7 +457,7 @@ function! s:buffer_expand(rev) dict abort
|
|
|
|
|
else
|
|
|
|
|
let file = a:rev
|
|
|
|
|
endif
|
|
|
|
|
return s:sub(file,'\%$',self.path())
|
|
|
|
|
return s:sub(s:sub(file,'\%$',self.path()),'\.\@<=/$','')
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:buffer_containing_commit() dict abort
|
|
|
|
|
@@ -443,7 +470,7 @@ function! s:buffer_containing_commit() dict abort
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','name','commit','path','rev','sha1','expand','containing_commit'])
|
|
|
|
|
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','rev','sha1','expand','containing_commit'])
|
|
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
|
" Git {{{1
|
|
|
|
|
@@ -538,24 +565,25 @@ function! fugitive#reload_status() abort
|
|
|
|
|
endfor
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:StageDiff() abort
|
|
|
|
|
function! s:StageDiff(...) abort
|
|
|
|
|
let cmd = a:0 ? a:1 : 'Gdiff'
|
|
|
|
|
let section = getline(search('^# .*:$','bnW'))
|
|
|
|
|
let line = getline('.')
|
|
|
|
|
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
|
|
|
|
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$')
|
|
|
|
|
if filename ==# '' && section == '# Changes to be committed:'
|
|
|
|
|
return 'Git diff --cached'
|
|
|
|
|
elseif filename ==# ''
|
|
|
|
|
return 'Git diff'
|
|
|
|
|
elseif line =~# '^#\trenamed:' && filename =~ ' -> '
|
|
|
|
|
elseif line =~# '^#\t\%(renamed\|copied\):' && filename =~ ' -> '
|
|
|
|
|
let [old, new] = split(filename,' -> ')
|
|
|
|
|
execute 'Gedit '.s:fnameescape(':0:'.new)
|
|
|
|
|
return 'Gdiff HEAD:'.s:fnameescape(old)
|
|
|
|
|
return cmd.' HEAD:'.s:fnameescape(old)
|
|
|
|
|
elseif section == '# Changes to be committed:'
|
|
|
|
|
execute 'Gedit '.s:fnameescape(':0:'.filename)
|
|
|
|
|
return 'Gdiff -'
|
|
|
|
|
return cmd.' -'
|
|
|
|
|
else
|
|
|
|
|
execute 'Gedit '.s:fnameescape('/'.filename)
|
|
|
|
|
return 'Gdiff'
|
|
|
|
|
return cmd
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
@@ -564,10 +592,34 @@ function! s:StageToggle(lnum1,lnum2) abort
|
|
|
|
|
let output = ''
|
|
|
|
|
for lnum in range(a:lnum1,a:lnum2)
|
|
|
|
|
let line = getline(lnum)
|
|
|
|
|
if getline('.') == '# Changes to be committed:'
|
|
|
|
|
return 'Gcommit'
|
|
|
|
|
let repo = s:repo()
|
|
|
|
|
if line ==# '# Changes to be committed:'
|
|
|
|
|
call repo.git_chomp_in_tree('reset','-q')
|
|
|
|
|
silent! edit!
|
|
|
|
|
1
|
|
|
|
|
if !search('^# Untracked files:$','W')
|
|
|
|
|
call search('^# Change','W')
|
|
|
|
|
endif
|
|
|
|
|
return ''
|
|
|
|
|
elseif line =~# '^# Change\%(d but not updated\|s not staged for commit\):$'
|
|
|
|
|
call repo.git_chomp_in_tree('add','-u')
|
|
|
|
|
silent! edit!
|
|
|
|
|
1
|
|
|
|
|
if !search('^# Untracked files:$','W')
|
|
|
|
|
call search('^# Change','W')
|
|
|
|
|
endif
|
|
|
|
|
return ''
|
|
|
|
|
elseif line ==# '# Untracked files:'
|
|
|
|
|
" Work around Vim parser idiosyncrasy
|
|
|
|
|
call repo.git_chomp_in_tree('add','-N','.')
|
|
|
|
|
silent! edit!
|
|
|
|
|
1
|
|
|
|
|
if !search('^# Change\%(d but not updated\|s not staged for commit\):$','W')
|
|
|
|
|
call search('^# Change','W')
|
|
|
|
|
endif
|
|
|
|
|
return ''
|
|
|
|
|
endif
|
|
|
|
|
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
|
|
|
|
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (\a\+ [[:alpha:], ]\+)\)\=$')
|
|
|
|
|
if filename ==# ''
|
|
|
|
|
continue
|
|
|
|
|
endif
|
|
|
|
|
@@ -580,13 +632,13 @@ function! s:StageToggle(lnum1,lnum2) abort
|
|
|
|
|
let cmd = ['mv','--'] + reverse(split(filename,' -> '))
|
|
|
|
|
let filename = cmd[-1]
|
|
|
|
|
elseif section =~? ' to be '
|
|
|
|
|
let cmd = ['reset','-q','--',filename]
|
|
|
|
|
let cmd = ['reset','-q','--',split(filename,' -> ')[-1]]
|
|
|
|
|
elseif line =~# '^#\tdeleted:'
|
|
|
|
|
let cmd = ['rm','--',filename]
|
|
|
|
|
else
|
|
|
|
|
let cmd = ['add','--',filename]
|
|
|
|
|
endif
|
|
|
|
|
let output .= call(s:repo().git_chomp_in_tree,cmd,s:repo())."\n"
|
|
|
|
|
let output .= call(repo.git_chomp_in_tree,cmd,s:repo())."\n"
|
|
|
|
|
endfor
|
|
|
|
|
if exists('first_filename')
|
|
|
|
|
let jump = first_filename
|
|
|
|
|
@@ -597,7 +649,7 @@ function! s:StageToggle(lnum1,lnum2) abort
|
|
|
|
|
silent! edit!
|
|
|
|
|
1
|
|
|
|
|
redraw
|
|
|
|
|
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'\$','W')
|
|
|
|
|
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'\%( (new commits)\)\=\$','W')
|
|
|
|
|
endif
|
|
|
|
|
echo s:sub(s:gsub(output,'\n+','\n'),'\n$','')
|
|
|
|
|
catch /^fugitive:/
|
|
|
|
|
@@ -612,12 +664,12 @@ function! s:StagePatch(lnum1,lnum2) abort
|
|
|
|
|
|
|
|
|
|
for lnum in range(a:lnum1,a:lnum2)
|
|
|
|
|
let line = getline(lnum)
|
|
|
|
|
if line == '# Changes to be committed:'
|
|
|
|
|
if line ==# '# Changes to be committed:'
|
|
|
|
|
return 'Git reset --patch'
|
|
|
|
|
elseif line == '# Changed but not updated:'
|
|
|
|
|
elseif line =~# '^# Change\%(d but not updated\|s not staged for commit\):$'
|
|
|
|
|
return 'Git add --patch'
|
|
|
|
|
endif
|
|
|
|
|
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*')
|
|
|
|
|
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$')
|
|
|
|
|
if filename ==# ''
|
|
|
|
|
continue
|
|
|
|
|
endif
|
|
|
|
|
@@ -645,7 +697,7 @@ function! s:StagePatch(lnum1,lnum2) abort
|
|
|
|
|
silent! edit!
|
|
|
|
|
1
|
|
|
|
|
redraw
|
|
|
|
|
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\$','W')
|
|
|
|
|
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\%( (new commits)\)\=\$','W')
|
|
|
|
|
endif
|
|
|
|
|
catch /^fugitive:/
|
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
|
@@ -667,20 +719,20 @@ function! s:Commit(args) abort
|
|
|
|
|
let errorfile = tempname()
|
|
|
|
|
try
|
|
|
|
|
execute cd.'`=s:repo().tree()`'
|
|
|
|
|
let command = ''
|
|
|
|
|
if &shell =~# 'cmd'
|
|
|
|
|
let command = ''
|
|
|
|
|
let old_editor = $GIT_EDITOR
|
|
|
|
|
let $GIT_EDITOR = 'false'
|
|
|
|
|
elseif &shell !~# 'csh'
|
|
|
|
|
let command = 'GIT_EDITOR=false '
|
|
|
|
|
else
|
|
|
|
|
let command = 'env GIT_EDITOR=false '
|
|
|
|
|
endif
|
|
|
|
|
let command .= s:repo().git_command('commit').' '.a:args
|
|
|
|
|
if &shell =~# 'csh'
|
|
|
|
|
silent execute '!setenv GIT_EDITOR false; ('.command.' > '.outfile.') >& '.errorfile
|
|
|
|
|
call system('('.command.' > '.outfile.') >& '.errorfile)
|
|
|
|
|
elseif a:args =~# '\%(^\| \)--interactive\>'
|
|
|
|
|
execute '!'.command.' 2> '.errorfile
|
|
|
|
|
call system(command.' 2> '.errorfile)
|
|
|
|
|
else
|
|
|
|
|
silent execute '!'.command.' > '.outfile.' 2> '.errorfile
|
|
|
|
|
call system(command.' > '.outfile.' 2> '.errorfile)
|
|
|
|
|
endif
|
|
|
|
|
if !v:shell_error
|
|
|
|
|
if filereadable(outfile)
|
|
|
|
|
@@ -690,8 +742,9 @@ function! s:Commit(args) abort
|
|
|
|
|
endif
|
|
|
|
|
return ''
|
|
|
|
|
else
|
|
|
|
|
let error = get(readfile(errorfile,'',1),0,'!')
|
|
|
|
|
if error =~# "'false'\\.$"
|
|
|
|
|
let errors = readfile(errorfile)
|
|
|
|
|
let error = get(errors,-2,get(errors,-1,'!'))
|
|
|
|
|
if error =~# '\<false''\=\.$'
|
|
|
|
|
let args = a:args
|
|
|
|
|
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[se]|--edit|--interactive)%($| )','')
|
|
|
|
|
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
|
|
|
|
|
@@ -700,13 +753,14 @@ function! s:Commit(args) abort
|
|
|
|
|
if args !~# '\%(^\| \)--cleanup\>'
|
|
|
|
|
let args = '--cleanup=strip '.args
|
|
|
|
|
endif
|
|
|
|
|
let old_nr = bufnr('')
|
|
|
|
|
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
|
|
|
|
|
edit `=msgfile`
|
|
|
|
|
else
|
|
|
|
|
split `=msgfile`
|
|
|
|
|
keepalt split `=msgfile`
|
|
|
|
|
endif
|
|
|
|
|
if old_type ==# 'index'
|
|
|
|
|
bdelete #
|
|
|
|
|
execute 'bdelete '.old_nr
|
|
|
|
|
endif
|
|
|
|
|
let b:fugitive_commit_arguments = args
|
|
|
|
|
setlocal bufhidden=delete filetype=gitcommit
|
|
|
|
|
@@ -741,7 +795,6 @@ endfunction
|
|
|
|
|
|
|
|
|
|
function! s:FinishCommit()
|
|
|
|
|
let args = getbufvar(+expand('<abuf>'),'fugitive_commit_arguments')
|
|
|
|
|
let g:args = args
|
|
|
|
|
if !empty(args)
|
|
|
|
|
call setbufvar(+expand('<abuf>'),'fugitive_commit_arguments','')
|
|
|
|
|
return s:Commit(args)
|
|
|
|
|
@@ -849,11 +902,8 @@ function! s:Edit(cmd,...) abort
|
|
|
|
|
catch /^fugitive:/
|
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
|
endtry
|
|
|
|
|
if a:cmd =~# 'read!$' || a:cmd ==# 'read'
|
|
|
|
|
if a:cmd =~# '!$'
|
|
|
|
|
call s:warn(':Gread! is deprecated. Use :Gread')
|
|
|
|
|
endif
|
|
|
|
|
return 'silent %delete|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
|
|
|
|
if a:cmd ==# 'read'
|
|
|
|
|
return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
|
|
|
|
else
|
|
|
|
|
if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
|
|
|
|
|
wincmd p
|
|
|
|
|
@@ -875,9 +925,11 @@ call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit
|
|
|
|
|
call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read<bang>',<f-args>)")
|
|
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
|
" Gwrite {{{1
|
|
|
|
|
" Gwrite, Gwq {{{1
|
|
|
|
|
|
|
|
|
|
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwrite :execute s:Write(<bang>0,<f-args>)")
|
|
|
|
|
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gw :execute s:Write(<bang>0,<f-args>)")
|
|
|
|
|
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwq :execute s:Wq(<bang>0,<f-args>)")
|
|
|
|
|
|
|
|
|
|
function! s:Write(force,...) abort
|
|
|
|
|
if exists('b:fugitive_commit_arguments')
|
|
|
|
|
@@ -941,7 +993,11 @@ function! s:Write(force,...) abort
|
|
|
|
|
execute 'write! '.s:fnameescape(s:repo().translate(path))
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
let error = s:repo().git_chomp_in_tree('add', file)
|
|
|
|
|
if a:force
|
|
|
|
|
let error = s:repo().git_chomp_in_tree('add', '--force', file)
|
|
|
|
|
else
|
|
|
|
|
let error = s:repo().git_chomp_in_tree('add', file)
|
|
|
|
|
endif
|
|
|
|
|
if v:shell_error
|
|
|
|
|
let v:errmsg = 'fugitive: '.error
|
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
|
@@ -993,16 +1049,57 @@ function! s:Write(force,...) abort
|
|
|
|
|
return 'checktime'
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:Wq(force,...) abort
|
|
|
|
|
let bang = a:force ? '!' : ''
|
|
|
|
|
if exists('b:fugitive_commit_arguments')
|
|
|
|
|
return 'wq'.bang
|
|
|
|
|
endif
|
|
|
|
|
let result = call(s:function('s:Write'),[a:force]+a:000)
|
|
|
|
|
if result =~# '^\%(write\|wq\|echoerr\)'
|
|
|
|
|
return s:sub(result,'^write','wq')
|
|
|
|
|
else
|
|
|
|
|
return result.'|quit'.bang
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
|
" Gdiff {{{1
|
|
|
|
|
|
|
|
|
|
call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(<f-args>)")
|
|
|
|
|
call s:command("-bang -bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(<bang>0,<f-args>)")
|
|
|
|
|
call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gvdiff :execute s:Diff(0,<f-args>)")
|
|
|
|
|
call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gsdiff :execute s:Diff(1,<f-args>)")
|
|
|
|
|
|
|
|
|
|
augroup fugitive_diff
|
|
|
|
|
autocmd BufWinLeave * if winnr('$') == 2 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff! | endif
|
|
|
|
|
autocmd BufWinEnter * if winnr('$') == 1 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff | endif
|
|
|
|
|
autocmd!
|
|
|
|
|
autocmd BufWinLeave * if s:diff_window_count() == 2 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | call s:diff_off_all(getbufvar(+expand('<abuf>'), 'git_dir')) | endif
|
|
|
|
|
autocmd BufWinEnter * if s:diff_window_count() == 1 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff | endif
|
|
|
|
|
augroup END
|
|
|
|
|
|
|
|
|
|
function! s:diff_window_count()
|
|
|
|
|
let c = 0
|
|
|
|
|
for nr in range(1,winnr('$'))
|
|
|
|
|
let c += getwinvar(nr,'&diff')
|
|
|
|
|
endfor
|
|
|
|
|
return c
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:diff_off_all(dir)
|
|
|
|
|
for nr in range(1,winnr('$'))
|
|
|
|
|
if getwinvar(nr,'&diff')
|
|
|
|
|
if nr != winnr()
|
|
|
|
|
execute nr.'wincmd w'
|
|
|
|
|
let restorewinnr = 1
|
|
|
|
|
endif
|
|
|
|
|
if exists('b:git_dir') && b:git_dir ==# a:dir
|
|
|
|
|
diffoff
|
|
|
|
|
endif
|
|
|
|
|
if exists('restorewinnr')
|
|
|
|
|
wincmd p
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
endfor
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:buffer_compare_age(commit) dict abort
|
|
|
|
|
let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
|
|
|
|
|
let my_score = get(scores,':'.self.commit(),0)
|
|
|
|
|
@@ -1025,18 +1122,22 @@ endfunction
|
|
|
|
|
|
|
|
|
|
call s:add_methods('buffer',['compare_age'])
|
|
|
|
|
|
|
|
|
|
function! s:Diff(...) abort
|
|
|
|
|
function! s:Diff(bang,...) abort
|
|
|
|
|
let split = a:bang ? 'split' : 'vsplit'
|
|
|
|
|
if exists(':DiffGitCached')
|
|
|
|
|
return 'DiffGitCached'
|
|
|
|
|
elseif (!a:0 || a:1 == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
|
|
|
|
|
leftabove vsplit `=fugitive#buffer().repo().translate(s:buffer().expand(':2'))`
|
|
|
|
|
diffthis
|
|
|
|
|
wincmd p
|
|
|
|
|
rightbelow vsplit `=fugitive#buffer().repo().translate(s:buffer().expand(':3'))`
|
|
|
|
|
diffthis
|
|
|
|
|
wincmd p
|
|
|
|
|
diffthis
|
|
|
|
|
return ''
|
|
|
|
|
let nr = bufnr('')
|
|
|
|
|
execute 'leftabove '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`'
|
|
|
|
|
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
|
|
|
|
diffthis
|
|
|
|
|
wincmd p
|
|
|
|
|
execute 'rightbelow '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`'
|
|
|
|
|
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
|
|
|
|
diffthis
|
|
|
|
|
wincmd p
|
|
|
|
|
diffthis
|
|
|
|
|
return ''
|
|
|
|
|
elseif a:0
|
|
|
|
|
if a:1 ==# ''
|
|
|
|
|
return ''
|
|
|
|
|
@@ -1044,7 +1145,7 @@ function! s:Diff(...) abort
|
|
|
|
|
let file = s:buffer().path('/')
|
|
|
|
|
elseif a:1 ==# ':'
|
|
|
|
|
let file = s:buffer().path(':0:')
|
|
|
|
|
elseif a:1 =~# '^:/'
|
|
|
|
|
elseif a:1 =~# '^:/.'
|
|
|
|
|
try
|
|
|
|
|
let file = s:repo().rev_parse(a:1).s:buffer().path(':')
|
|
|
|
|
catch /^fugitive:/
|
|
|
|
|
@@ -1063,9 +1164,9 @@ function! s:Diff(...) abort
|
|
|
|
|
let spec = s:repo().translate(file)
|
|
|
|
|
let commit = matchstr(spec,'\C[^:/]//\zs\x\+')
|
|
|
|
|
if s:buffer().compare_age(commit) < 0
|
|
|
|
|
rightbelow vsplit `=spec`
|
|
|
|
|
execute 'rightbelow '.split.' `=spec`'
|
|
|
|
|
else
|
|
|
|
|
leftabove vsplit `=spec`
|
|
|
|
|
execute 'leftabove '.split.' `=spec`'
|
|
|
|
|
endif
|
|
|
|
|
diffthis
|
|
|
|
|
wincmd p
|
|
|
|
|
@@ -1088,6 +1189,10 @@ function! s:Move(force,destination)
|
|
|
|
|
let destination = destination[strlen(s:repo().tree('')):-1]
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
if isdirectory(s:buffer().name())
|
|
|
|
|
" Work around Vim parser idiosyncrasy
|
|
|
|
|
let discarded = s:buffer().setvar('&swapfile',0)
|
|
|
|
|
endif
|
|
|
|
|
let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo())
|
|
|
|
|
if v:shell_error
|
|
|
|
|
let v:errmsg = 'fugitive: '.message
|
|
|
|
|
@@ -1099,7 +1204,11 @@ function! s:Move(force,destination)
|
|
|
|
|
endif
|
|
|
|
|
call fugitive#reload_status()
|
|
|
|
|
if s:buffer().commit() == ''
|
|
|
|
|
return 'saveas! '.s:fnameescape(destination)
|
|
|
|
|
if isdirectory(destination)
|
|
|
|
|
return 'edit '.s:fnameescape(destination)
|
|
|
|
|
else
|
|
|
|
|
return 'saveas! '.s:fnameescape(destination)
|
|
|
|
|
endif
|
|
|
|
|
else
|
|
|
|
|
return 'file '.s:fnameescape(s:repo().translate(':0:'.destination)
|
|
|
|
|
endif
|
|
|
|
|
@@ -1184,17 +1293,25 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
|
|
|
|
else
|
|
|
|
|
let error = tempname()
|
|
|
|
|
let temp = error.'.fugitiveblame'
|
|
|
|
|
silent! exe '%write !'.basecmd.' > '.temp.' 2> '.error
|
|
|
|
|
if &shell =~# 'csh'
|
|
|
|
|
silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
|
|
|
|
|
else
|
|
|
|
|
silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
|
|
|
|
|
endif
|
|
|
|
|
if exists('l:dir')
|
|
|
|
|
execute cd.'`=dir`'
|
|
|
|
|
unlet dir
|
|
|
|
|
endif
|
|
|
|
|
if v:shell_error
|
|
|
|
|
call s:throw(join(readfile(error),"\n"))
|
|
|
|
|
endif
|
|
|
|
|
let bufnr = bufnr('')
|
|
|
|
|
let restore = 'call setbufvar('.bufnr.',"&scrollbind",0)'
|
|
|
|
|
let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)'
|
|
|
|
|
if &l:wrap
|
|
|
|
|
let restore .= '|call setbufvar('.bufnr.',"&wrap",1)'
|
|
|
|
|
let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&wrap",1)'
|
|
|
|
|
endif
|
|
|
|
|
if &l:foldenable
|
|
|
|
|
let restore .= '|call setbufvar('.bufnr.',"&foldenable",1)'
|
|
|
|
|
let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&foldenable",1)'
|
|
|
|
|
endif
|
|
|
|
|
let winnr = winnr()
|
|
|
|
|
windo set noscrollbind
|
|
|
|
|
@@ -1206,7 +1323,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
|
|
|
|
let b:git_dir = git_dir
|
|
|
|
|
let b:fugitive_type = 'blame'
|
|
|
|
|
let b:fugitive_blamed_bufnr = bufnr
|
|
|
|
|
let b:fugitive_restore = restore
|
|
|
|
|
let w:fugitive_restore = restore
|
|
|
|
|
let b:fugitive_blame_arguments = join(a:args,' ')
|
|
|
|
|
call s:Detect(expand('%:p'))
|
|
|
|
|
execute top
|
|
|
|
|
@@ -1292,6 +1409,200 @@ function! s:BlameSyntax() abort
|
|
|
|
|
hi def link FugitiveblameNotCommittedYet Comment
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
|
" Gbrowse {{{1
|
|
|
|
|
|
|
|
|
|
call s:command("-bar -bang -count=0 -nargs=? -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
|
|
|
|
|
|
|
|
|
|
function! s:Browse(bang,line1,count,...) abort
|
|
|
|
|
try
|
|
|
|
|
let rev = a:0 ? substitute(a:1,'@[[:alnum:]_-]*\%(://.\{-\}\)\=$','','') : ''
|
|
|
|
|
if rev ==# ''
|
|
|
|
|
let expanded = s:buffer().rev()
|
|
|
|
|
elseif rev ==# ':'
|
|
|
|
|
let expanded = s:buffer().path('/')
|
|
|
|
|
else
|
|
|
|
|
let expanded = s:buffer().expand(rev)
|
|
|
|
|
endif
|
|
|
|
|
let full = s:repo().translate(expanded)
|
|
|
|
|
let commit = ''
|
|
|
|
|
if full =~# '^fugitive://'
|
|
|
|
|
let commit = matchstr(full,'://.*//\zs\w\+')
|
|
|
|
|
let path = matchstr(full,'://.*//\w\+\zs/.*')
|
|
|
|
|
if commit =~ '..'
|
|
|
|
|
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
|
|
|
|
|
else
|
|
|
|
|
let type = 'blob'
|
|
|
|
|
endif
|
|
|
|
|
let path = path[1:-1]
|
|
|
|
|
elseif s:repo().bare()
|
|
|
|
|
let path = '.git/' . full[strlen(s:repo().dir())+1:-1]
|
|
|
|
|
let type = ''
|
|
|
|
|
else
|
|
|
|
|
let path = full[strlen(s:repo().tree())+1:-1]
|
|
|
|
|
if path =~# '^\.git/'
|
|
|
|
|
let type = ''
|
|
|
|
|
elseif isdirectory(full)
|
|
|
|
|
let type = 'tree'
|
|
|
|
|
else
|
|
|
|
|
let type = 'blob'
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
|
|
|
|
|
let body = readfile(s:repo().dir(path[5:-1]))[0]
|
|
|
|
|
if body =~# '^\x\{40\}$'
|
|
|
|
|
let commit = body
|
|
|
|
|
let type = 'commit'
|
|
|
|
|
let path = ''
|
|
|
|
|
elseif body =~# '^ref: refs/'
|
|
|
|
|
let path = '.git/' . matchstr(body,'ref: \zs.*')
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
if a:0 && a:1 =~# '@[[:alnum:]_-]*\%(://.\{-\}\)\=$'
|
|
|
|
|
let remote = matchstr(a:1,'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$')
|
|
|
|
|
elseif path =~# '^\.git/refs/remotes/.'
|
|
|
|
|
let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+')
|
|
|
|
|
else
|
|
|
|
|
let remote = 'origin'
|
|
|
|
|
let branch = matchstr(rev,'^[[:alnum:]/._-]\+\ze[:^~@]')
|
|
|
|
|
if branch ==# '' && path =~# '^\.git/refs/\w\+/'
|
|
|
|
|
let branch = s:sub(path,'^\.git/refs/\w+/','')
|
|
|
|
|
endif
|
|
|
|
|
if filereadable(s:repo().dir('refs/remotes/'.branch))
|
|
|
|
|
let remote = matchstr(branch,'[^/]\+')
|
|
|
|
|
let rev = rev[strlen(remote)+1:-1]
|
|
|
|
|
else
|
|
|
|
|
if branch ==# ''
|
|
|
|
|
let branch = matchstr(s:repo().head_ref(),'\<refs/heads/\zs.*')
|
|
|
|
|
endif
|
|
|
|
|
if branch != ''
|
|
|
|
|
let remote = s:repo().git_chomp('config','branch.'.branch.'.remote')
|
|
|
|
|
if remote ==# ''
|
|
|
|
|
let remote = 'origin'
|
|
|
|
|
elseif rev[0:strlen(branch)-1] ==# branch && rev[strlen(branch)] =~# '[:^~@]'
|
|
|
|
|
let rev = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1] . rev[strlen(branch):-1]
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
let raw = s:repo().git_chomp('config','remote.'.remote.'.url')
|
|
|
|
|
if raw ==# ''
|
|
|
|
|
let raw = remote
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
let url = s:github_url(s:repo(),raw,rev,commit,path,type,a:line1,a:count)
|
|
|
|
|
if url == ''
|
|
|
|
|
let url = s:instaweb_url(s:repo(),rev,commit,path,type,a:count ? a:line1 : 0)
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
if url == ''
|
|
|
|
|
call s:throw("Instaweb failed to start and '".remote."' is not a GitHub remote")
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
if a:bang
|
|
|
|
|
let @* = url
|
|
|
|
|
return 'echomsg '.string(url)
|
|
|
|
|
else
|
|
|
|
|
return 'echomsg '.string(url).'|silent Git web--browse '.shellescape(url,1)
|
|
|
|
|
endif
|
|
|
|
|
catch /^fugitive:/
|
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
|
endtry
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
|
|
|
|
|
let path = a:path
|
|
|
|
|
let repo_path = matchstr(a:url,'^\%(https\=://\|git://\|git@\)github\.com[/:]\zs.\{-\}\ze\%(\.git\)\=$')
|
|
|
|
|
if repo_path ==# ''
|
|
|
|
|
return ''
|
|
|
|
|
endif
|
|
|
|
|
let root = 'https://github.com/' . repo_path
|
|
|
|
|
if path =~# '^\.git/refs/heads/'
|
|
|
|
|
let branch = a:repo.git_chomp('config','branch.'.path[16:-1].'.merge')[11:-1]
|
|
|
|
|
if branch ==# ''
|
|
|
|
|
return root . '/commits/' . path[16:-1]
|
|
|
|
|
else
|
|
|
|
|
return root . '/commits/' . branch
|
|
|
|
|
endif
|
|
|
|
|
elseif path =~# '^\.git/refs/.'
|
|
|
|
|
return root . '/commits/' . matchstr(path,'[^/]\+$')
|
|
|
|
|
elseif path =~# '.git/\%(config$\|hooks\>\)'
|
|
|
|
|
return root . '/admin'
|
|
|
|
|
elseif path =~# '^\.git\>'
|
|
|
|
|
return root
|
|
|
|
|
endif
|
|
|
|
|
if a:rev =~# '^[[:alnum:]._-]\+:'
|
|
|
|
|
let commit = matchstr(a:rev,'^[^:]*')
|
|
|
|
|
elseif a:commit =~# '^\d\=$'
|
|
|
|
|
let local = matchstr(a:repo.head_ref(),'\<refs/heads/\zs.*')
|
|
|
|
|
let commit = a:repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
|
|
|
|
|
if commit ==# ''
|
|
|
|
|
let commit = local
|
|
|
|
|
endif
|
|
|
|
|
else
|
|
|
|
|
let commit = a:commit
|
|
|
|
|
endif
|
|
|
|
|
if a:type == 'tree'
|
|
|
|
|
let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
|
|
|
|
|
elseif a:type == 'blob'
|
|
|
|
|
let url = root . '/blob/' . commit . '/' . path
|
|
|
|
|
if a:line2 && a:line1 == a:line2
|
|
|
|
|
let url .= '#L' . a:line1
|
|
|
|
|
elseif a:line2
|
|
|
|
|
let url .= '#L' . a:line1 . '-' . a:line2
|
|
|
|
|
endif
|
|
|
|
|
elseif a:type == 'tag'
|
|
|
|
|
let commit = matchstr(getline(3),'^tag \zs.*')
|
|
|
|
|
let url = root . '/tree/' . commit
|
|
|
|
|
else
|
|
|
|
|
let url = root . '/commit/' . commit
|
|
|
|
|
endif
|
|
|
|
|
return url
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:instaweb_url(repo,rev,commit,path,type,...) abort
|
|
|
|
|
let output = a:repo.git_chomp('instaweb','-b','unknown')
|
|
|
|
|
if output =~# 'http://'
|
|
|
|
|
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:repo.dir(),':t')
|
|
|
|
|
else
|
|
|
|
|
return ''
|
|
|
|
|
endif
|
|
|
|
|
if a:path =~# '^\.git/refs/.'
|
|
|
|
|
return root . ';a=shortlog;h=' . matchstr(a:path,'^\.git/\zs.*')
|
|
|
|
|
elseif a:path =~# '^\.git\>'
|
|
|
|
|
return root
|
|
|
|
|
endif
|
|
|
|
|
let url = root
|
|
|
|
|
if a:commit =~# '^\x\{40\}$'
|
|
|
|
|
if a:type ==# 'commit'
|
|
|
|
|
let url .= ';a=commit'
|
|
|
|
|
endif
|
|
|
|
|
let url .= ';h=' . a:repo.rev_parse(a:commit . (a:path == '' ? '' : ':' . a:path))
|
|
|
|
|
else
|
|
|
|
|
if a:type ==# 'blob'
|
|
|
|
|
let tmp = tempname()
|
|
|
|
|
silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp
|
|
|
|
|
let url .= ';h=' . readfile(tmp)[0]
|
|
|
|
|
else
|
|
|
|
|
try
|
|
|
|
|
let url .= ';h=' . a:repo.rev_parse((a:commit == '' ? 'HEAD' : ':' . a:commit) . ':' . a:path)
|
|
|
|
|
catch /^fugitive:/
|
|
|
|
|
call s:throw('fugitive: cannot browse uncommitted file')
|
|
|
|
|
endtry
|
|
|
|
|
endif
|
|
|
|
|
let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$')
|
|
|
|
|
endif
|
|
|
|
|
if a:path !=# ''
|
|
|
|
|
let url .= ';f=' . a:path
|
|
|
|
|
endif
|
|
|
|
|
if a:0 && a:1
|
|
|
|
|
let url .= '#l' . a:1
|
|
|
|
|
endif
|
|
|
|
|
return url
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
|
" File access {{{1
|
|
|
|
|
|
|
|
|
|
@@ -1305,14 +1616,12 @@ function! s:ReplaceCmd(cmd,...) abort
|
|
|
|
|
if &shell =~# 'cmd'
|
|
|
|
|
let old_index = $GIT_INDEX_FILE
|
|
|
|
|
let $GIT_INDEX_FILE = a:1
|
|
|
|
|
elseif &shell =~# 'csh'
|
|
|
|
|
let prefix = 'setenv GIT_INDEX_FILE '.s:shellesc(a:1).'; '
|
|
|
|
|
else
|
|
|
|
|
let prefix = 'GIT_INDEX_FILE='.s:shellesc(a:1).' '
|
|
|
|
|
let prefix = 'env GIT_INDEX_FILE='.s:shellesc(a:1).' '
|
|
|
|
|
endif
|
|
|
|
|
endif
|
|
|
|
|
set noautowrite
|
|
|
|
|
silent exe '!'.escape(prefix.a:cmd,'%#').' > '.tmp
|
|
|
|
|
call system(prefix.a:cmd.' > '.tmp)
|
|
|
|
|
finally
|
|
|
|
|
let &autowrite = aw
|
|
|
|
|
if exists('old_index')
|
|
|
|
|
@@ -1338,7 +1647,7 @@ function! s:BufReadIndex()
|
|
|
|
|
if fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : b:git_dir . '/index', ':p') ==# expand('%:p')
|
|
|
|
|
let index = ''
|
|
|
|
|
else
|
|
|
|
|
let index = expand('%')
|
|
|
|
|
let index = expand('%:p')
|
|
|
|
|
endif
|
|
|
|
|
if b:fugitive_display_format
|
|
|
|
|
call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index)
|
|
|
|
|
@@ -1358,10 +1667,16 @@ function! s:BufReadIndex()
|
|
|
|
|
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe <SID>BufReadIndex()<CR>
|
|
|
|
|
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe <SID>BufReadIndex()<CR>
|
|
|
|
|
nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff()<CR>
|
|
|
|
|
nnoremap <buffer> <silent> dd :<C-U>execute <SID>StageDiff()<CR>
|
|
|
|
|
nnoremap <buffer> <silent> dh :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
|
|
|
|
|
nnoremap <buffer> <silent> ds :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
|
|
|
|
|
nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff()<CR>
|
|
|
|
|
nnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
|
|
|
|
|
xnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line("'<"),line("'>"))<CR>
|
|
|
|
|
nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
|
|
|
|
|
xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
|
|
|
|
|
nnoremap <buffer> <silent> <C-N> :call search('^#\t.*','W')<Bar>.<CR>
|
|
|
|
|
nnoremap <buffer> <silent> <C-P> :call search('^#\t.*','Wbe')<Bar>.<CR>
|
|
|
|
|
call s:JumpInit()
|
|
|
|
|
nunmap <buffer> P
|
|
|
|
|
nunmap <buffer> ~
|
|
|
|
|
@@ -1415,7 +1730,11 @@ function! s:BufWriteIndexFile()
|
|
|
|
|
endif
|
|
|
|
|
let info = old_mode.' '.sha1.' '.stage."\t".path
|
|
|
|
|
call writefile([info],tmp)
|
|
|
|
|
let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp)
|
|
|
|
|
if has('win32')
|
|
|
|
|
let error = system('type '.tmp.'|'.s:repo().git_command('update-index','--index-info'))
|
|
|
|
|
else
|
|
|
|
|
let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp)
|
|
|
|
|
endif
|
|
|
|
|
if v:shell_error == 0
|
|
|
|
|
setlocal nomodified
|
|
|
|
|
silent execute 'doautocmd BufWritePost '.s:fnameescape(expand('%:p'))
|
|
|
|
|
@@ -1539,9 +1858,9 @@ function! s:GF(mode) abort
|
|
|
|
|
if showtree && line('.') == 1
|
|
|
|
|
return ""
|
|
|
|
|
elseif showtree && line('.') > 2
|
|
|
|
|
return s:Edit(a:mode,buffer.commit().':'.(buffer.path() == '' ? '' : buffer.path().'/').s:sub(getline('.'),'/$',''))
|
|
|
|
|
return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$',''))
|
|
|
|
|
elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
|
|
|
|
|
return s:Edit(a:mode,buffer.commit().':'.(buffer.path() == '' ? '' : buffer.path().'/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
|
|
|
|
|
return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
elseif buffer.type('blob')
|
|
|
|
|
@@ -1566,7 +1885,7 @@ function! s:GF(mode) abort
|
|
|
|
|
let file = '/'.matchstr(getline('.'),' -> \zs.*')
|
|
|
|
|
return s:Edit(a:mode,file)
|
|
|
|
|
elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.'
|
|
|
|
|
let file = '/'.matchstr(getline('.'),': *\zs.*')
|
|
|
|
|
let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( (new commits)\)\=$')
|
|
|
|
|
return s:Edit(a:mode,file)
|
|
|
|
|
elseif getline('.') =~# '^#\t.'
|
|
|
|
|
let file = '/'.matchstr(getline('.'),'#\t\zs.*')
|
|
|
|
|
@@ -1629,6 +1948,13 @@ function! s:GF(mode) abort
|
|
|
|
|
elseif getline('.') =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
|
|
|
|
|
let dref = matchstr(getline('.'),'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
|
|
|
|
let ref = matchstr(getline('.'),'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
|
|
|
|
let dcmd = 'Gdiff'
|
|
|
|
|
|
|
|
|
|
elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
|
|
|
|
|
let line = getline(line('.')-1)
|
|
|
|
|
let dref = matchstr(line,'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
|
|
|
|
let ref = matchstr(line,'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
|
|
|
|
let dcmd = 'Gdiff!'
|
|
|
|
|
|
|
|
|
|
elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
|
|
|
|
|
let ref = getline('.')
|
|
|
|
|
@@ -1656,7 +1982,7 @@ function! s:GF(mode) abort
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
if exists('dref')
|
|
|
|
|
return s:Edit(a:mode,ref) . '|Gdiff '.s:fnameescape(dref)
|
|
|
|
|
return s:Edit(a:mode,ref) . '|'.dcmd.' '.s:fnameescape(dref)
|
|
|
|
|
elseif ref != ""
|
|
|
|
|
return s:Edit(a:mode,ref)
|
|
|
|
|
endif
|
|
|
|
|
@@ -1698,6 +2024,18 @@ function! fugitive#statusline(...)
|
|
|
|
|
endif
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
function! s:repo_config(conf) dict abort
|
|
|
|
|
return matchstr(system(s:repo().git_command('config').' '.a:conf),"[^\r\n]*")
|
|
|
|
|
endfun
|
|
|
|
|
|
|
|
|
|
function! s:repo_user() dict abort
|
|
|
|
|
let username = s:repo().config('user.name')
|
|
|
|
|
let useremail = s:repo().config('user.email')
|
|
|
|
|
return username.' <'.useremail.'>'
|
|
|
|
|
endfun
|
|
|
|
|
|
|
|
|
|
call s:add_methods('repo',['config', 'user'])
|
|
|
|
|
|
|
|
|
|
" }}}1
|
|
|
|
|
|
|
|
|
|
" vim:set ft=vim ts=8 sw=2 sts=2:
|
|
|
|
|
|