Windows Guide · · Approx. 20 min read

Route Git and GitHub CLI Through Clash on Windows: HTTPS Clone and Credential Setup Guide (2026)

On Windows, developers often run Clash or a mihomo-based GUI with system proxy enabled, then watch git clone or git fetch against GitHub stall—or succeed once and mysteriously fail after a reboot. The GitHub CLI (gh) adds another layer: its OAuth device flow and the api.github.com calls must follow the same intentional path as Git’s HTTPS stack. This guide treats the problem as two coupled contracts. First, make the shell and tools honor the de-facto proxy environment variables—HTTP_PROXY, HTTPS_PROXY, and a carefully scoped NO_PROXY—pointing at your local mixed port. Second, align Git Credential Manager (GCM) so stored tokens are not fighting a topology where Git went through a tunnel once and Microsoft Edge completed OAuth on a different path. The article pairs naturally with our Windows npm and pnpm proxy walkthrough and the MCP npm and GitHub routing guide, but focuses on terminal Git, HTTPS cloning, and credential calibration rather than package registries alone.

1. Mental model: what Git, GCM, and gh actually send over the network

Git over HTTPS uses standard TLS clients. For most users on modern Windows builds, multiple HTTP stacks can coexist: the Git for Windows bundle, the credential helper process launched by GCM, and the browser window that GCM opens for GitHub OAuth. If the Git process sees HTTP_PROXY while the browser session that completes login does not—or vice versa—you can end up with a token minted in a context that no longer matches how Git reaches github.com. That mismatch shows up as recurring Authentication failed dialogs, endless credential prompts, or HTTPS clones that work in one terminal profile but not another.

The GitHub CLI is a separate binary that reads both general-purpose proxy variables and its own GH_PROXY knob. It talks to api.github.com for almost everything important. When people say “GitHub is blocked” while the website loads in a browser, they often mean one of the API or CDN hostnames is classified differently in the Clash ruleset, not that DNS is globally broken.

Your goal is boring reproducibility: pick one primary mechanism for CLI tools—usually explicit environment variables toward 127.0.0.1:mixed-port—then verify every helper process spawned by Git inherits that environment or uses equivalent Git configuration. Reserve TUN mode as an accelerator, not a substitute for understanding who is CONNECT-ing where.

2. Clash on Windows: listener, system proxy, TUN, and mixed-port sanity checks

Before touching Git, confirm your inbound is real. Desktop bundles such as Clash Verge Rev expose a mixed port that accepts HTTP CONNECT for HTTPS targets. The address must match what you reference in proxy variables—typically 127.0.0.1 for single-machine use. If you recently adjusted allow-lan or Windows Defender Firewall, revisit those settings using the allow-lan article so you are not debugging Git while the TCP listener is silently blocked for non-browser clients.

System proxy toggles and TUN both change default routes, but terminal sessions do not magically inherit every GUI choice. Many “Git only works in VS Code’s integrated terminal” reports trace back to the IDE injecting environment variables while an external PowerShell window does not. For a tour of how system proxy and TUN interact on current Windows, skim Clash Verge Rev on Windows 11, then return here with a single test plan: same commands in PowerShell, CMD, and Git Bash after you standardize exports.

If outbound health is uncertain—slow nodes, expired subscription, or noisy TLS interception—fix that before blaming credentials. Walk through subscription import, watch mihomo logs during a deliberate git ls-remote https://github.com/git/git.git, and only then tighten domain rules.

3. PowerShell, CMD, and Git Bash: HTTP_PROXY, HTTPS_PROXY, NO_PROXY

The pattern is identical to the one we document for Node tooling: point tools at an HTTP CONNECT port even when the ultimate destination is HTTPS. Replace 7890 with your real mixed port.

# PowerShell session: Git and gh follow Clash local inbound
$env:HTTP_PROXY   = "http://127.0.0.1:7890"
$env:HTTPS_PROXY  = "http://127.0.0.1:7890"
$env:ALL_PROXY    = "http://127.0.0.1:7890"
$env:NO_PROXY     = "localhost,127.0.0.1,::1,.local,git.internal.example.com"

Expand NO_PROXY for every hostname that must never traverse a remote exit: corporate GitLab or self-hosted gitea FQDNs, legacy HTTP git servers on RFC1918 space, and local mirrors. Some tools read lowercase no_proxy; documenting both for your team removes pointless friction between Windows shells and Linux CI images.

Git Bash uses POSIX startup files. If your exports live only in the PowerShell profile, Git Bash will look “broken” until you duplicate them in ~/.bashrc or launch Git from a parent process that forwards the environment. Likewise, WSL2 Linux distributions do not share 127.0.0.1 with the host; follow the WSL2 networking guide when Git runs inside Linux while Clash runs on Windows.

Persist variables through the Windows Environment Variables UI or automation your company approves. Avoid stuffing long corporate bypass lists into brittle setx one-liners without testing length limits; open a fresh terminal after changes, then run git -c credential.helper= -c http.proxy= ls-remote https://github.com/git/git.git to confirm connectivity without yet involving stored passwords.

4. Git config: http.proxy, insteadOf, and when env vars should win

Git respects http.proxy and https.proxy in addition to environment variables. If both exist, you can create hard-to-read precedence stories—especially when a global config from an old laptop still pins http://127.0.0.1:1080 while your current Clash listens on 7890. Inspect effective configuration with git config --show-origin --get-regexp 'http\..*proxy' and delete stale entries from the right scope (--global versus --system).

URL rewrite rules via url.<base>.insteadOf are powerful for forcing SSH or internal mirrors, but they are also a footgun when a rewrite sends HTTPS traffic to a host that your NO_PROXY list forgot. Treat insteadOf as infrastructure: document it in your team handbook alongside the bypass list.

For quick, project-local debugging without editing disk, prefer one-shot flags: git -c http.proxy=http://127.0.0.1:7890 clone …. Once the path is proven, promote the same value to your standard shell exports so IDEs and build agents inherit it consistently.

5. HTTPS clone paths: GitHub hostnames your rules should recognize

A minimal HTTPS clone touches more than github.com. Large object transfers and redirects often involve objects.githubusercontent.com, codeload.github.com, or raw.githubusercontent.com. Authentication and REST calls use api.github.com. If your rules send the HTML front door through an exit node but classify CDN-like object hosts as DIRECT into an ISP path that rate-limits Git, you will see slow git clone progress bars or mid-fetch resets.

Do not guess huge public suffixes into a single policy group without watching logs first. Instead, reproduce with GIT_CURL_VERBOSE=1 GIT_TRACE_PACKET=1 git ls-remote … (temporarily, in a safe repository), copy the exact failing hostname, and add a precise DOMAIN or DOMAIN-SUFFIX row ahead of your catch-all GEOIP or MATCH rule in mihomo. This is the same incremental discipline we recommend when splitting npm tarball traffic.

6. Git Credential Manager: clearing stale entries and keeping OAuth on-path

Git Credential Manager stores OAuth tokens and passwords in the Windows Credential Manager and may launch a browser for interactive sign-in. When users toggle proxies weekly, stale entries are normal. If GitHub rotated tokens or your enterprise conditional-access policies changed, you will need to evict old secrets before asking Git to authenticate again.

Practical sequence: ensure your shell exports match the topology you intend, then run Git’s credential erase flow for the relevant URL, or use GCM’s own diagnostic commands from a recent release—your installer’s git credential-manager --help enumerates the current verbs. After clearing, repeat git clone once with tracing disabled and confirm the browser sign-in completes while the same proxy variables remain set in the parent shell that launched Git.

Mixed-path failures often look like “browser says success, Git still 401.” That is classic split-brain: the browser exited through system proxy or TUN while the Git child process did not. Align them temporarily by opening the sign-in window from the same user session that has working proxy exports, or disable conflicting VPN HTTP stacks while you renew credentials, then document the steady-state.

7. GitHub CLI (gh): GH_PROXY, auth login, and API failures

Install gh from a trusted channel, then verify version and host connectivity with gh auth status -h github.com. For corporate environments that require an explicit outbound, set HTTPS_PROXY and, if needed, GH_PROXY to the same http://127.0.0.1:mixed-port string you use for Git. The CLI’s HTTP client should then align with Clash’s view of the flow.

When device-flow or web-based login fails at the API step, inspect whether api.github.com is hitting the intended policy group in your logs. Rate limiting presents differently from TLS MITM noise; use GH_DEBUG=api sparingly to capture one clean failure, then turn tracing off. Personal access tokens as GH_TOKEN remain a valid fallback for automation-only boxes where browser OAuth is impossible—store them with your secrets manager, not in plaintext scripts committed beside sample YAML.

8. mihomo split rules: policy groups before the catch-all

Environment variables answer whether Git offered traffic to the local inbound. mihomo rules answer what happens next: DIRECT to ISP WAN versus forwarded to a remote outbound. Those layers must tell the same story. Replace PROXY with your real policy group name.

# Example rules — tailor to your provider list and geo constraints
rules:
  - DOMAIN-SUFFIX,github.com,PROXY
  - DOMAIN-SUFFIX,githubusercontent.com,PROXY
  - DOMAIN-SUFFIX,githubassets.com,PROXY
  - DOMAIN,api.github.com,PROXY

If domestic direct access to GitHub is intentionally fast and policy-compliant in your region, you may choose DIRECT for these rows instead. The anti-pattern is oscillation—Monday’s profile sends GitHub through an exit node, Tuesday’s “optimization” sends it direct, and GCM tokens see two different apparent regions. Pick a default, log it, and change it deliberately.

DNS mode and fake-ip interactions can surprise you when domains resolve one way in the browser and another for CLI resolvers. If symptoms look like DNS, cross-read fake-ip versus redir-host before you widen rules blindly.

9. Symptom matrix: mixed proxy versus DIRECT mistakes

What you see Likely cause First corrective step
Timeout mid-clone on large repos Object CDN host treated differently than main site Add missing object host from logs to same policy row family
401 after OAuth “success” Browser and Git used different egress paths Align proxy env for shell and relaunch auth; clear stale GCM entry
gh errors while git works GH_PROXY unset or API hostname differs in rules Set proxy vars for gh; confirm api.github.com in rules
Works in IDE only IDE injects env vars; bare PowerShell does not Move exports to persistent user env or shared profile

When two symptoms appear together, fix topology before credential rotation. Chasing new OAuth sessions while half your tools still bypass the tunnel wastes time and triggers protective rate limits on GitHub’s side.

10. Verification checklist

Getting Git and gh through Clash on Windows is less about exotic flags and more about two habits: explicit HTTP_PROXY contracts every shell agrees on, and credential helpers that are reset whenever you change how traffic leaves the machine. Compared with chasing one-off browser tweaks, that combination survives subscription updates, new laptops, and CI tutorials that assume a “normal” path to GitHub. When you want installers and updates aligned with the rest of the site, start from our download center, then layer terminal exports and YAML refinements so git fetch and repository automation behave the same on Friday night as they did on Monday morning.

→ Download Clash for free and experience the difference

Hand-picked deep-dives on the same topic — practical Clash routing guides in the same category.