凌晨两点十七分,代码上传我盯着终端里那行红色的代码上传报错信息,手指悬在回车键上方。代码上传`fatal: unable to access 'https://github.com/...': Failed to connect to github.com port 443`。代码上传这已经是代码上传今晚第四次了。桌上咖啡凉透,代码上传杯壁凝着一圈深褐色的代码上传渍。我深吸一口气,代码上传把代理切到手机热点,代码上传重新敲下 `git push origin main`。代码上传
代码上传这件事,代码上传看起来只是代码上传敲一行命令,实际上经常是代码上传一场小型战争。办公室网络有防火墙,代码上传家里宽带偶尔抽风,代码上传公司内网又限制外联。最离谱的一次,我在客户现场演示前十分钟发现远程仓库地址写错了,把 `gitlab.company.com` 打成了 `gitlab.compan.com`。域名解析失败,浏览器转圈,我额头冒汗,手指在键盘上飞舞改 remote url。旁边产品经理还在问“好了没”,我只能说“马上马上”。
大多数人第一次接触上传,是在 GitHub 上创建仓库后看到的那几行提示。`git init`、`git add .`、`git commit -m "first commit"`、`git remote add origin ...`、`git push -u origin main`。照着敲一遍,如果网络通畅,十秒完事。但现实往往卡在认证上。GitHub 从 2021 年起不再支持密码推送,必须用 token 或 SSH 密钥。我见过新人把密码输进去,终端反复提示 `Authentication failed`,他以为是自己记错了密码,重置了三遍,最后发现要用 Personal Access Token。
SSH 密钥稍微省心一点。`ssh-keygen -t ed25519 -C "你的邮箱"`,一路回车,然后把 `~/.ssh/id_ed25519.pub` 里的内容复制到 GitHub 的 SSH keys 设置页。测试连接:`ssh -T git@github.com`。如果看到 `Hi 用户名! You've successfully authenticated...`,说明通了。但 Windows 用户可能会遇到 ssh-agent 没启动,或者权限问题导致密钥被忽略。我帮同事排查过一次,他密钥放在 `C:\Users\名字\.ssh\` 下,但 Git Bash 默认去 `/c/Users/名字/.ssh/` 找,路径没错,可文件权限是 777,SSH 直接拒绝使用。`chmod 600 id_ed25519` 之后,世界安静了。
大文件是另一个坑。有次我把一个 200MB 的数据集误提交了,`git push` 卡在 `Writing objects: 45%` 整整二十分钟,最后超时断开。远程仓库没收到,本地却多了一个巨大的 commit。删掉文件重新提交也没用,历史里还留着那个 blob。只能用 `git filter-branch` 或者 BFG 工具清理,再强制推送。那之后我养成了习惯:提交前先 `git status` 看一眼,确认没有 `data/` 或 `*.zip` 混进去。`.gitignore` 文件必须提前写好,别等出事了再补。
网络层面的问题最让人无力。公司代理需要配置 `git config --global http.proxy http://proxy.company.com:8080`,但有时候 HTTPS 走代理,SSH 不走,你得分开设。家里用 Clash 或者 V2Ray,端口经常变,今天 7890,明天 7891。我干脆写了个脚本,每次切换网络就重新设一遍代理。`git config --global --unset http.proxy` 和 `git config --global http.proxy socks5://127.0.0.1:7890` 来回切。听起来麻烦,但比对着红色报错干瞪眼强。
还有一次,推送成功但远程仓库看不到新提交。刷了好几遍页面,以为是缓存。后来发现推到了 `master` 分支,而 GitHub 默认显示 `main`。`git branch -M main` 改个名,再推一次,解决了。这种小坑不常遇到,遇到一次就记一辈子。
现在我的流程固定下来了。新项目先 `git init`,写 `.gitignore`,`git add` 后 `git status` 确认,提交,添加远程,推送。如果推送失败,按顺序查:网络通不通、代理对不对、认证有没有过期、分支名是否匹配、文件大小是否超限。大部分问题在第一步或第二步就能定位。剩下那些玄学问题,重启终端或者换个网络,往往就好了。
凌晨两点四十一分,终端终于输出 `To github.com:user/repo.git abc1234..def5678 main -> main`。我合上电脑,咖啡杯扔进水槽。代码上传成功,世界暂时安静了。