mirror of
https://github.com/tpope/vim-fugitive.git
synced 2026-04-26 17:10:23 +08:00
Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 62c50ff296 | |||
| c2877d0d5c | |||
| c640ee78a8 | |||
| c9b26e20d3 | |||
| 79f4a49a94 | |||
| 0cb46585ac | |||
| d4df8882c5 | |||
| d5208d494f | |||
| cf248fa66d | |||
| 779949c255 | |||
| 785bb15745 | |||
| fbf89773b4 | |||
| 02a0be79aa | |||
| b2767d204b | |||
| 26504eecbd | |||
| 0d281a2607 | |||
| b2665cc650 | |||
| c3052fba84 | |||
| 4f24757df2 | |||
| eb945e9a11 | |||
| 90cbbf5854 | |||
| 87c1bda4d5 | |||
| c5c1bd66d8 | |||
| f44845e440 | |||
| 245ce889e2 | |||
| 444ba9fda5 | |||
| b754bc2031 | |||
| b3a8be6975 | |||
| 58ed86e434 | |||
| aac85a268e | |||
| c00ebd75ac | |||
| 50cc268d29 | |||
| 4865891565 | |||
| 3439f999b1 | |||
| 6460734b5e | |||
| bdd216827a | |||
| 0ac4915cd7 | |||
| 841adb49ad | |||
| 57afba5bdd | |||
| e1ae9effbc | |||
| 19d1c944db | |||
| 9315ec694d | |||
| 90250785d1 | |||
| 099d65826e | |||
| 008b957086 | |||
| 16c2b7abb9 | |||
| 1e3f1103d9 | |||
| 9835920a3c | |||
| fd36aa9c61 | |||
| 4dd41688cf | |||
| 18d6d1ab82 | |||
| 9ce67cdc93 | |||
| bf04261080 | |||
| 52d180af0a | |||
| 14daf094d9 | |||
| ac904e806d | |||
| 9f768cd3bc | |||
| 09cdce7add | |||
| 8851b8fe64 | |||
| cfa485ede7 | |||
| 207c643ea4 | |||
| cac2c8ef8e | |||
| a9a22e0e4e | |||
| c3e918072f |
+9
-3
@@ -35,9 +35,15 @@ and you never get any warnings about the file changing outside Vim.
|
|||||||
making it like `git add` when called from a work tree file and like
|
making it like `git add` when called from a work tree file and like
|
||||||
`git checkout` when called from the index or a blob in history.
|
`git checkout` when called from the index or a blob in history.
|
||||||
|
|
||||||
Use `:Gbrowse` to open the current file on GitHub, with optional line
|
Use `:Gbrowse` to open the current file on the web front-end of your favorite
|
||||||
range (try it in visual mode!). If your current repository isn't on
|
hosting provider, with optional line range (try it in visual mode!). Built-in
|
||||||
GitHub, `git instaweb` will be spun up instead.
|
support is provided for `git instaweb`, and plugins are available for popular
|
||||||
|
providers such as [GitHub][rhubarb.vim], [GitLab][fugitive-gitlab.vim], and
|
||||||
|
[Bitbucket][fubitive.vim].
|
||||||
|
|
||||||
|
[rhubarb.vim]: https://github.com/tpope/vim-rhubarb
|
||||||
|
[fugitive-gitlab.vim]: https://github.com/shumphrey/fugitive-gitlab.vim
|
||||||
|
[fubitive.vim]: https://github.com/tommcdo/vim-fubitive
|
||||||
|
|
||||||
Add `%{fugitive#statusline()}` to `'statusline'` to get an indicator
|
Add `%{fugitive#statusline()}` to `'statusline'` to get an indicator
|
||||||
with the current branch in (surprise!) your statusline.
|
with the current branch in (surprise!) your statusline.
|
||||||
|
|||||||
+18
-12
@@ -57,6 +57,10 @@ that are part of Git repositories).
|
|||||||
q close status
|
q close status
|
||||||
r reload status
|
r reload status
|
||||||
S |:Gvsplit|
|
S |:Gvsplit|
|
||||||
|
U |:Git| checkout
|
||||||
|
U |:Git| checkout HEAD (staged files)
|
||||||
|
U |:Git| clean (untracked files)
|
||||||
|
U |:Git| rm (unmerged files)
|
||||||
|
|
||||||
*fugitive-:Gcommit*
|
*fugitive-:Gcommit*
|
||||||
:Gcommit [args] A wrapper around git-commit. If there is nothing
|
:Gcommit [args] A wrapper around git-commit. If there is nothing
|
||||||
@@ -91,10 +95,10 @@ that are part of Git repositories).
|
|||||||
:Gfetch [args] Like |:Gpush|, but for git-fetch.
|
:Gfetch [args] Like |:Gpush|, but for git-fetch.
|
||||||
|
|
||||||
*fugitive-:Ggrep*
|
*fugitive-:Ggrep*
|
||||||
:Ggrep [args] |:grep| with git-grep as 'grepprg'.
|
:Ggrep[!] [args] |:grep|[!] with git-grep as 'grepprg'.
|
||||||
|
|
||||||
*fugitive-:Glgrep*
|
*fugitive-:Glgrep*
|
||||||
:Glgrep [args] |:lgrep| with git-grep as 'grepprg'.
|
:Glgrep[!] [args] |:lgrep|[!] with git-grep as 'grepprg'.
|
||||||
|
|
||||||
*fugitive-:Glog*
|
*fugitive-:Glog*
|
||||||
:Glog [args] Load all previous revisions of the current file into
|
:Glog [args] Load all previous revisions of the current file into
|
||||||
@@ -177,7 +181,9 @@ that are part of Git repositories).
|
|||||||
to the right or bottom, depending on 'diffopt' and
|
to the right or bottom, depending on 'diffopt' and
|
||||||
the width of the window relative to 'textwidth'. Use
|
the width of the window relative to 'textwidth'. Use
|
||||||
|do| and |dp| and write to the index file to simulate
|
|do| and |dp| and write to the index file to simulate
|
||||||
"git add --patch".
|
"git add --patch". For the three-way diff, there is
|
||||||
|
also d2o and d3o pulling the hunk to the middle from
|
||||||
|
the left or the right window, respectively.
|
||||||
|
|
||||||
*fugitive-:Gsdiff*
|
*fugitive-:Gsdiff*
|
||||||
:Gsdiff [revision] Like |:Gdiff|, but always split horizontally.
|
:Gsdiff [revision] Like |:Gdiff|, but always split horizontally.
|
||||||
@@ -221,20 +227,20 @@ that are part of Git repositories).
|
|||||||
|
|
||||||
*fugitive-:Gbrowse*
|
*fugitive-:Gbrowse*
|
||||||
:Gbrowse Open the current file, blob, tree, commit, or tag
|
:Gbrowse Open the current file, blob, tree, commit, or tag
|
||||||
in your browser at the upstream hosting provider
|
in your browser at the upstream hosting provider.
|
||||||
indicated by the "origin" remote. If a range is
|
If a range is given, it is appropriately appended to
|
||||||
given, it is appropriately appended to the URL as an
|
the URL as an anchor.
|
||||||
anchor.
|
|
||||||
|
|
||||||
Upstream providers can be added by installing an
|
Upstream providers can be added by installing an
|
||||||
appropriate Vim plugin. For example, GitHub can be
|
appropriate Vim plugin. For example, GitHub can be
|
||||||
supported by installing rhubarb.vim, available at
|
supported by installing rhubarb.vim, available at
|
||||||
<https://github.com/tpope/vim-rhubarb>. (Native
|
<https://github.com/tpope/vim-rhubarb>.
|
||||||
support for GitHub is currently included, but that is
|
|
||||||
slated to be removed.)
|
|
||||||
|
|
||||||
If no upstream support is available, a local instance
|
The hosting provider is determined by looking at the
|
||||||
of git-instaweb will be started and used instead.
|
remote for the current or specified branch and falls
|
||||||
|
back to "origin". In the special case of a "."
|
||||||
|
remote, a local instance of git-instaweb will be
|
||||||
|
started and used.
|
||||||
|
|
||||||
:Gbrowse {revision} Like :Gbrowse, but for a given |fugitive-revision|. A
|
:Gbrowse {revision} Like :Gbrowse, but for a given |fugitive-revision|. A
|
||||||
useful value here is -, which ties the URL to the
|
useful value here is -, which ties the URL to the
|
||||||
|
|||||||
+223
-148
@@ -70,6 +70,10 @@ endfunction
|
|||||||
|
|
||||||
let s:git_versions = {}
|
let s:git_versions = {}
|
||||||
|
|
||||||
|
function! s:git_command() abort
|
||||||
|
return get(g:, 'fugitive_git_command', g:fugitive_git_executable)
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! fugitive#git_version(...) abort
|
function! fugitive#git_version(...) abort
|
||||||
if !has_key(s:git_versions, g:fugitive_git_executable)
|
if !has_key(s:git_versions, g:fugitive_git_executable)
|
||||||
let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\n")
|
let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\n")
|
||||||
@@ -112,25 +116,27 @@ function! s:define_commands() abort
|
|||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
augroup fugitive_utility
|
|
||||||
autocmd!
|
|
||||||
autocmd User Fugitive call s:define_commands()
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
let s:abstract_prototype = {}
|
let s:abstract_prototype = {}
|
||||||
|
|
||||||
" Section: Initialization
|
" Section: Initialization
|
||||||
|
|
||||||
function! fugitive#is_git_dir(path) abort
|
function! fugitive#is_git_dir(path) abort
|
||||||
let path = s:sub(a:path, '[\/]$', '') . '/'
|
let path = s:sub(a:path, '[\/]$', '') . '/'
|
||||||
return isdirectory(path.'objects') && isdirectory(path.'refs') && getfsize(path.'HEAD') > 10
|
return getfsize(path.'HEAD') > 10 && (
|
||||||
|
\ isdirectory(path.'objects') && isdirectory(path.'refs') ||
|
||||||
|
\ getftype(path.'commondir') ==# 'file')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! fugitive#extract_git_dir(path) abort
|
function! fugitive#extract_git_dir(path) abort
|
||||||
if s:shellslash(a:path) =~# '^fugitive://.*//'
|
if s:shellslash(a:path) =~# '^fugitive://.*//'
|
||||||
return matchstr(s:shellslash(a:path), '\C^fugitive://\zs.\{-\}\ze//')
|
return matchstr(s:shellslash(a:path), '\C^fugitive://\zs.\{-\}\ze//')
|
||||||
endif
|
endif
|
||||||
let root = s:shellslash(simplify(fnamemodify(a:path, ':p:s?[\/]$??')))
|
if isdirectory(a:path)
|
||||||
|
let path = fnamemodify(a:path, ':p:s?[\/]$??')
|
||||||
|
else
|
||||||
|
let path = fnamemodify(a:path, ':p:h:s?[\/]$??')
|
||||||
|
endif
|
||||||
|
let root = s:shellslash(resolve(path))
|
||||||
let previous = ""
|
let previous = ""
|
||||||
while root !=# previous
|
while root !=# previous
|
||||||
if root =~# '\v^//%([^/]+/?)?$'
|
if root =~# '\v^//%([^/]+/?)?$'
|
||||||
@@ -182,6 +188,9 @@ function! fugitive#detect(path) abort
|
|||||||
let dir = fugitive#extract_git_dir(a:path)
|
let dir = fugitive#extract_git_dir(a:path)
|
||||||
if dir !=# ''
|
if dir !=# ''
|
||||||
let b:git_dir = dir
|
let b:git_dir = dir
|
||||||
|
if empty(fugitive#buffer().path())
|
||||||
|
silent! exe haslocaldir() ? 'lcd .' : 'cd .'
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
if exists('b:git_dir')
|
if exists('b:git_dir')
|
||||||
@@ -198,7 +207,7 @@ function! fugitive#detect(path) abort
|
|||||||
nnoremap <buffer> <silent> y<C-G> :call setreg(v:register, <SID>recall())<CR>
|
nnoremap <buffer> <silent> y<C-G> :call setreg(v:register, <SID>recall())<CR>
|
||||||
endif
|
endif
|
||||||
let buffer = fugitive#buffer()
|
let buffer = fugitive#buffer()
|
||||||
if expand('%:p') =~# '//'
|
if expand('%:p') =~# '://'
|
||||||
call buffer.setvar('&path', s:sub(buffer.getvar('&path'), '^\.%(,|$)', ''))
|
call buffer.setvar('&path', s:sub(buffer.getvar('&path'), '^\.%(,|$)', ''))
|
||||||
endif
|
endif
|
||||||
if stridx(buffer.getvar('&tags'), escape(b:git_dir, ', ')) == -1
|
if stridx(buffer.getvar('&tags'), escape(b:git_dir, ', ')) == -1
|
||||||
@@ -211,6 +220,7 @@ function! fugitive#detect(path) abort
|
|||||||
endif
|
endif
|
||||||
try
|
try
|
||||||
let [save_mls, &modelines] = [&mls, 0]
|
let [save_mls, &modelines] = [&mls, 0]
|
||||||
|
call s:define_commands()
|
||||||
doautocmd User Fugitive
|
doautocmd User Fugitive
|
||||||
finally
|
finally
|
||||||
let &mls = save_mls
|
let &mls = save_mls
|
||||||
@@ -265,9 +275,17 @@ function! s:configured_tree(git_dir) abort
|
|||||||
let config = readfile(config_file,'',10)
|
let config = readfile(config_file,'',10)
|
||||||
call filter(config,'v:val =~# "^\\s*worktree *="')
|
call filter(config,'v:val =~# "^\\s*worktree *="')
|
||||||
if len(config) == 1
|
if len(config) == 1
|
||||||
let s:worktree_for_dir[a:git_dir] = matchstr(config[0], '= *\zs.*')
|
let worktree = matchstr(config[0], '= *\zs.*')
|
||||||
let s:dir_for_worktree[s:worktree_for_dir[a:git_dir]] = a:git_dir
|
|
||||||
endif
|
endif
|
||||||
|
elseif filereadable(a:git_dir . '/gitdir')
|
||||||
|
let worktree = fnamemodify(readfile(a:git_dir . '/gitdir')[0], ':h')
|
||||||
|
if worktree ==# '.'
|
||||||
|
unlet! worktree
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
if exists('worktree')
|
||||||
|
let s:worktree_for_dir[a:git_dir] = worktree
|
||||||
|
let s:dir_for_worktree[s:worktree_for_dir[a:git_dir]] = a:git_dir
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
if s:worktree_for_dir[a:git_dir] =~# '^\.'
|
if s:worktree_for_dir[a:git_dir] =~# '^\.'
|
||||||
@@ -280,6 +298,9 @@ endfunction
|
|||||||
function! s:repo_tree(...) dict abort
|
function! s:repo_tree(...) dict abort
|
||||||
if self.dir() =~# '/\.git$'
|
if self.dir() =~# '/\.git$'
|
||||||
let dir = self.dir()[0:-6]
|
let dir = self.dir()[0:-6]
|
||||||
|
if dir !~# '/'
|
||||||
|
let dir .= '/'
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
let dir = s:configured_tree(self.git_dir)
|
let dir = s:configured_tree(self.git_dir)
|
||||||
endif
|
endif
|
||||||
@@ -299,6 +320,10 @@ function! s:repo_bare() dict abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:repo_translate(spec) dict abort
|
function! s:repo_translate(spec) dict abort
|
||||||
|
let refs = self.dir('refs/')
|
||||||
|
if filereadable(self.dir('commondir'))
|
||||||
|
let refs = simplify(self.dir(get(readfile(self.dir('commondir'), 1), 0, ''))) . '/refs/'
|
||||||
|
endif
|
||||||
if a:spec ==# '.' || a:spec ==# '/.'
|
if a:spec ==# '.' || a:spec ==# '/.'
|
||||||
return self.bare() ? self.dir() : self.tree()
|
return self.bare() ? self.dir() : self.tree()
|
||||||
elseif a:spec =~# '^/\=\.git$' && self.bare()
|
elseif a:spec =~# '^/\=\.git$' && self.bare()
|
||||||
@@ -320,18 +345,20 @@ function! s:repo_translate(spec) dict abort
|
|||||||
return 'fugitive://'.self.dir().'//'.ref
|
return 'fugitive://'.self.dir().'//'.ref
|
||||||
elseif a:spec =~# '^:'
|
elseif a:spec =~# '^:'
|
||||||
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
|
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
|
||||||
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(self.dir(a:spec))
|
elseif a:spec ==# '@'
|
||||||
return self.dir(a:spec)
|
return self.dir('HEAD')
|
||||||
elseif filereadable(self.dir('refs/'.a:spec))
|
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(refs . '../' . a:spec)
|
||||||
return self.dir('refs/'.a:spec)
|
return simplify(refs . '../' . a:spec)
|
||||||
elseif filereadable(self.dir('refs/tags/'.a:spec))
|
elseif filereadable(refs.a:spec)
|
||||||
return self.dir('refs/tags/'.a:spec)
|
return refs.a:spec
|
||||||
elseif filereadable(self.dir('refs/heads/'.a:spec))
|
elseif filereadable(refs.'tags/'.a:spec)
|
||||||
return self.dir('refs/heads/'.a:spec)
|
return refs.'tags/'.a:spec
|
||||||
elseif filereadable(self.dir('refs/remotes/'.a:spec))
|
elseif filereadable(refs.'heads/'.a:spec)
|
||||||
return self.dir('refs/remotes/'.a:spec)
|
return refs.'heads/'.a:spec
|
||||||
elseif filereadable(self.dir('refs/remotes/'.a:spec.'/HEAD'))
|
elseif filereadable(refs.'remotes/'.a:spec)
|
||||||
return self.dir('refs/remotes/'.a:spec,'/HEAD')
|
return refs.'remotes/'.a:spec
|
||||||
|
elseif filereadable(refs.'remotes/'.a:spec.'/HEAD')
|
||||||
|
return refs.'remotes/'.a:spec.'/HEAD'
|
||||||
else
|
else
|
||||||
try
|
try
|
||||||
let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
|
let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
|
||||||
@@ -362,12 +389,14 @@ endfunction
|
|||||||
call s:add_methods('repo',['dir','tree','bare','translate','head'])
|
call s:add_methods('repo',['dir','tree','bare','translate','head'])
|
||||||
|
|
||||||
function! s:repo_git_command(...) dict abort
|
function! s:repo_git_command(...) dict abort
|
||||||
let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
|
let git = s:git_command() . ' --git-dir='.s:shellesc(self.git_dir)
|
||||||
return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
|
return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:repo_git_chomp(...) dict abort
|
function! s:repo_git_chomp(...) dict abort
|
||||||
return s:sub(system(call(self.git_command,a:000,self)),'\n$','')
|
let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
|
||||||
|
let output = git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
|
||||||
|
return s:sub(system(output),'\n$','')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:repo_git_chomp_in_tree(...) dict abort
|
function! s:repo_git_chomp_in_tree(...) dict abort
|
||||||
@@ -444,7 +473,7 @@ endfunction
|
|||||||
call s:add_methods('repo',['dirglob','superglob'])
|
call s:add_methods('repo',['dirglob','superglob'])
|
||||||
|
|
||||||
function! s:repo_config(conf) dict abort
|
function! s:repo_config(conf) dict abort
|
||||||
return matchstr(system(s:repo().git_command('config').' '.a:conf),"[^\r\n]*")
|
return matchstr(s:repo().git_chomp('config',a:conf),"[^\r\n]*")
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
function! s:repo_user() dict abort
|
function! s:repo_user() dict abort
|
||||||
@@ -456,8 +485,8 @@ endfun
|
|||||||
function! s:repo_aliases() dict abort
|
function! s:repo_aliases() dict abort
|
||||||
if !has_key(self,'_aliases')
|
if !has_key(self,'_aliases')
|
||||||
let self._aliases = {}
|
let self._aliases = {}
|
||||||
for line in split(self.git_chomp('config','--get-regexp','^alias[.]'),"\n")
|
for line in split(self.git_chomp('config','-z','--get-regexp','^alias[.]'),"\1")
|
||||||
let self._aliases[matchstr(line,'\.\zs\S\+')] = matchstr(line,' \zs.*')
|
let self._aliases[matchstr(line, '\.\zs.\{-}\ze\n')] = matchstr(line, '\n\zs.*')
|
||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
return self._aliases
|
return self._aliases
|
||||||
@@ -468,9 +497,9 @@ call s:add_methods('repo',['config', 'user', 'aliases'])
|
|||||||
function! s:repo_keywordprg() dict abort
|
function! s:repo_keywordprg() dict abort
|
||||||
let args = ' --git-dir='.escape(self.dir(),"\\\"' ")
|
let args = ' --git-dir='.escape(self.dir(),"\\\"' ")
|
||||||
if has('gui_running') && !has('win32')
|
if has('gui_running') && !has('win32')
|
||||||
return g:fugitive_git_executable . ' --no-pager' . args . ' log -1'
|
return s:git_command() . ' --no-pager' . args . ' log -1'
|
||||||
else
|
else
|
||||||
return g:fugitive_git_executable . args . ' show'
|
return s:git_command() . args . ' show'
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -681,14 +710,18 @@ function! s:Git(bang, args) abort
|
|||||||
if a:bang
|
if a:bang
|
||||||
return s:Edit('edit', 1, a:args)
|
return s:Edit('edit', 1, a:args)
|
||||||
endif
|
endif
|
||||||
let git = g:fugitive_git_executable
|
let git = s:git_command()
|
||||||
if has('gui_running') && !has('win32')
|
if has('gui_running') && !has('win32')
|
||||||
let git .= ' --no-pager'
|
let git .= ' --no-pager'
|
||||||
endif
|
endif
|
||||||
let args = matchstr(a:args,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
|
let args = matchstr(a:args,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
|
||||||
if exists(':terminal')
|
if exists(':terminal')
|
||||||
let dir = s:repo().tree()
|
let dir = s:repo().tree()
|
||||||
tabedit %
|
if expand('%') != ''
|
||||||
|
-tabedit %
|
||||||
|
else
|
||||||
|
-tabnew
|
||||||
|
endif
|
||||||
execute 'lcd' fnameescape(dir)
|
execute 'lcd' fnameescape(dir)
|
||||||
execute 'terminal' git args
|
execute 'terminal' git args
|
||||||
else
|
else
|
||||||
@@ -847,7 +880,9 @@ function! s:StageUndo() abort
|
|||||||
let hash = repo.git_chomp('hash-object', '-w', filename)
|
let hash = repo.git_chomp('hash-object', '-w', filename)
|
||||||
if !empty(hash)
|
if !empty(hash)
|
||||||
if section ==# 'untracked'
|
if section ==# 'untracked'
|
||||||
call delete(s:repo().tree(filename))
|
call repo.git_chomp_in_tree('clean', '-f', '--', filename)
|
||||||
|
elseif section ==# 'unmerged'
|
||||||
|
call repo.git_chomp_in_tree('rm', '--', filename)
|
||||||
elseif section ==# 'unstaged'
|
elseif section ==# 'unstaged'
|
||||||
call repo.git_chomp_in_tree('checkout', '--', filename)
|
call repo.git_chomp_in_tree('checkout', '--', filename)
|
||||||
else
|
else
|
||||||
@@ -1042,13 +1077,14 @@ function! s:Commit(args, ...) abort
|
|||||||
else
|
else
|
||||||
noautocmd silent execute '!'.command.' > '.outfile.' 2> '.errorfile
|
noautocmd silent execute '!'.command.' > '.outfile.' 2> '.errorfile
|
||||||
endif
|
endif
|
||||||
|
let error = v:shell_error
|
||||||
finally
|
finally
|
||||||
execute cd.'`=dir`'
|
execute cd.'`=dir`'
|
||||||
endtry
|
endtry
|
||||||
if !has('gui_running')
|
if !has('gui_running')
|
||||||
redraw!
|
redraw!
|
||||||
endif
|
endif
|
||||||
if !v:shell_error
|
if !error
|
||||||
if filereadable(outfile)
|
if filereadable(outfile)
|
||||||
for line in readfile(outfile)
|
for line in readfile(outfile)
|
||||||
echo line
|
echo line
|
||||||
@@ -1071,7 +1107,7 @@ function! s:Commit(args, ...) abort
|
|||||||
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
|
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
|
||||||
execute 'keepalt edit '.s:fnameescape(msgfile)
|
execute 'keepalt edit '.s:fnameescape(msgfile)
|
||||||
elseif a:args =~# '\%(^\| \)-\%(-verbose\|\w*v\)\>'
|
elseif a:args =~# '\%(^\| \)-\%(-verbose\|\w*v\)\>'
|
||||||
execute 'keepalt '.(tabpagenr()-1).'tabedit '.s:fnameescape(msgfile)
|
execute 'keepalt -tabedit '.s:fnameescape(msgfile)
|
||||||
elseif s:buffer().type() ==# 'index'
|
elseif s:buffer().type() ==# 'index'
|
||||||
execute 'keepalt edit '.s:fnameescape(msgfile)
|
execute 'keepalt edit '.s:fnameescape(msgfile)
|
||||||
execute (search('^#','n')+1).'wincmd+'
|
execute (search('^#','n')+1).'wincmd+'
|
||||||
@@ -1102,7 +1138,7 @@ endfunction
|
|||||||
|
|
||||||
function! s:CommitComplete(A,L,P) abort
|
function! s:CommitComplete(A,L,P) abort
|
||||||
if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
|
if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
|
||||||
let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--template=', '--untracked-files', '--verbose']
|
let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--fixup=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--squash=', '--template=', '--untracked-files', '--verbose']
|
||||||
return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
|
return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
|
||||||
else
|
else
|
||||||
return s:repo().superglob(a:A)
|
return s:repo().superglob(a:A)
|
||||||
@@ -1192,7 +1228,7 @@ function! s:Merge(cmd, bang, args) abort
|
|||||||
\ !empty(s:repo().git_chomp('diff-files', '--diff-filter=U')))
|
\ !empty(s:repo().git_chomp('diff-files', '--diff-filter=U')))
|
||||||
let &l:makeprg = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U'
|
let &l:makeprg = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U'
|
||||||
else
|
else
|
||||||
let &l:makeprg = s:sub(g:fugitive_git_executable . ' ' . a:cmd .
|
let &l:makeprg = s:sub(s:git_command() . ' ' . a:cmd .
|
||||||
\ (a:args =~# ' \%(--no-edit\|--abort\|-m\)\>' ? '' : ' --edit') .
|
\ (a:args =~# ' \%(--no-edit\|--abort\|-m\)\>' ? '' : ' --edit') .
|
||||||
\ ' ' . a:args, ' *$', '')
|
\ ' ' . a:args, ' *$', '')
|
||||||
endif
|
endif
|
||||||
@@ -1258,7 +1294,7 @@ function! s:Grep(cmd,bang,arg) abort
|
|||||||
try
|
try
|
||||||
execute cd.'`=s:repo().tree()`'
|
execute cd.'`=s:repo().tree()`'
|
||||||
let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n', '--no-color')
|
let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n', '--no-color')
|
||||||
let &grepformat = '%f:%l:%m,%f'
|
let &grepformat = '%f:%l:%m,%m %f match%ts,%f'
|
||||||
exe a:cmd.'! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
|
exe a:cmd.'! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
|
||||||
let list = a:cmd =~# '^l' ? getloclist(0) : getqflist()
|
let list = a:cmd =~# '^l' ? getloclist(0) : getqflist()
|
||||||
for entry in list
|
for entry in list
|
||||||
@@ -1371,6 +1407,9 @@ function! s:Edit(cmd,bang,...) abort
|
|||||||
return 'redraw|echo '.string(':!'.git.' '.args)
|
return 'redraw|echo '.string(':!'.git.' '.args)
|
||||||
else
|
else
|
||||||
let temp = resolve(tempname())
|
let temp = resolve(tempname())
|
||||||
|
if has('win32')
|
||||||
|
let temp = fnamemodify(fnamemodify(temp, ':h'), ':p').fnamemodify(temp, ':t')
|
||||||
|
endif
|
||||||
let s:temp_files[s:cpath(temp)] = { 'dir': buffer.repo().dir(), 'args': arglist }
|
let s:temp_files[s:cpath(temp)] = { 'dir': buffer.repo().dir(), 'args': arglist }
|
||||||
silent execute a:cmd.' '.temp
|
silent execute a:cmd.' '.temp
|
||||||
if a:cmd =~# 'pedit'
|
if a:cmd =~# 'pedit'
|
||||||
@@ -1406,6 +1445,9 @@ function! s:Edit(cmd,bang,...) abort
|
|||||||
catch /^fugitive:/
|
catch /^fugitive:/
|
||||||
return 'echoerr v:errmsg'
|
return 'echoerr v:errmsg'
|
||||||
endtry
|
endtry
|
||||||
|
if file !~# '^fugitive:'
|
||||||
|
let file = s:sub(file, '/$', '')
|
||||||
|
endif
|
||||||
if a:cmd ==# 'read'
|
if a:cmd ==# 'read'
|
||||||
return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
||||||
else
|
else
|
||||||
@@ -1547,6 +1589,7 @@ function! s:Write(force,...) abort
|
|||||||
|
|
||||||
unlet! restorewinnr
|
unlet! restorewinnr
|
||||||
let zero = s:repo().translate(':0:'.path)
|
let zero = s:repo().translate(':0:'.path)
|
||||||
|
silent execute 'doautocmd BufWritePost' s:fnameescape(zero)
|
||||||
for tab in range(1,tabpagenr('$'))
|
for tab in range(1,tabpagenr('$'))
|
||||||
for winnr in range(1,tabpagewinnr(tab,'$'))
|
for winnr in range(1,tabpagewinnr(tab,'$'))
|
||||||
let bufnr = tabpagebuflist(tab)[winnr-1]
|
let bufnr = tabpagebuflist(tab)[winnr-1]
|
||||||
@@ -1609,7 +1652,7 @@ function! s:Dispatch(bang, args)
|
|||||||
try
|
try
|
||||||
let b:current_compiler = 'git'
|
let b:current_compiler = 'git'
|
||||||
let &l:errorformat = s:common_efm
|
let &l:errorformat = s:common_efm
|
||||||
let &l:makeprg = g:fugitive_git_executable . ' ' . a:args
|
let &l:makeprg = substitute(s:git_command() . ' ' . a:args, '\s\+$', '', '')
|
||||||
execute cd fnameescape(s:repo().tree())
|
execute cd fnameescape(s:repo().tree())
|
||||||
if exists(':Make') == 2
|
if exists(':Make') == 2
|
||||||
noautocmd Make
|
noautocmd Make
|
||||||
@@ -1758,13 +1801,17 @@ function! s:Diff(vert,keepfocus,...) abort
|
|||||||
let nr = bufnr('')
|
let nr = bufnr('')
|
||||||
execute 'leftabove '.vert.'split `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`'
|
execute 'leftabove '.vert.'split `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`'
|
||||||
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
||||||
|
let nr2 = bufnr('')
|
||||||
call s:diffthis()
|
call s:diffthis()
|
||||||
wincmd p
|
wincmd p
|
||||||
execute 'rightbelow '.vert.'split `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`'
|
execute 'rightbelow '.vert.'split `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`'
|
||||||
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
||||||
|
let nr3 = bufnr('')
|
||||||
call s:diffthis()
|
call s:diffthis()
|
||||||
wincmd p
|
wincmd p
|
||||||
call s:diffthis()
|
call s:diffthis()
|
||||||
|
execute 'nnoremap <buffer> <silent> d2o :diffget '.nr2.'<Bar>diffupdate<CR>'
|
||||||
|
execute 'nnoremap <buffer> <silent> d3o :diffget '.nr3.'<Bar>diffupdate<CR>'
|
||||||
return post
|
return post
|
||||||
elseif len(args)
|
elseif len(args)
|
||||||
let arg = join(args, ' ')
|
let arg = join(args, ' ')
|
||||||
@@ -1984,6 +2031,9 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
|||||||
endif
|
endif
|
||||||
let top = line('w0') + &scrolloff
|
let top = line('w0') + &scrolloff
|
||||||
let current = line('.')
|
let current = line('.')
|
||||||
|
if has('win32')
|
||||||
|
let temp = fnamemodify(fnamemodify(temp, ':h'), ':p').fnamemodify(temp, ':t')
|
||||||
|
endif
|
||||||
let s:temp_files[s:cpath(temp)] = { 'dir': s:repo().dir(), 'args': cmd }
|
let s:temp_files[s:cpath(temp)] = { 'dir': s:repo().dir(), 'args': cmd }
|
||||||
exe 'keepalt leftabove vsplit '.temp
|
exe 'keepalt leftabove vsplit '.temp
|
||||||
let b:fugitive_blamed_bufnr = bufnr
|
let b:fugitive_blamed_bufnr = bufnr
|
||||||
@@ -2002,6 +2052,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
|||||||
if exists('+relativenumber')
|
if exists('+relativenumber')
|
||||||
setlocal norelativenumber
|
setlocal norelativenumber
|
||||||
endif
|
endif
|
||||||
|
let &l:statusline = '%{fugitive#blame_statusline('.bufnr('').')}%<'
|
||||||
execute "vertical resize ".(s:linechars('.\{-\}\ze\s\+\d\+)')+1)
|
execute "vertical resize ".(s:linechars('.\{-\}\ze\s\+\d\+)')+1)
|
||||||
nnoremap <buffer> <silent> <F1> :help fugitive-:Gblame<CR>
|
nnoremap <buffer> <silent> <F1> :help fugitive-:Gblame<CR>
|
||||||
nnoremap <buffer> <silent> g? :help fugitive-:Gblame<CR>
|
nnoremap <buffer> <silent> g? :help fugitive-:Gblame<CR>
|
||||||
@@ -2161,7 +2212,7 @@ endfunction
|
|||||||
|
|
||||||
function! s:RehighlightBlame() abort
|
function! s:RehighlightBlame() abort
|
||||||
for [hash, cterm] in items(s:hash_colors)
|
for [hash, cterm] in items(s:hash_colors)
|
||||||
if !empty(cterm) || has('gui_running')
|
if !empty(cterm) || has('gui_running') || has('termguicolors') && &termguicolors
|
||||||
exe 'hi FugitiveblameHash'.hash.' guifg=#'.hash.get(s:hash_colors, hash, '')
|
exe 'hi FugitiveblameHash'.hash.' guifg=#'.hash.get(s:hash_colors, hash, '')
|
||||||
else
|
else
|
||||||
exe 'hi link FugitiveblameHash'.hash.' Identifier'
|
exe 'hi link FugitiveblameHash'.hash.' Identifier'
|
||||||
@@ -2169,13 +2220,39 @@ function! s:RehighlightBlame() abort
|
|||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#blame_statusline(nr) abort
|
||||||
|
if bufnr('%') != a:nr && !getwinvar(0, '&cursorbind')
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
let line = getbufline(a:nr, line('.'))[0]
|
||||||
|
let hash = matchstr(line, '^\^\=\zs\x\{7}')
|
||||||
|
if hash =~# '^0*$'
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
if type(getbufvar(a:nr, 'fugitive_blame_lookup')) != type({})
|
||||||
|
call setbufvar(a:nr, 'fugitive_blame_lookup', {})
|
||||||
|
endif
|
||||||
|
let lookup = getbufvar(a:nr, 'fugitive_blame_lookup')
|
||||||
|
if !has_key(lookup, hash)
|
||||||
|
let lookup[hash] = s:repo().git_chomp('log', '-1', hash, '--pretty=format:'.g:fugitive_summary_format)
|
||||||
|
endif
|
||||||
|
return get(lookup, hash, '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Section: Gbrowse
|
" Section: Gbrowse
|
||||||
|
|
||||||
call s:command("-bar -bang -range -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
|
call s:command("-bar -bang -range=0 -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
|
||||||
|
|
||||||
function! s:Browse(bang,line1,count,...) abort
|
function! s:Browse(bang,line1,count,...) abort
|
||||||
try
|
try
|
||||||
let rev = a:0 ? substitute(join(a:000, ' '),'@[[:alnum:]_-]*\%(://.\{-\}\)\=$','','') : ''
|
let validremote = '\.\|\.\=/.*\|[[:alnum:]_-]\+\%(://.\{-\}\)\='
|
||||||
|
if a:0
|
||||||
|
let remote = matchstr(join(a:000, ' '),'@\zs\%('.validremote.'\)$')
|
||||||
|
let rev = substitute(join(a:000, ' '),'@\%('.validremote.'\)$','','')
|
||||||
|
else
|
||||||
|
let remote = ''
|
||||||
|
let rev = ''
|
||||||
|
endif
|
||||||
if rev ==# ''
|
if rev ==# ''
|
||||||
let expanded = s:buffer().rev()
|
let expanded = s:buffer().rev()
|
||||||
elseif rev ==# ':'
|
elseif rev ==# ':'
|
||||||
@@ -2186,10 +2263,11 @@ function! s:Browse(bang,line1,count,...) abort
|
|||||||
let full = s:repo().translate(expanded)
|
let full = s:repo().translate(expanded)
|
||||||
let commit = ''
|
let commit = ''
|
||||||
if full =~# '^fugitive://'
|
if full =~# '^fugitive://'
|
||||||
let commit = matchstr(full,'://.*//\zs\w\+')
|
let commit = matchstr(full,'://.*//\zs\w\w\+')
|
||||||
let path = matchstr(full,'://.*//\w\+\zs/.*')
|
let path = matchstr(full,'://.*//\w\+\zs/.*')
|
||||||
if commit =~ '..'
|
if commit =~ '..'
|
||||||
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
|
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
|
||||||
|
let branch = matchstr(expanded, '^[^:]*')
|
||||||
else
|
else
|
||||||
let type = 'blob'
|
let type = 'blob'
|
||||||
endif
|
endif
|
||||||
@@ -2207,6 +2285,9 @@ function! s:Browse(bang,line1,count,...) abort
|
|||||||
let type = 'blob'
|
let type = 'blob'
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
if type ==# 'tree' && !empty(path)
|
||||||
|
let path = s:sub(path, '/\=$', '/')
|
||||||
|
endif
|
||||||
if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
|
if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
|
||||||
let body = readfile(s:repo().dir(path[5:-1]))[0]
|
let body = readfile(s:repo().dir(path[5:-1]))[0]
|
||||||
if body =~# '^\x\{40\}$'
|
if body =~# '^\x\{40\}$'
|
||||||
@@ -2218,35 +2299,60 @@ function! s:Browse(bang,line1,count,...) abort
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if a:0 && join(a:000, ' ') =~# '@[[:alnum:]_-]*\%(://.\{-\}\)\=$'
|
let merge = ''
|
||||||
let remote = matchstr(join(a:000, ' '),'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$')
|
if path =~# '^\.git/refs/remotes/.'
|
||||||
elseif path =~# '^\.git/refs/remotes/.'
|
if empty(remote)
|
||||||
let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+')
|
let remote = matchstr(path, '^\.git/refs/remotes/\zs[^/]\+')
|
||||||
else
|
let branch = matchstr(path, '^\.git/refs/remotes/[^/]\+/\zs.\+')
|
||||||
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
|
else
|
||||||
if branch ==# ''
|
let merge = matchstr(path, '^\.git/refs/remotes/[^/]\+/\zs.\+')
|
||||||
let branch = matchstr(s:repo().head_ref(),'\<refs/heads/\zs.*')
|
let path = '.git/refs/heads/'.merge
|
||||||
|
endif
|
||||||
|
elseif path =~# '^\.git/refs/heads/.'
|
||||||
|
let branch = path[16:-1]
|
||||||
|
elseif !exists('branch')
|
||||||
|
let branch = s:repo().head()
|
||||||
|
endif
|
||||||
|
if !empty(branch)
|
||||||
|
let r = s:repo().git_chomp('config','branch.'.branch.'.remote')
|
||||||
|
let m = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1]
|
||||||
|
if r ==# '.' && !empty(m)
|
||||||
|
let r2 = s:repo().git_chomp('config','branch.'.m.'.remote')
|
||||||
|
if r2 !~# '^\.\=$'
|
||||||
|
let r = r2
|
||||||
|
let m = s:repo().git_chomp('config','branch.'.m.'.merge')[11:-1]
|
||||||
endif
|
endif
|
||||||
if branch != ''
|
endif
|
||||||
let remote = s:repo().git_chomp('config','branch.'.branch.'.remote')
|
if empty(remote)
|
||||||
if remote =~# '^\.\=$'
|
let remote = r
|
||||||
let remote = 'origin'
|
endif
|
||||||
elseif rev[0:strlen(branch)-1] ==# branch && rev[strlen(branch)] =~# '[:^~@]'
|
if r ==# '.' || r ==# remote
|
||||||
let rev = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1] . rev[strlen(branch):-1]
|
let merge = m
|
||||||
endif
|
if path =~# '^\.git/refs/heads/.'
|
||||||
|
let path = '.git/refs/heads/'.merge
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let raw = s:repo().git_chomp('config','remote.'.remote.'.url')
|
if empty(commit) && path !~# '^\.git/'
|
||||||
|
if a:line1 && !a:count && !empty(merge)
|
||||||
|
let commit = merge
|
||||||
|
else
|
||||||
|
let commit = s:repo().rev_parse('HEAD')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if empty(remote)
|
||||||
|
let remote = '.'
|
||||||
|
let remote_for_url = 'origin'
|
||||||
|
else
|
||||||
|
let remote_for_url = remote
|
||||||
|
endif
|
||||||
|
if fugitive#git_version() =~# '^[01]\.|^2\.[0-6]\.'
|
||||||
|
let raw = s:repo().git_chomp('config','remote.'.remote_for_url.'.url')
|
||||||
|
else
|
||||||
|
let raw = s:repo().git_chomp('remote','get-url',remote_for_url)
|
||||||
|
endif
|
||||||
if raw ==# ''
|
if raw ==# ''
|
||||||
let raw = remote
|
let raw = remote
|
||||||
endif
|
endif
|
||||||
@@ -2255,7 +2361,7 @@ function! s:Browse(bang,line1,count,...) abort
|
|||||||
let url = call(Handler, [{
|
let url = call(Handler, [{
|
||||||
\ 'repo': s:repo(),
|
\ 'repo': s:repo(),
|
||||||
\ 'remote': raw,
|
\ 'remote': raw,
|
||||||
\ 'revision': rev,
|
\ 'revision': 'No longer provided',
|
||||||
\ 'commit': commit,
|
\ 'commit': commit,
|
||||||
\ 'path': path,
|
\ 'path': path,
|
||||||
\ 'type': type,
|
\ 'type': type,
|
||||||
@@ -2266,13 +2372,16 @@ function! s:Browse(bang,line1,count,...) abort
|
|||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
if empty(url)
|
if empty(url) && raw ==# '.'
|
||||||
call s:throw("Instaweb failed to start and '".remote."' is not a supported remote")
|
call s:throw("Instaweb failed to start")
|
||||||
|
elseif empty(url)
|
||||||
|
call s:throw("'".remote."' is not a supported remote")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
|
||||||
if a:bang
|
if a:bang
|
||||||
if has('clipboard')
|
if has('clipboard')
|
||||||
let @* = url
|
let @+ = url
|
||||||
endif
|
endif
|
||||||
return 'echomsg '.string(url)
|
return 'echomsg '.string(url)
|
||||||
elseif exists(':Browse') == 2
|
elseif exists(':Browse') == 2
|
||||||
@@ -2305,55 +2414,14 @@ function! s:github_url(opts, ...) abort
|
|||||||
if repo ==# ''
|
if repo ==# ''
|
||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
let path = a:opts.path
|
call s:warn('Install rhubarb.vim for GitHub support')
|
||||||
if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0
|
return 'https://github.com/tpope/vim-rhubarb'
|
||||||
let root = 'http://' . s:sub(repo,':','/')
|
|
||||||
else
|
|
||||||
let root = 'https://' . s:sub(repo,':','/')
|
|
||||||
endif
|
|
||||||
if path =~# '^\.git/refs/heads/'
|
|
||||||
let branch = a:opts.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/tags/'
|
|
||||||
return root . '/releases/tag/' . matchstr(path,'[^/]\+$')
|
|
||||||
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:opts.revision =~# '^[[:alnum:]._-]\+:'
|
|
||||||
let commit = matchstr(a:opts.revision,'^[^:]*')
|
|
||||||
elseif a:opts.commit =~# '^\d\=$'
|
|
||||||
let local = matchstr(a:opts.repo.head_ref(),'\<refs/heads/\zs.*')
|
|
||||||
let commit = a:opts.repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
|
|
||||||
if commit ==# ''
|
|
||||||
let commit = local
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let commit = a:opts.commit
|
|
||||||
endif
|
|
||||||
if a:opts.type == 'tree'
|
|
||||||
let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
|
|
||||||
elseif a:opts.type == 'blob'
|
|
||||||
let url = root . '/blob/' . commit . '/' . path
|
|
||||||
if get(a:opts, 'line2') && a:opts.line1 == a:opts.line2
|
|
||||||
let url .= '#L' . a:opts.line1
|
|
||||||
elseif get(a:opts, 'line2')
|
|
||||||
let url .= '#L' . a:opts.line1 . '-L' . a:opts.line2
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let url = root . '/commit/' . commit
|
|
||||||
endif
|
|
||||||
return url
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:instaweb_url(opts) abort
|
function! s:instaweb_url(opts) abort
|
||||||
|
if a:opts.remote !=# '.'
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
let output = a:opts.repo.git_chomp('instaweb','-b','unknown')
|
let output = a:opts.repo.git_chomp('instaweb','-b','unknown')
|
||||||
if output =~# 'http://'
|
if output =~# 'http://'
|
||||||
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:opts.repo.dir(),':t')
|
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:opts.repo.dir(),':t')
|
||||||
@@ -2372,10 +2440,8 @@ function! s:instaweb_url(opts) abort
|
|||||||
endif
|
endif
|
||||||
let url .= ';h=' . a:opts.repo.rev_parse(a:opts.commit . (a:opts.path == '' ? '' : ':' . a:opts.path))
|
let url .= ';h=' . a:opts.repo.rev_parse(a:opts.commit . (a:opts.path == '' ? '' : ':' . a:opts.path))
|
||||||
else
|
else
|
||||||
if a:opts.type ==# 'blob'
|
if a:opts.type ==# 'blob' && empty(a:opts.commit)
|
||||||
let tmp = tempname()
|
let url .= ';h='.a:opts.repo.git_chomp('hash-object', '-w', a:opts.path)
|
||||||
silent execute 'write !'.a:opts.repo.git_command('hash-object','-w','--stdin').' > '.tmp
|
|
||||||
let url .= ';h=' . readfile(tmp)[0]
|
|
||||||
else
|
else
|
||||||
try
|
try
|
||||||
let url .= ';h=' . a:opts.repo.rev_parse((a:opts.commit == '' ? 'HEAD' : ':' . a:opts.commit) . ':' . a:opts.path)
|
let url .= ';h=' . a:opts.repo.rev_parse((a:opts.commit == '' ? 'HEAD' : ':' . a:opts.commit) . ':' . a:opts.path)
|
||||||
@@ -2514,6 +2580,8 @@ function! s:BufReadIndex() abort
|
|||||||
nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff('Gvdiff')<CR>
|
nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff('Gvdiff')<CR>
|
||||||
nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<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>
|
xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(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> q :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR>
|
nnoremap <buffer> <silent> q :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR>
|
||||||
nnoremap <buffer> <silent> r :<C-U>edit<CR>
|
nnoremap <buffer> <silent> r :<C-U>edit<CR>
|
||||||
nnoremap <buffer> <silent> R :<C-U>edit<CR>
|
nnoremap <buffer> <silent> R :<C-U>edit<CR>
|
||||||
@@ -2605,7 +2673,7 @@ function! s:BufReadObject() abort
|
|||||||
let b:fugitive_type = s:repo().git_chomp('cat-file','-t',hash)
|
let b:fugitive_type = s:repo().git_chomp('cat-file','-t',hash)
|
||||||
endif
|
endif
|
||||||
if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
|
if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
|
||||||
return "echoerr 'fugitive: unrecognized git type'"
|
return "echoerr ".string("fugitive: unrecognized git type '".b:fugitive_type."'")
|
||||||
endif
|
endif
|
||||||
let firstline = getline('.')
|
let firstline = getline('.')
|
||||||
if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
|
if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
|
||||||
@@ -2640,7 +2708,7 @@ function! s:BufReadObject() abort
|
|||||||
if b:fugitive_display_format
|
if b:fugitive_display_format
|
||||||
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
||||||
else
|
else
|
||||||
call s:ReplaceCmd(s:repo().git_command('show','--no-color','--pretty=format:tree %T%nparent %P%nauthor %an <%ae> %ad%ncommitter %cn <%ce> %cd%nencoding %e%n%n%s%n%n%b',hash))
|
call s:ReplaceCmd(s:repo().git_command('show','--no-color','--pretty=format:tree%x20%T%nparent%x20%P%nauthor%x20%an%x20<%ae>%x20%ad%ncommitter%x20%cn%x20<%ce>%x20%cd%nencoding%x20%e%n%n%s%n%n%b',hash))
|
||||||
keepjumps call search('^parent ')
|
keepjumps call search('^parent ')
|
||||||
if getline('.') ==# 'parent '
|
if getline('.') ==# 'parent '
|
||||||
silent keepjumps delete_
|
silent keepjumps delete_
|
||||||
@@ -2792,7 +2860,7 @@ function! s:cfile() abort
|
|||||||
elseif getline('.') =~# '^#\trenamed:.* -> '
|
elseif getline('.') =~# '^#\trenamed:.* -> '
|
||||||
let file = '/'.matchstr(getline('.'),' -> \zs.*')
|
let file = '/'.matchstr(getline('.'),' -> \zs.*')
|
||||||
return [file]
|
return [file]
|
||||||
elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.'
|
elseif getline('.') =~# '^#\t\(\k\| \)\+\p\?: *.'
|
||||||
let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$')
|
let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$')
|
||||||
return [file]
|
return [file]
|
||||||
elseif getline('.') =~# '^#\t.'
|
elseif getline('.') =~# '^#\t.'
|
||||||
@@ -2849,13 +2917,13 @@ function! s:cfile() abort
|
|||||||
let ref = matchstr(getline('.'),'\x\{40\}')
|
let ref = matchstr(getline('.'),'\x\{40\}')
|
||||||
echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
|
echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
|
||||||
|
|
||||||
elseif getline('.') =~# '^[+-]\{3\} [ab/]'
|
elseif getline('.') =~# '^[+-]\{3\} [abciow12]\=/'
|
||||||
let ref = getline('.')[4:]
|
let ref = getline('.')[4:]
|
||||||
|
|
||||||
elseif getline('.') =~# '^[+-]' && search('^@@ -\d\+,\d\+ +\d\+,','bnW')
|
elseif getline('.') =~# '^[+-]' && search('^@@ -\d\+,\d\+ +\d\+,','bnW')
|
||||||
let type = getline('.')[0]
|
let type = getline('.')[0]
|
||||||
let lnum = line('.') - 1
|
let lnum = line('.') - 1
|
||||||
let offset = -1
|
let offset = 0
|
||||||
while getline(lnum) !~# '^@@ -\d\+,\d\+ +\d\+,'
|
while getline(lnum) !~# '^@@ -\d\+,\d\+ +\d\+,'
|
||||||
if getline(lnum) =~# '^[ '.type.']'
|
if getline(lnum) =~# '^[ '.type.']'
|
||||||
let offset += 1
|
let offset += 1
|
||||||
@@ -2863,7 +2931,7 @@ function! s:cfile() abort
|
|||||||
let lnum -= 1
|
let lnum -= 1
|
||||||
endwhile
|
endwhile
|
||||||
let offset += matchstr(getline(lnum), type.'\zs\d\+')
|
let offset += matchstr(getline(lnum), type.'\zs\d\+')
|
||||||
let ref = getline(search('^'.type.'\{3\} [ab]/','bnW'))[4:-1]
|
let ref = getline(search('^'.type.'\{3\} [abciow12]/','bnW'))[4:-1]
|
||||||
let dcmds = [offset, 'normal!zv']
|
let dcmds = [offset, 'normal!zv']
|
||||||
|
|
||||||
elseif getline('.') =~# '^rename from '
|
elseif getline('.') =~# '^rename from '
|
||||||
@@ -2872,22 +2940,22 @@ function! s:cfile() abort
|
|||||||
let ref = 'b/'.getline('.')[10:]
|
let ref = 'b/'.getline('.')[10:]
|
||||||
|
|
||||||
elseif getline('.') =~# '^@@ -\d\+,\d\+ +\d\+,'
|
elseif getline('.') =~# '^@@ -\d\+,\d\+ +\d\+,'
|
||||||
let diff = getline(search('^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)', 'bcnW'))
|
let diff = getline(search('^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)', 'bcnW'))
|
||||||
let offset = matchstr(getline('.'), '+\zs\d\+')
|
let offset = matchstr(getline('.'), '+\zs\d\+')
|
||||||
|
|
||||||
let dref = matchstr(diff, '\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
let dref = matchstr(diff, '\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
|
||||||
let ref = matchstr(diff, '\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
let ref = matchstr(diff, '\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
|
||||||
let dcmd = 'Gdiff! +'.offset
|
let dcmd = 'Gdiff! +'.offset
|
||||||
|
|
||||||
elseif getline('.') =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
|
elseif getline('.') =~# '^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)'
|
||||||
let dref = matchstr(getline('.'),'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
let dref = matchstr(getline('.'),'\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
|
||||||
let ref = matchstr(getline('.'),'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
let ref = matchstr(getline('.'),'\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
|
||||||
let dcmd = 'Gdiff!'
|
let dcmd = 'Gdiff!'
|
||||||
|
|
||||||
elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
|
elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)'
|
||||||
let line = getline(line('.')-1)
|
let line = getline(line('.')-1)
|
||||||
let dref = matchstr(line,'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
let dref = matchstr(line,'\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
|
||||||
let ref = matchstr(line,'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
let ref = matchstr(line,'\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
|
||||||
let dcmd = 'Gdiff!'
|
let dcmd = 'Gdiff!'
|
||||||
|
|
||||||
elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
|
elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
|
||||||
@@ -2900,18 +2968,21 @@ function! s:cfile() abort
|
|||||||
let ref = ''
|
let ref = ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if myhash ==# ''
|
let prefixes = {
|
||||||
let ref = s:sub(ref,'^a/','HEAD:')
|
\ '1': '',
|
||||||
let ref = s:sub(ref,'^b/',':0:')
|
\ '2': '',
|
||||||
if exists('dref')
|
\ 'b': ':0:',
|
||||||
let dref = s:sub(dref,'^a/','HEAD:')
|
\ 'i': ':0:',
|
||||||
endif
|
\ 'o': '',
|
||||||
else
|
\ 'w': ''}
|
||||||
let ref = s:sub(ref,'^a/',myhash.'^:')
|
|
||||||
let ref = s:sub(ref,'^b/',myhash.':')
|
if len(myhash)
|
||||||
if exists('dref')
|
let prefixes.a = myhash.'^:'
|
||||||
let dref = s:sub(dref,'^a/',myhash.'^:')
|
let prefixes.b = myhash.':'
|
||||||
endif
|
endif
|
||||||
|
let ref = substitute(ref, '^\(\w\)/', '\=get(prefixes, submatch(1), "HEAD:")', '')
|
||||||
|
if exists('dref')
|
||||||
|
let dref = substitute(dref, '^\(\w\)/', '\=get(prefixes, submatch(1), "HEAD:")', '')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ref ==# '/dev/null'
|
if ref ==# '/dev/null'
|
||||||
@@ -2947,7 +3018,11 @@ function! fugitive#cfile() abort
|
|||||||
let pre = ''
|
let pre = ''
|
||||||
let results = s:cfile()
|
let results = s:cfile()
|
||||||
if empty(results)
|
if empty(results)
|
||||||
return expand('<cfile>')
|
let cfile = expand('<cfile>')
|
||||||
|
if &includeexpr =~# '\<v:fname\>'
|
||||||
|
sandbox let cfile = eval(substitute(&includeexpr, '\C\<v:fname\>', '\=string(cfile)', 'g'))
|
||||||
|
endif
|
||||||
|
return cfile
|
||||||
elseif len(results) > 1
|
elseif len(results) > 1
|
||||||
let pre = '+' . join(map(results[1:-1], 'escape(v:val, " ")'), '\|') . ' '
|
let pre = '+' . join(map(results[1:-1], 'escape(v:val, " ")'), '\|') . ' '
|
||||||
endif
|
endif
|
||||||
@@ -3015,7 +3090,7 @@ function! fugitive#foldtext() abort
|
|||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
if filename ==# ''
|
if filename ==# ''
|
||||||
let filename = matchstr(getline(v:foldstart), '^diff .\{-\} a/\zs.*\ze b/')
|
let filename = matchstr(getline(v:foldstart), '^diff .\{-\} [abciow12]/\zs.*\ze [abciow12]/')
|
||||||
endif
|
endif
|
||||||
if filename ==# ''
|
if filename ==# ''
|
||||||
let filename = getline(v:foldstart)[5:-1]
|
let filename = getline(v:foldstart)[5:-1]
|
||||||
|
|||||||
Reference in New Issue
Block a user