diff --git a/bundle/git.vim/autoload/git.vim b/bundle/git.vim/autoload/git.vim index 95a6e5cc6..9afc1f5ad 100644 --- a/bundle/git.vim/autoload/git.vim +++ b/bundle/git.vim/autoload/git.vim @@ -13,7 +13,7 @@ " git.vim is a simple plugin for using git in vim and neovim. " This plugin requires SpaceVim API and |job| support. -function! git#run(...) +function! git#run(...) abort let cmd = get(a:000, 0, '') if cmd ==# 'add' call git#add#run(a:000[1:]) @@ -49,6 +49,8 @@ function! git#run(...) call git#branch#run(a:000[1:]) elseif cmd ==# 'checkout' call git#checkout#run(a:000[1:]) + elseif cmd ==# 'cherry-pick' + call git#cherry_pick#run(a:000[1:]) elseif cmd ==# '--log' let args = get(a:000, 1, '') if args ==# 'clear' @@ -70,7 +72,7 @@ function! git#complete(ArgLead, CmdLine, CursorPos) abort return join(['add', 'push', 'status', 'commit', 'diff', \ 'merge', 'rebase', 'branch', 'checkout', \ 'fetch', 'reset', 'log', 'config', 'reflog', - \ 'blame', 'pull', 'stash', + \ 'blame', 'pull', 'stash', 'cherry-pick', \ ], \ "\n") elseif str =~# '^Git\s\+add\s\+.*$' diff --git a/bundle/git.vim/autoload/git/cherry_pick.vim b/bundle/git.vim/autoload/git/cherry_pick.vim new file mode 100644 index 000000000..9ad6d2b00 --- /dev/null +++ b/bundle/git.vim/autoload/git/cherry_pick.vim @@ -0,0 +1,116 @@ +"" +" @section git-cherry-pick, cherry-pick +" @parentsection commands +" This command is to cherry pick commit from other branch. +" > +" :Git cherry-pick +" < + +let s:JOB = SpaceVim#api#import('job') + +function! git#cherry_pick#run(args) abort + if len(a:args) == 0 + finish + else + let cmd = ['git', 'cherry-pick'] + a:args + endif + call git#logger#info('git-cherry-pick cmd:' . string(cmd)) + let s:conflict_files = [] + call s:JOB.start(cmd, + \ { + \ 'on_stderr' : function('s:on_stderr'), + \ 'on_stdout' : function('s:on_stdout'), + \ 'on_exit' : function('s:on_exit'), + \ } + \ ) + +endfunction + +function! s:on_exit(id, data, event) abort + call git#logger#info('git-cherry-pick exit data:' . string(a:data)) + if a:data ==# 0 + echo 'cherry-pick done!' + else + if s:list_conflict_files() + echo 'you need to resolve all conflicts' + else + echo 'cherry-pick failed!' + endif + endif +endfunction + +function! s:on_stdout(id, data, event) abort + for data in a:data + call git#logger#info('git-cherry-pick stdout:' . data) + if data =~# '^CONFLICT' + " CONFLICT (content): Merge conflict in test.txt + let file = data[38:] + call add(s:conflict_files, file) + endif + endfor +endfunction + +function! s:on_stderr(id, data, event) abort + for data in a:data + call git#logger#info('git-cherry-pick stderr:' . data) + endfor + " stderr should not be added to commit buffer + " let s:lines += a:data +endfunction + +function! s:list_conflict_files() abort + if !empty(s:conflict_files) + let rst = [] + for file in s:conflict_files + call add(rst, { + \ 'filename' : fnamemodify(file, ':p'), + \ }) + endfor + if len(rst) >= 1 + call setqflist([], 'r', {'title': ' ' . len(rst) . ' items', + \ 'items' : rst + \ }) + botright copen + return 1 + endif + endif +endfunction + +" usage: git cherry-pick [] [...] +" or: git cherry-pick --abort +" or: git cherry-pick --continue +" + + +function! s:args_with_two() abort + return join([ + \ '--no-commit', + \ '--continue', + \ '--abort', + \ '--quit', + \ ], "\n") +endfunction + +function! s:args_with_one() abort + return join([ + \ '-x', + \ ], "\n") + +endfunction + +function! git#cherry_pick#complete(ArgLead, CmdLine, CursorPos) abort + if a:ArgLead =~# '^--' + return s:args_with_two() + elseif a:ArgLead =~# '^-' + return s:args_with_one() + endif + + return join(s:unmerged_branchs(), "\n") + +endfunction + +function! s:unmerged_branchs() abort + return map(systemlist('git branch --no-merged'), 'trim(v:val)') +endfunction + + diff --git a/bundle/git.vim/doc/git.txt b/bundle/git.vim/doc/git.txt index 10deedef4..14f41ec0d 100644 --- a/bundle/git.vim/doc/git.txt +++ b/bundle/git.vim/doc/git.txt @@ -6,7 +6,8 @@ CONTENTS *git-contents* 1. Introduction..................................................|git-intro| 2. Commands...................................................|git-commands| 1. git-add.....................................................|git-add| - 2. git-stash.................................................|git-stash| + 2. git-cherry-pick.....................................|git-cherry-pick| + 3. git-stash.................................................|git-stash| ============================================================================== INTRODUCTION *git-intro* @@ -29,6 +30,14 @@ file to the index. :Git add % < +============================================================================== +GIT-CHERRY-PICK *git-cherry-pick* + +This command is to cherry pick commit from other branch. +> + :Git cherry-pick +< + ============================================================================== GIT-STASH *git-stash*