
Hey everyone!
Ever had one of those tech problems that just… won’t… quit? You know, the kind that makes you question your life choices, your career path, and whether you should just go live in a cabin in the woods? Yeah, I had one of those recently, and it involved my good old friend, Git, and a very stubborn GPG password prompt.
The Frustration Begins: “Password, Please… Again?”
It all started innocently enough. I made some changes to look cool in GitHub commits with Verified tag. I was happily coding away, making my usual small, frequent commits (because that’s what good developers do, right?). But every single time I typed git commit -S -m "My awesome changes", my terminal would just… stop. It would hang there, silently judging me, until I eventually realized it was waiting for a GPG password. Again. And again. And again.
Now, I’m all for security, but typing my GPG passphrase for every single commit on my own machine felt like a cruel and unusual punishment. I knew there had to be a way to cache it, to make it remember for at least a reasonable amount of time. I mean, what’s a gpg-agent for if not to be an agent of convenience?
The “Why” Behind the Madness (or, What I Thought Was Happening)
My initial hunch was that my gpg-agent wasn’t configured correctly. I remembered reading about default-cache-ttl and max-cache-ttl settings in gpg-agent.conf. The idea is that you tell GPG to hold onto your passphrase for a longer period, so you’re not constantly re-entering it.
So, my first thought was: “Okay, I need to find gpg-agent.conf and extend those cache times.”
The Troubleshooting Odyssey: A Deep Dive into My Dotfiles
This is where the fun (and the head-scratching) truly began.
- Finding
gpg-agent.conf: My first hurdle was that the file didn’t even exist in~/.gnupg/. No problem, I thought, I’ll just create it! So I did, adding the generousdefault-cache-ttl 34560000andmax-cache-ttl 34560000(that’s about 400 days, folks!). I also made sureuse-agentwas enabled ingpg.conf. - Restarting the Agent: After any GPG config change, you need to kill the
gpg-agentso it restarts with the new settings.gpgconf --kill gpg-agentbecame my new favorite command. - The Hanging
git commit: This is where things got weird. Instead of asking for a password,git commitjust… hung. No prompt, no error, just silence. This usually means the GPG agent is trying to show a prompt but can’t. - Enter
pinentryandGPG_TTY: My research pointed topinentry(the program that displays the password prompt) and theGPG_TTYenvironment variable. I installedpinentry-mac(because, well, Mac) and configuredgpg-agent.confto use it. I also addedexport GPG_TTY=$(tty)to my.zshrcto ensure the agent knew which terminal to use. - The
gpg2Error: After all that, I finally got an error message!error: cannot run gpg2: No such file or directory. Progress, right? This meant Git was explicitly looking forgpg2, and it couldn’t find it. My first instinct was to tell Git to usegpg2globally:git config --global gpg.program gpg2. - The
which gpg2Mystery: But thenwhich gpg2returned “gpg2 not found,” even thoughbrew install gnupgsaid it was already installed! This was the most confusing part. Homebrew said it was there, but my shell couldn’t find it. - The
PATHProblem: This led me down the rabbit hole of myPATHenvironment variable. It turned out that whilegnupgwas installed by Homebrew, the directory where Homebrew puts its executables (/opt/homebrew/bin) wasn’t correctly prioritized in myPATH. Other tools likepyenvandbunwere messing with it. The fix involved ensuringeval "$(/opt/homebrew/bin/brew shellenv)"was placed early in my.zshrc. - The Final Revelation: It’s Just
gpg, Notgpg2! After all thatPATHdebugging, I finally ranls -l /opt/homebrew/Cellar/gnupg/2.4.8/bin/and discovered the truth: my Homebrew installation of GnuPG 2.4.8 simply named its main executablegpg, notgpg2! Thegpg2error was literally because the file didn’t exist.
My Learnings (and Your Takeaways!)
This whole ordeal was a masterclass in debugging, and here’s what I took away:
- Read Error Messages Carefully (and Literally!): “No such file or directory” meant exactly that. I was trying to make Git use a program that didn’t exist by that name on my system.
- Understand Your
PATH: ThePATHenvironment variable is fundamental to how your shell finds executables. Ifwhichcan’t find something, it’s almost always aPATHissue. - Homebrew’s
brew shellenvis Your Friend: For macOS users,eval "$(/opt/homebrew/bin/brew shellenv)"placed early in your shell config is the most reliable way to ensure Homebrew’s binaries are found. - GnuPG Naming Conventions: Be aware that
gpgandgpg2can refer to the same underlying GnuPG 2.x executable, or one might be a symlink to the other, or one might not exist at all depending on your installation. Always check what’s actually there! - The
gpg-agentis Key: For passphrase caching, thegpg-agentand itsgpg-agent.confsettings are paramount. pinentryis the Prompt: If you’re not getting a password prompt, it’s likely apinentryissue (either not installed, not configured, orGPG_TTYis wrong).
Finally, after changing git config --global gpg.program gpg and ensuring my PATH was clean, I killed the gpg-agent one last time. The next git commit prompted me for my password, and then… glorious silence! No more prompts for days.
It was a journey, but a valuable one. Hopefully, sharing my pain (and solution!) helps someone else avoid a similar headache. Happy committing!