Some days ago I briefly wrote about my
willingness to give Emacs built-in VC system a try for real. For real means that
it’s easy to praise the beauties of vc-git
when working on personal projects
such as this blog, but is VC actually worth it on bigger projects where
different people commit and push regularly, rebasing is a habit, and merge
conflicts are unavoidable necessities?
A warning first. This article is not intended as a VC tutorial. It aims to be an example of how I use it or, to phrase it better, how I started to use it. As Mickey Petersen suggests in the “Exploring Emacs” section of his great Mastering Emacs book, if you want to know more about VC there is plenty of information right within our favourite text editor. Furthermore, Protesilaos Stavrou has a couple of nice videos on VC you might want to check out: Introduction to VC and Workflow with VC for Git.
Now, let’s break down a common workflow of mine:
- A new ticket is assigned to me
- I create a new branch for this ticket, starting from the
master
one - I code my thing
- I commit and push my code
- I file a new merge request ready to be reviewed
- The review may require changes to my code
- I may need to rebase my changes onto
master
because other developers have merged their branches before me - Merge conflicts may arise and need to be fixed
- I push my updated code ready to be reviewed again
- If everything’s fine I merge my changes, otherwise back to my edit/rebase/merge process until it’s properly done
- Meanwhile, it may happen that I need to stash my changes and quickly fix a higher priority bug
This more or less happens on a daily basis, so the interaction with Git (the only VCS I have used in the last ten years) must be smooth. On the other hand, Git-wise the above workflow is not that complicated. For instance, I rarely use features such as cherry-picking or bisecting.
On the surface, the main difference between Magit and VC is transient
. Magit
transient menus make all the operations I described above1 a breeze. From
checking out a branch to interactive rebasing, Magit requires few key strokes to
accommodate my needs. The blatant truth is that Magit wraps everything I want
from Git and much more in a user interface that just works.
VC, however, is not tightly coupled to Git, so it does not cover all of its many options. And yet I was able to manage my work projects with VC alternatives to Magit commands.
Operation | VC | Magit |
---|---|---|
Project status | project-vc-dir |
magit-status |
Pull | vc-update |
magit-pull |
New branch | vc-retrieve-tag |
magit-branch |
Commit | vc-next-action |
magit-commit |
Rebase | shell-command + git rebase master |
magit-rebase |
Push | vc-push |
magit-push |
Stash | mu-vc-git-stash |
magit-stash |
Log | vc-print-root-log |
magit-log |
VC has its own vc-git-stash
, vc-git-stash-pop
, and vc-git-stash-delete
commands, but instead of calling them via M-x
I devised
mu-vc-git-stash
and bound it to z
in vc-dir-mode-map
:
(defun mu-vc-git-stash (pop-or-delete)
"Create, pop, or delete Git stashes.
With no POP-OR-DELETE call `vc-git-stash'. With one prefix
argument call `vc-git-stash-pop'. With two prefix arguments call
`vc-git-stash-delete'."
(interactive "P" vc-dir-mode)
(cond ((= (prefix-numeric-value pop-or-delete) 4)
(call-interactively #'vc-git-stash-pop))
((= (prefix-numeric-value pop-or-delete) 16)
(call-interactively #'vc-git-stash-delete))
(t (call-interactively #'vc-git-stash))))
As you can see, C-u z
issues vc-git-stash-pop
while C-u C-u z
runs vc-git-stash-delete
.
One thing that Magit really shines at for me is interactive rebasing (r i
). I haven’t had the opportunity so far to check how I can handle this
with VC. I guess a combination of shell-command
and something I have yet to
discover would do, probably.
Anyway, I’ll keep using VC in the next days and report back if I manage to adapt
more of my Git workflows to it. I suspect Magit will outshine the humbler Emacs
built-in eventually, but who knows. Reading on the emacs-devel
mailing list
that some wild Emacs developers prefer VC to Magit seems to confirm that the
world is still full of surprises.
-
Well, only the ones related to Git of course. ↩︎