8、Git远程仓库:git remote、git push、git fetch、git pull,以及 upstream 分支的追踪关系
聊到远程仓库,我得先坦白一件事。我刚入行那会儿,总觉得远程仓库就是个“备份盘”。代码写完了,push 上去就完事了。直到有一次,我和同事同时改了同一个文件……嗯,那场面,现在想起来都头皮发麻。从那以后,我才真正开始理解远程仓库的协作逻辑。
说白了,远程仓库不是你的U盘。它是团队协作的中枢神经。今天我们就来把这套东西彻底捋清楚。
8.1 什么是远程仓库?
远程仓库,就是托管在服务器上的 Git 仓库。你可以把它理解成一个“公共副本”。每个人的本地仓库,都可以和它同步数据。
常见的远程仓库服务有 GitHub、GitLab、Gitee。但不管用哪个,核心操作都是一样的。
核心概念:远程仓库不是“真正的仓库”,它只是一个引用。你的本地仓库才是你真正干活的地方。远程仓库只是帮你和其他人交换数据的中介。
8.2 git remote:管理远程连接
先看看你当前关联了哪些远程仓库:
git remote -v
输出大概长这样:
origin https://github.com/yourname/project.git (fetch)
origin https://github.com/yourname/project.git (push)
这里的 origin 是远程仓库的默认名字。你可以把它理解成一个“快捷方式”。每次 push 或 pull 的时候,不用输完整 URL,直接说 origin 就行。
添加一个新的远程仓库:
git remote add upstream https://github.com/othername/project.git
删除一个远程仓库:
git remote remove upstream
重命名:
git remote rename origin upstream
我的习惯:我个人习惯把主仓库叫 origin,把上游仓库(比如开源项目的原仓库)叫 upstream。这样一眼就能分清谁是谁。
8.3 git push:把本地代码推上去
这是最常用的操作。但很多人 push 的方式其实不太对。
基本用法:
git push origin main
这条命令的意思是:把本地的 main 分支,推送到远程的 origin 仓库,远程分支也叫 main。
如果你想推送到不同的分支名:
git push origin local-branch:remote-branch
举个例子:
git push origin feature/login:feature/v2-login
这样本地叫 feature/login 的分支,到了远程就变成了 feature/v2-login。
注意:push 之前一定要先 pull。我曾经见过有人直接 force push 把同事的代码覆盖了……那场面,真的,别学我。
8.4 git fetch:只下载,不合并
git fetch 是个被低估的命令。很多人只用 git pull,但 fetch 其实更安全。
基本用法:
git fetch origin
这条命令会从远程仓库下载所有新的提交、分支、标签。但它不会自动合并到你的工作区。
换句话说,你的本地代码纹丝不动。只是 Git 悄悄告诉你:“嘿,远程那边有更新了,你自己看着办。”
查看 fetch 下来的内容:
git log origin/main
或者切换到远程分支看看:
git checkout origin/main
我的建议:如果你不确定远程的更新会不会影响你的代码,先用 fetch 看看。确认没问题了,再手动合并。这样更稳。
8.5 git pull:下载并合并
git pull 其实是 git fetch + git merge 的合体。一步到位,但也一步到位地可能出问题。
基本用法:
git pull origin main
这条命令做了两件事:
- 从远程
origin的main分支下载最新提交 - 自动合并到当前分支
如果你想让 pull 用 rebase 而不是 merge:
git pull --rebase origin main
我个人更推荐用 --rebase。为什么?因为合并提交(merge commit)会让历史变得很乱。而 rebase 会让历史保持线性,看起来更清爽。
避坑指南:我曾经在 pull 的时候遇到冲突,然后 Git 自动生成了一个合并提交。结果那个合并提交里混了别人的代码,我还没发现。后来排查问题花了整整一下午。所以我现在要么用 fetch + merge 手动控制,要么用 pull --rebase。
8.6 upstream 分支追踪关系
这是很多人容易忽略的点。什么叫“追踪关系”?
说白了,就是让本地分支知道:“我该从哪个远程分支拉代码,又该推送到哪个远程分支。”
当你执行 git clone 的时候,Git 会自动帮你设置好追踪关系。比如本地的 main 分支,会自动追踪 origin/main。
但如果你自己创建了一个新分支:
git checkout -b feature/new
这时候,这个分支还没有对应的远程分支。你 push 的时候需要指定:
git push -u origin feature/new
这里的 -u 就是 --set-upstream 的简写。它告诉 Git:“以后这个本地分支,就追踪远程的 feature/new 分支。”
设置好之后,下次你直接 git push 或 git pull 就行了,不用再写远程仓库名和分支名。
查看当前分支的追踪关系:
git branch -vv
输出示例:
main abc1234 [origin/main] 修复登录bug
feature/new def5678 [origin/feature/new] 新增注册功能
方括号里的内容,就是追踪的远程分支。
核心要点:upstream 分支追踪关系,本质上是一个“默认配置”。它让你不用每次都说“我要推送到哪里”。但前提是,你得先设置好。
8.7 知识体系图
下面这张图,帮你把今天讲的内容串起来:
8.8 常见场景与操作对照
| 场景 | 推荐操作 | 说明 |
|---|---|---|
| 首次推送新分支 | git push -u origin 分支名 |
设置 upstream 追踪关系 |
| 查看远程有哪些分支 | git branch -r |
列出所有远程分支 |
| 只下载不合并 | git fetch origin |
安全查看远程更新 |
| 下载并合并 | git pull origin 分支名 |
一步到位,但小心冲突 |
| 查看追踪关系 | git branch -vv |
显示本地与远程的对应关系 |
| 删除远程分支 | git push origin --delete 分支名 |
远程分支清理 |
8.9 几个实用小技巧
- 设置默认远程仓库:如果你只有一个远程仓库,可以用
git push -u origin main设置一次,以后直接git push就行。 - 避免重复输入密码:配置 SSH 密钥,或者用
git config --global credential.helper cache缓存凭证。 - 查看远程仓库详情:
git remote show origin会显示所有分支的追踪状态,非常详细。 - 清理本地过时的远程分支引用:
git remote prune origin会删除本地已经不存在于远程的分支引用。
我的经验:我习惯每天早上到公司第一件事就是 git fetch --prune。这样既能拿到最新代码,又能清理掉那些已经被删除的远程分支引用。保持本地仓库干净,心里才踏实。
好了,远程仓库这块的内容就这些。记住一个核心原则:push 之前先 pull,pull 之前先 fetch 看看。做到这三点,你在团队协作中基本不会踩坑。