远程同步包括两件独立的事:获取别人已经提交的历史,以及把自己整理好的提交交给服务器。fetch first 或 non-fast-forward 表示需要先了解两边的关系,不是让你立即强制覆盖远端。
分清四种名称
跳转到“分清四种名称”| 名称 | 示例 | 所在位置 |
|---|---|---|
| 本地分支 | main、swei | 当前仓库 |
| 远程别名 | origin、github | 本地配置中保存的远程 URL 名称 |
| 远程跟踪引用 | origin/main | 本地最近一次 fetch 所见的远端位置 |
| 服务器分支 | refs/heads/main | 远程仓库 |
git remote -vgit branch -vvgit status --short --branchorigin 只是惯用别名;名为 github 的 remote 也可以使用。首次添加用 git remote add origin <url>,已存在时检查后用 git remote set-url origin <url>。切勿把访问令牌写进示例 URL 或提交到配置笔记。
fetch、pull 与当前分支
跳转到“fetch、pull 与当前分支”fetch 获取对象并按 refspec 更新引用,通常不会改动当前工作区。pull 先获取,再按选项/配置整合到当前分支,并不自动切换分支。示例明确写出整合策略,避免依赖机器上的默认设置:
git switch maingit fetch origingit log --oneline --graph --left-right HEAD...origin/maingit merge --ff-only origin/main最后一步成功意味着本地只需快进;如果分叉,命令会停下。要保留分叉结构可选择 merge,要重放尚未公开的本地提交可选择 rebase,过程见 冲突处理。对应的组合命令是 git pull --ff-only、git pull --no-rebase、git pull --rebase,根据项目规则选择,不能依次全部执行。
只有远程跟踪分支时,可以建立本地跟踪分支:
git fetch origingit switch --track -c suyuhan origin/suyuhanpush 的左右两边
跳转到“push 的左右两边”git push <remote> <本地来源>:<远程目标>例如 git push origin swei:jp 把本地 swei 推向服务器的 jp。它不会切换当前分支。省略冒号的 git push origin swei 通常推送同名分支。首次设置上游:
git switch sweigit push -u origin swei远端没有目标分支时会尝试创建它,是否允许仍取决于服务器权限和分支保护。已明确目标时,可以用 git push origin HEAD:main 推送当前提交到远端 main;不要在不知道当前 HEAD 的情况下复制执行。
拒绝推送的处理顺序
跳转到“拒绝推送的处理顺序”git status确認工作区;未提交工作先提交到合适分支或精确 stash。git fetch origin,然后比较本地与目标远端分支。- 对同源历史选择快进、合并或变基,并运行项目检查。
- 使用普通 push。若别人期间又提交了内容,重新 fetch 和比较。
# 这个例子只处理本地 swei 对远端同名 sweigit switch sweigit fetch origingit log --oneline --graph --left-right swei...origin/swei如果远端新建仓库时初始化了 README,而本地另行 git init,两边可能没有共同祖先。先用 git merge-base HEAD origin/main 判断。通常最容易审查的是克隆远端到新目录,把需要的本地文件复制进去后提交;必须保留两段独立历史时才在备份后考虑 merge --allow-unrelated-histories 并处理冲突。不能用一条 push --force 替代这些判断。
维护边界
跳转到“维护边界”--force 会跳过快进保护。--force-with-lease 要求远端引用仍等于预期值,但隐式预期值依赖本地跟踪引用,可能被后台 fetch 更新。只有确实需要协作重写已公开历史时,才讨论带明确 <ref>:<expect> 的 lease;它不是日常同步步骤。详见 git-push。
git remote set-head origin main 仅设置本地 origin/HEAD,服务器默认分支应通过服务器管理方式修改。fetch --prune 的删除范围取决于 refspec;不要把带标签映射的配置也当作仅清理普通远程分支。
成功的判据
跳转到“成功的判据”git rev-parse HEADgit ls-remote --heads origin maingit status --short --branch在当前分支确为 main 的前提下比较两边提交号,同时确认没有意外的未提交修改。Git 推送成功只说明服务器收到了提交,网站或应用是否上线还需看独立构建部署结果。