跨Windows系统Git仓库同步遇push拒绝及分支合并问题求助
为什么git push被拒绝?
非裸仓库(带工作目录的仓库,比如你在System1上克隆的s:/cap2office)默认禁止推送到当前已检出的分支。原因很直接:推送会直接修改仓库的分支指针,但如果该分支正处于检出状态,工作目录里的文件状态会和更新后的仓库历史不一致,很容易导致工作目录混乱,所以Git直接拦截了这种操作。
git fetch + git rebase origin/master的原理
1. git fetch的作用
这条命令会从目标仓库(这里是System1的s:/cap2office)拉取所有最新的提交记录,但不会自动合并到你本地的分支。它只会更新本地存储的远程分支镜像(比如origin/master),让你能看到本地分支和远程分支的分叉差异,但完全不会改动你的工作目录和本地当前分支的状态。
比如你在System2的本地master有自己的新提交,而System1的origin/master也有之前的提交,fetch之后你可以通过git log --oneline --graph清楚看到两个分支的分叉情况,但本地代码还是你编辑后的样子。
2. git rebase origin/master的作用
rebase的核心是**“变基”**——把你本地当前分支(这里是System2的master)上的所有新提交,“搬运”到远程分支origin/master的最新提交后面,让分支历史变回线性。
举个实际场景的例子:
- 两台仓库最初的共同提交是
C1 - System1的
origin/master后续有提交C2 - System2的本地
master有自己的提交C3
执行rebase后,Git会先把你的C3临时存起来,然后把本地master分支的指针移到origin/master的最新提交C2上,最后把C3重新应用到C2后面,形成新的线性历史C1 -> C2 -> C3'(C3'是重新生成的提交,内容和C3完全一致,但提交哈希会变)。这样就彻底解决了分支分叉的问题,让本地分支和远程分支的历史对齐。
和git merge不同,merge会生成一个新的合并提交(比如C4,把C2和C3合并),分支历史会保留分叉;而rebase是把你的提交挪到远程分支的最新状态之后,最终的历史更简洁线性。
双系统同步仓库的更省心方案
既然用VPN映射了磁盘,建议把其中一个仓库改成裸仓库(只有Git版本数据,没有工作目录)作为共享的中央仓库:
- 在任意一台电脑上执行:
git init --bare c:/cap2office-bare - 两台电脑都将这个裸仓库设为远程仓库:
git remote add origin c:/cap2office-bare - 之后同步就用
git push origin master和git pull origin master,既不会出现推送到非裸仓库检出分支的报错,也能避免手动操作导致的分支分叉混乱。
内容的提问来源于stack exchange,提问作者Paul Kinzelman

