<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>nunogrl.com - git</title><link href="https://nunogrl.com/" rel="alternate"></link><link href="https://nunogrl.com/categories/git/atom.xml" rel="self"></link><id>https://nunogrl.com/</id><updated>2024-03-21T00:00:00+00:00</updated><entry><title>Enforcing GPG-Signed Commits in Git</title><link href="https://nunogrl.com/articles/enforcing-gpg-signed-commits-git/" rel="alternate"></link><published>2024-03-21T00:00:00+00:00</published><updated>2024-03-21T00:00:00+00:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2024-03-21:/articles/enforcing-gpg-signed-commits-git/</id><summary type="html">&lt;p class="first last"&gt;Learn how to enforce GPG-signed commits in Git to prevent commit impersonation and ensure code authenticity&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="problem-solution"&gt;
&lt;h2&gt;🚀 Problem &amp;amp; Solution&lt;/h2&gt;
&lt;div class="section" id="context-backstory"&gt;
&lt;h3&gt;📌 &lt;strong&gt;Context / Backstory&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In our collaborative development environment, we discovered that Git's flexibility allows commits under any name and email. This became a security concern when we realized that GitHub identifies users by email, not SSH keys.&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram--1710153734321077480"&gt;
sequenceDiagram
  participant Alice
  participant Bob
  participant GitHub

  Alice-&gt;&gt;GitHub: Commit signed with alice@example.com (GPG signed)
  GitHub-&gt;&gt;GitHub: Shows "Verified" commit from Alice

  Bob-&gt;&gt;GitHub: Commit using alice@example.com (no signature)
  GitHub-&gt;&gt;GitHub: Shows commit as from "Alice" (Unverified)

  Note over GitHub: GitHub matches commits by email, not by SSH or true identity.&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="the-problem"&gt;
&lt;h3&gt;⚠️ &lt;strong&gt;The Problem&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Anyone with repository access can spoof another contributor's identity&lt;/li&gt;
&lt;li&gt;Commit history could be manipulated without detection&lt;/li&gt;
&lt;li&gt;No cryptographic proof of commit authenticity&lt;/li&gt;
&lt;li&gt;GitHub's user identification relies solely on email addresses&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-solution"&gt;
&lt;h3&gt;💡 &lt;strong&gt;The Solution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We implemented mandatory GPG-signed commits, which:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Cryptographically verify commit authenticity&lt;/li&gt;
&lt;li&gt;Prevent identity spoofing&lt;/li&gt;
&lt;li&gt;Create traceable commit history&lt;/li&gt;
&lt;li&gt;Integrate with GitHub's verification system&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="who-this-helps"&gt;
&lt;h3&gt;👥 &lt;strong&gt;Who This Helps&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Security-conscious development teams&lt;/li&gt;
&lt;li&gt;Open-source project maintainers&lt;/li&gt;
&lt;li&gt;Regulated environments requiring audit trails&lt;/li&gt;
&lt;li&gt;Organizations needing verified commit history&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="technical-implementation"&gt;
&lt;h2&gt;⚙️ Technical Implementation&lt;/h2&gt;
&lt;p&gt;Let's visualize the GPG signing workflow:&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram-1440076246032696055"&gt;
flowchart LR
   C[Commit] --&gt;|Sign| G[GPG Key]
   G --&gt;|Verify| GH[GitHub]

   subgraph "Local System"
   C
   G
   end

   subgraph "Remote"
   GH
   end

   style GH fill:#f96,stroke:#333
   style G fill:#9f6,stroke:#333&lt;/div&gt;&lt;div class="section" id="setting-up-gpg-keys"&gt;
&lt;h3&gt;1️⃣ Setting Up GPG Keys&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Generate a new GPG key&lt;/span&gt;
gpg&lt;span class="w"&gt; &lt;/span&gt;--full-generate-key

&lt;span class="c1"&gt;# List your keys&lt;/span&gt;
gpg&lt;span class="w"&gt; &lt;/span&gt;--list-secret-keys&lt;span class="w"&gt; &lt;/span&gt;--keyid-format&lt;span class="o"&gt;=&lt;/span&gt;long
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="configuring-git"&gt;
&lt;h3&gt;2️⃣ Configuring Git&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;# &lt;/span&gt;Configure&lt;span class="w"&gt; &lt;/span&gt;Git&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;use&lt;span class="w"&gt; &lt;/span&gt;your&lt;span class="w"&gt; &lt;/span&gt;GPG&lt;span class="w"&gt; &lt;/span&gt;key
&lt;span class="gp"&gt;$ &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;user.signingkey&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;YOUR_KEY_ID&amp;gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;commit.gpgsign&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;gpg.program&lt;span class="w"&gt; &lt;/span&gt;gpg
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="github-integration"&gt;
&lt;h3&gt;3️⃣ GitHub Integration&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Export your public GPG key:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;gpg&lt;span class="w"&gt; &lt;/span&gt;--armor&lt;span class="w"&gt; &lt;/span&gt;--export&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;YOUR_KEY_ID&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;Add the key to your GitHub account settings&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="enforcing-signed-commits"&gt;
&lt;h3&gt;4️⃣ Enforcing Signed Commits&lt;/h3&gt;
&lt;p&gt;In GitHub repository settings:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Navigate to Settings &amp;gt; Branches&lt;/li&gt;
&lt;li&gt;Add branch protection rule&lt;/li&gt;
&lt;li&gt;Enable &amp;quot;Require signed commits&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting-debugging"&gt;
&lt;h2&gt;🛠️ Troubleshooting &amp;amp; Debugging&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;GPG signing fails&lt;/strong&gt;: Check &lt;cite&gt;gpg-agent&lt;/cite&gt; configuration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub doesn't show &amp;quot;Verified&amp;quot;&lt;/strong&gt;: Ensure GPG key is added to GitHub&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD issues&lt;/strong&gt;: Set up proper &lt;cite&gt;GNUPGHOME&lt;/cite&gt; environment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smart card/YubiKey&lt;/strong&gt;: Verify proper card reader access&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="optimizations-best-practices"&gt;
&lt;h2&gt;🔁 Optimizations &amp;amp; Best Practices&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Use GPG subkeys instead of master keys&lt;/li&gt;
&lt;li&gt;Implement regular key rotation&lt;/li&gt;
&lt;li&gt;Set up separate signing keys for different contexts&lt;/li&gt;
&lt;li&gt;Use environment isolation in CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Consider hardware security keys (YubiKey) for key storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion-takeaways"&gt;
&lt;h2&gt;✅ Conclusion &amp;amp; Takeaways&lt;/h2&gt;
&lt;p&gt;GPG-signed commits provide a robust security layer for Git workflows, ensuring:
- Verified commit authenticity
- Protected repository history
- Clear accountability
- Compliance with security best practices&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comments-next-steps"&gt;
&lt;h2&gt;💬 Comments &amp;amp; Next Steps&lt;/h2&gt;
&lt;p&gt;How do you handle commit verification in your organization? Share your experience or ask questions below!&lt;/p&gt;
&lt;/div&gt;
</content><category term="Infrastructure Security"></category><category term="git"></category><category term="gpg"></category><category term="security"></category><category term="devops"></category><category term="version-control"></category><category term="cryptography"></category><category term="authentication"></category></entry><entry><title>Password Store with GPG and Git</title><link href="https://nunogrl.com/articles/password-store-gpg-git/" rel="alternate"></link><published>2024-03-21T00:00:00+00:00</published><updated>2024-03-21T00:00:00+00:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2024-03-21:/articles/password-store-gpg-git/</id><summary type="html">&lt;p class="first last"&gt;Learn how to set up a secure, Git-based password management system using password-store and GPG encryption&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="problem-solution"&gt;
&lt;h2&gt;🚀 Problem &amp;amp; Solution&lt;/h2&gt;
&lt;div class="section" id="context-backstory"&gt;
&lt;h3&gt;📌 &lt;strong&gt;Context / Backstory&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We needed a secure way to manage passwords and secrets across multiple servers and team members. Commercial password managers were either too complex, costly, or required external services we wanted to avoid.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-problem"&gt;
&lt;h3&gt;⚠️ &lt;strong&gt;The Problem&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Managing secrets across systems and teams presents several challenges:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Keeping passwords secure yet accessible&lt;/li&gt;
&lt;li&gt;Tracking changes and maintaining history&lt;/li&gt;
&lt;li&gt;Sharing secrets securely between team members&lt;/li&gt;
&lt;li&gt;Avoiding dependency on external services&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-solution"&gt;
&lt;h3&gt;💡 &lt;strong&gt;The Solution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We implemented &lt;cite&gt;password-store&lt;/cite&gt; with GPG encryption and Git integration, providing:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Secure GPG encryption for all secrets&lt;/li&gt;
&lt;li&gt;Git-based version control and distribution&lt;/li&gt;
&lt;li&gt;Fully local operation with no external dependencies&lt;/li&gt;
&lt;li&gt;Command-line interface for automation&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="who-this-helps"&gt;
&lt;h3&gt;👥 &lt;strong&gt;Who This Helps&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;System administrators managing multiple servers&lt;/li&gt;
&lt;li&gt;DevOps teams handling shared credentials&lt;/li&gt;
&lt;li&gt;Security-conscious users wanting local password management&lt;/li&gt;
&lt;li&gt;Teams needing version-controlled secrets&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="technical-implementation"&gt;
&lt;h2&gt;⚙️ Technical Implementation&lt;/h2&gt;
&lt;p&gt;Let's visualize the password-store workflow:&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram--7232498932700614839"&gt;
flowchart LR
   P[Password] --&gt;|Encrypt| G[GPG]
   G --&gt;|Store| PS[password-store]
   PS --&gt;|Version| Git[Git Repository]
   Git --&gt;|Sync| T[Team Members]

   subgraph "Local System"
   P
   G
   PS
   end

   subgraph "Distribution"
   Git
   T
   end&lt;/div&gt;&lt;div class="section" id="generating-gpg-keys-in-batch-mode"&gt;
&lt;h3&gt;1️⃣ Generating GPG Keys in Batch Mode&lt;/h3&gt;
&lt;p&gt;For automated environments:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;gpg-server-key.conf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;span class="s"&gt;%no-protection&lt;/span&gt;
&lt;span class="s"&gt;Key-Type: default&lt;/span&gt;
&lt;span class="s"&gt;Subkey-Type: default&lt;/span&gt;
&lt;span class="s"&gt;Name-Real: Server Automation Key&lt;/span&gt;
&lt;span class="s"&gt;Name-Email: server@example.com&lt;/span&gt;
&lt;span class="s"&gt;Expire-Date: 0&lt;/span&gt;
&lt;span class="s"&gt;%commit&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;

gpg&lt;span class="w"&gt; &lt;/span&gt;--batch&lt;span class="w"&gt; &lt;/span&gt;--generate-key&lt;span class="w"&gt; &lt;/span&gt;gpg-server-key.conf
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="setting-up-the-environment"&gt;
&lt;h3&gt;2️⃣ Setting Up the Environment&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PASSWORD_STORE_GPG_OPTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;--armor&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;GNUPGHOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/password-store/.gnupg
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/password-store/store
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="initializing-the-password-store"&gt;
&lt;h3&gt;3️⃣ Initializing the Password Store&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$GNUPGHOME&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$GNUPGHOME&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
pass&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;server@example.com
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="git-integration"&gt;
&lt;h3&gt;4️⃣ Git Integration&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;init
git&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;.
git&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Initial password store&amp;quot;&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;remote&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;git@example.com:secrets.git
git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;main
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting-debugging"&gt;
&lt;h2&gt;🛠️ Troubleshooting &amp;amp; Debugging&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Ensure proper GPG key permissions (700 for directories, 600 for files)&lt;/li&gt;
&lt;li&gt;Verify GPG recipient when encryption fails&lt;/li&gt;
&lt;li&gt;Check Git remote access rights for sync issues&lt;/li&gt;
&lt;li&gt;Monitor Git conflicts when multiple users update simultaneously&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="optimizations-alternatives"&gt;
&lt;h2&gt;🔁 Optimizations &amp;amp; Alternatives&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Consider using GPG agent for improved key handling&lt;/li&gt;
&lt;li&gt;Implement Git hooks for pre-commit validation&lt;/li&gt;
&lt;li&gt;Use Git branches for testing password updates&lt;/li&gt;
&lt;li&gt;Consider &lt;cite&gt;pass&lt;/cite&gt; extensions for additional features&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion-takeaways"&gt;
&lt;h2&gt;✅ Conclusion &amp;amp; Takeaways&lt;/h2&gt;
&lt;p&gt;Using GPG with password-store provides a &lt;strong&gt;flexible, secure, and lightweight&lt;/strong&gt; method for managing secrets across machines. With Git integration, you get version history, team sharing, and distributed backup—&lt;strong&gt;without compromising security&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comments-next-steps"&gt;
&lt;h2&gt;💬 Comments &amp;amp; Next Steps&lt;/h2&gt;
&lt;p&gt;How do you manage shared secrets in your infrastructure? Share your experience or ask questions below!&lt;/p&gt;
&lt;/div&gt;
</content><category term="Infrastructure Security"></category><category term="gpg"></category><category term="git"></category><category term="password-management"></category><category term="security"></category><category term="encryption"></category><category term="devops"></category><category term="secrets-management"></category></entry><entry><title>Managing Multiple Git Configurations</title><link href="https://nunogrl.com/articles/git-config/" rel="alternate"></link><published>2020-08-31T10:00:00+01:00</published><updated>2020-08-31T10:00:00+01:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2020-08-31:/articles/git-config/</id><summary type="html">&lt;p class="first last"&gt;A guide to managing multiple Git configurations for different contexts (work, personal) using gitconfig&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;When working with Git across different contexts (personal projects, work repositories), it's crucial to maintain separate configurations to ensure commits are made with the correct identity and settings. This guide demonstrates how to set up and manage multiple Git configurations effectively.&lt;/p&gt;
&lt;object data="https://nunogrl.com/images/dotfiles/dotfiles.svg" style="width: 100%;" type="image/svg+xml"&gt;"My dotfiles"&lt;/object&gt;
&lt;div class="admonition warning"&gt;
&lt;p class="first admonition-title"&gt;Warning&lt;/p&gt;
&lt;p class="last"&gt;Using incorrect Git credentials can lead to commits being associated with the wrong identity,
which may expose personal email addresses in work repositories or vice versa.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="configuration-structure"&gt;
&lt;h2&gt;Configuration Structure&lt;/h2&gt;
&lt;div class="mermaid" id="mermaid-diagram-5689537300094488405"&gt;
flowchart TD
   A[~/.gitconfig] --&gt; B[~/.gitconfig-personal]
   A --&gt; C[~/.gitconfig-work]
   B --&gt; D[Personal Repos]
   C --&gt; E[Work Repos]&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="primary-configuration"&gt;
&lt;h2&gt;Primary Configuration&lt;/h2&gt;
&lt;p&gt;The main &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.gitconfig&lt;/span&gt;&lt;/tt&gt; file serves as the entry point for Git's configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/src/*&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/.gitconfig-work&lt;/span&gt;

&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/src/sandbox/*&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/.gitconfig-personal&lt;/span&gt;

&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/Documents/*&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/.gitconfig-personal&lt;/span&gt;

&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/src/&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/Documents/git-work-precommit&lt;/span&gt;

&lt;span class="k"&gt;[commit]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;gpgsign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="k"&gt;[alias]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;lg1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;log &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--graph &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--abbrev-commit &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--decorate &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--format=format:&amp;#39;%C(bold blue)%h%C(reset) - &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(bold green)(%ar)%C(reset) &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(white)%s%C(reset) %C(dim white)- &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%an%C(reset)%C(bold yellow)%d%C(reset)&amp;#39; &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--all&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;lg2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;log &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--graph &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--abbrev-commit &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--decorate &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--format=format:&amp;#39;%C(bold blue)%h%C(reset) - &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(bold cyan)%aD%C(reset) &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n&amp;#39;&amp;#39;&lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(white)%s%C(reset) %C(dim white)- %an%C(reset)&amp;#39; &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--all&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;lg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;!&amp;quot;git lg1&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;diffc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;diff --color-words=.&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;meld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;difftool --tool=meld -y&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;meldd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;difftool --dir-diff --tool=meld&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;meldbase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;!git meld $(git merge-base origin/master HEAD)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;!git fetch $1 $2 &amp;amp;&amp;amp; git checkout FETCH_HEAD &amp;amp;&amp;amp; git meldbase &amp;amp;&amp;amp; true&lt;/span&gt;

&lt;span class="k"&gt;[core]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;vim&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="personal-git-configuration"&gt;
&lt;h2&gt;Personal Git Configuration&lt;/h2&gt;
&lt;p&gt;Create &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.gitconfig-personal&lt;/span&gt;&lt;/tt&gt; for personal projects:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[user]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;Nuno Leitao&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;example@example.com&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;signingkey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;1234ABCD&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="work-git-configuration"&gt;
&lt;h2&gt;Work Git Configuration&lt;/h2&gt;
&lt;p&gt;Create &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.gitconfig-work&lt;/span&gt;&lt;/tt&gt; for work-related projects:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[user]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;Nuno Leitao&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;example@acme.com&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;signingkey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;1234ABCD&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="gpg-key-configuration"&gt;
&lt;h2&gt;GPG Key Configuration&lt;/h2&gt;
&lt;p&gt;The same GPG key can be used for both configurations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt; $ &lt;/span&gt;gpg&lt;span class="w"&gt; &lt;/span&gt;-K
&lt;span class="go"&gt; /home/nuno/.gnupg/pubring.kbx&lt;/span&gt;
&lt;span class="go"&gt; -----------------------------&lt;/span&gt;
&lt;span class="go"&gt; sec   rsa4096 2018-05-09 [SC] [expires: 2022-05-09]&lt;/span&gt;
&lt;span class="hll"&gt;&lt;span class="go"&gt;       123456789ABCDEFG56780000123456781234ABCD&lt;/span&gt;
&lt;/span&gt;&lt;span class="go"&gt; uid           [ultimate] Nuno Leitao &amp;lt;example@example.com&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt; uid           [ultimate] Nuno Leitao &amp;lt;example@acme.com&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt; uid           [ultimate] [jpeg image of size 10099]&lt;/span&gt;
&lt;span class="go"&gt; ssb   rsa4096 2018-05-09 [E] [expires: 2022-05-09]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The GPG key is associated with multiple email addresses, allowing it to sign
commits for both personal and work accounts.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="key-considerations"&gt;
&lt;h2&gt;Key Considerations&lt;/h2&gt;
&lt;div class="admonition tip"&gt;
&lt;p class="first admonition-title"&gt;Tip&lt;/p&gt;
&lt;ul class="last simple"&gt;
&lt;li&gt;Always verify the active Git configuration before starting work on a new repository&lt;/li&gt;
&lt;li&gt;Use &lt;tt class="docutils literal"&gt;git config &lt;span class="pre"&gt;--list&lt;/span&gt;&lt;/tt&gt; to check current settings&lt;/li&gt;
&lt;li&gt;Consider adding repository-specific configurations for special cases&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="common-issues"&gt;
&lt;h2&gt;Common Issues&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;strong&gt;Wrong Email in Commits&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you notice commits with incorrect email:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;--amend&lt;span class="w"&gt; &lt;/span&gt;--author&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Nuno Leitao &amp;lt;correct@email.com&amp;gt;&amp;quot;&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;--force&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Use with caution!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;strong&gt;Verifying Configuration&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Check active configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--list&lt;span class="w"&gt; &lt;/span&gt;--show-origin
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="further-reading"&gt;
&lt;h2&gt;Further Reading&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://git-scm.com/docs/git-config"&gt;Git Config Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://stackoverflow.com/questions/1057564/pretty-git-branch-graphs"&gt;Pretty Git Branch Graphs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://mikegerwitz.com/2012/05/a-git-horror-story-repository-integrity-with-signed-commits"&gt;A Git Horror Story: Repository Integrity with Signed Commits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Shell Script &amp; Setup Symphony"></category><category term="dotfiles"></category><category term="git"></category><category term="configuration"></category><category term="security"></category></entry></feed>