Git 远程仓库 — push / pull / fetch / clone
前面学的 init/add/commit/branch 都是在本地操作。但要团队协作、要备份、要参与开源,就必须有一个"远程中心"——这就是远程仓库。这一章讲怎么把本地代码推(push)上去、把同事的代码拉(pull)下来,以及 Fork 工作流。
1. 远程仓库是什么
本地 Git 是完全离线的——你的提交、分支、历史都存在自己电脑的 .git 目录里。但团队协作需要一个"中心枢纽",让所有人能同步代码。这个枢纽就是远程仓库。
常见的远程托管平台:
- GitHub:全球最大,4 亿+ 仓库,开源项目首选。
- GitLab:可自部署,企业用得多,自带 CI/CD。
- Gitee(码云):国内访问快,中文界面。
- Bitbucket:Atlassian 出品,和 Jira 集成好。
一个本地仓库可以关联多个远程(比如同时推 GitHub 和 Gitee 做备份),但通常只用一个,约定叫 origin。
2. git remote — 关联远程
本地仓库建好后,要告诉它"远程在哪":
# 关联远程仓库(GitHub/GitLab/Gitee)
# 1. 先在网站建一个空仓库,拿到地址(SSH 或 HTTPS)
# 2. 本地关联远程
git remote add origin git@github.com:you/repo.git
# 远程名 ↑ ↑ 远程地址
# "origin" 是约定俗成的默认远程名,可以自定义
# 查看已关联的远程
git remote -v
# 输出:
# origin git@github.com:you/repo.git (fetch)
# origin git@github.com:you/repo.git (push)
# 修改远程地址(换了服务器或改用 SSH)
git remote set-url origin git@github.com:you/new-repo.git
# 删除远程关联
git remote remove origin
# 一个仓库可以关联多个远程(比如同时推 GitHub 和 Gitee)
git remote add github git@github.com:you/repo.git
git remote add gitee git@gitee.com:you/repo.git3. git push / pull — 推送与拉取
这是日常协作最高频的两个命令。push 把本地提交上传到远程,pull 把远程更新下载并合并到本地。
# 第一次推送:-u 把本地 main 和远程 main 关联(建立追踪)
git push -u origin main
# 之后这个分支就能直接 git push / git pull,不用带参数
# 日常三件套
git fetch # 只下载远程变化到本地,不合并(更安全)
git pull # 拉远程更新并合并到当前分支(= fetch + merge)
git push # 推本地提交到远程
# 推送其他分支
git push -u origin feature-login
# 删除远程分支
git push origin --delete feature-login
# 强制推送(覆盖远程历史!慎用,只在私人分支)
git push --force-with-lease # 比 --force 安全:远程被别人改过会拒绝
git push -f # 暴力覆盖,不推荐黄金法则:已 push 到共享分支的提交,绝不强制覆盖(--force)。否则同事 pull 时会遇到噩梦般的冲突——他们的提交会"消失"。如果一定要强推,务必用 --force-with-lease(远程被别人改过会自动拒绝,更安全)。
4. fetch vs pull — 关键区别
新手最容易混淆这两个命令。简单说:fetch 只下载不合并(更安全可控),pull 下载并合并(更方便但可能突然出冲突)。
# fetch 和 pull 的关键区别
#
# git fetch:只下载,不合并
# - 把远程的新提交下载到本地的 origin/main(远程跟踪分支)
# - 你的工作区、本地 main 都不变
# - 适合:想先看看远程有啥变化再决定怎么合
git fetch origin
git log main..origin/main --oneline # 看远程比我多了哪些提交
git diff main origin/main # 看具体差异
git merge origin/main # 看完再决定合并
# git pull:下载 + 合并(= fetch + merge 一步到位)
# - 直接把远程变化合并进当前分支
# - 方便,但有冲突时会突然进入合并状态
git pull
# 推荐:用 pull --rebase 保持线性历史
git pull --rebase
# 等价于 git fetch + git rebase,避免多余的 merge 提交推荐养成"先 fetch 看看再决定"的习惯,尤其在多人协作的分支上。pull --rebase 能避免产生无意义的 merge 提交,保持历史线性干净。
5. git clone — 克隆远程仓库
加入一个已有项目时,第一步永远是 clone——把远程仓库整个下载到本地(含全部历史)。
# 克隆:把远程仓库整个下载到本地(含全部历史)
git clone git@github.com:vuejs/vue.git
# 自动建立 origin 关联、自动 checkout 默认分支
# 克隆到指定目录名
git clone git@github.com:vuejs/vue.git my-vue
# 浅克隆:只取最近 1 次提交(大仓库省时间/流量)
git clone --depth 1 git@github.com:torvalds/linux.git
# 克隆后补全历史(浅克隆后想要完整历史)
git fetch --unshallow
# 克隆指定分支
git clone -b dev git@github.com:you/repo.git
# 只克隆最近 N 次提交
git clone --depth 50 git@github.com:you/repo.git大仓库(如 Linux 内核、Chromium)全量克隆可能几 GB,用 --depth 1 浅克隆只取最新一次提交,省时省流量。
6. SSH vs HTTPS
远程地址有两种协议,各有优劣:
- HTTPS(
https://github.com/...):简单,任何网络都能用;但每次 push 要输 token(配 GCM 后能记住)。 - SSH(
git@github.com:...):配一次密钥后终身免密;但有些公司防火墙封了 22 端口。
长期开发推荐 SSH(配法见上一篇"安装与配置")。临时 clone 别人的项目用 HTTPS 更省事。
7. Fork 工作流 — 参与开源
给别人的开源项目(你没有写权限)贡献代码,要用 Fork 模式:
# Fork 工作流(给开源项目贡献代码)
# 1. 在 GitHub 网页点 Fork,把别人的仓库复制一份到你账号下
# 2. 克隆你 fork 的仓库
git clone git@github.com:你/vue.git
cd vue
# 3. 添加原始仓库为 upstream(上游)
git remote add upstream git@github.com:vuejs/vue.git
git remote -v
# origin git@github.com:你/vue.git (你的 fork)
# upstream git@github.com:vuejs/vue.git (原仓库)
# 4. 开发前同步 upstream 的最新改动
git fetch upstream
git switch main
git merge upstream/main # 把原仓库 main 合并到你的 main
git push origin main # 推到你的 fork
# 5. 开 feature 分支开发,完成后 push 到 origin
git switch -c fix-typo
# ... 改代码 ...
git push -u origin fix-typo
# 6. 在 GitHub 网页发起 Pull Request:你/vue:fix-typo → vuejs/vue:main这里出现了第二个远程 upstream(上游)——指原始仓库,用来同步原作者的最新改动。你的 origin 是自己 fork 的副本(有写权限)。这种"双远程"结构是开源协作的标准姿势。
日常协作命令总结
- 开始工作前:
git pull同步最新。 - 开发完一段:
git add+git commit。 - 下班前:
git push推上去(备份 + 让同事看到)。 - 切换分支前:
git status确认干净,或git stash暂存。 - 遇到"push 被拒绝":说明远程有新提交,先
git pull --rebase再 push。
← 上一篇 Git 合并与冲突
下一篇 Git 工作流 →