开发向 · 常见问题

卡住的时候回来查:开发向常见问题

这一页不按顺序读。四篇正文之外,真实卡住过的问题按现象收在这里——标题保留当时的问法,方便你按"我现在卡在哪"检索。

学一样新东西,真正拦住你的往往不是没看懂原理,是某个具体动作卡在那里、而它看起来像"我把东西弄坏了"。这一页收的就是这类问题:每条都来自真实的卡点,先给你一句话答案让你安心,再讲清它为什么会这样、怎么走出去。

这一页会持续增加。你在使用中遇到没被收录的卡点,欢迎告诉我们。

FAQ

问题

分叉、合并与回退

Q. 两台设备各自提交后,pull 说 "Need to specify how to reconcile divergent branches",push 又被 rejected —— 是不是把仓库搞坏了?

两个都不是错误。一个是 Git 在让你做一次策略选择,另一个是 Git 在保护另一台机器上的工作。设一次合并策略就通了,仓库好好的。

为什么会这样

你两边都各自往前走了一步。用第 2 篇的比喻说:档案馆里出现了两册各自往下写的草案,Git 不替你决定该用哪种方式把它们并成一册,所以停下来问你。

再仔细看 pull 的输出——它其实抓取成功了(你能看到类似 <旧哈希>..<新哈希> master -> origin/master 的一行),只是没有合并。而 push 被拒是连带的:你本地还不包含远端那些提交,硬推上去会覆盖掉另一台机器的工作,Git 直接拦下。

merge 还是 rebase

mergerebase
做法造一个合并提交,把两条线接起来把你的提交摘下来,重新贴到对方最新提交之上
历史保留真实的分叉痕迹变成一条直线,更整洁
冲突处理一次性解决完可能要边走边解,步骤多
提交哈希不变会变
适合新手、多人协作熟练之后

怎么做(新手选 merge)

git config --global pull.rebase false
git pull origin master
git push origin master

中间会弹出编辑器让你写一句合并说明,保存退出即可(弹出来出不去,见本页下一条)。

怎么确认真的同步上了

三种硬证据,可靠度递增:

git rev-parse HEAD origin/master

git show origin/master:<项目说明文件> | grep -n "<你新增的章节标题>"

git --no-pager log --oneline --graph -8

第一条最硬:两个哈希完全一样就是同步了。第二条直接读远端分支上的文件内容,证明东西真的推上去了。第三条看图——|\ 是分开、|/ 是合上,三个指针落在同一处就是同步:

*   a1b2c3d (HEAD -> master, origin/master) Merge branch ...
|\
| * e4f5a6b  另一台机器的提交
* | 7c8d9e0  你的提交
|/
* 1122334  共同起点

容易踩的坑:顺序必须是 先 commit → 再 pull → 最后 push。先 pull 会因为工作区还有没提交的改动而被拒绝。

记录于 2026-07-25

终端与编辑器

Q. 弹出一个满屏 ~ 的编辑器,我输入 :wq 它变成了正文,按 Esc 也没反应,怎么出去?

十有八九是中文输入法在作祟——切成英文输入法再试。

为什么会这样

中文输入法下按 : 打出来的是全角的 :,编辑器不认识它;按 Esc 又可能被输入法先吃掉(它拿去取消候选词了),根本传不到编辑器。

通用规则:终端里的所有操作都必须在英文输入法下进行。全角的 :、,、() 和半角是完全不同的字符,程序一律不认。

这个编辑器(vim)的核心是模式分离——没有输入框,你敲的字跑到哪里,取决于当前处在什么模式。新手所有的困惑都来自这一点。

你按 : 之后说明怎么办
冒号出现在屏幕最底行普通模式,这是命令继续敲 wq 回车
冒号出现在文字中间还在插入模式先按 Esc 或 Ctrl+C

怎么做

  • 保存退出:Esc → :wq → 回车
  • 放弃退出:Esc → :q! → 回车
  • 误输入了内容:Esc → u(撤销)→ 再 :wq

治本(建议直接做)

git config --global core.editor nano

nano 底部常驻显示快捷键(^O 保存、^X 退出),不分模式,输入即所见。vim 很强大,但它的学习曲线不该出现在"我只是想写一句合并说明"这种场景里。

合并时也可以干脆跳过编辑器:

git pull --no-edit origin master

容易踩的坑:以为是"电脑卡住了"而强行关掉终端窗口。它没卡,只是在等你用它认识的方式说话。

记录于 2026-07-25

仓库与工作目录

Q. 同一个项目,我电脑上有好几个文件夹。改完、提交、推送全都成功,一个错都没报,可网页上看不到我的改动——是没推上去吗?

推上去了,只是推到了另一个地方。命令全部成功恰恰是这类问题最难发现的原因——它不报错,只是安静地把东西放到了你没在看的那个仓库里。

为什么会这样

托管平台允许仓库换地址——改个名、转到组织名下、或者换个账号托管,都会让地址变一次。为了不让别人手上的旧副本突然失联,平台会把旧地址自动重定向到新地址。

这是个善意的设计,代价藏在后面:一个几个月前克隆下来的旧文件夹,今天你在里面 pull、push 依然全部成功,回显跟平时一模一样。它连的是旧地址,而旧地址被悄悄转到了新地址——所以你的改动确实推上去了,只是你人站在另一个文件夹里,改的是另一份副本。

「命令成功」和「你以为的那件事发生了」是两回事。报错会喊你,静默的成功不会。

先确认你站在哪儿

pwd
git remote -v

第一条告诉你此刻在哪个文件夹,第二条告诉你这个文件夹连的是哪个仓库地址。先看清楚这两个,再动手改任何东西。

怎么收拾

一台机器上,一个项目只留一个工作目录。多出来的那些这样处理:

  • 逐个进去跑上面那两条命令,认出哪个是你现在真正在用的;
  • 其余的先整体打包备份一份,别直接删——里面可能有你以为已经推上去、其实还躺在本地的改动;
  • 备份完,把多余的删掉。

容易踩的坑:靠文件夹名字判断哪个是对的。名字是你几个月前起的,地址是平台后来改的,两者不同步——能回答「这是哪个仓库」的只有 git remote -v。

记录于 2026-08-18

分叉、合并与回退

Q. 送审合并都完成了,回头删掉那个分支,git branch -d 却拒绝我,提示里还写着 "even though it is merged to HEAD" —— 到底合进去了没有?

合了。这句提示读着像自相矛盾,其实它在说另一件事:删除前的安全检查比对的是「上游」那条线,不是你刚刚合进去的主干。

为什么会这样

git branch -d 会先做一道安全检查,问的是:这个分支上的提交,别处已经收进去了吗?如果没有,删掉就等于把工作丢了,所以它拦下来。

问题在于「别处」指哪儿。你的分支若推到过远端(用 -u 推的那次就会设上),这道检查比对的就是远端那条线;而你的合并发生在主干上。两条线不是同一条,于是检查没通过。

提示里那半句 "even though it is merged to HEAD" 正是 Git 在告诉你:它知道你已经合进当前所在的主干了,但它检查的不是这个。它不是在跟你唱反调,是在说清楚自己刚才量的是什么。

先证明它真的可以删

git log origin/main..feat/your-branch

这条命令问的是:这个分支上,有没有主干还没有的提交?没有任何输出,就是没有——分支上的东西主干全都有了,删它不会丢任何工作。

确认之后再删

git branch -D feat/your-branch

大写的 -D 表示跳过那道检查。顺序不能反:先用上面那条命令拿到「零输出」这个证据,再用 -D。

容易踩的坑:因为「我记得已经合过了」就直接上大写 -D。记得合过和实际合过是两回事,而 -D 不会再问你第二遍——它删完就完了。那条 git log 只要一秒,它把「我记得」换成了「我看过」。

记录于 2026-08-18