FAQ Library
全部常见问题
把首页里的高频问答整理成一页更完整的 Git FAQ,方便集中阅读和后续持续扩充。
FAQ Library
pull 与同步
围绕 fetch、pull、push 以及远端同步节奏,把最常见的理解偏差拆开说明。
`git pull` 会先执行 fetch,再把上游分支整合进当前分支。官方文档说明它可以走 `--ff-only`、`--rebase`、`--no-rebase` 或 `--squash` 等不同路径,所以结果取决于你的命令参数和 `pull.rebase`、`pull.ff` 等配置。想减少意外,最稳妥的习惯仍然是先 fetch,再明确决定是 merge 还是 rebase。
因为 pull 解决的是“获取并整合上游变化”,但它不保证你对当前分支、跟踪关系和历史状态的理解一定正确。更稳的排查顺序通常是先看 `git branch -vv`,确认当前分支跟踪谁,再看 `git log --oneline --graph --decorate --all`,确认分叉位置。很多“pull 了还是不一样”的问题,本质上是站错了分支,或者在错误的远端关系上做了同步。
最常见的原因是远端分支已经有了你本地没有的新提交,Git 不允许你直接把历史覆盖掉。通常更稳的动作不是立刻强推,而是先 `git fetch origin`,再判断应该 merge、rebase,还是只是站错了分支。只有在你完全明确历史覆盖风险的情况下,才考虑 force push,而且这通常不应该发生在共享分支上。
`--ff-only` 最适合你希望“只接受快进更新,不做额外整合动作”的场景。它的价值在于:如果当前分支已经和远端分叉,它会直接失败,而不是替你创建 merge commit 或触发其他整合路径。所以在稳定主分支、发布分支或你想强制保持同步动作可解释的时候,这个参数特别有用。
因为 fetch 把“观察远端状态”和“改动当前分支”拆成了两步。你可以先看清远端有没有变化、当前分支有没有分叉、接下来更适合 merge、rebase 还是继续等待。对于初学者和团队协作来说,这种先观察再整合的节奏通常比直接 pull 更容易控制风险。
FAQ Library
reset 与恢复
围绕 reset、reflog、回滚与找回,把常见误操作后的判断路径说明清楚。
官方手册把区别讲得很明确:`--soft` 只移动 HEAD,保留暂存区和工作区;`--mixed` 会把暂存区重置到目标提交,但保留工作区改动;`--hard` 会同时改写 HEAD、暂存区和工作区。也就是说,真正危险的是 `--hard`,因为它会直接覆盖当前文件状态。
很多时候可以。Git 官方在 `git reset` 文档里专门说明了 `ORIG_HEAD` 和 reflog 的用途:reset、merge、pull 这类操作通常会留下可回溯的引用。只要对象还没被垃圾回收清理掉,通常都能先通过 reflog 找到原来的提交,再决定是新建分支还是回退引用。
可以简单理解为:`revert` 是通过新提交“抵消旧提交”,更适合已经共享出去的历史;`reset` 是直接移动分支引用,更适合你还在本地整理、撤销或重排历史的时候。高风险点在于,如果一段历史已经被别人拉走了,再用 reset 改写它,往往会把自己的整理动作变成团队同步问题。
reflog 记录的是引用移动历史,而不是“你做过的全部事情”。像 HEAD、分支、merge、reset、rebase 这类会移动引用的位置,通常都会留下 reflog 记录。它之所以常常能救命,是因为你哪怕把分支指针挪走了,Git 仍然可能暂时记得它曾经指向哪里,从而让你重新找到那个提交。
因为 reflog 和底层对象都不是永久保存的。只要对象不再被任何引用保留,而且超过了垃圾回收窗口,就可能被 Git 清理掉。所以恢复动作通常越早越好;一旦你意识到自己可能误删或误 reset,最好先停止继续折腾仓库,先把 reflog、log 和当前引用位置看清楚。
FAQ Library
stash、切换与历史边界
围绕 stash、切换分支、detached HEAD 以及 merge/rebase 选择,补齐最常见的判断边界。
因为 stash 默认保存的是已跟踪文件在工作区和暂存区中的改动。官方文档说明,如果你还想把未跟踪文件一起收进去,需要用 `git stash push -u`;如果连忽略文件也要一起处理,则使用 `-a`。另外,`git stash apply` 会保留 stash,而 `git stash pop` 会在成功应用后尝试把它移出列表。
不一定。官方 `git switch` 文档把 detached HEAD 描述成一种用于检查历史提交或做临时实验的状态,此时 HEAD 指向的是某个提交而不是分支名。它本身不是错误;如果你在这个状态下做出的提交值得保留,只要立刻新建一个分支把它接住就可以。
Git 官方书把两者都视为整合历史的正常方式:merge 会保留分叉结构,rebase 会把你的提交重新放到新的基底上,让历史更线性。但官方书也特别强调,不要 rebase 那些已经离开你本地仓库、并且别人可能已经基于它继续工作的提交。简单说,个人本地整理历史常用 rebase,已共享历史默认更安全的是 merge。
官方 `git switch` 文档说明,当切换分支会导致本地改动丢失时,Git 会直接中止操作。这不是故障,而是保护机制。通常你有三种稳妥处理方式:先提交、先 stash,或者在你确认可以丢弃本地改动时再显式使用 `--discard-changes`。
如果你只是短时间切任务、且当前改动还不适合形成提交,stash 往往最方便;如果这些改动已经具备明确边界,而且你希望保留上下文,直接 commit 到当前分支通常更清晰;如果改动既不适合进正式分支、又可能需要较长时间保留,切一个临时分支往往比长期堆 stash 更容易追踪。核心判断标准不是命令偏好,而是这些改动值不值得被长期命名和保留。