emacs/var/elfeed/db/data/e3/e3e120fd9625e59cb10fffb1d2eadf04a089d0a5
2022-01-03 12:49:32 -06:00

148 lines
8.8 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<p><a href="https://www.manueluberti.eu/emacs/2021/11/21/eglot-and-vc/">Some days ago</a> I
briefly wrote about my willingness to give Emacs built-in VC system a try for
real. For real means that its easy to praise the beauties of <code class="language-plaintext highlighter-rouge">vc-git</code> 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?</p>
<p>A warning first. This article is not intended as a VC tutorial. It aims to be an
example of how <em>I</em> use it or, to phrase it better, how I <em>started</em> to use it. As
<a href="https://www.masteringemacs.org/">Mickey Petersen</a> suggests in the “Exploring
Emacs” section of his great <em>Mastering Emacs</em> 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: <a href="https://www.youtube.com/watch?v=SQ3Beqn2CEc">Introduction to
VC</a> and <a href="https://www.youtube.com/watch?v=0YlYX_UjH5Q">Workflow with VC for
Git</a>.</p>
<p>Now, lets break down a common workflow of mine:</p>
<ul>
<li>A new ticket is assigned to me</li>
<li>I create a new branch for this ticket, starting from the <code class="language-plaintext highlighter-rouge">master</code> one</li>
<li>I code my thing</li>
<li>I commit and push my code</li>
<li>I file a new merge request ready to be reviewed</li>
<li>The review may require changes to my code</li>
<li>I may need to rebase my changes onto <code class="language-plaintext highlighter-rouge">master</code> because other developers have
merged their branches before me</li>
<li>Merge conflicts may arise and need to be fixed</li>
<li>I push my updated code ready to be reviewed again</li>
<li>If everythings fine I merge my changes, otherwise back to my
edit/rebase/merge process until its properly done</li>
<li>Meanwhile, it may happen that I need to stash my changes and quickly fix a
higher priority bug</li>
</ul>
<p>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.</p>
<p>On the surface, the main difference between Magit and VC is <code class="language-plaintext highlighter-rouge">transient</code>. Magit
transient menus make all the operations I described above<sup id="fnref:1"><a class="footnote" href="https://www.manueluberti.eu/feed#fn:1" rel="footnote">1</a></sup> 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.</p>
<p>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.</p>
<table>
<thead>
<tr>
<th>Operation</th>
<th>VC</th>
<th>Magit</th>
</tr>
</thead>
<tbody>
<tr>
<td>Project status</td>
<td><code class="language-plaintext highlighter-rouge">project-vc-dir</code> (<kbd>C-x p v</kbd>)</td>
<td><code class="language-plaintext highlighter-rouge">magit-status</code> (<kbd>C-x g</kbd>)</td>
</tr>
<tr>
<td>Pull</td>
<td><code class="language-plaintext highlighter-rouge">vc-update</code> (<kbd>F</kbd>, in my case)</td>
<td><code class="language-plaintext highlighter-rouge">magit-pull</code> (<kbd>F p</kbd>)</td>
</tr>
<tr>
<td>New branch</td>
<td><code class="language-plaintext highlighter-rouge">vc-retrieve-tag</code> (<kbd>C-u B s</kbd>)</td>
<td><code class="language-plaintext highlighter-rouge">magit-branch</code> (<kbd>b c</kbd>)</td>
</tr>
<tr>
<td>Commit</td>
<td><code class="language-plaintext highlighter-rouge">vc-next-action</code> (<kbd>C-x v v</kbd>)</td>
<td><code class="language-plaintext highlighter-rouge">magit-commit</code> (<kbd>c c</kbd>)</td>
</tr>
<tr>
<td>Rebase</td>
<td><code class="language-plaintext highlighter-rouge">shell-command</code> (<kbd>M-!</kbd>) + <code class="language-plaintext highlighter-rouge">git rebase master</code></td>
<td><code class="language-plaintext highlighter-rouge">magit-rebase</code> (<kbd>r p</kbd>)</td>
</tr>
<tr>
<td>Push</td>
<td><code class="language-plaintext highlighter-rouge">vc-push</code> (<kbd>P</kbd> or <kbd>C-u P</kbd>)</td>
<td><code class="language-plaintext highlighter-rouge">magit-push</code> (<kbd>P p</kbd>)</td>
</tr>
<tr>
<td>Stash</td>
<td><code class="language-plaintext highlighter-rouge">mu-vc-git-stash</code> (<kbd>z</kbd>)</td>
<td><code class="language-plaintext highlighter-rouge">magit-stash</code> (<kbd>z</kbd>)</td>
</tr>
<tr>
<td>Log</td>
<td><code class="language-plaintext highlighter-rouge">vc-print-root-log</code> (<kbd>L</kbd>)</td>
<td><code class="language-plaintext highlighter-rouge">magit-log</code> (<kbd>l l</kbd>)</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>
<p>VC has its own <code class="language-plaintext highlighter-rouge">vc-git-stash</code>, <code class="language-plaintext highlighter-rouge">vc-git-stash-pop</code>, and <code class="language-plaintext highlighter-rouge">vc-git-stash-delete</code>
commands, but instead of calling them via <kbd>M-x</kbd> every time I devised
<code class="language-plaintext highlighter-rouge">mu-vc-git-stash</code> and bound it to <kbd>z</kbd> in <code class="language-plaintext highlighter-rouge">vc-dir-mode-map</code>:</p>
<div class="language-emacs-lisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">mu-vc-git-stash</span> <span class="p">(</span><span class="nv">pop-or-delete</span><span class="p">)</span>
<span class="s">"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'."</span>
<span class="p">(</span><span class="nv">interactive</span> <span class="s">"P"</span> <span class="nv">vc-dir-mode</span><span class="p">)</span>
<span class="p">(</span><span class="nb">cond</span> <span class="p">((</span><span class="nb">=</span> <span class="p">(</span><span class="nv">prefix-numeric-value</span> <span class="nv">pop-or-delete</span><span class="p">)</span> <span class="mi">4</span><span class="p">)</span>
<span class="p">(</span><span class="nv">call-interactively</span> <span class="nf">#'</span><span class="nv">vc-git-stash-pop</span><span class="p">))</span>
<span class="p">((</span><span class="nb">=</span> <span class="p">(</span><span class="nv">prefix-numeric-value</span> <span class="nv">pop-or-delete</span><span class="p">)</span> <span class="mi">16</span><span class="p">)</span>
<span class="p">(</span><span class="nv">call-interactively</span> <span class="nf">#'</span><span class="nv">vc-git-stash-delete</span><span class="p">))</span>
<span class="p">(</span><span class="no">t</span> <span class="p">(</span><span class="nv">call-interactively</span> <span class="nf">#'</span><span class="nv">vc-git-stash</span><span class="p">))))</span>
</code></pre></div></div>
<p>As you can see, <kbd>C-u z</kbd> issues <code class="language-plaintext highlighter-rouge">vc-git-stash-pop</code> while <kbd>C-u C-u
z</kbd> runs <code class="language-plaintext highlighter-rouge">vc-git-stash-delete</code>.</p>
<p>One thing that Magit really shines at for me is interactive rebasing (<kbd>r
i</kbd>). I havent had the opportunity so far to check how I can handle this
with VC. I guess a combination of <code class="language-plaintext highlighter-rouge">shell-command</code> and something I have yet to
discover would do, probably.</p>
<p>Anyway, Ill 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 <code class="language-plaintext highlighter-rouge">emacs-devel</code> mailing list
that some wild Emacs developers prefer VC to Magit seems to confirm that the
world is still full of surprises.</p>
<h3 id="notes">Notes</h3>
<div class="footnotes">
<ol>
<li id="fn:1">
<p>Well, only the ones related to Git of course. <a class="reversefootnote" href="https://www.manueluberti.eu/feed#fnref:1">↩</a></p>
</li>
</ol>
</div>