I hit two Git papercuts back to back this week, and I suspect I’m not the only one. The first cost me ten minutes of staring at a button that did nothing. The second has cost me, cumulatively, hours across every machine I own.
Here they are, with the fixes.
Papercut 1: “Publish Branch” does nothing
I had a fresh folder, git init done, a GitHub repo created, origin pointing at it. In VS Code’s Source Control panel I clicked Publish Branch โ and nothing happened. No error, no dialog, no push.
The clue was in git status:
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
There was nothing to publish. The folder was genuinely empty โ not a single file.
Here’s the thing worth internalising: in Git, a branch is a pointer to a commit. Until you make your first commit, main doesn’t really exist. HEAD points at a branch name that has nothing behind it. When VS Code offers to publish the branch, there’s no branch object to send, and it quietly declines to do anything useful.
You can confirm the remote is fine while the branch is not:
git ls-remote origin
If that returns nothing but exits cleanly, the remote exists, is reachable, and is simply empty. Good news โ your problem is local.
The fix: make one commit
That’s it. Give Git something to point at:
printf '# My Project\n' > README.md
git add README.md
git commit -m "Initial commit"
git push -u origin main
The -u matters. It sets origin/main as the upstream for your local main, which is what flips VS Code from Publish Branch to the normal sync arrows.
This is also why GitHub nudges you to “Add a README” when creating a repo through the web UI. It’s not decoration โ it’s making sure the repo has a commit so everything downstream behaves.
Papercut 2: Git doesn’t know my GitHub credentials
This is the one that has bitten me on laptop after laptop.
GitHub removed password authentication for Git operations back in 2021. So git push over HTTPS needs a Personal Access Token instead of your password. Which means, on every new machine, you either generate a PAT in the GitHub web UI, scope it correctly, and paste it into a terminal prompt you hope caches it โ or you generate an SSH key, add it to the agent, register the public key with GitHub, and remember to use SSH remote URLs.
Both work. Both are tedious. Both are easy to get subtly wrong, and the failure mode is a confusing 403 weeks later when a token silently expires.
Enter the GitHub CLI
gh is GitHub’s official command-line tool. Install it with Homebrew:
brew install gh
Not on a Mac? gh is available everywhere โ on Debian and Ubuntu sudo apt install gh, on Fedora sudo dnf install gh, and on Windows winget install --id GitHub.cli. Everything from here on is identical on all three platforms.
Then log in:
gh auth login
It walks you through a short set of questions:
- What account do you want to log into? โ GitHub.com
- Preferred protocol for Git operations? โ HTTPS
- Authenticate Git with your GitHub credentials? โ Yes โ this is the important one
- How would you like to authenticate? โ Login with a web browser
Pick the browser option and it shows you an eight-character code, then sends you to GitHub to paste it.
A snag worth knowing about the browser step
When the browser opens, you may land on GitHub’s sign-in / two-factor screen rather than the code box โ passkey, authenticator app, recovery codes. This confused me for a minute, because I had a code in my terminal and nowhere obvious to put it.
They are two different steps, in order:
- Sign in to GitHub in that browser (passkey, or authenticator app six-digit code). GitHub needs to know who you are before it can authorise anything.
- Then you get the Device Activation page, and that’s where the eight-character code from your terminal goes.
Don’t reach for the 2FA recovery codes here โ those are for genuine lockouts. And note the terminal code expires after about 15 minutes; if you’ve dawdled, Ctrl+C and re-run gh auth login for a fresh one.
The bit that actually fixes credentials
Here’s the real gotcha, and the reason I’m writing this section.
That third question โ “Authenticate Git with your GitHub credentials?” โ is the one that solves the problem. It configures Git to ask gh for a token on every push and pull. But it can be skipped, or answered “No”, or not offered at all if you authenticate a different way.
Check whether it actually took effect:
git config --get-all credential.https://github.com.helper
You want to see something like:
!/opt/homebrew/bin/gh auth git-credential
If it comes back empty, it didn’t take. Fix it with one command:
gh auth setup-git
That’s the command to remember. It’s the whole trick. Run it on every machine and git push over HTTPS simply works from then on โ no PAT juggling, no SSH keys, no “Support for password authentication was removed” wall.
Verify the whole picture with gh auth status:
github.com
โ Logged in to github.com account yourname (keyring)
- Active account: true
- Git operations protocol: https
- Token: gho_************************************
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
Watch out for stale credentials
On my Mac, credential.helper was already set to osxkeychain, with a GitHub entry whose username was a string of digits. That’s a user-ID-style entry, typically written by VS Code’s or GitHub Desktop’s built-in GitHub authentication rather than by you.
Entries like that work right up until they don’t, and then you get opaque permission errors. The good news: gh auth setup-git writes a github.com-specific helper, and Git prefers the more specific match. So it supersedes the stale entry rather than fighting with it.
If you want to inspect what’s cached:
printf "protocol=https\nhost=github.com\n\n" | git credential fill
While you’re here: skip the whole dance next time
Once gh is authenticated, you don’t need to create repos in the browser at all:
gh repo create my-project --private --source=. --remote=origin --push
That creates the GitHub repo, wires up origin, and pushes โ in one command. Though note it still needs at least one commit locally, for exactly the reason in Papercut 1.
Other bits I reach for constantly:
gh repo clone owner/nameโ clone with auth already sortedgh pr createandgh pr checkout 42gh run watchโ follow a GitHub Actions run in the terminalgh apiโ authenticated REST and GraphQL calls without wrangling tokens
The two-line summary
If Publish Branch does nothing, you have no commits. Make one.
If Git keeps forgetting who you are, install gh, run gh auth login, and then run gh auth setup-git to be certain the credential helper is actually wired up.
One caveat: gh only handles GitHub. For GitLab, Bitbucket, or a self-hosted Git server you’re back to your system keychain or SSH keys. But if GitHub is where your work lives, this is ten minutes that pays for itself many times over.
Every command in this article was actually run, on a Mac Studio (M2 Ultra) under macOS Tahoe 26.6.2 in September 2026, with gh 2.100.0 and git 2.50.1 โ the terminal output above is real, not reconstructed. The gh auth setup-git section exists precisely because on that machine gh auth login did not wire up the credential helper, and the check came back empty. Tooling moves on, so if a future release of gh changes any of this, the official gh manual is the first place to check.