<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Abreu Mieses</title>
    <description>The latest articles on DEV Community by James Abreu Mieses (@implosion).</description>
    <link>https://dev.to/implosion</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2678481%2F47e80cf0-c9bb-417e-a57d-b7728109817e.png</url>
      <title>DEV Community: James Abreu Mieses</title>
      <link>https://dev.to/implosion</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/implosion"/>
    <language>en</language>
    <item>
      <title>Improving Your Productivity With Git Worktrees</title>
      <dc:creator>James Abreu Mieses</dc:creator>
      <pubDate>Sat, 11 Jan 2025 18:46:19 +0000</pubDate>
      <link>https://dev.to/implosion/improving-your-productivity-with-git-worktrees-1k54</link>
      <guid>https://dev.to/implosion/improving-your-productivity-with-git-worktrees-1k54</guid>
      <description>&lt;p&gt;Working on applications and services with many moving parts is hard and time consuming: you might be responsible for long running test suits. You might be responsible of peer reviewing multiple Merge Requests at a time or even, you might be responsible of fixing a critical bug found in production that can't wait. These are all scenarios we have faced before and have used &lt;code&gt;git-switch&lt;/code&gt; to help move between branches. However, this is very limiting since you can only work on one branch at the time and your dev environment will have to change across branches. There is a better way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Worktree
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;git-worktree&lt;/code&gt; is a way to work on multiple branches at a time in a non-blocking pattern. We can checkout multiple branches and we can open each on it's on Integrated Development Environment (IDE) or Code Editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Checkout a new branch based on the current branch&lt;/span&gt;
git worktree add /path/to/new-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Way to create a new branch where branch and dir name are different&lt;/span&gt;
git worktree add /path/to/branch &lt;span class="nt"&gt;-b&lt;/span&gt; my-new-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# To work on an exisiting branch&lt;/span&gt;
git worktree add /path/to/branch existing-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Deliting a worktree&lt;/span&gt;
git worktree remove /path/to/branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git worktrees are synced to the main repo (where the checkout) happened which means we can manage them from there. Further, object references (refs) are also shared across the main worktree (repo where the checkout happened) and other worktrees. &lt;/p&gt;

&lt;h3&gt;
  
  
  Important
&lt;/h3&gt;

&lt;p&gt;Git manages the worktrees for us. This means that it maintains metadata to remove and cleanout stale worktrees. To avoid this, we have to use the &lt;code&gt;lock&lt;/code&gt; feature of worktree and/or configure the &lt;code&gt;git-gc&lt;/code&gt; (Garbage Collection) utility.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git worktree add /path/to/new-branch &lt;span class="nt"&gt;--lock&lt;/span&gt;

&lt;span class="c"&gt;# Or&lt;/span&gt;

git worktree lock &lt;span class="nt"&gt;--reason&lt;/span&gt; &lt;span class="s2"&gt;"I am not done with you"&lt;/span&gt; /path/to/new-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, now that we know how to create a new worktree, how can worktree help us where switch can't?&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch VS Worktree
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Checkout Process
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;git-switch
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git-checkout&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Committing before moving to another branch"&lt;/span&gt;
&lt;span class="c"&gt;# git push -u origin current-branch&lt;/span&gt;

&lt;span class="c"&gt;# Checkout a new branch based on main&lt;/span&gt;
git switch &lt;span class="nt"&gt;-c&lt;/span&gt; hotfix/broken-link main

&lt;span class="c"&gt;# Or&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git stash
git switch &lt;span class="nt"&gt;-c&lt;/span&gt; hotfix/broken-link main

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;git-worktree
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# By default, worktrees checkout the new branch from the main branch unless specifid otherwise.&lt;/span&gt;
git worktree add ../urgent-fix &lt;span class="nt"&gt;--reason&lt;/span&gt; &lt;span class="s2"&gt;"To fix a broken link in our UI"&lt;/span&gt; &lt;span class="nt"&gt;--checkout&lt;/span&gt; hotfix/broken-link 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can reduce the amount of time we take to get started on the new branch as we don't have to stage or commit anything. &lt;/p&gt;

&lt;h2&gt;
  
  
  Non-Blocked Workflows.
&lt;/h2&gt;

&lt;p&gt;Because you can only checkout one branch at a time with &lt;code&gt;git-switch&lt;/code&gt;, if you are running for example, a deployment , you can't make changes to the source code without risking introducing syntax errors that the deployment command line interface (CLI) will pick up and crash the deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git worktree add ../deployment-test &lt;span class="nt"&gt;--reason&lt;/span&gt; &lt;span class="s2"&gt;"To test my deployment for failure"&lt;/span&gt; &lt;span class="nt"&gt;--checkout&lt;/span&gt; my-working-branch

make &lt;span class="nt"&gt;-f&lt;/span&gt; ../deployment-test/Makefile

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using worktrees allows us to delegate the deployment testing to another worktree with our working branch checked out while we can continue to work on the current copy we are on in the main worktree.&lt;/p&gt;

&lt;h1&gt;
  
  
  Quick Experimentation
&lt;/h1&gt;

&lt;p&gt;Using &lt;code&gt;git-switch&lt;/code&gt; to set an experimentation branch can be time consuming and expensive as mentioned before. Additionally, if we are experimenting with new packages and configurations, these are things that are not usually tracked and are added to the &lt;code&gt;.gitignore&lt;/code&gt; file to avoid accidental commits. To avoid these issues, we can leverage &lt;code&gt;git-worktree&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Checkout a throw-away branch for a quick experiment&lt;/span&gt;
git worktree add ../my-experiment &lt;span class="nt"&gt;--checkout&lt;/span&gt; working-branch &lt;span class="nt"&gt;--detach&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove the branch when done &lt;/span&gt;
git worktree remove ../my-experiment

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As developers, we are always moving fast and living dangerously. It is always a positive when we can find ways to help us continue to do so with reduced risks. Git worktrees is a great way to speed up your workflow and experiment in a non-blocking, non-destructive manner. &lt;/p&gt;

&lt;p&gt;Hope you found this guide useful and as awesome as I did.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-worktree" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-worktree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ftp.gnu.org/old-gnu/Manuals/make-3.80/html_node/make.html" rel="noopener noreferrer"&gt;https://ftp.gnu.org/old-gnu/Manuals/make-3.80/html_node/make.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-config#Documentation/git-config.txt-gcworktreePruneExpire" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-config#Documentation/git-config.txt-gcworktreePruneExpire&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>Using git Conditionals to Manage Your Git Identities</title>
      <dc:creator>James Abreu Mieses</dc:creator>
      <pubDate>Thu, 09 Jan 2025 03:58:26 +0000</pubDate>
      <link>https://dev.to/implosion/using-git-conditionals-to-manage-your-git-identities-3664</link>
      <guid>https://dev.to/implosion/using-git-conditionals-to-manage-your-git-identities-3664</guid>
      <description>&lt;p&gt;As developers, we have to maintain multiple credentials to authenticate and sign our code changes before pushing to remote. This is used to be simple: just use the https endpoint offered by the remote git repository provider, authenticate with our email and password and call it a day. However, now a-day, git remote providers are moving to enforcing SSH authentication which provides a host of benefits out of the scope of discussion for this blog. On this one, we are focusing on how can we leverage &lt;code&gt;git&lt;/code&gt; &lt;code&gt;conditionals&lt;/code&gt; and &lt;code&gt;ssh&lt;/code&gt; to manage our credentials.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Old
&lt;/h2&gt;

&lt;p&gt;Image you have created your public and private key pair and configured the &lt;code&gt;~/.ssh/config&lt;/code&gt;  file to map your private key to the &lt;code&gt;ssh&lt;/code&gt; host of your git provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
Host ssh.gitlab.env-1

  PreferredAuthentications publickey
  IdentityFile ~/.ssh/internal-gitlab
  AddKeysToAgent &lt;span class="nb"&gt;yes&lt;/span&gt;
  UseKeychain &lt;span class="nb"&gt;yes&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then move to configuring our &lt;code&gt;~/gitconfig&lt;/code&gt; file to tell git to use &lt;code&gt;SSH&lt;/code&gt; as the signing key and authentication key for our repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="o"&gt;[&lt;/span&gt;gpg]
  format &lt;span class="o"&gt;=&lt;/span&gt; ssh
  
&lt;span class="o"&gt;[&lt;/span&gt;user]

  name &lt;span class="o"&gt;=&lt;/span&gt; James S. Abreu Mieses
  email &lt;span class="o"&gt;=&lt;/span&gt; email@email.com
  signingkey &lt;span class="o"&gt;=&lt;/span&gt; /Users/abreuj/.ssh/internal-gitlab.pub

&lt;span class="o"&gt;[&lt;/span&gt;core]

  editor &lt;span class="o"&gt;=&lt;/span&gt; neovim
  excludesfile &lt;span class="o"&gt;=&lt;/span&gt; /Users/abreuj/.gitignore_global

&lt;span class="o"&gt;[&lt;/span&gt;commit]

  gpgsign &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
  template &lt;span class="o"&gt;=&lt;/span&gt; /Users/abreuj/.stCommitMsg

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks great if we are simply pushing to a single repository and nothing else. With this configuration we will be able to both authenticate and sign our commits.&lt;/p&gt;

&lt;p&gt;But, what if we have a second repo to push to? Or maybe a third? How would we manage this? We would have to repeat the steps of generating our key pairs and add the private key and ssh domain to the &lt;code&gt;~/.ssh/config&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Host ssh.gitlab.env-1

  PreferredAuthentications publickey
  IdentityFile ~/.ssh/internal-gitlab
  AddKeysToAgent yes
  UseKeychain yes



Host ssh.github.com

  PreferredAuthentications publickey
  IdentityFile ~/.ssh/personal-github
  AddKeysToAgent yes
  UseKeychain yes

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy. Now, You will be able to push to the new repo under the &lt;code&gt;ssh.github.com&lt;/code&gt; host. Which is great for authentication. For commit signatures on the other hand, this will not work because we have already configured our git identity to use &lt;code&gt;internal-gitlab.pub&lt;/code&gt; for commit signatures. So the commits pushed to the &lt;code&gt;github&lt;/code&gt; repo will end up being &lt;code&gt;unverified&lt;/code&gt; which means the signature is not trusted. &lt;/p&gt;

&lt;p&gt;The initial option here is to again configure the &lt;code&gt;~/.gitconfig&lt;/code&gt; file to use the &lt;code&gt;personal-github.pub&lt;/code&gt; private key for signatures. This will work, but when we go back to pushing changes to the &lt;code&gt;gitlab&lt;/code&gt; repo, we will go back to having the commit signature not be &lt;code&gt;verified&lt;/code&gt; by the provider. So now what?&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Git Conditional
&lt;/h2&gt;

&lt;p&gt;To solve this issue of having to manually configure our git identity to use the correct public key to sign our commits, we can use git' &lt;code&gt;includeIf&lt;/code&gt; to load an identity based on some condition. Here is an example using our initial config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;gpg]
  format &lt;span class="o"&gt;=&lt;/span&gt; ssh
  
&lt;span class="o"&gt;[&lt;/span&gt;user]

  name &lt;span class="o"&gt;=&lt;/span&gt; James S. Abreu Mieses
  email &lt;span class="o"&gt;=&lt;/span&gt; email@email.com
  signingkey &lt;span class="o"&gt;=&lt;/span&gt; /Users/abreuj/.ssh/internal-gitlab.pub

&lt;span class="o"&gt;[&lt;/span&gt;core]

  editor &lt;span class="o"&gt;=&lt;/span&gt; neovim
  excludesfile &lt;span class="o"&gt;=&lt;/span&gt; /Users/abreuj/.gitignore_global

&lt;span class="o"&gt;[&lt;/span&gt;commit]

  gpgsign &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
  template &lt;span class="o"&gt;=&lt;/span&gt; /Users/abreuj/.stCommitMsg

&lt;span class="o"&gt;[&lt;/span&gt;includeIf &lt;span class="s2"&gt;"hasconfig:remote.*.url:git@github.com:*/**"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/path/to/github-iden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the new config, we are including the git &lt;code&gt;includeIf&lt;/code&gt; telling git to load the &lt;code&gt;github-iden&lt;/code&gt; config if the repository we are in has a remote url under the &lt;code&gt;ssh.github.com&lt;/code&gt; host. If this is not the case, continue using the default identity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;user]

    &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;James S. Abreu Mieses
    &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;another@another-email.com
    &lt;span class="nv"&gt;signingkey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/Users/abreuj/.ssh/personal-gitlab.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For here on, we will be able to authenticate and sign our commits using the correct credentials for the repository we are trying to deploy. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Git conditionals are a game changer  when it comes to automating identity selection for a give repository. Hopefully you find this article and git conditions as awesome as I did. &lt;/p&gt;

</description>
      <category>git</category>
      <category>security</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
