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:
master
onemaster
because other developers have
merged their branches before meThis 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 (C-x p v) |
magit-status (C-x g) |
Pull | vc-update (F, in my case) |
magit-pull (F p) |
New branch | vc-retrieve-tag (C-u B s) |
magit-branch (b c) |
Commit | vc-next-action (C-x v v) |
magit-commit (c c) |
Rebase | shell-command (M-!) + git rebase master |
magit-rebase (r p) |
Push | vc-push (P or C-u P) |
magit-push (P p) |
Stash | mu-vc-git-stash (z) |
magit-stash (z) |
Log | vc-print-root-log (L) |
magit-log (l l) |
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 every time 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. ↩