Jean-Charles Quillet - Practical introduction to fugitive
Practical introduction to fugitive
Fugitive, the git wrapper so awesome, it should be illegal.<br>That’s at least what states the github page. And it is indeed<br>awesome and I’m glad it is not illegal. I do most of my work in vim and<br>fugitive is my go-to wrapper for git in vim.
Why would you want to use git inside vim in the first place ? The command line<br>interface is fine.
Well, most of my work consists in software development. I carefully craft my<br>commits to make them atomic and to keep the code history clean. My workflow<br>consists in reviewing every changes before staging and committing them. During<br>the review I often find myself editing the changes. Once there are changes they<br>need to be at least compiled and sometimes even tested.
With fugitive I can do this without quitting vim (who knowns how to do that<br>anyway ?). Here I’ll present most of the important features of fugitive and<br>how I use them.
Basics
git status is available with the command :Git. It opens a new window with<br>all the information returned by git status. Quite a few commands can be<br>started from this window, I will described the most important in the following<br>sections.
By default the arguments of the :Git commands if they are not handled by<br>fugitive itself are sent to the git program. For example, one can create<br>and checkout a new branch with :Git checkout -b bug-fix-1234 or fetch the<br>latest changes in the remote with :Git fetch.
Viewing current editing changes
Let’s say that I currently edit a file tracked by git. I want to see the<br>changes I made. I can see them in diff mode in a split view with:
:Gvdiffsplit for a vertical split diff view
:Ghdiffsplit for a horizontal split diff view
:Gdiffsplit for a vertical or horizontal split depending on the current<br>window ratio
Now I can browse and edit the changes. Every shortcuts from diff mode are of<br>course available here. I use mostly:
do to obtain the changes from the other window
dp to put the changes to the other window
Some other interesting commands when editing files tracked by git are:
:Gread to revert the local changes
:Gwrite to stage the file for the next commit
Change review and commit
Now I have done a bunch changes I want to commit. I can get the git status of<br>my working directory with :Git.
A window appears in an horizontal split showing usually three sections:
The list of untracked files
The list of modified files tracked by git in the section unstaged
The list of staged files
I can put the cursor on each of these files and toggle the staged/unstaged<br>state with the key -. Hitting X reverts a changed file for the version in<br>the repository.
Once I’m done I can hit:
cc to commit staged changes
ca to amend the latest commit
Then I’m presented a new buffer where I can write the commit message. Once<br>saved and closed the commit is added to the git database. That’s the most<br>basic workflow, it assumes that I’m happy with the changes I made which is<br>rarely the case.
Now before committing my changes, I want to review every single hunk to make<br>sure that they are all relevant for the commit I want to add.
I can put my cursor on an unstaged file and hit:
dv for a vertical split diff view
dh for a horizontal split diff view
dd for a vertical or horizontal split depending on the current window ratio
Then I can review my changes and make the appropriate modifications if needed.
Split views are very powerful. It is even possible to stage individual hunks<br>editing the version of the file in the index.
For example, let’s say I have changed a file. I open a vertical diff. On the<br>left I can see the version in the repository, on the right I have the version I<br>have edited. The buffer on the left is editable and represents what it is about<br>to be staged. Practically it means that being in my version on the right if I<br>go to the first change, I hit dp it will put my changes in the buffer on the<br>left. When I save this buffer, that change will be staged.
That’s great, that means that I don’t have to delete all temporary statement in<br>my code before committing them.
Browsing logs
Browsing logs can be achieved with the command :Git log. It opens a buffer<br>showing the commits in a reverse chronological order such as the latest<br>commits are located at the top.
Hitting the Enter key on any ref in the log opens the corresponding commit.<br>The commit buffer shows the commit message, its author and the changes it<br>contains as a diff. Well, viewing diff is not very helpful, we usually need to<br>see the changes in the context of a file. It is fortunately possible to do it<br>with fugitive.
This is how I like to do it:
:set foldmethod=syntax folds the diff under each modified filename. Great,<br>now I can see the list of files changed by the commit. zo zc open/close<br>the diff on each filename. But there is better.
O on a file opens a new tab with a diff view of the changes
:tabclose I’m back to the commit view and I can choose another...