跳转到内容
新建笔记

Git 远程同步:fetch、pull、push 与拒绝推送

远程同步包括两件独立的事:获取别人已经提交的历史,以及把自己整理好的提交交给服务器。fetch first 或 non-fast-forward 表示需要先了解两边的关系,不是让你立即强制覆盖远端。

名称示例所在位置
本地分支main、swei当前仓库
远程别名origin、github本地配置中保存的远程 URL 名称
远程跟踪引用origin/main本地最近一次 fetch 所见的远端位置
服务器分支refs/heads/main远程仓库
终端窗口
git remote -v
git branch -vv
git status --short --branch

origin 只是惯用别名;名为 github 的 remote 也可以使用。首次添加用 git remote add origin <url>,已存在时检查后用 git remote set-url origin <url>。切勿把访问令牌写进示例 URL 或提交到配置笔记。

fetch 获取对象并按 refspec 更新引用,通常不会改动当前工作区。pull 先获取,再按选项/配置整合到当前分支,并不自动切换分支。示例明确写出整合策略,避免依赖机器上的默认设置:

终端窗口
git switch main
git fetch origin
git log --oneline --graph --left-right HEAD...origin/main
git merge --ff-only origin/main

最后一步成功意味着本地只需快进;如果分叉,命令会停下。要保留分叉结构可选择 merge,要重放尚未公开的本地提交可选择 rebase,过程见 冲突处理。对应的组合命令是 git pull --ff-only、git pull --no-rebase、git pull --rebase,根据项目规则选择,不能依次全部执行。

只有远程跟踪分支时,可以建立本地跟踪分支:

终端窗口
git fetch origin
git switch --track -c suyuhan origin/suyuhan
git push <remote> <本地来源>:<远程目标>

例如 git push origin swei:jp 把本地 swei 推向服务器的 jp。它不会切换当前分支。省略冒号的 git push origin swei 通常推送同名分支。首次设置上游:

终端窗口
git switch swei
git push -u origin swei

远端没有目标分支时会尝试创建它,是否允许仍取决于服务器权限和分支保护。已明确目标时,可以用 git push origin HEAD:main 推送当前提交到远端 main;不要在不知道当前 HEAD 的情况下复制执行。

  1. git status 确認工作区;未提交工作先提交到合适分支或精确 stash。
  2. git fetch origin,然后比较本地与目标远端分支。
  3. 对同源历史选择快进、合并或变基,并运行项目检查。
  4. 使用普通 push。若别人期间又提交了内容,重新 fetch 和比较。
终端窗口
# 这个例子只处理本地 swei 对远端同名 swei
git switch swei
git fetch origin
git 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 HEAD
git ls-remote --heads origin main
git status --short --branch

在当前分支确为 main 的前提下比较两边提交号,同时确认没有意外的未提交修改。Git 推送成功只说明服务器收到了提交,网站或应用是否上线还需看独立构建部署结果。

参考:git-fetch、git-pull、git-remote。