DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
雨云;给项目一台云服务器
RackNerd;$21.99/年 · 1GB KVM

Git 新建分支时执行 switch 报 invalid reference

新分支名在本地和远程跟踪引用中都不存在时,git switch 分支名可能报 invalid reference。用小写 -c 创建,明确起点,并区分远程分支自动猜测与强制创建 -C 的行为。

准备开一个新分支,执行 git switch feature-login,却收到:

fatal: invalid reference: feature-login

如果 feature-login 是刚想好的新名字,本地和已抓取的远程跟踪分支中都没有它,通常是因为这条命令要求切换到一个可识别的分支,没有明确要求从当前提交创建新分支。应使用小写 -c:

git switch -c feature-login

这里的分支名是示例,请换成尚未使用的实际名称。以下针对已经有提交的普通工作仓库,git switch 需要 Git 2.23 或更新版本。若提示 switch 不是 Git 命令,那是版本能力问题,不是本文的引用不存在错误。

先分清是要新建,还是要接着已有分支工作

在仓库目录中查看状态,并列出相关分支:

git status --short --branch
git branch --list feature-login
git branch -r --list '*/feature-login'

第一条显示当前分支、跟踪关系及未提交文件状态。第二条查本地同名分支,第三条查本机保存的远程跟踪分支。'*/feature-login' 的引号让通配符交给 Git 处理,避免 shell 先展开。

根据结果决定下一步:

  • 本地已有同名分支:用 git switch feature-login 切换,不再加创建选项。仍失败时检查拼写、大小写、当前仓库,以及完整错误是否其实是工作目录修改冲突。
  • 本地没有,但列出了 origin/feature-login:如果要继续这个远程分支,应从它创建本地跟踪分支,不能随手从当前提交新建同名分支。
  • 两边都没有,且确实要开全新工作:确认当前提交就是期望起点,再执行 git switch -c feature-login。

远程跟踪分支列表只是本机记录,不是服务器实时列表。如果期望的分支应该在服务器上,先确认远程名,再抓取并重新查看,例如:

git fetch origin
git branch -r --list origin/feature-login

普通 fetch 按配置的抓取范围更新引用;单分支克隆或自定义映射可能没有包含目标分支。因此列表仍为空不能直接证明服务器上不存在它。这个分支应转去核对远端与抓取范围,而不是用创建同名本地分支掩盖问题。本站的单分支仓库抓取范围说明处理这一情况。

用小写 -c 指定创建,并确认起点

不写起点时,新分支从当前 HEAD 指向的提交开始:

git switch -c feature-login

长选项 git switch --create feature-login 含义相同,二选一执行即可。如果应该从另一个已有本地分支开始,可以明确指定它:

git switch -c feature-login main

这两种起点写法二选一。main 必须是仓库中的实际起点;它代表本地分支当前的提交,不保证与服务器最新内容一致。创建前先确认自己要基于哪个版本,避免解决了报错,却在错误的历史上开始开发。

-c 创建并切换分支,不会把未提交文件自动提交。Git 不要求每次切换前工作目录都完全干净,但切换如果会丢失本地修改,通常会中止。遇到覆盖修改的提示,应先保存需要的工作,再处理切换;不要追加 --discard-changes 强行越过保护。重要的未跟踪、忽略文件及本地配置也需要独立保存。

为何有时不加 -c 也能创建

git switch feature-login 默认启用远程分支猜测:本地同名分支不存在,而恰好有一个远程保存着同名远程跟踪分支时,Git 可以据此创建本地分支并设置上游。

这依赖本机已有相应远程跟踪引用,而且猜测没有被 --no-guess 或 checkout.guess 配置关闭。多个远程都有同名分支时,还涉及 checkout.defaultRemote 的选择规则。它不能让 Git 凭空知道一个从未存在的新分支该从哪里创建。

已经确认 origin/feature-login 存在,并且希望继续它的开发时,显式写法更清楚:

git switch -c feature-login --track origin/feature-login

前提仍是本地 feature-login 尚不存在。命令以远程跟踪引用当前保存的提交为起点,设置本地分支上游;不会向服务器推送新分支或提交。

如果输入的是 git switch origin/feature-login,可能收到另一种错误:a branch is expected, got remote branch。那是把远程跟踪引用直接当作本地工作分支切换。打算继续开发时使用上面的跟踪分支写法;不要只为消除提示而改成 detached HEAD,再忘记保存后续提交。

不要把 -c 改成大写 -C 重试

如果执行创建后提示同名分支已经存在,先列出它的提交和上游:

git branch -vv --list feature-login

小写 -c 遇到已存在的名字会拒绝创建。大写 -C 是强制创建:已有分支会被重置到指定起点;没有写起点时,就是当前起点。它不是更强的“查找分支”选项,可能让原来的分支不再指向原提交。

没有必要通过删除旧分支、强制重建或硬重置来修复遗漏创建选项的问题。已有分支若属于别的工作,可以换一个未使用的名字;如果就是要继续已有分支,正常切换即可。

切换后检查分支与上游

执行成功后检查:

git status --short --branch
git branch -vv --list feature-login

当前分支应为 feature-login,第二条的星号表示正在使用它。如果使用了 --track origin/feature-login,还应看到对应上游。若只是从当前提交创建全新本地分支,不能要求它一定有远程上游。

这些检查分别确认“现在在哪个分支”和“它从哪里跟踪”。工作目录里的代码看起来没有变化,并不表示创建失败:从当前 HEAD 开新分支时,起点提交本来就相同。

如果刚切换后发现选错了起点,先保留需要的修改,再用 git switch - 返回上一次分支或提交。它只负责切回,不会撤销已经产生的提交或自动删除刚创建的分支。已经在新分支产生了工作时,保留该分支,确认提交去向后再调整;不需要为了撤销一次切换而强制删除它。