diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 6b3d903..d000561 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -273,10 +273,11 @@ function! s:TempScript(...) abort if !filereadable(temp) call writefile(['#!/bin/sh'] + a:000, temp) endif + let temp = FugitiveGitPath(temp) if temp =~# '\s' let temp = '"' . temp . '"' endif - return FugitiveGitPath(temp) + return temp endfunction function! s:DoAutocmd(...) abort @@ -1255,11 +1256,14 @@ function! s:SshParseConfig(into, root, file) abort let host = s:SshParseHost(value) elseif key ==# 'include' for glob in split(value) - if glob !~# '^/' + if glob !~# '^[~/]' let glob = a:root . glob endif for included in reverse(split(glob(glob), "\n")) - call extend(lines, readfile(included), 'keep') + try + call extend(lines, readfile(included), 'keep') + catch + endtry endfor endfor elseif len(key) && len(host) @@ -2710,10 +2714,10 @@ function! s:MapStatus() abort call s:Map('n', 'd?', ":help fugitive_d", '') call s:Map('n', 'P', ":execute StagePatch(line('.'),line('.')+v:count1-1)", '') call s:Map('x', 'P', ":execute StagePatch(line(\"'<\"),line(\"'>\"))", '') - call s:Map('n', 'p', ":if v:countsilent exe GF('pedit')elseechoerr 'Use = for inline diff, P for :Git add/reset --patch, 1p for :pedit'endif", '') + call s:Map('n', 'p', ":if v:countsilent exe GF('pedit')elseechoerr 'Use = for inline diff, I for :Git add/reset --patch, 1p for :pedit'endif", '') call s:Map('x', 'p', ":execute StagePatch(line(\"'<\"),line(\"'>\"))", '') - call s:Map('n', 'I', ":execute StagePatch(line('.'),line('.'))", '') - call s:Map('x', 'I', ":execute StagePatch(line(\"'<\"),line(\"'>\"))", '') + call s:Map('n', 'I', ":execute StagePatch(line('.'),line('.'), 1)", '') + call s:Map('x', 'I', ":execute StagePatch(line(\"'<\"),line(\"'>\"), 1)", '') call s:Map('n', 'gq', ":if bufnr('$') == 1quitelsebdeleteendif", '') call s:Map('n', 'R', ":echohl WarningMsgecho 'Reloading is automatic. Use :e to force'echohl NONE", '') call s:Map('n', 'g', ":echoerr 'Changed to X'", '') @@ -2726,48 +2730,21 @@ function! s:MapStatus() abort call s:Map('x', '.', ': =StageArgs(1)') endfunction -function! fugitive#BufReadStatus(cmdbang) abort - exe s:VersionCheck() - let amatch = s:Slash(expand('%:p')) - if a:cmdbang - unlet! b:fugitive_expanded - endif - let b:fugitive_type = 'index' - let dir = s:Dir() - let stat = {'bufnr': bufnr(''), 'reltime': reltime(), 'work_tree': s:Tree(dir)} +function! s:StatusProcess(result, stat) abort + let stat = a:stat + let status_exec = a:stat.status + let config = a:stat.config + let dir = s:Dir(config) try - let b:fugitive_loading = stat - let config = fugitive#Config(dir) - - let cmd = [dir] - if amatch !~# '^fugitive:' && s:cpath($GIT_INDEX_FILE !=# '' ? resolve(s:GitIndexFileEnv()) : fugitive#Find('.git/index', dir)) !=# s:cpath(amatch) - let cmd += [{'env': {'GIT_INDEX_FILE': FugitiveGitPath(amatch)}}] - endif - - if fugitive#GitVersion(2, 15) - call add(cmd, '--no-optional-locks') - endif - - if !empty(stat.work_tree) - let status_cmd = cmd + ['status', '-bz'] - call add(status_cmd, fugitive#GitVersion(2, 11) ? '--porcelain=v2' : '--porcelain') - let status_exec = fugitive#Execute(status_cmd, function('len')) - endif - - doautocmd BufReadPre - - setlocal readonly nomodifiable noswapfile nomodeline buftype=nowrite - call s:MapStatus() - let [staged, unstaged, untracked] = [[], [], []] let stat.props = {} - if !exists('status_exec') - let branch = FugitiveHead(0, dir) - let head = FugitiveHead(11, dir) + if empty(status_exec) + let stat.branch = FugitiveHead(0, config) - elseif fugitive#Wait(status_exec).exit_status - return 'echoerr ' . string('fugitive: ' . s:JoinChomp(status_exec.stderr)) + elseif status_exec.exit_status + let stat.error = s:JoinChomp(status_exec.stderr) + return elseif status_exec.args[-1] ==# '--porcelain=v2' let output = split(tr(join(status_exec.stdout, "\1"), "\1\n", "\n\1"), "\1", 1)[0:-2] @@ -2804,29 +2781,18 @@ function! fugitive#BufReadStatus(cmdbang) abort endif let i += 1 endwhile - let branch = substitute(get(stat.props, 'branch.head', '(unknown)'), '\C^(\%(detached\|unknown\))$', '', '') - if len(branch) - let head = branch - elseif has_key(stat.props, 'branch.oid') - let head = stat.props['branch.oid'][0:10] - else - let head = FugitiveHead(11, dir) - endif + let stat.branch = substitute(get(stat.props, 'branch.head', '(unknown)'), '\C^(\%(detached\|unknown\))$', '', '') else let output = split(tr(join(status_exec.stdout, "\1"), "\1\n", "\n\1"), "\1", 1)[0:-2] while get(output, 0, '') =~# '^\l\+:' call remove(output, 0) endwhile - let head = matchstr(output[0], '^## \zs\S\+\ze\%($\| \[\)') - if head =~# '\.\.\.' - let head = split(head, '\.\.\.')[0] - let branch = head - elseif head ==# 'HEAD' || empty(head) - let head = FugitiveHead(11, dir) - let branch = '' + let branch = matchstr(output[0], '^## \zs\S\+\ze\%($\| \[\)') + if branch =~# '\.\.\.' + let stat.branch = split(branch, '\.\.\.')[0] else - let branch = head + let stat.branch = branch ==# 'HEAD' ? '' : branch endif let i = 0 @@ -2855,7 +2821,7 @@ function! fugitive#BufReadStatus(cmdbang) abort endwhile endif - let diff_cmd = cmd + ['-c', 'diff.suppressBlankEmpty=false', '-c', 'core.quotePath=false', 'diff', '--color=never', '--no-ext-diff', '--no-prefix'] + let diff_cmd = stat.cmd + ['-c', 'diff.suppressBlankEmpty=false', '-c', 'core.quotePath=false', 'diff', '--color=never', '--no-ext-diff', '--no-prefix'] let stat.diff = {'Staged': {'stdout': ['']}, 'Unstaged': {'stdout': ['']}} if len(staged) let stat.diff['Staged'] = fugitive#Execute(diff_cmd + ['--cached'], function('len')) @@ -2864,6 +2830,8 @@ function! fugitive#BufReadStatus(cmdbang) abort let stat.diff['Unstaged'] = fugitive#Execute(diff_cmd + ['--'] + map(copy(unstaged), 'stat.work_tree . "/" . v:val.relative[0]'), function('len')) endif + let [stat.staged, stat.unstaged, stat.untracked] = [staged, unstaged, untracked] + let stat.files = {'Staged': {}, 'Unstaged': {}} for dict in staged let stat.files['Staged'][dict.filename] = dict @@ -2872,6 +2840,7 @@ function! fugitive#BufReadStatus(cmdbang) abort let stat.files['Unstaged'][dict.filename] = dict endfor + let branch = stat.branch let fetch_remote = config.Get('branch.' . branch . '.remote', 'origin') let push_remote = config.Get('branch.' . branch . '.pushRemote', \ config.Get('remote.pushDefault', fetch_remote)) @@ -2914,6 +2883,18 @@ function! fugitive#BufReadStatus(cmdbang) abort let stat.pull_type = 'Merge' endif endif + endtry +endfunction + +function! s:StatusRender(stat) abort + try + let stat = a:stat + call fugitive#Wait(stat.running) + if has_key(stat, 'error') + return 'echoerr ' . string('fugitive: ' . stat.error) + endif + let [staged, unstaged, untracked, config] = [stat.staged, stat.unstaged, stat.untracked, stat.config] + let dir = s:Dir(config) let pull_ref = stat.merge if stat.fetch_remote !=# '.' @@ -2934,19 +2915,15 @@ function! fugitive#BufReadStatus(cmdbang) abort let rebasing_dir = fugitive#Find('.git/rebase-apply/', dir) endif + call fugitive#Wait(stat.rev_parse) + let head = empty(stat.branch) ? stat.rev_parse.stdout[0] : stat.branch + let rebasing = [] let rebasing_head = 'detached HEAD' if exists('rebasing_dir') && filereadable(rebasing_dir . 'git-rebase-todo') let rebasing_head = substitute(readfile(rebasing_dir . 'head-name')[0], '\C^refs/heads/', '', '') - let len = 11 + let len = len(stat.rev_parse.stdout[0]) let lines = readfile(rebasing_dir . 'git-rebase-todo') - for line in lines - let hash = matchstr(line, '^[^a-z].*\s\zs[0-9a-f]\{4,\}\ze\.\.') - if len(hash) - let len = len(hash) - break - endif - endfor if getfsize(rebasing_dir . 'done') > 0 let done = readfile(rebasing_dir . 'done') call map(done, 'substitute(v:val, ''^\l\+\>'', "done", "")') @@ -3036,6 +3013,57 @@ function! fugitive#BufReadStatus(cmdbang) abort call setbufvar(bufnr, 'fugitive_status', stat) call setbufvar(bufnr, 'fugitive_expanded', stat.expanded) setlocal nomodified readonly nomodifiable + return '' + finally + let b:fugitive_type = 'index' + endtry +endfunction + +function! s:StatusRetrieve(bufnr, ...) abort + let amatch = s:Slash(fnamemodify(bufname(a:bufnr), ':p')) + let dir = s:Dir(a:bufnr) + let config = fugitive#Config(dir, function('len')) + + let cmd = [dir] + if amatch !~# '^fugitive:' && s:cpath($GIT_INDEX_FILE !=# '' ? resolve(s:GitIndexFileEnv()) : fugitive#Find('.git/index', dir)) !=# s:cpath(amatch) + let cmd += [{'env': {'GIT_INDEX_FILE': FugitiveGitPath(amatch)}}] + endif + + if fugitive#GitVersion(2, 15) + call add(cmd, '--no-optional-locks') + endif + + let rev_parse_cmd = cmd + ['rev-parse', '--short', 'HEAD', '--'] + + let stat = {'bufnr': a:bufnr, 'reltime': reltime(), 'work_tree': s:Tree(dir), 'cmd': cmd, 'config': config} + if empty(stat.work_tree) + let stat.rev_parse = call('fugitive#Execute', [rev_parse_cmd, function('s:StatusProcess'), stat] + a:000) + let stat.status = {} + let stat.running = stat.rev_parse + else + let stat.rev_parse = fugitive#Execute(rev_parse_cmd) + let status_cmd = cmd + ['status', '-bz', fugitive#GitVersion(2, 11) ? '--porcelain=v2' : '--porcelain'] + let stat.status = call('fugitive#Execute', [status_cmd, function('s:StatusProcess'), stat] + a:000) + let stat.running = stat.status + endif + return stat +endfunction + +function! fugitive#BufReadStatus(cmdbang) abort + exe s:VersionCheck() + if a:cmdbang + unlet! b:fugitive_expanded + endif + let b:fugitive_type = 'index' + let stat = s:StatusRetrieve(bufnr('')) + try + let b:fugitive_loading = stat + doautocmd BufReadPre + + setlocal readonly nomodifiable noswapfile nomodeline buftype=nowrite + call s:MapStatus() + + call s:StatusRender(stat) doautocmd BufReadPost if &bufhidden ==# '' @@ -3193,7 +3221,7 @@ function! fugitive#BufReadCmd(...) abort if b:fugitive_display_format call s:ReplaceCmd([dir, 'cat-file', b:fugitive_type, rev]) else - call s:ReplaceCmd([dir, '-c', 'diff.noprefix=false', '-c', 'log.showRoot=false', 'show', '--no-color', '-m', '--first-parent', '--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', rev]) + call s:ReplaceCmd([dir, '-c', 'diff.noprefix=false', '-c', 'log.showRoot=false', 'show', '--no-color', '-m', '--first-parent', '--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%B', rev]) keepjumps 1 keepjumps call search('^parent ') if getline('.') ==# 'parent ' @@ -3352,6 +3380,7 @@ function! s:TempReadPost(file) abort endif return 'doautocmd User FugitivePager' endif + return '' endfunction function! s:TempDelete(file) abort @@ -3767,6 +3796,7 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg, ...) abort let flags = [] let pager = -1 let explicit_pathspec_option = 0 + let did_expand_alias = 0 while len(args) if args[0] ==# '-c' && len(args) > 1 call extend(flags, remove(args, 0, 1)) @@ -3783,8 +3813,18 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg, ...) abort call add(flags, remove(args, 0)) elseif args[0] =~# '^-C$\|^--\%(exec-path=\|git-dir=\|work-tree=\|bare$\)' return 'echoerr ' . string('fugitive: ' . args[0] . ' is not supported') - else + elseif did_expand_alias break + else + let alias = FugitiveConfigGet('alias.' . get(args, 0, ''), config) + if get(args, 1, '') !=# '--help' && alias !~# '^$\|^!\|[\"'']' && !filereadable(s:VimExecPath() . '/git-' . args[0]) + \ && !(has('win32') && filereadable(s:VimExecPath() . '/git-' . args[0] . '.exe')) + call remove(args, 0) + call extend(args, split(alias, '\s\+'), 'keep') + let did_expand_alias = 1 + else + break + endif endif endwhile if !explicit_pathspec_option @@ -3816,12 +3856,6 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg, ...) abort let cmd = s:StatusCommand(a:line1, a:line2, a:range, curwin ? 0 : a:line2, a:bang, a:mods, '', '', [], options) return (empty(cmd) ? 'exe' : cmd) . after endif - let alias = FugitiveConfigGet('alias.' . get(args, 0, ''), config) - if get(args, 1, '') !=# '--help' && alias !~# '^$\|^!\|[\"'']' && !filereadable(s:VimExecPath() . '/git-' . args[0]) - \ && !(has('win32') && filereadable(s:VimExecPath() . '/git-' . args[0] . '.exe')) - call remove(args, 0) - call extend(args, split(alias, '\s\+'), 'keep') - endif let name = substitute(get(args, 0, ''), '\%(^\|-\)\(\l\)', '\u\1', 'g') if pager is# -1 && name =~# '^\a\+$' && exists('*s:' . name . 'Subcommand') && get(args, 1, '') !=# '--help' try @@ -3916,6 +3950,9 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg, ...) abort \ 'GIT_SEQUENCE_EDITOR': editor, \ 'GIT_PAGER': 'cat', \ 'PAGER': 'cat'}, 'keep') + if s:executable('col') + let env.MANPAGER = 'col -b' + endif if len($GPG_TTY) && !has_key(env, 'GPG_TTY') let env.GPG_TTY = '' let did_override_gpg_tty = 1 @@ -4949,19 +4986,19 @@ function! s:StageDiff(diff) abort return 'Git --paginate diff --no-ext-diff' elseif len(info.paths) > 1 execute 'Gedit' . prefix s:fnameescape(':0:' . info.paths[0]) - return a:diff . '! @:'.s:fnameescape(info.paths[1]) + return 'keepalt ' . a:diff . '! @:'.s:fnameescape(info.paths[1]) elseif info.section ==# 'Staged' && info.sigil ==# '-' execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0]) - return a:diff . '! :0:%' + return 'keepalt ' . a:diff . '! :0:%' elseif info.section ==# 'Staged' execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0]) - return a:diff . '! @:%' + return 'keepalt ' . a:diff . '! @:%' elseif info.sigil ==# '-' execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0]) - return a:diff . '! :(top)%' + return 'keepalt ' . a:diff . '! :(top)%' else execute 'Gedit' prefix s:fnameescape(':(top)'.info.paths[0]) - return a:diff . '!' + return 'keepalt ' . a:diff . '!' endif endfunction @@ -5154,7 +5191,7 @@ function! s:DoToggleHeadHeader(value) abort endfunction function! s:DoToggleHelpHeader(value) abort - exe 'help fugitive-map' + exe 'help fugitive-maps' endfunction function! s:DoStagePushHeader(value) abort @@ -5290,10 +5327,11 @@ function! s:DoStageUntracked(record) abort return s:DoToggleUntracked(a:record) endfunction -function! s:StagePatch(lnum1,lnum2) abort +function! s:StagePatch(lnum1, lnum2, ...) abort let add = [] let reset = [] let intend = [] + let patch_only = a:0 && a:1 for lnum in range(a:lnum1,a:lnum2) let info = s:StageInfo(lnum) @@ -5306,6 +5344,13 @@ function! s:StagePatch(lnum1,lnum2) abort elseif empty(info.paths) && info.section ==# 'Untracked' execute 'tab Git add --interactive' break + elseif !patch_only && info.section ==# 'Unpushed' + if empty(info.commit) + call s:DoStageUnpushedHeading(info) + else + call s:DoStageUnpushed(info) + endif + return '' elseif empty(info.paths) continue endif @@ -5460,7 +5505,9 @@ function! s:ToolItems(state, from, to, offsets, text, ...) abort endif call add(items, item) endfor - let items[-1].context = {'diff': items[0:-2]} + if get(a:offsets, 0, '') isnot# 'none' + let items[-1].context = {'diff': items[0:-2]} + endif return [items[-1]] endfunction @@ -5516,6 +5563,10 @@ function! s:ToolParse(state, line) abort let [_, add, remove, to; __] = matchlist(a:line, '^\(\d\+\|-\)\t\(\d\+\|-\)\t\(.*\)') let [to, from] = s:ToolToFrom(to) return s:ToolItems(a:state, from, to, [], add ==# '-' ? 'Binary file' : '+' . add . ' -' . remove, add !=# '-') + elseif a:line =~# '^\f\+:\d\+: \D' + " --check + let [_, to, line, text; __] = matchlist(a:line, '^\(\f\+\):\(\d\+\):\s*\(.*\)$') + return s:ToolItems(a:state, to, to, ['none', line], text) elseif a:state.mode !=# 'diffhead' && a:state.mode !=# 'hunk' && len(a:line) || a:line =~# '^git: \|^usage: \|^error: \|^fatal: ' return [{'text': a:line}] endif @@ -5570,7 +5621,7 @@ function! s:ToolStream(line1, line2, range, bang, mods, options, args, state) ab for item in s:ToolParse(a:state, line) if len(get(item, 'filename', '')) && item.filename != filename call add(cmd, 'tabedit ' . s:fnameescape(item.filename)) - for i in reverse(range(len(get(item.context, 'diff', [])))) + for i in reverse(range(len(get(get(item, 'context', {}), 'diff', [])))) call add(cmd, (i ? 'rightbelow' : 'leftabove') . ' vertical Gdiffsplit! ' . s:fnameescape(item.context.diff[i].filename)) endfor call add(cmd, 'wincmd =') @@ -6576,7 +6627,7 @@ function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, ...) abort let commit = s:DirCommitFile(@%)[1] if a:mods =~# '\<\d*tab\>' let mods = substitute(a:mods, '\<\d*tab\>', '', 'g') - let pre = matchstr(a:mods, '\<\d*tab\>') . 'edit' + let pre = matchstr(a:mods, '\<\d*tab\>') . ' split' else let mods = 'keepalt ' . a:mods let pre = '' @@ -6718,7 +6769,6 @@ function! s:Move(force, rename, destination) abort if destination !~# '^/\|^\a\+:' let destination = s:Tree(dir) . '/' . destination endif - let destination = s:Tree(dir) . elseif a:destination =~# '^:(\%(top,literal\|literal,top\))' let destination = s:Tree(dir) . matchstr(a:destination, ')\zs.*') elseif a:destination =~# '^:(literal)\.\.\=\%(/\|$\)' @@ -6727,8 +6777,8 @@ function! s:Move(force, rename, destination) abort let destination = simplify(default_root . matchstr(a:destination, ')\zs.*')) else let destination = s:Expand(a:destination) - if destination =~# '^\.\.\=\%(/\|$\)' - let destination = simplify(getcwd() . '/' . destination) + if destination =~# '^\.\.\=\%(/\|$\)' && !a:rename + let destination = simplify((a:rename ? default_root : getcwd() . '/') . destination) elseif destination !~# '^\a\+:\|^/' let destination = default_root . destination endif @@ -7312,7 +7362,7 @@ function! s:BlameMaps(is_ftplugin) abort call s:Map('n', '-', ':exe BlameJump("")', '', ft) call s:Map('n', 's', ':exe BlameJump("")', '', ft) call s:Map('n', 'u', ':exe BlameJump("")', '', ft) - call s:Map('n', 'P', ':exe BlameJump("^".v:count1)', '', ft) + call s:Map('n', 'P', ':if !v:countechoerr "Use ~ (or provide a count)"elseexe BlameJump("^".v:count1)endif', '', ft) call s:Map('n', '~', ':exe BlameJump("~".v:count1)', '', ft) call s:Map('n', 'i', ':exe BlameCommit("exe BlameLeave()edit")', '', ft) call s:Map('n', 'o', ':exe BlameCommit("split")', '', ft) @@ -7386,10 +7436,14 @@ function! s:BrowserOpen(url, mods, echo_copy) abort if !exists('g:loaded_netrw') runtime! autoload/netrw.vim endif - if exists('*netrw#BrowseX') + if exists('*netrw#Open') + return 'echo '.string(url).'|' . mods . 'call netrw#Open('.string(url).')' + elseif exists('*netrw#BrowseX') return 'echo '.string(url).'|' . mods . 'call netrw#BrowseX('.string(url).', 0)' elseif exists('*netrw#NetrwBrowseX') return 'echo '.string(url).'|' . mods . 'call netrw#NetrwBrowseX('.string(url).', 0)' + elseif has('nvim-0.10') + return mods . 'echo luaeval("({vim.ui.open(_A)})[2] or _A", ' . string(url) . ')' else return 'echoerr ' . string('Netrw not found. Define your own :Browse to use :GBrowse') endif @@ -7863,6 +7917,7 @@ function! s:MapGitOps(is_ftplugin) abort exe s:Map('n', 'cc', ':Git commit', '', ft) exe s:Map('n', 'ce', ':Git commit --amend --no-edit', '', ft) exe s:Map('n', 'cw', ':Git commit --amend --only', '', ft) + exe s:Map('n', 'cW', ':Git commit --fixup=reword:=SquashArgument()', '', ft) exe s:Map('n', 'cva', ':tab Git commit -v --amend', '', ft) exe s:Map('n', 'cvc', ':tab Git commit -v', '', ft) exe s:Map('n', 'cRa', ':Git commit --reset-author --amend', '', ft) @@ -7872,7 +7927,8 @@ function! s:MapGitOps(is_ftplugin) abort exe s:Map('n', 'cF', ':Git -c sequence.editor=true rebase --interactive --autosquash=RebaseArgument()Git commit --fixup==SquashArgument()', '', ft) exe s:Map('n', 'cs', ':Git commit --no-edit --squash==SquashArgument()', '', ft) exe s:Map('n', 'cS', ':Git -c sequence.editor=true rebase --interactive --autosquash=RebaseArgument()Git commit --no-edit --squash==SquashArgument()', '', ft) - exe s:Map('n', 'cA', ':Git commit --edit --squash==SquashArgument()', '', ft) + exe s:Map('n', 'cn', ':Git commit --edit --squash==SquashArgument()', '', ft) + exe s:Map('n', 'cA', ':echoerr "Use cn"', '', ft) exe s:Map('n', 'c?', ':help fugitive_c', '', ft) exe s:Map('n', 'cr', ':Git revert', '', ft) @@ -7942,10 +7998,10 @@ function! fugitive#MapJumps(...) abort endif call s:Map('n', 'D', ":echoerr 'fugitive: D has been removed in favor of dd'", '') - call s:Map('n', 'dd', ":call fugitive#DiffClose()Gdiffsplit!", '') - call s:Map('n', 'dh', ":call fugitive#DiffClose()Ghdiffsplit!", '') - call s:Map('n', 'ds', ":call fugitive#DiffClose()Ghdiffsplit!", '') - call s:Map('n', 'dv', ":call fugitive#DiffClose()Gvdiffsplit!", '') + call s:Map('n', 'dd', ":call fugitive#DiffClose()keepalt Gdiffsplit!", '') + call s:Map('n', 'dh', ":call fugitive#DiffClose()keepalt Ghdiffsplit!", '') + call s:Map('n', 'ds', ":call fugitive#DiffClose()keepalt Ghdiffsplit!", '') + call s:Map('n', 'dv', ":call fugitive#DiffClose()keepalt Gvdiffsplit!", '') call s:Map('n', 'd?', ":help fugitive_d", '') else @@ -7980,7 +8036,7 @@ function! fugitive#MapJumps(...) abort call s:Map('n', 'S', ':echoerr "Use gO"', '') call s:Map('n', 'dq', ":call fugitive#DiffClose()", '') call s:Map('n', '-', ":exe 'Gedit ' . fnameescape(NavigateUp(v:count1)) if getline(1) =~# '^tree \x\{40,\}$' && empty(getline(2))call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')endif", '') - call s:Map('n', 'P', ":exe 'Gedit ' . fnameescape(ContainingCommit().'^'.v:count1.Relative(':'))", '') + call s:Map('n', 'P', ":if !v:countechoerr 'Use ~ (or provide a count)'elseexe 'Gedit ' . fnameescape(ContainingCommit().'^'.v:count1.Relative(':'))endif", '') call s:Map('n', '~', ":exe 'Gedit ' . fnameescape(ContainingCommit().'~'.v:count1.Relative(':'))", '') call s:Map('n', 'C', ":exe 'Gedit ' . fnameescape(ContainingCommit())", '') call s:Map('n', 'cp', ":echoerr 'Use gC'", '') @@ -7991,8 +8047,8 @@ function! fugitive#MapJumps(...) abort call s:Map('n', '.', ": =fnameescape(fugitive#Real(@%))") call s:Map('x', '.', ": =fnameescape(fugitive#Real(@%))") - call s:Map('n', 'g?', ":help fugitive-map", '') - call s:Map('n', '', ":help fugitive-map", '') + call s:Map('n', 'g?', ":help fugitive-maps", '') + call s:Map('n', '', ":help fugitive-maps", '') endif let old_browsex = maparg('NetrwBrowseX', 'n') diff --git a/doc/fugitive.txt b/doc/fugitive.txt index d5d4300..1a52f95 100644 --- a/doc/fugitive.txt +++ b/doc/fugitive.txt @@ -18,6 +18,12 @@ that are part of Git repositories). *fugitive-:G* :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 {args} Run an arbitrary git command and display any output. On UNIX this uses a pty and on other platforms it uses @@ -47,12 +53,6 @@ that are part of Git repositories). :{range}Git! -p {args} Run an arbitrary git command, and insert the output after {range} in the current buffer. - *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_blame* :Git blame [flags] Run git-blame [flags] on the current file and open the results in a scroll-bound vertical split. The @@ -341,8 +341,8 @@ ds Perform a |:Ghdiffsplit| on the file under the cursor. dh *fugitive_dq* -dq Close all but one diff buffer, and |:diffoff|! the - last one. +dq Close all but the currently focused diff buffer, and + invoke |:diffoff|!. *fugitive_d?* d? Show this help. @@ -380,6 +380,9 @@ p Open the file or |fugitive-object| under the cursor in *fugitive_P* 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* C Open the commit containing the current file. @@ -462,15 +465,18 @@ Commit maps ~ cc Create a commit. +cvc Create a commit with -v. + 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. cw Reword the last commit. -cvc Create a commit with -v. - -cva Amend the last commit with -v +cW Create an `amend!` commit that rewords the commit + under the cursor. cf Create a `fixup!` commit for the commit under the cursor. @@ -484,8 +490,8 @@ 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. -cA Create a `squash!` commit for the commit under the - cursor and edit the message. +cn Create a `squash!` commit for the commit under the +(formerly cA) cursor and edit the message. c Populate command line with ":Git commit ".