讲解
git push 把本地提交上传到远程:git push origin main 把本地 main 分支推到远程 origin。第一次推某个分支时加 -u(--set-upstream):git push -u origin main,它除了推送还建立本地分支与远程分支的跟踪关系,之后在这个分支上直接敲 git push、git pull 就够了,status 也会显示「领先/落后 origin/main 几个提交」。推送标签默认不会跟着分支走,要 git push origin 标签名 或 git push --tags。
git pull 把远程的更新取回本地并合并进当前分支,等价于 git fetch + git merge 两步(下一章细说)。队友推送了新提交后,你 pull 一下就能拿到。如果两边都有新提交,pull 会产生一次合并(或者按配置做 rebase);只有远程有新提交时则是快进,干净利落。
最常见的挫折是 push 被拒绝:error: failed to push some refs,原因几乎都是远程有你本地没有的提交(队友推过了)。Git 拒绝覆盖你不知道的历史,这是保护。正确做法:先 git pull 合并远程的提交(解决可能的冲突),再重新 push。千万别下意识用 --force 强推——那会用你的本地覆盖远程,队友的提交就没了。改写历史后确实需要强推时,用更安全的 --force-with-lease(远程被别人更新过就拒绝),并且只对个人分支使用。
示例
推送到(本地路径模拟的)远程,再模拟队友推送后拉回来:
git remote add origin ../origin.git
git push -u origin main
git push --tags
git clone -q ../origin.git ../teammate
cd ../teammate
git config user.name "队友"
git config user.email "teammate@example.com"
echo "队友的新功能" > teammate.txt
git add teammate.txt
git commit -qm "feat: 队友的新功能"
git push -q origin main
cd ../repo
git pull --no-edit
git log --oneline -3
pull 之后,队友的 teammate.txt 出现在你的工作区,log 里能看到他的提交。push 被拒绝的场景长这样(示意):
# 仅示意:本地落后于远程时 push 会被拒绝
git push origin main
# ! [rejected] main -> main (non-fast-forward)
# 正确做法:先 git pull 合并队友的提交,再重新 push
常见坑
- 第一次推送忘关联远程:本地 init 的项目直接 git push 会报 no configured push destination,先 git remote add origin 再 git push -u origin main。
- 被拒绝就 --force:强推覆盖远程历史,是协作事故的经典源头。先 pull 解决,再推;非用不可时只用 --force-with-lease 且只对个人分支。
- 以为 push 会带上标签:默认不会,标签要单独 push 或用 --tags。
- pull 产生意外合并提交:只想快进不想合并的话,配置 git config --global pull.ff only,不能快进时让 pull 报错提醒你手动处理。
小结
push 上传(-u 建立跟踪关系),pull 下载并合并;push 被拒绝先 pull 再推,永不轻易 --force。下一章拆开 pull,看清 fetch 和 merge 这两步。