1 Commits

Author SHA1 Message Date
Tim Pope
2685422e17 Attempt to catch overlapping status reloads 2021-10-16 11:14:15 -04:00
5 changed files with 1345 additions and 1907 deletions

View File

@@ -86,8 +86,7 @@ For more information, see `:help fugitive`.
## Installation ## Installation
Install using your favorite package manager, or use Vim's built-in package Install using your favorite package manager, or use Vim's built-in package support:
support:
mkdir -p ~/.vim/pack/tpope/start mkdir -p ~/.vim/pack/tpope/start
cd ~/.vim/pack/tpope/start cd ~/.vim/pack/tpope/start
@@ -104,17 +103,6 @@ it was removed. Use `:Git! push` to use Fugitive's own asynchronous
execution, or retroactively make `:Git push` asynchronous by pressing execution, or retroactively make `:Git push` asynchronous by pressing
`CTRL-D`. `CTRL-D`.
> Why am I getting `core.worktree is required when using an external Git dir`?
Git generally sets `core.worktree` for you automatically when necessary, but
if you're doing something weird, or using a third-party tool that does
something weird, you may need to set it manually:
git config core.worktree "$PWD"
This may be necessary even when simple `git` commands seem to work fine
without it.
> So I have a symlink and... > So I have a symlink and...
Stop. Just stop. If Git won't deal with your symlink, then Fugitive won't Stop. Just stop. If Git won't deal with your symlink, then Fugitive won't

File diff suppressed because it is too large Load Diff

View File

@@ -18,12 +18,6 @@ that are part of Git repositories).
*fugitive-:G* *fugitive-:G*
:G [args] Same as :Git, but two characters shorter. :G [args] Same as :Git, but two characters shorter.
*fugitive-summary*
:Git With no arguments, bring up a summary window vaguely
akin to git-status. If a summary window is already
open for the current repository, it is focused
instead. Press g? or see |fugitive-maps| for usage.
*:Git* *:Git*
:Git {args} Run an arbitrary git command and display any output. :Git {args} Run an arbitrary git command and display any output.
On UNIX this uses a pty and on other platforms it uses On UNIX this uses a pty and on other platforms it uses
@@ -53,6 +47,11 @@ that are part of Git repositories).
:{range}Git! -p {args} Run an arbitrary git command, and insert the output :{range}Git! -p {args} Run an arbitrary git command, and insert the output
after {range} in the current buffer. after {range} in the current buffer.
*fugitive-summary*
:Git With no arguments, bring up a summary window vaguely
akin to git-status. Press g? or see |fugitive-maps|
for usage.
*:Git_blame* *:Git_blame*
:Git blame [flags] Run git-blame [flags] on the current file and open the :Git blame [flags] Run git-blame [flags] on the current file and open the
results in a scroll-bound vertical split. The results in a scroll-bound vertical split. The
@@ -71,20 +70,12 @@ that are part of Git repositories).
O jump to patch or blob in new tab O jump to patch or blob in new tab
p jump to patch or blob in preview window p jump to patch or blob in preview window
- reblame at commit - reblame at commit
~ reblame at [count]th first grandparent
The maps |fugitive_P| and |fugitive_~| are also P reblame at [count]th parent (like HEAD^[count])
supported to reblame on a parent commit, but this is
inherently fragile, as the line being blamed will no
longer exist. The preferred alternative is to use
<CR> to open up the commit, select the corresponding
`-` line that you care about, and press <CR> twice
more to reblame at that line. Viewing the commit also
gives you additional context as to why the line
changed.
*g:fugitive_dynamic_colors* *g:fugitive_dynamic_colors*
In the GUI or a 256 color terminal, commit hashes will In the GUI or a 256 color terminal, commit hashes will
be highlighted in different colors. To disable this: highlighted in different colors. To disable this:
> >
let g:fugitive_dynamic_colors = 0 let g:fugitive_dynamic_colors = 0
< <
@@ -107,12 +98,6 @@ that are part of Git repositories).
*:Git_mergetool* *:Git_mergetool*
:Git mergetool [args] Like |:Git_difftool|, but target merge conflicts. :Git mergetool [args] Like |:Git_difftool|, but target merge conflicts.
Wrappers for Vim built-ins ~
These all directly map onto a built-in Vim command, and generally have names
that prepend "G" to the command they are wrapping. For example, :Ggrep is G
plus |:grep|.
*:Ggrep* *:Git_grep* *:Ggrep* *:Git_grep*
:Ggrep[!] [args] An approximation of |:grep|[!] with git-grep as :Ggrep[!] [args] An approximation of |:grep|[!] with git-grep as
:Git[!] grep -O [args] 'grepprg'. :Git[!] grep -O [args] 'grepprg'.
@@ -128,12 +113,11 @@ plus |:grep|.
*:Gclog* *:Gclog*
:Gclog[!] [args] Use git-log [args] to load the commit history into the :Gclog[!] [args] Use git-log [args] to load the commit history into the
|quickfix| list. Jumps to the first commit unless [!] |quickfix| list. Jumps to the first commit unless [!]
is given. This command wraps |:cfile|. is given.
The quickfix list can be awkward for many use cases The quickfix list can be awkward for many use cases
and exhibits extremely poor performance with larger and exhibits extremely poor performance with larger
data sets. Consider using |:Git| log --oneline data sets. Consider using |:Git| log instead.
instead.
:{range}Gclog[!] [args] Use git-log -L to load previous revisions of the given :{range}Gclog[!] [args] Use git-log -L to load previous revisions of the given
range of the current file into the |quickfix| list. range of the current file into the |quickfix| list.
@@ -166,9 +150,6 @@ plus |:grep|.
*:Gpedit* *:Gpedit*
:Gpedit [object] |:pedit| a |fugitive-object|. :Gpedit [object] |:pedit| a |fugitive-object|.
*:Gdrop*
:Gdrop [object] |:drop| a |fugitive-object|.
*:Gread* *fugitive-:Gr* *:Gread* *fugitive-:Gr*
:Gread [object] Empty the buffer and |:read| a |fugitive-object|. :Gread [object] Empty the buffer and |:read| a |fugitive-object|.
When the argument is omitted, this is similar to When the argument is omitted, this is similar to
@@ -177,6 +158,12 @@ plus |:grep|.
:{range}Gread [object] |:read| in a |fugitive-object| after {range}. :{range}Gread [object] |:read| in a |fugitive-object| after {range}.
*:Gread!* *fugitive-:Gr!*
:Gread! [args] Empty the buffer and |:read| the output of a Git
command. For example, :Gread! show HEAD:%.
:{range}Gread! [args] |:read| the output of a Git command after {range}.
*:Gwrite* *fugitive-:Gw* *:Gwrite* *fugitive-:Gw*
:Gwrite Write to the current file's path and stage the results. :Gwrite Write to the current file's path and stage the results.
When run in a work tree file, it is effectively git When run in a work tree file, it is effectively git
@@ -226,13 +213,6 @@ plus |:grep|.
'diffopt'. The split will still be vertical if 'diffopt'. The split will still be vertical if
combined with |:vertical|. combined with |:vertical|.
Other commands ~
These do not directly correspond to any built-in Vim command, and have a
capital letter after the "G" to convey this. For example, the file move
operation has nothing to do with the |:move| built-in, so it is named :GMove,
not :Gmove.
*:GMove* *:GMove*
:GMove {destination} Wrapper around git-mv that renames the buffer :GMove {destination} Wrapper around git-mv that renames the buffer
afterward. Add a ! to pass -f. afterward. Add a ! to pass -f.
@@ -247,9 +227,8 @@ not :Gmove.
passed. Add a ! to pass -f and forcefully discard the passed. Add a ! to pass -f and forcefully discard the
buffer. buffer.
*:GRemove* *:GUnlink* *:GRemove*
:GRemove Like |:GDelete|, but keep the (now empty) buffer around. :GRemove Like |:GDelete|, but keep the (now empty) buffer around.
:GUnlink
*:GBrowse* *:GBrowse*
:GBrowse Open the current file, blob, tree, commit, or tag :GBrowse Open the current file, blob, tree, commit, or tag
@@ -341,8 +320,8 @@ ds Perform a |:Ghdiffsplit| on the file under the cursor.
dh dh
*fugitive_dq* *fugitive_dq*
dq Close all but the currently focused diff buffer, and dq Close all but one diff buffer, and |:diffoff|! the
invoke |:diffoff|!. last one.
*fugitive_d?* *fugitive_d?*
d? Show this help. d? Show this help.
@@ -380,9 +359,6 @@ p Open the file or |fugitive-object| under the cursor in
*fugitive_P* *fugitive_P*
P Open the current file in the [count]th parent. P Open the current file in the [count]th parent.
Experimental: In the "Unpushed" section of the status
buffer, this will populate the command line with a
":Git push" command for the commit under the cursor.
*fugitive_C* *fugitive_C*
C Open the commit containing the current file. C Open the commit containing the current file.
@@ -465,18 +441,15 @@ Commit maps ~
cc Create a commit. cc Create a commit.
cvc Create a commit with -v.
ca Amend the last commit and edit the message. ca Amend the last commit and edit the message.
cva Amend the last commit with -v.
ce Amend the last commit without editing the message. ce Amend the last commit without editing the message.
cw Reword the last commit. cw Reword the last commit.
cW Create an `amend!` commit that rewords the commit cvc Create a commit with -v.
under the cursor.
cva Amend the last commit with -v
cf Create a `fixup!` commit for the commit under the cf Create a `fixup!` commit for the commit under the
cursor. cursor.
@@ -490,8 +463,8 @@ cs Create a `squash!` commit for the commit under the
cS Create a `squash!` commit for the commit under the cS Create a `squash!` commit for the commit under the
cursor and immediately rebase it. cursor and immediately rebase it.
cn Create a `squash!` commit for the commit under the cA Create a `squash!` commit for the commit under the
(formerly cA) cursor and edit the message. cursor and edit the message.
c<Space> Populate command line with ":Git commit ". c<Space> Populate command line with ":Git commit ".
@@ -527,11 +500,9 @@ Stash maps ~
czz Push stash. Pass a [count] of 1 to add czz Push stash. Pass a [count] of 1 to add
`--include-untracked` or 2 to add `--all`. `--include-untracked` or 2 to add `--all`.
czw Push stash of the work-tree. Like `czz` with czw Push stash of worktree. Like `czz` with
`--keep-index`. `--keep-index`.
czs Push stash of the stage. Does not accept a count.
czA Apply topmost stash, or stash@{count}. czA Apply topmost stash, or stash@{count}.
cza Apply topmost stash, or stash@{count}, preserving the cza Apply topmost stash, or stash@{count}, preserving the
@@ -732,7 +703,7 @@ version.
*User_Fugitive* *User_Fugitive*
Fugitive used to support `:autocmd User Fugitive` to run an autocommand after Fugitive used to support `:autocmd User Fugitive` to run an autocommand after
loading any buffer belonging to a Git repository, but this has been phased loading any buffer belonging to a Git repository, but this is being phased
out. Instead, one can leverage regular autocommand events like |BufNewFile| out. Instead, one can leverage regular autocommand events like |BufNewFile|
and |BufReadPost|, and check !empty(FugitiveGitDir()) to confirm Fugitive has and |BufReadPost|, and check !empty(FugitiveGitDir()) to confirm Fugitive has
found a repository. See also |fugitive-autocommands| for other, more found a repository. See also |fugitive-autocommands| for other, more

View File

@@ -1,6 +1,6 @@
" fugitive.vim - A Git wrapper so awesome, it should be illegal " fugitive.vim - A Git wrapper so awesome, it should be illegal
" Maintainer: Tim Pope <http://tpo.pe/> " Maintainer: Tim Pope <http://tpo.pe/>
" Version: 3.7 " Version: 3.4
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim " GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
if exists('g:loaded_fugitive') if exists('g:loaded_fugitive')
@@ -16,30 +16,30 @@ let s:bad_git_dir = '/$\|^fugitive:'
" Fugitive is active in the current buffer. Do not rely on this for direct " Fugitive is active in the current buffer. Do not rely on this for direct
" filesystem access; use FugitiveFind('.git/whatever') instead. " filesystem access; use FugitiveFind('.git/whatever') instead.
function! FugitiveGitDir(...) abort function! FugitiveGitDir(...) abort
if v:version < 704 if v:version < 703
return '' return ''
elseif !a:0 || type(a:1) == type(0) && a:1 < 0 || a:1 is# get(v:, 'true', -1) elseif !a:0 || type(a:1) == type(0) && a:1 < 0 || a:1 is# get(v:, 'true', -1)
if exists('g:fugitive_event') if exists('g:fugitive_event')
return g:fugitive_event return g:fugitive_event
endif endif
let dir = get(b:, 'git_dir', '') let dir = get(b:, 'git_dir', '')
if empty(dir) && (empty(bufname('')) && &filetype !=# 'netrw' || &buftype =~# '^\%(nofile\|acwrite\|quickfix\|terminal\|prompt\)$') if empty(dir) && (empty(bufname('')) || &buftype =~# '^\%(nofile\|acwrite\|quickfix\|terminal\|prompt\)$')
return FugitiveExtractGitDir(getcwd()) return FugitiveExtractGitDir(getcwd())
elseif (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && &buftype =~# '^\%(nowrite\)\=$' elseif (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && empty(&buftype)
let b:git_dir = FugitiveExtractGitDir(bufnr('')) let b:git_dir = FugitiveExtractGitDir(expand('%:p'))
return b:git_dir return b:git_dir
endif endif
return dir =~# s:bad_git_dir ? '' : dir return dir =~# s:bad_git_dir ? '' : dir
elseif type(a:1) == type(0) && a:1 isnot# 0 elseif type(a:1) == type(0) && a:1 isnot# 0
if a:1 == bufnr('') && (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && &buftype =~# '^\%(nowrite\)\=$' if a:1 == bufnr('') && (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && empty(&buftype)
let b:git_dir = FugitiveExtractGitDir(a:1) let b:git_dir = FugitiveExtractGitDir(expand('%:p'))
endif endif
let dir = getbufvar(a:1, 'git_dir') let dir = getbufvar(a:1, 'git_dir')
return dir =~# s:bad_git_dir ? '' : dir return dir =~# s:bad_git_dir ? '' : dir
elseif type(a:1) == type('') elseif type(a:1) == type('')
return substitute(s:Slash(a:1), '/$', '', '') return substitute(s:Slash(a:1), '/$', '', '')
elseif type(a:1) == type({}) elseif type(a:1) == type({})
return get(a:1, 'fugitive_dir', get(a:1, 'git_dir', '')) return get(a:1, 'git_dir', '')
else else
return '' return ''
endif endif
@@ -58,7 +58,7 @@ function! FugitiveReal(...) abort
if type(file) ==# type({}) if type(file) ==# type({})
let dir = FugitiveGitDir(file) let dir = FugitiveGitDir(file)
let tree = s:Tree(dir) let tree = s:Tree(dir)
return s:VimSlash(empty(tree) ? dir : tree) return FugitiveVimPath(empty(tree) ? dir : tree)
elseif file =~# '^\a\a\+:' || a:0 > 1 elseif file =~# '^\a\a\+:' || a:0 > 1
return call('fugitive#Real', [file] + a:000[1:-1]) return call('fugitive#Real', [file] + a:000[1:-1])
elseif file =~# '^/\|^\a:\|^$' elseif file =~# '^/\|^\a:\|^$'
@@ -88,14 +88,15 @@ endfunction
" the inverse of FugitiveFind(). " the inverse of FugitiveFind().
function! FugitiveParse(...) abort function! FugitiveParse(...) abort
let path = s:Slash(a:0 ? a:1 : @%) let path = s:Slash(a:0 ? a:1 : @%)
if path !~# '^fugitive://' if path !~# '^fugitive:'
return ['', ''] return ['', '']
endif endif
let [rev, dir] = fugitive#Parse(path) let vals = matchlist(path, '\c^fugitive:\%(//\)\=\(.\{-\}\)\%(//\|::\)\(\x\{40,\}\|[0-3]\)\(/.*\)\=$')
if !empty(dir) if len(vals)
return [rev, dir] return [(vals[2] =~# '^.$' ? ':' : '') . vals[2] . substitute(vals[3], '^/', ':', ''), vals[1]]
endif endif
throw 'fugitive: invalid Fugitive URL ' . path let v:errmsg = 'fugitive: invalid Fugitive URL ' . path
throw v:errmsg
endfunction endfunction
" FugitiveGitVersion() queries the version of Git in use. Pass up to 3 " FugitiveGitVersion() queries the version of Git in use. Pass up to 3
@@ -140,7 +141,7 @@ function! FugitiveExecute(args, ...) abort
return call('fugitive#Execute', [a:args] + a:000) return call('fugitive#Execute', [a:args] + a:000)
endfunction endfunction
" FugitiveShellCommand() turns an array of arguments into a Git command string " FugitiveShellCommand() turns an array of arugments into a Git command string
" which can be executed with functions like system() and commands like :!. " which can be executed with functions like system() and commands like :!.
" Integer arguments will be treated as buffer numbers, and the appropriate " Integer arguments will be treated as buffer numbers, and the appropriate
" relative path inserted in their place. " relative path inserted in their place.
@@ -151,6 +152,19 @@ function! FugitiveShellCommand(...) abort
return call('fugitive#ShellCommand', a:000) return call('fugitive#ShellCommand', a:000)
endfunction endfunction
" FugitivePrepare() is a deprecated alias for FugitiveShellCommand(). If you
" are using this in conjunction with system(), consider using
" FugitiveExecute() instead.
function! FugitivePrepare(...) abort
if !exists('s:did_prepare_warning')
let s:did_prepare_warning = 1
echohl WarningMsg
unsilent echomsg 'FugitivePrepare() has been superseded by FugitiveShellCommand()'
echohl NONE
endif
return call('fugitive#ShellCommand', a:000)
endfunction
" FugitiveConfig() get returns an opaque structure that can be passed to other " FugitiveConfig() get returns an opaque structure that can be passed to other
" FugitiveConfig functions in lieu of a Git directory. This can be faster " FugitiveConfig functions in lieu of a Git directory. This can be faster
" when performing multiple config queries. Do not rely on the internal " when performing multiple config queries. Do not rely on the internal
@@ -168,7 +182,7 @@ endfunction
" argument can be either the object returned by FugitiveConfig(), or a Git " argument can be either the object returned by FugitiveConfig(), or a Git
" dir or buffer number to be passed along to FugitiveConfig(). " dir or buffer number to be passed along to FugitiveConfig().
function! FugitiveConfigGet(name, ...) abort function! FugitiveConfigGet(name, ...) abort
return get(call('FugitiveConfigGetAll', [a:name] + (a:0 ? [a:1] : [])), -1, get(a:, 2, '')) return get(call('FugitiveConfigGetAll', [a:name] + (a:0 ? [a:1] : [])), 0, get(a:, 2, ''))
endfunction endfunction
" FugitiveConfigGetAll() is like FugitiveConfigGet() but returns a list of " FugitiveConfigGetAll() is like FugitiveConfigGet() but returns a list of
@@ -196,24 +210,6 @@ function! FugitiveRemoteUrl(...) abort
return call('fugitive#RemoteUrl', a:000) return call('fugitive#RemoteUrl', a:000)
endfunction endfunction
" FugitiveRemote() returns a data structure parsed from the remote URL.
" For example, for remote URL "https://me@example.com:1234/repo.git", the
" returned dictionary will contain the following:
"
" * "scheme": "https"
" * "authority": "user@example.com:1234"
" * "path": "/repo.git" (for SSH URLs this may be a relative path)
" * "pathname": "/repo.git" (always coerced to absolute path)
" * "host": "example.com:1234"
" * "hostname": "example.com"
" * "port": "1234"
" * "user": "me"
" * "path": "/repo.git"
" * "url": "https://me@example.com:1234/repo.git"
function! FugitiveRemote(...) abort
return call('fugitive#Remote', a:000)
endfunction
" FugitiveDidChange() triggers a FugitiveChanged event and reloads the summary " FugitiveDidChange() triggers a FugitiveChanged event and reloads the summary
" buffer for the current or given buffer number's repository. You can also " buffer for the current or given buffer number's repository. You can also
" give the result of a FugitiveExecute() and that context will be made " give the result of a FugitiveExecute() and that context will be made
@@ -269,40 +265,12 @@ function! FugitiveStatusline(...) abort
return fugitive#Statusline() return fugitive#Statusline()
endfunction endfunction
let s:resolved_git_dirs = {}
function! FugitiveActualDir(...) abort
let dir = call('FugitiveGitDir', a:000)
if empty(dir)
return ''
endif
if !has_key(s:resolved_git_dirs, dir)
let s:resolved_git_dirs[dir] = s:ResolveGitDir(dir)
endif
return empty(s:resolved_git_dirs[dir]) ? dir : s:resolved_git_dirs[dir]
endfunction
let s:commondirs = {}
function! FugitiveCommonDir(...) abort function! FugitiveCommonDir(...) abort
let dir = call('FugitiveActualDir', a:000) let dir = FugitiveGitDir(a:0 ? a:1 : -1)
if empty(dir) if empty(dir)
return '' return ''
endif endif
if has_key(s:commondirs, dir) return fugitive#Find('.git/refs/..', dir)
return s:commondirs[dir]
endif
if getfsize(dir . '/HEAD') >= 10
let cdir = get(s:ReadFile(dir . '/commondir', 1), 0, '')
if cdir =~# '^/\|^\a:/'
let s:commondirs[dir] = s:Slash(FugitiveVimPath(cdir))
elseif len(cdir)
let s:commondirs[dir] = simplify(dir . '/' . cdir)
else
let s:commondirs[dir] = dir
endif
else
let s:commondirs[dir] = dir
endif
return s:commondirs[dir]
endfunction endfunction
function! FugitiveWorkTree(...) abort function! FugitiveWorkTree(...) abort
@@ -324,54 +292,34 @@ function! FugitiveIsGitDir(...) abort
\ getftype(path.'commondir') ==# 'file') \ getftype(path.'commondir') ==# 'file')
endfunction endfunction
function! s:ReadFile(path, line_count) abort
if v:version < 800 && !filereadable(a:path)
return []
endif
try
return readfile(a:path, 'b', a:line_count)
catch
return []
endtry
endfunction
let s:worktree_for_dir = {} let s:worktree_for_dir = {}
let s:dir_for_worktree = {} let s:dir_for_worktree = {}
function! s:Tree(path) abort function! s:Tree(path) abort
if a:path =~# '/\.git$' let dir = a:path
return len(a:path) ==# 5 ? '/' : a:path[0:-6] if dir =~# '/\.git$'
elseif a:path ==# '' return len(dir) ==# 5 ? '/' : dir[0:-6]
elseif dir ==# ''
return '' return ''
endif endif
let dir = FugitiveActualDir(a:path)
if !has_key(s:worktree_for_dir, dir) if !has_key(s:worktree_for_dir, dir)
let s:worktree_for_dir[dir] = '' let s:worktree_for_dir[dir] = ''
let ext_wtc_pat = 'v:val =~# "^\\s*worktreeConfig *= *\\%(true\\|yes\\|on\\|1\\) *$"' let config_file = dir . '/config'
let config = s:ReadFile(dir . '/config', 50) if filereadable(config_file)
if len(config) let config = readfile(config_file,'',10)
let ext_wtc_config = filter(copy(config), ext_wtc_pat) let wt_config = filter(copy(config),'v:val =~# "^\\s*worktree *="')
if len(ext_wtc_config) == 1 && filereadable(dir . '/config.worktree') if len(wt_config) == 1
let config += s:ReadFile(dir . '/config.worktree', 50)
endif
else
let worktree = fnamemodify(FugitiveVimPath(get(s:ReadFile(dir . '/gitdir', 1), '0', '')), ':h')
if worktree ==# '.'
unlet! worktree
endif
if len(filter(s:ReadFile(FugitiveCommonDir(dir) . '/config', 50), ext_wtc_pat))
let config = s:ReadFile(dir . '/config.worktree', 50)
endif
endif
if len(config)
let wt_config = filter(copy(config), 'v:val =~# "^\\s*worktree *="')
if len(wt_config)
let worktree = FugitiveVimPath(matchstr(wt_config[0], '= *\zs.*')) let worktree = FugitiveVimPath(matchstr(wt_config[0], '= *\zs.*'))
elseif !exists('worktree') else
call filter(config,'v:val =~# "^\\s*bare *= *true *$"') call filter(config,'v:val =~# "^\\s*bare *= *false *$"')
if empty(config) if len(config)
let s:worktree_for_dir[dir] = 0 let s:worktree_for_dir[dir] = 0
endif endif
endif endif
elseif filereadable(dir . '/gitdir')
let worktree = fnamemodify(FugitiveVimPath(readfile(dir . '/gitdir')[0]), ':h')
if worktree ==# '.'
unlet! worktree
endif
endif endif
if exists('worktree') if exists('worktree')
let s:worktree_for_dir[dir] = s:Slash(resolve(worktree)) let s:worktree_for_dir[dir] = s:Slash(resolve(worktree))
@@ -393,60 +341,48 @@ function! s:CeilingDirectories() abort
if empty(dir) if empty(dir)
let resolve = 0 let resolve = 0
elseif resolve elseif resolve
call add(s:ceiling_directories, s:Slash(resolve(dir))) call add(s:ceiling_directories, resolve(dir))
else else
call add(s:ceiling_directories, s:Slash(dir)) call add(s:ceiling_directories, dir)
endif endif
endfor endfor
endif endif
return s:ceiling_directories + get(g:, 'ceiling_directories', [s:Slash(fnamemodify(expand('~'), ':h'))]) return s:ceiling_directories + get(g:, 'ceiling_directories', [])
endfunction
function! s:ResolveGitDir(git_dir) abort
let type = getftype(a:git_dir)
if type ==# 'dir' && FugitiveIsGitDir(a:git_dir)
return a:git_dir
elseif type ==# 'link' && FugitiveIsGitDir(a:git_dir)
return resolve(a:git_dir)
elseif type !=# ''
let line = get(s:ReadFile(a:git_dir, 1), 0, '')
let file_dir = s:Slash(FugitiveVimPath(matchstr(line, '^gitdir: \zs.*')))
if file_dir !~# '^/\|^\a:\|^$' && a:git_dir =~# '/\.git$' && FugitiveIsGitDir(a:git_dir[0:-5] . file_dir)
return simplify(a:git_dir[0:-5] . file_dir)
elseif file_dir =~# '^/\|^\a:' && FugitiveIsGitDir(file_dir)
return file_dir
endif
endif
return ''
endfunction endfunction
function! FugitiveExtractGitDir(path) abort function! FugitiveExtractGitDir(path) abort
if type(a:path) ==# type({}) if type(a:path) ==# type({})
return get(a:path, 'fugitive_dir', get(a:path, 'git_dir', '')) return get(a:path, 'git_dir', '')
elseif type(a:path) == type(0) elseif type(a:path) == type(0)
let path = s:Slash(a:path > 0 ? bufname(a:path) : bufname('')) let path = s:Slash(a:path >= 0 ? bufname(a:path) : bufname(''))
if getbufvar(a:path, '&filetype') ==# 'netrw'
let path = s:Slash(getbufvar(a:path, 'netrw_curdir', path))
endif
else else
let path = s:Slash(a:path) let path = s:Slash(a:path)
endif endif
if path =~# '^fugitive://' if path =~# '^fugitive:'
return fugitive#Parse(path)[1] return matchstr(path, '\C^fugitive:\%(//\)\=\zs.\{-\}\ze\%(//\|::\|$\)')
elseif empty(path) elseif empty(path)
return '' return ''
elseif isdirectory(path)
let path = fnamemodify(path, ':p:s?/$??')
else
let path = fnamemodify(path, ':p:h:s?/$??')
endif endif
let pre = substitute(matchstr(path, '^\a\a\+\ze:'), '^.', '\u&', '') let pre = substitute(matchstr(path, '^\a\a\+\ze:'), '^.', '\u&', '')
if len(pre) && exists('*' . pre . 'Real') if len(pre) && exists('*' . pre . 'Real')
let path = {pre}Real(path) let path = s:Slash({pre}Real(path))
endif
let root = resolve(path)
if root !=# path
silent! exe (haslocaldir() ? 'lcd' : exists(':tcd') && haslocaldir(-1) ? 'tcd' : 'cd') '.'
endif endif
let root = s:Slash(fnamemodify(path, ':p:h'))
let previous = "" let previous = ""
let env_git_dir = len($GIT_DIR) ? s:Slash(simplify(fnamemodify(FugitiveVimPath($GIT_DIR), ':p:s?[\/]$??'))) : '' let env_git_dir = len($GIT_DIR) ? s:Slash(simplify(fnamemodify(FugitiveVimPath($GIT_DIR), ':p:s?[\/]$??'))) : ''
call s:Tree(env_git_dir) call s:Tree(env_git_dir)
let ceiling_directories = s:CeilingDirectories() while root !=# previous
while root !=# previous && root !~# '^$\|^//[^/]*$' if root =~# '\v^//%([^/]+/?)?$'
if index(ceiling_directories, root) >= 0 break
endif
if index(s:CeilingDirectories(), root) >= 0
break break
endif endif
if root ==# $GIT_WORK_TREE && FugitiveIsGitDir(env_git_dir) if root ==# $GIT_WORK_TREE && FugitiveIsGitDir(env_git_dir)
@@ -455,12 +391,20 @@ function! FugitiveExtractGitDir(path) abort
return s:dir_for_worktree[root] return s:dir_for_worktree[root]
endif endif
let dir = substitute(root, '[\/]$', '', '') . '/.git' let dir = substitute(root, '[\/]$', '', '') . '/.git'
let resolved = s:ResolveGitDir(dir) let type = getftype(dir)
if !empty(resolved) if type ==# 'dir' && FugitiveIsGitDir(dir)
let s:resolved_git_dirs[dir] = resolved return dir
return dir is# resolved || s:Tree(resolved) is# 0 ? dir : resolved elseif type ==# 'link' && FugitiveIsGitDir(dir)
return resolve(dir)
elseif type !=# '' && filereadable(dir)
let line = get(readfile(dir, '', 1), 0, '')
let file_dir = s:Slash(FugitiveVimPath(matchstr(line, '^gitdir: \zs.*')))
if file_dir !~# '^/\|^\a:' && FugitiveIsGitDir(root . '/' . file_dir)
return simplify(root . '/' . file_dir)
elseif len(file_dir) && FugitiveIsGitDir(file_dir)
return file_dir
endif
elseif FugitiveIsGitDir(root) elseif FugitiveIsGitDir(root)
let s:resolved_git_dirs[root] = root
return root return root
endif endif
let previous = root let previous = root
@@ -470,56 +414,57 @@ function! FugitiveExtractGitDir(path) abort
endfunction endfunction
function! FugitiveDetect(...) abort function! FugitiveDetect(...) abort
if v:version < 704 if v:version < 703
return '' return ''
endif endif
if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir
unlet b:git_dir unlet b:git_dir
endif endif
if a:0 > 1 && a:2 is# 0 && !exists('#User#Fugitive')
return ''
endif
if !exists('b:git_dir') if !exists('b:git_dir')
let b:git_dir = FugitiveExtractGitDir(a:0 ? a:1 : bufnr('')) let b:git_dir = FugitiveExtractGitDir(a:0 ? a:1 : bufnr(''))
endif endif
if empty(b:git_dir) || !exists('#User#Fugitive')
return ''
endif
if v:version >= 704 || (v:version == 703 && has('patch442'))
doautocmd <nomodeline> User Fugitive
elseif &modelines > 0
let modelines = &modelines
try
set modelines=0
doautocmd User Fugitive
finally
let &modelines = modelines
endtry
else
doautocmd User Fugitive
endif
return '' return ''
endfunction endfunction
function! FugitiveVimPath(path) abort
if exists('+shellslash') && !&shellslash
return tr(a:path, '/', '\')
else
return a:path
endif
endfunction
function! FugitiveGitPath(path) abort function! FugitiveGitPath(path) abort
return s:Slash(a:path) return s:Slash(a:path)
endfunction endfunction
if exists('+shellslash') if exists('+shellslash')
function! s:Slash(path) abort function! s:Slash(path) abort
return tr(a:path, '\', '/') return tr(a:path, '\', '/')
endfunction endfunction
function! s:VimSlash(path) abort
return tr(a:path, '\/', &shellslash ? '//' : '\\')
endfunction
function FugitiveVimPath(path) abort
return tr(a:path, '\/', &shellslash ? '//' : '\\')
endfunction
else else
function! s:Slash(path) abort function! s:Slash(path) abort
return a:path return a:path
endfunction endfunction
function! s:VimSlash(path) abort
return a:path
endfunction
if has('win32unix') && filereadable('/git-bash.exe')
function! FugitiveVimPath(path) abort
return substitute(a:path, '^\(\a\):', '/\l\1', '')
endfunction
else
function! FugitiveVimPath(path) abort
return a:path
endfunction
endif
endif endif
function! s:ProjectionistDetect() abort function! s:ProjectionistDetect() abort
@@ -552,6 +497,9 @@ command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#Complete Git exe
if exists(':Gstatus') != 2 && get(g:, 'fugitive_legacy_commands', 0) if exists(':Gstatus') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bang -bar -range=-1' s:addr_other 'Gstatus exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bang -bar -range=-1' s:addr_other 'Gstatus exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gstatus is deprecated in favor of :Git (with no arguments)"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gstatus is deprecated in favor of :Git (with no arguments)"|echohl NONE'
elseif exists(':Gstatus') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bang -bar -range=-1' s:addr_other 'Gstatus'
\ ' echoerr ":Gstatus has been removed in favor of :Git (with no arguments)"'
endif endif
for s:cmd in ['Commit', 'Revert', 'Merge', 'Rebase', 'Pull', 'Push', 'Fetch', 'Blame'] for s:cmd in ['Commit', 'Revert', 'Merge', 'Rebase', 'Pull', 'Push', 'Fetch', 'Blame']
@@ -559,6 +507,9 @@ for s:cmd in ['Commit', 'Revert', 'Merge', 'Rebase', 'Pull', 'Push', 'Fetch', 'B
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#' . s:cmd . 'Complete G' . tolower(s:cmd) exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#' . s:cmd . 'Complete G' . tolower(s:cmd)
\ 'echohl WarningMSG|echomsg ":G' . tolower(s:cmd) . ' is deprecated in favor of :Git ' . tolower(s:cmd) . '"|echohl NONE|' \ 'echohl WarningMSG|echomsg ":G' . tolower(s:cmd) . ' is deprecated in favor of :Git ' . tolower(s:cmd) . '"|echohl NONE|'
\ 'exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", "' . tolower(s:cmd) . ' " . <q-args>)' \ 'exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", "' . tolower(s:cmd) . ' " . <q-args>)'
elseif exists(':G' . tolower(s:cmd)) != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#' . s:cmd . 'Complete G' . tolower(s:cmd)
\ 'echoerr ":G' . tolower(s:cmd) . ' has been removed in favor of :Git ' . tolower(s:cmd) . '"'
endif endif
endfor endfor
unlet s:cmd unlet s:cmd
@@ -569,6 +520,13 @@ exe "command! -bar -bang -nargs=? -complete=customlist,fugitive#CdComplete Glcd
exe 'command! -bang -nargs=? -range=-1' s:addr_wins '-complete=customlist,fugitive#GrepComplete Ggrep exe fugitive#GrepCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bang -nargs=? -range=-1' s:addr_wins '-complete=customlist,fugitive#GrepComplete Ggrep exe fugitive#GrepCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bang -nargs=? -range=-1' s:addr_wins '-complete=customlist,fugitive#GrepComplete Glgrep exe fugitive#GrepCommand(0, <count> > 0 ? <count> : 0, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bang -nargs=? -range=-1' s:addr_wins '-complete=customlist,fugitive#GrepComplete Glgrep exe fugitive#GrepCommand(0, <count> > 0 ? <count> : 0, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Glog') != 2 && get(g:, 'fugitive_legacy_commands', 0)
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Glog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "")'
\ '|echohl WarningMSG|echomsg ":Glog is deprecated in favor of :Gclog"|echohl NONE'
elseif exists(':Glog') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Glog'
\ ' echoerr ":Glog has been removed in favor of :Gclog"'
endif
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gclog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")' exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gclog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete GcLog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")' exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete GcLog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gllog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "l")' exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gllog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "l")'
@@ -576,11 +534,10 @@ exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ge exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ge exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gedit exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gedit exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gpedit exe fugitive#Open("pedit", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#ReadComplete Gpedit exe fugitive#Open("pedit", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#EditComplete Gsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "split" : "edit"), <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#ReadComplete Gsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "split" : "edit"), <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#EditComplete Gvsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "vsplit" : "edit!"), <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#ReadComplete Gvsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "vsplit" : "edit!"), <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_tabs '-complete=customlist,fugitive#EditComplete Gtabedit exe fugitive#Open((<count> >= 0 ? <count> : "")."tabedit", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -range=-1' s:addr_tabs '-complete=customlist,fugitive#ReadComplete Gtabedit exe fugitive#Open((<count> >= 0 ? <count> : "")."tabedit", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gdrop exe fugitive#DropCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gr') != 2 if exists(':Gr') != 2
exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gr exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gr exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
@@ -596,47 +553,33 @@ exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwr
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwq exe fugitive#WqCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwq exe fugitive#WqCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GRemove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=0 GRemove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GUnlink exe fugitive#UnlinkCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GDelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=0 GDelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject GMove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject GMove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete GRename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete GRename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gremove') != 2 && get(g:, 'fugitive_legacy_commands', 0) if exists(':Gremove') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=0 Gremove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=0 Gremove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gremove is deprecated in favor of :GRemove"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gremove is deprecated in favor of :GRemove"|echohl NONE'
elseif exists(':Gremove') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=0 Gremove echoerr ":Gremove has been removed in favor of :GRemove"'
endif endif
if exists(':Gdelete') != 2 && get(g:, 'fugitive_legacy_commands', 0) if exists(':Gdelete') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=0 Gdelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=0 Gdelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gdelete is deprecated in favor of :GDelete"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gdelete is deprecated in favor of :GDelete"|echohl NONE'
elseif exists(':Gdelete') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=0 Gdelete echoerr ":Gdelete has been removed in favor of :GDelete"'
endif endif
if exists(':Gmove') != 2 && get(g:, 'fugitive_legacy_commands', 0) if exists(':Gmove') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject Gmove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject Gmove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gmove is deprecated in favor of :GMove"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gmove is deprecated in favor of :GMove"|echohl NONE'
elseif exists(':Gmove') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=? -complete=customlist,fugitive#CompleteObject Gmove'
\ 'echoerr ":Gmove has been removed in favor of :GMove"'
endif endif
if exists(':Grename') != 2 && get(g:, 'fugitive_legacy_commands', 0) if exists(':Grename') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete Grename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete Grename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Grename is deprecated in favor of :GRename"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Grename is deprecated in favor of :GRename"|echohl NONE'
elseif exists(':Grename') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -nargs=? -complete=customlist,fugitive#RenameComplete Grename'
\ 'echoerr ":Grename has been removed in favor of :GRename"'
endif endif
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject GBrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject GBrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gbrowse') != 2 && get(g:, 'fugitive_legacy_commands', 0) if exists(':Gbrowse') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|if <bang>1|redraw!|endif|echohl WarningMSG|echomsg ":Gbrowse is deprecated in favor of :GBrowse"|echohl NONE' \ '|if <bang>1|redraw!|endif|echohl WarningMSG|echomsg ":Gbrowse is deprecated in favor of :GBrowse"|echohl NONE'
elseif exists(':Gbrowse') != 2 && !exists('g:fugitive_legacy_commands')
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse'
\ 'echoerr ":Gbrowse has been removed in favor of :GBrowse"'
endif endif
if v:version < 704 if v:version < 703
finish finish
endif endif
@@ -661,14 +604,8 @@ augroup fugitive
autocmd! autocmd!
autocmd BufNewFile,BufReadPost * autocmd BufNewFile,BufReadPost *
\ if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir | \ call FugitiveDetect(expand('<amatch>:p'), 0)
\ unlet b:git_dir | autocmd FileType netrw call FugitiveDetect(fnamemodify(get(b:, 'netrw_curdir', expand('<afile>:p')), ':p'), 1)
\ endif
autocmd FileType netrw
\ if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir |
\ unlet b:git_dir |
\ endif
autocmd BufFilePost * unlet! b:git_dir
autocmd FileType git autocmd FileType git
\ call fugitive#MapCfile() \ call fugitive#MapCfile()
@@ -688,31 +625,28 @@ augroup fugitive
\ endif | \ endif |
\ let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') . '|setl inex= inc=' \ let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') . '|setl inex= inc='
autocmd BufReadCmd index{,.lock} nested autocmd BufReadCmd index{,.lock}
\ if FugitiveIsGitDir(expand('<amatch>:p:h')) | \ if FugitiveIsGitDir(expand('<amatch>:p:h')) |
\ let b:git_dir = s:Slash(expand('<amatch>:p:h')) | \ let b:git_dir = s:Slash(expand('<amatch>:p:h')) |
\ exe fugitive#BufReadStatus(v:cmdbang) | \ exe fugitive#BufReadStatus() |
\ echohl WarningMSG |
\ echo "fugitive: Direct editing of .git/" . expand('%:t') . " is deprecated" |
\ echohl NONE |
\ elseif filereadable(expand('<amatch>')) | \ elseif filereadable(expand('<amatch>')) |
\ silent doautocmd BufReadPre | \ silent doautocmd BufReadPre |
\ keepalt noautocmd read <amatch> | \ keepalt read <amatch> |
\ silent 1delete_ | \ 1delete_ |
\ silent doautocmd BufReadPost | \ silent doautocmd BufReadPost |
\ else | \ else |
\ silent doautocmd BufNewFile | \ silent doautocmd BufNewFile |
\ endif \ endif
autocmd BufReadCmd fugitive://* nested exe fugitive#BufReadCmd() | autocmd BufReadCmd fugitive://*//* exe fugitive#BufReadCmd() |
\ if &path =~# '^\.\%(,\|$\)' | \ if &path =~# '^\.\%(,\|$\)' |
\ let &l:path = substitute(&path, '^\.,\=', '', '') | \ let &l:path = substitute(&path, '^\.,\=', '', '') |
\ endif \ endif
autocmd BufWriteCmd fugitive://* nested exe fugitive#BufWriteCmd() autocmd BufWriteCmd fugitive://*//[0-3]/* exe fugitive#BufWriteCmd()
autocmd FileReadCmd fugitive://* nested exe fugitive#FileReadCmd() autocmd FileReadCmd fugitive://*//* exe fugitive#FileReadCmd()
autocmd FileWriteCmd fugitive://* nested exe fugitive#FileWriteCmd() autocmd FileWriteCmd fugitive://*//[0-3]/* exe fugitive#FileWriteCmd()
if exists('##SourceCmd') if exists('##SourceCmd')
autocmd SourceCmd fugitive://* nested exe fugitive#SourceCmd() autocmd SourceCmd fugitive://*//* nested exe fugitive#SourceCmd()
endif endif
autocmd User Flags call Hoist('buffer', function('FugitiveStatusline')) autocmd User Flags call Hoist('buffer', function('FugitiveStatusline'))
@@ -720,15 +654,14 @@ augroup fugitive
autocmd User ProjectionistDetect call s:ProjectionistDetect() autocmd User ProjectionistDetect call s:ProjectionistDetect()
augroup END augroup END
nmap <script><silent> <Plug>fugitive:y<C-G> :<C-U>call setreg(v:register, fugitive#Object(@%))<CR>
nmap <script> <Plug>fugitive: <Nop>
if get(g:, 'fugitive_no_maps') if get(g:, 'fugitive_no_maps')
finish finish
endif endif
let s:nowait = v:version >= 704 ? '<nowait>' : ''
function! s:Map(mode, lhs, rhs, flags) abort function! s:Map(mode, lhs, rhs, flags) abort
let flags = a:flags . (a:rhs =~# '<Plug>' ? '' : '<script>') . '<nowait>' let flags = a:flags . (a:rhs =~# '<Plug>' ? '' : '<script>')
let head = a:lhs let head = a:lhs
let tail = '' let tail = ''
let keys = get(g:, a:mode.'remap', {}) let keys = get(g:, a:mode.'remap', {})
@@ -745,8 +678,8 @@ function! s:Map(mode, lhs, rhs, flags) abort
let head = substitute(head, '<[^<>]*>$\|.$', '', '') let head = substitute(head, '<[^<>]*>$\|.$', '', '')
endwhile endwhile
endif endif
if empty(mapcheck(head.tail, a:mode)) if flags !~# '<unique>' || empty(mapcheck(head.tail, a:mode))
exe a:mode.'map' flags head.tail a:rhs exe a:mode.'map' s:nowait flags head.tail a:rhs
endif endif
endfunction endfunction

View File

@@ -13,7 +13,7 @@ syn match fugitiveHeader /^Pull:\|^Rebase:\|^Merge:\|^Push:/ nextgroup=fugitiveS
syn match fugitiveHelpHeader /^Help:/ nextgroup=fugitiveHelpTag skipwhite syn match fugitiveHelpHeader /^Help:/ nextgroup=fugitiveHelpTag skipwhite
syn match fugitiveHelpTag /\S\+/ contained syn match fugitiveHelpTag /\S\+/ contained
syn region fugitiveSection start=/^\%(.*(\d\++\=)$\)\@=/ contains=fugitiveHeading end=/^$/ fold syn region fugitiveSection start=/^\%(.*(\d\++\=)$\)\@=/ contains=fugitiveHeading end=/^$/
syn cluster fugitiveSection contains=fugitiveSection syn cluster fugitiveSection contains=fugitiveSection
syn match fugitiveHeading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite syn match fugitiveHeading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite
syn match fugitiveCount /(\d\++\=)/hs=s+1,he=e-1 contained syn match fugitiveCount /(\d\++\=)/hs=s+1,he=e-1 contained
@@ -30,7 +30,7 @@ syn match fugitiveHash /\S\@<!\x\{4,\}\S\@!/ contained
syn region fugitiveHunk start=/^\%(@@\+ -\)\@=/ end=/^\%([A-Za-z?@]\|$\)\@=/ contains=diffLine,diffRemoved,diffAdded,diffNoEOL containedin=@fugitiveSection fold syn region fugitiveHunk start=/^\%(@@\+ -\)\@=/ end=/^\%([A-Za-z?@]\|$\)\@=/ contains=diffLine,diffRemoved,diffAdded,diffNoEOL containedin=@fugitiveSection fold
for s:section in ['Untracked', 'Unstaged', 'Staged'] for s:section in ['Untracked', 'Unstaged', 'Staged']
exe 'syn region fugitive' . s:section . 'Section start=/^\%(' . s:section . ' .*(\d\++\=)$\)\@=/ contains=fugitive' . s:section . 'Heading end=/^$/ fold' exe 'syn region fugitive' . s:section . 'Section start=/^\%(' . s:section . ' .*(\d\++\=)$\)\@=/ contains=fugitive' . s:section . 'Heading end=/^$/'
exe 'syn match fugitive' . s:section . 'Modifier /^[MADRCU?] / contained containedin=fugitive' . s:section . 'Section' exe 'syn match fugitive' . s:section . 'Modifier /^[MADRCU?] / contained containedin=fugitive' . s:section . 'Section'
exe 'syn cluster fugitiveSection add=fugitive' . s:section . 'Section' exe 'syn cluster fugitiveSection add=fugitive' . s:section . 'Section'
exe 'syn match fugitive' . s:section . 'Heading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite' exe 'syn match fugitive' . s:section . 'Heading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite'