Git切换分支无反应且无报错,需进子目录操作的原因与解决办法
为啥会出现这种怪事?
这十有八九是你们的项目仓库用了嵌套Git仓库或者没配置好的Git子模块结构!
直白点说:每个人的独立子目录本身就是一个单独的Git仓库,而项目根目录是另一个“主仓库”。当你在根目录跑git checkout [branch]时,主仓库里根本不存在这个分支(或者这个分支在主仓库里没有任何关联子目录的变更),所以Git执行了命令但没实际效果——毕竟没东西可切换嘛。但当你进入子目录后,操作的是子目录自己的Git仓库,这里面才存着你要切换的他人分支,所以就能正常切换拉取代码了。
怎么验证这个猜想?你可以分别在根目录和子目录里执行git status,看看输出里显示的“On branch”和仓库根路径是不是不一样;或者直接看子目录里有没有隐藏的.git文件夹——有的话就实锤是嵌套仓库了。
解决办法来了
根据你们的项目情况,有两种靠谱的处理方式:
直接操作子目录仓库(最省心的当前方案)
每次要切换他人分支时,先cd到对应的子目录,然后再执行git checkout [branch]和git pull就行。如果还没把他人的仓库设为上游,进入子目录后可以跑:git remote add upstream [他人子目录仓库的Git地址]之后就能直接用
git pull upstream [branch]拉取最新代码了。统一转为Git子模块(适合长期规范管理)
如果项目本来就应该用子模块来统一管理所有子目录,那可能是当初初始化的时候没做全。你可以在根目录执行:git submodule add [子目录仓库地址] [子目录路径]把每个子目录正式注册为根仓库的子模块。之后在根目录跑
git submodule update --remote就能批量拉取所有子模块的最新代码;要是想给所有子目录统一切换分支,还能这么干:git submodule foreach git checkout [branch](不过这个命令要求所有子目录都有同名分支才适用哦)
额外小提醒
如果是团队里有人不小心在子目录里单独初始化了Git仓库(而不是在主仓库的分支里管理),最好赶紧和队友统一规范:要么全用子模块,要么全在主仓库的分支下管理各自子目录,避免再出现这种让人摸不着头脑的情况。
内容的提问来源于stack exchange,提问作者OnStandBy

