148 lines
		
	
	
		
			No EOL
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			No EOL
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
<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 it’s 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, let’s 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 everything’s fine I merge my changes, otherwise back to my
 | 
						||
edit/rebase/merge process until it’s 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 haven’t 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, 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 <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> |