远程协作
Git 的分布式特性通过远程仓库实现。本节涵盖 push、pull、fetch、remote 管理和协作工作流。
远程仓库管理
# 查看远程仓库
git remote # 列出名称
git remote -v # 列出名称 + URL
# 添加远程仓库
git remote add <name> <url>
git remote add origin git@github.com:user/repo.git
# 修改 URL
git remote set-url <name> <new_url>
git remote set-url origin git@github.com:new-user/repo.git
# 删除远程
git remote remove <name>
# 重命名
git remote rename <old> <new>
# 查看远程详细信息
git remote show originfetch(获取)
# 从远程下载所有新数据(但不合并到工作目录)
git fetch <remote>
git fetch origin
git fetch --all # 全部远程
# 获取后查看差异
git log main..origin/main # 远程比本地多哪些提交
# 获取并清理已删除的远程分支
git fetch --prune
git fetch -p💡 fetch 是安全的操作——它只下载数据,不修改工作目录或本地分支。
pull(拉取并合并)
# pull = fetch + merge(默认)
git pull
# pull = fetch + rebase
git pull --rebase
# 设置默认使用 rebase
git config --global pull.rebase true
# 拉取远程并修剪
git pull --prunepull 策略
| 策略 | 命令 | 效果 |
|---|---|---|
| merge(默认) | git pull |
fetch + merge,产生 merge commit |
| rebase | git pull --rebase |
fetch + rebase,线性历史 |
| ff-only | git pull --ff-only |
仅在快进时合并(安全) |
💡 推荐设置:
git config --global pull.ff only——只有能快进时才拉取,如果有分叉则报错,强迫你手动处理,避免无意识的合并。
push(推送)
# 推送当前分支到远程
git push
# 推送并设置上游(首次推送)
git push -u origin <branch>
git push --set-upstream origin <branch>
# 推送所有分支
git push --all origin
# 推送标签
git push origin <tag>
git push --tags # 推送所有本地标签
# 删除远程分支
git push origin --delete <branch>
git push origin :<branch> # 旧语法
# 强制推送(⚠️ 危险)
git push --force # 直接覆盖
git push --force-with-lease # 安全强制推送(推荐)🚨 危险操作:
git push --force会直接覆盖远程分支,他人的提交可能丢失。优先使用git push --force-with-lease——它只在远程与你的本地记录一致时才允许强制推送。
force-with-lease 原理
# --force:不管远程状态,直接覆盖
# --force-with-lease:检查远程分支是否和你本地记录一致
# - 如果同事推送了新提交 → 拒绝推送,你先 fetch
# - 如果远程没有新提交 → 允许覆盖上游分支(Upstream)
# 设置上游分支
git branch --set-upstream-to=origin/main
git push -u origin feature # 首次推送时设置
# 查看追踪关系
git branch -vv
# 输出示例:
# * feature a1b2c3d [origin/feature: ahead 2, behind 1] Add login page
# main d4e5f6g [origin/main] Update README| 状态 | 含义 |
|---|---|
ahead 2 |
本地比远程多 2 个提交 |
behind 1 |
远程比本地多 1 个提交 |
ahead 2, behind 1 |
分支分叉,需要 merge/rebase |
Pull Request / Merge Request 流程
1. Fork / Clone 仓库
2. 创建 feature 分支
↓
3. 开发 → commit → push
↓
4. 在 GitHub/GitLab 创建 PR/MR
↓
5. Code Review → 讨论修改 → 更新提交
↓
6. 合并到目标分支
↓
7. 删除 feature 分支# 完整操作示例
git clone git@github.com:user/repo.git
cd repo
git checkout -b feature/new-login
# 开发...提交...
git add .
git commit -m "Add login page"
git push -u origin feature/new-login
# 在 GitHub 上创建 Pull Request
# Code Review 后可能需要修改:
# 修改后更新 PR(追加提交)
git add .
git commit -m "Fix review comments"
git push
# 或整理提交(rebase 后强制推送)
git rebase -i HEAD~2
git push --force-with-lease常见远程协作场景
同步上游变更(Fork 工作流)
# 添加上游仓库
git remote add upstream git@github.com:original/repo.git
# 从上游拉取最新
git fetch upstream
git checkout main
git merge upstream/main
git push origin main解决"non-fast-forward"推送错误
# 错误:! [rejected] main -> main (non-fast-forward)
# 原因是远程有本地没有的提交
# 正确做法:
git pull --rebase # 先拉取并 rebase
git push # 再推送
# 如果确定要用本地覆盖远程(谨慎)
git push --force-with-lease某次提交有问题,需要撤销
# 本地 + 远程都撤销(revert 不破坏历史)
git revert <bad_hash>
git push
# 本地 reset 后强制推送(仅自己的分支)
git reset --hard HEAD~1
git push --force-with-lease多 Remote 工作流
# 场景:同时推送到多个远程(如 GitHub + Gitee)
git remote add github git@github.com:user/repo.git
git remote add gitee git@gitee.com:user/repo.git
# 推送
git push github main
git push gitee main
# 或者一次推多个
git remote add all git@github.com:user/repo.git
git remote set-url --add --push all git@github.com:user/repo.git
git remote set-url --add --push all git@gitee.com:user/repo.git
git push all main远程协作安全规则
| 规则 | 原因 |
|---|---|
| 永远不 force push 到 main/master | 覆盖团队共享历史 |
仅在自己的 feature 分支上用 --force-with-lease |
可控且可恢复 |
| Push 前先 pull/fetch | 避免冲突和推送被拒 |
使用 git push --force-with-lease 而非 --force |
防止覆盖他人的提交 |
定期 git fetch --prune |
清理已删除的远程分支 |