251 lines
9.9 KiB
VimL
251 lines
9.9 KiB
VimL
call merginal#modulelib#makeModule(s:, 'branchList', 'immutableBranchList')
|
|
|
|
|
|
|
|
function! s:f.checkoutBranch() dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
call self.gitEcho('checkout', l:branch.handle)
|
|
call self.refresh()
|
|
call self.jumpToCurrentItem()
|
|
call merginal#reloadBuffers()
|
|
endfunction
|
|
call s:f.addCommand('checkoutBranch', [], 'MerginalCheckout', ['cc', 'C'], 'Checkout the branch under the cursor')
|
|
|
|
|
|
function! s:f.trackBranch(promptForName) dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
if !l:branch.isRemote
|
|
throw 'Can not track - branch is not remote'
|
|
endif
|
|
let l:newBranchName = l:branch.name
|
|
if a:promptForName
|
|
let l:newBranchName = input('Track `'.l:branch.handle.'` as: ', l:newBranchName)
|
|
if empty(l:newBranchName)
|
|
echo ' '
|
|
echom 'Branch tracking canceled by user.'
|
|
return
|
|
endif
|
|
endif
|
|
call self.gitEcho('checkout', '-b', l:newBranchName, '--track', l:branch.handle)
|
|
if !v:shell_error
|
|
call merginal#reloadBuffers()
|
|
endif
|
|
call self.refresh()
|
|
call self.jumpToCurrentItem()
|
|
endfunction
|
|
call s:f.addCommand('trackBranch', [0], 'MerginalTrack', 'ct', 'Track the remote branch under the cursor')
|
|
call s:f.addCommand('trackBranch', [1], 'MerginalTrackPrompt', 'cT', 'Track the remote branch under the cursor, prompting for a name')
|
|
|
|
function! s:f.promptToCreateNewBranch() dict abort
|
|
let l:newBranchName = input('Branch `'.self.repo.head().'` to: ')
|
|
if empty(l:newBranchName)
|
|
echo ' '
|
|
echom 'Branch creation canceled by user.'
|
|
return
|
|
endif
|
|
call self.gitEcho('checkout', '-b', l:newBranchName)
|
|
call merginal#reloadBuffers()
|
|
|
|
call self.refresh()
|
|
call self.jumpToCurrentItem()
|
|
endfunction
|
|
call s:f.addCommand('promptToCreateNewBranch', [], 'MerginalNewBranch', ['aa', 'A'], 'Create a new branch')
|
|
|
|
function! s:f.deleteBranchUnderCursor() dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
let l:answer = 0
|
|
if l:branch.isLocal
|
|
let l:answer = 'yes' == input('Delete branch `'.l:branch.handle.'`? (type "yes" to confirm) ')
|
|
elseif l:branch.isRemote
|
|
"Deleting remote branches needs a special warning
|
|
let l:answer = 'yes-remote' == input('Delete remote(!) branch `'.l:branch.handle.'`? (type "yes-remote" to confirm) ')
|
|
endif
|
|
if l:answer
|
|
if l:branch.isLocal
|
|
call self.gitEcho('branch', '-D', l:branch.handle)
|
|
else
|
|
call self.gitBang('push', l:branch.remote, '--delete', l:branch.name)
|
|
endif
|
|
call self.refresh()
|
|
else
|
|
echo ' '
|
|
echom 'Branch deletion canceled by user.'
|
|
endif
|
|
endfunction
|
|
call s:f.addCommand('deleteBranchUnderCursor', [], 'MerginalDelete', ['dd', 'D'], 'Delete the branch under the cursor')
|
|
|
|
function! s:f.mergeBranchUnderCursor(...) dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
let l:gitArgs = ['merge', '--no-commit', l:branch.handle]
|
|
call extend(l:gitArgs, a:000)
|
|
call call(self.gitEcho, l:gitArgs, self)
|
|
let l:confilctsBuffer = self.gotoSpecialModeBuffer()
|
|
if empty(l:confilctsBuffer)
|
|
call self.refresh()
|
|
else
|
|
if empty(l:confilctsBuffer.body)
|
|
"If we are in merge mode without actual conflicts, this means
|
|
"there are not conflicts and the user can be prompted to enter a
|
|
"merge message.
|
|
Gstatus
|
|
call merginal#closeMerginalBuffer()
|
|
endif
|
|
endif
|
|
call merginal#reloadBuffers()
|
|
endfunction
|
|
call s:f.addCommand('mergeBranchUnderCursor', [], 'MerginalMerge', ['mm', 'M'], 'Merge the branch under the cursor')
|
|
call s:f.addCommand('mergeBranchUnderCursor', ['--no-ff'], 'MerginalMergeNoFF', ['mn'], 'Merge the branch under the cursor using --no-ff')
|
|
|
|
function! s:f.mergeBranchUnderCursorUsingFugitive() dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
execute ':Gmerge '.l:branch.handle
|
|
endfunction
|
|
call s:f.addCommand('mergeBranchUnderCursorUsingFugitive', [], 'MerginalMergeUsingFugitive', ['mf'], 'Merge the branch under the cursor using fugitive')
|
|
|
|
function! s:f.rebaseBranchUnderCursor() dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
call self.gitEcho('rebase', l:branch.handle)
|
|
call merginal#reloadBuffers()
|
|
call self.gotoSpecialModeBuffer()
|
|
endfunction
|
|
call s:f.addCommand('rebaseBranchUnderCursor', [], 'MerginalRebase', 'rb', 'Rebase the branch under the cursor')
|
|
|
|
function! s:f.remoteActionForBranchUnderCursor(action, ...) dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
if l:branch.isLocal
|
|
let l:remotes = self.gitLines('remote')
|
|
if empty(l:remotes)
|
|
throw 'Can not '.a:action.' - no remotes defined'
|
|
endif
|
|
|
|
let l:chosenRemoteIndex=0
|
|
if 1 < len(l:remotes)
|
|
""Choose the correct text accoring to the action:
|
|
let l:prompt = 'Choose remote to '.a:action.' `'.l:branch.handle.'`'
|
|
if 'push' == a:action
|
|
let l:prompt .= ' to:'
|
|
else
|
|
let l:prompt .= ' from:'
|
|
endif
|
|
let l:chosenRemoteIndex = merginal#util#inputList(l:prompt, l:remotes, 'MORE')
|
|
"Check that the chosen index is in range
|
|
if l:chosenRemoteIndex <= 0 || len(l:remotes) < l:chosenRemoteIndex
|
|
return
|
|
endif
|
|
endif
|
|
|
|
let l:localBranchName = l:branch.name
|
|
let l:chosenRemote = l:remotes[l:chosenRemoteIndex]
|
|
|
|
let l:remoteBranchNameCanadidate = self.getRemoteBranchTrackedByLocalBranch(l:branch.name)
|
|
if !empty(l:remoteBranchNameCanadidate)
|
|
"Check that this is the same remote:
|
|
if l:remoteBranchNameCanadidate =~ '\V\^'.escape(l:chosenRemote, '\').'/'
|
|
"Remove the remote repository name
|
|
let l:remoteBranchName = l:remoteBranchNameCanadidate[len(l:chosenRemote) + 1:(-1)]
|
|
endif
|
|
endif
|
|
elseif l:branch.isRemote
|
|
let l:chosenRemote = l:branch.remote
|
|
if 'push' == a:action
|
|
"For push, we want to specify the remote branch name
|
|
let l:remoteBranchName = l:branch.name
|
|
|
|
let l:locals = self.getLocalBranchNamesThatTrackARemoteBranch(l:branch.handle)
|
|
|
|
if empty(l:locals)
|
|
let l:localBranchName = l:branch.name
|
|
elseif 1 == len(l:locals)
|
|
let l:localBranchName = l:locals[0]
|
|
else
|
|
let l:chosenLocalIndex = merginal#util#inputList('Choose local branch to push `'.l:branch.handle.'` from:', l:locals, 'MORE')
|
|
|
|
"Check that the chosen index is in range
|
|
if l:chosenLocalIndex <= 0 || len(l:locals) < l:chosenLocalIndex
|
|
return
|
|
endif
|
|
|
|
let l:localBranchName = l:locals[l:chosenLocalIndex]
|
|
endif
|
|
else
|
|
"For pull and fetch, git automatically resolves the tracking
|
|
"branch based on the remote branch.
|
|
let l:localBranchName = l:branch.name
|
|
endif
|
|
endif
|
|
|
|
if exists('l:remoteBranchName') && empty(l:remoteBranchName)
|
|
unlet l:remoteBranchName
|
|
endif
|
|
|
|
let l:gitCommandWithArgs = [a:action]
|
|
for l:flag in a:000
|
|
call add(l:gitCommandWithArgs, l:flag)
|
|
endfor
|
|
|
|
let l:reloadBuffers = 0
|
|
|
|
"Pulling requires the --no-commit flag
|
|
if 'pull' == a:action
|
|
if exists('l:remoteBranchName')
|
|
let l:remoteBranchNameAsPrefix = l:remoteBranchName
|
|
else
|
|
let l:remoteBranchNameAsPrefix = ''
|
|
endif
|
|
let l:remoteBranchEscapedName = l:remoteBranchNameAsPrefix.l:localBranchName
|
|
call add(l:gitCommandWithArgs, '--no-commit')
|
|
let l:reloadBuffers = 1
|
|
|
|
elseif 'push' == a:action
|
|
if exists('l:remoteBranchName')
|
|
let l:remoteBranchNameAsSuffix = ':'.l:remoteBranchName
|
|
else
|
|
let l:remoteBranchNameAsSuffix = ''
|
|
endif
|
|
let l:remoteBranchEscapedName = l:localBranchName.l:remoteBranchNameAsSuffix
|
|
|
|
elseif 'fetch' == a:action
|
|
if exists('l:remoteBranchName')
|
|
let l:targetBranchName = l:remoteBranchName
|
|
else
|
|
let l:targetBranchName = l:localBranchName
|
|
endif
|
|
let l:remoteBranchEscapedName = l:targetBranchName
|
|
endif
|
|
|
|
call add(l:gitCommandWithArgs, l:chosenRemote)
|
|
call add(l:gitCommandWithArgs, l:remoteBranchEscapedName)
|
|
|
|
call call(self.gitBang, l:gitCommandWithArgs, self)
|
|
"if l:reloadBuffers
|
|
"call merginal#reloadBuffers()
|
|
"endif
|
|
"call self.refresh()
|
|
endfunction
|
|
call s:f.addCommand('remoteActionForBranchUnderCursor', ['push'], 'MerginalPush', ['ps'], 'Prompt to choose a remote to push the branch under the cursor.')
|
|
call s:f.addCommand('remoteActionForBranchUnderCursor', ['push', '--force'], 'MerginalPushForce', ['pS'], 'Prompt to choose a remote to force push the branch under the cursor.')
|
|
call s:f.addCommand('remoteActionForBranchUnderCursor', ['pull'], 'MerginalPull', ['pl'], 'Prompt to choose a remote to pull the branch under the cursor.')
|
|
call s:f.addCommand('remoteActionForBranchUnderCursor', ['pull', '--rebase'], 'MerginalPullRebase', ['pr'], 'Prompt to choose a remote to pull-rebase the branch under the cursor.')
|
|
call s:f.addCommand('remoteActionForBranchUnderCursor', ['fetch'], 'MerginalFetch', ['pf'], 'Prompt to choose a remote to fetch the branch under the cursor.')
|
|
|
|
function! s:f.renameBranchUnderCursor() dict abort
|
|
let l:branch = self.branchDetails('.')
|
|
if !l:branch.isLocal
|
|
throw 'Can not rename - not a local branch'
|
|
endif
|
|
let l:newName = input('Rename `'.l:branch.handle.'` to: ', l:branch.name)
|
|
echo ' '
|
|
if empty(l:newName)
|
|
echom 'Branch rename canceled by user.'
|
|
return
|
|
elseif l:newName==l:branch.name
|
|
echom 'Branch name was not modified.'
|
|
return
|
|
endif
|
|
|
|
call self.gitEcho('branch', '-m', l:branch.name, l:newName)
|
|
call self.refresh()
|
|
endfunction
|
|
call s:f.addCommand('renameBranchUnderCursor', [], 'MerginalRenameBranch', 'rn', 'Prompt to rename the branch under the cursor.')
|
|
|