30

Right now I'm using fugitive to manage almost everything git related, but I can't find a good workflow to quickly visualize and switch between available branches.

I can do :Git checkout <branch-name>, the problem is that it autocompletes both file names and branches, and I'd prefer a branch list.

7 Answers 7

20

To summarize the answers, here are the ways to accomplish this:

Vanilla Terminal Vim in a shell with job control

Press CTRL-Z in normal mode will drop you back in to the shell and suspend Vim. After executing your git checkout [branchname], run the fg builtin to return to the suspended Vim which will also force Vim to refresh (:help timestamp).

It is also noteworthy that the :checktime command in Vim will perform a buffer scan to see what filesystem changes there have been. See :help :checktime for more info.

In vim 8, you can use :terminal to start a shell, or :terminal git checkout [branchname] to run one command. Neither will automatically :checktime.

Vanilla GUI Vim

Some gvim implementations will have :shell support which will open a shell inside of Vim using a dumb terminal. However it may be easier to just type:

:!git checkout [branchname]

This will execute the command without having to open a new shell prompt. (This option is also usable in the terminal Vim).

vim-fugitive

is a plugin that allows you to use Git from within Vim. The command would be:

:Git checkout [branchname]

vim-merginal

vim-merginal is a plugin that uses and provides a user friendly-ish interface.

  1. Type :Merginal.
  2. Move cursor to the branch you want.
  3. Type cc to check out that branch.
3
  • 2
    Awesome answer. vim-merginal is what I was looking for. Dec 23, 2015 at 20:09
  • 2
    I like the ctrl-z because it auto loads the files. Co-workers like to have a tmux window for the command line and one for vim but when they do a checkout or merge when they return to vim they have to go to each open file and :e! each time. (:bufdo e) which is a pain to remember. Instead it is easier to ctrl-z then when fg happens Vim performs the :e auto-magically.
    – Sukima
    Nov 25, 2016 at 17:25
  • I Another nice fugitive extension you could add to the list: github.com/sodapopcan/vim-twiggy Mar 16, 2018 at 19:00
13

Use the vim-merginal plugin (fugitive extension). It offers interactive TUI for:

  • Viewing the list of branches
  • Checking out branches from that list
  • Creating new branches
  • Deleting branches
  • Merging branches
  • Rebasing branches
  • Solving merge conflicts
  • Interacting with remotes(pulling, pushing, fetching, tracking)
  • Diffing against other branches
  • Renaming branches
  • Viewing git history for branches

enter image description here

8

You should embrace your terminal. If you use CTRL-Z, it will background Vim (or whichever process you are currently running), then you can run any commands you want, the fg to bring the process back to the foreground:

<CTRL-Z>
git checkout <tab>
fg
3
  • 3
    ... and when using GVim?
    – muru
    Dec 23, 2015 at 5:30
  • 2
    :shell is the way to go or alt tabbing in to your other favorite terminal emulator Dec 23, 2015 at 5:32
  • 2
    I always like !git checkout [branchname] Dec 23, 2015 at 18:46
7

The fugitive Git checkout <branch> has a downside that it doesn't autocomplete the branch name. Using fzf.vim I've created this command:

function! s:changebranch(branch) 
    execute 'Git checkout' . a:branch
    call feedkeys("i")
endfunction

command! -bang Gbranch call fzf#run({
            \ 'source': 'git branch -a --no-color | grep -v "^\* " ', 
            \ 'sink': function('s:changebranch')
            \ })

hope you find it useful

5

Ever since this commit in Jul 2019, this has been possible using Git fugitive only.

Type :G branch will open a split buffer with all the branches in a list. Place your cursor on the branch and press coo to checkout the branch.

From :h fugitive_co

Checkout/branch mappings ~

coo                     Check out the commit under the cursor.

cb<Space>               Populate command line with ":G branch ".

co<Space>               Populate command line with ":G checkout ".

cb?                     Show this help.
co?
3

The answer provided by @kubek2k is so phenomenal. That solution is better than I could have imagined and implemented in in less lines of code that I could have imaged. It opened the door to help me understand the powerful personalization use of 'fzf'.

I have slightly modified it to additionally provide:

  1. Makes use of fugitive to get the refs instead of the command line, (better support for windows)
  2. List tags along with branches

Here is the slight modification:

function! s:gitCheckoutRef(ref) 
    execute('Git checkout ' . a:ref)
    " call feedkeys("i")
endfunction
function! s:gitListRefs()
   let l:refs = execute("Git for-each-ref --format='\\%(refname:short)'")
   return split(l:refs,'\r\n*')[1:] "jump past the first line which is the git command
endfunction
command! -bang Gbranch call fzf#run({ 'source': s:gitListRefs(), 'sink': function('s:gitCheckoutRef'), 'dir':expand('%:p:h') })
1
  • That sounds like a nice addition. However this doesn't work for me (no results are shown after :Gbranch) whereas kubek2k solution does work. Mar 7, 2020 at 22:57
1

I found this FZF plugin that adds a GBranches command to browse your repo.

https://github.com/stsewd/fzf-checkout.vim

Edit:

I'm now using https://github.com/nvim-telescope/telescope.nvim to switch git branches: :Telescope git_branches<CR>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.