Skip to content
Git
远程协作

远程协作

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 origin

fetch(获取)

# 从远程下载所有新数据(但不合并到工作目录)
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 --prune

pull 策略

策略 命令 效果
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 清理已删除的远程分支