Git工作区、协作与故障恢复
检查状态、差异与提交身份
需能区分工作区、暂存区和提交。先按当前状态选择合并冲突处理、推送拒绝排查或本地提交练习;练习使用支持 --initial-branch 的 Git 与 POSIX shell,在独立目录创建两次提交,不连接远端。 示例未在本轮执行。
Git 三棵树
工作区保存当前文件,暂存区保存下一次提交的快照,HEAD指向当前提交。编辑后不暂存的行不会进入普通commit;先区分这三份状态,再决定比较或恢复哪一份。
Git 差异比较
普通diff比较工作区与暂存区,diff --cached比较暂存区与HEAD。若文件同时有暂存和未暂存修改,两次比较都会出现;不能把空的普通diff当作没有待提交修改。
Git 身份配置
提交身份是提交元数据,远端认证是访问权限。仓库local配置可以覆盖global身份;共享机器不把个人邮箱写入仓库模板,SSH密钥和HTTPS令牌也不等于user.name。
依据与适用范围
- 本课官方依据,资料核对日2026-10-17。
以上依据用于解释本文列明的规则;示例未执行,不代表产品全部能力或跨平台验证。历史资料的版本、账号与界面位置需按目标环境确认。
选择分支与整合方式
Git 分支引用
分支引用指向提交,创建分支不复制全部文件。切换分支可能更新工作区;未提交改动若与目标冲突会阻止切换。先保留修改,再选择新分支承接工作,不把分支名当备份文件。
Git 合并与变基
merge保留分叉并连接两条历史,rebase把提交重放到新基底,通常产生新的提交标识。已共享历史需要协作约定;选择取决于历史语义而非图是否好看。
Git cherry-pick 顺序
cherry-pick按补丁重放选定提交,不自动带上所有前置依赖。若B依赖A,应先A后B并核对目标分支是否已包含等价修改。冲突时继续前必须审阅最终差异,不能只删冲突标记。
处理冲突、恢复与拒绝推送
Git 合并冲突处理
合并冲突表示同一结果无法自动决定,并不表示任一边必然正确。逐块理解共同祖先与双方目的,保留需要的业务语义,再暂存解决结果。未完成时使用对应merge或cherry-pick的abort,不能混用流程。
Git reset 恢复边界
reset --soft移动当前分支而保留暂存区和工作区;mixed还重置暂存区;hard会覆盖工作区并可能覆盖妨碍写入的未跟踪路径。先独立备份再选择,revert更适合需要保留共享历史的反向修改。
Git non-fast-forward
non-fast-forward说明远端目标不是本地提交的祖先,需要先获取并检查分叉。权限拒绝属于认证或授权问题,不能用强制推送解决。即使用force-with-lease也要理解预期远端引用与协作边界。
代理、忽略、对象与子模块的排错分流
Git 代理拒绝和受保护分支如何分别排错?旧环境出现 Failed to connect to 127.0.0.1 port 1080,先用 git config --show-origin --get-regexp '.*proxy' 查来源及作用域,再核对代理进程和端口。确认不再需要该 global http.proxy 时才 unset;全局修改影响其他仓库,取消代理不能修复必须经代理访问的网络。
文件持续被忽略时,核对 core.excludesFile 返回的路径,再用 git check-ignore -v <path> 定位具体规则;历史机器的 .gitignore_global 只是一个配置实例。fetch first / non-fast-forward 需要 fetch 后检查分叉,受保护分支的 pre-receive hook declined 则由托管策略决定;这两类故障均不能靠清空历史绕过。
对象存储异常先保留仓库副本与完整错误,再用 git fsck --full 和 git log --oneline --decorate --all 分别检查完整性与可达历史。旧记录没有足够证据判断损坏原因,直接删对象文件的建议已撤回。
子模块 api already exists in the index 怎么判断?添加子模块遇到 'api' already exists in the index,先辨认普通目录、既有子模块和残留索引。只有确认要转换并保存原内容后,才移除该路径索引记录、把原目录移至已核对备份,再按真实地址 submodule add,sync 与 update --init。--cached 保留工作区但会改变提交跟踪方式,不等于无副作用。原拼写 submodoule 已撤回;本节没有执行任何转换。
Git 合并冲突
定位冲突文件,逐处确认保留的内容,再完成合并。
适用于 merge 已停在冲突状态的分支。先确认当前分支和未提交改动;冲突标记两侧都可能包含必须保留的业务逻辑,不能机械地只选一边。
排查步骤
1. 列出尚未解决的文件
git status --short
git diff --name-only --diff-filter=U预期结果: 输出仅包含待处理文件;记录当前分支,避免改错分支。
2. 逐处阅读冲突区域
git diff -- <file>预期结果: 结合上下文理解双方改动,在编辑器中处理 <<<<<<<、=======、>>>>>>> 标记。
3. 暂存并完成合并
git add <file>
git status --short
git merge --continue预期结果: 所有冲突文件均已解决后,合并继续;再运行项目测试验证最终组合。
常见报错
Unmerged paths
原因: 文件仍有未解决的冲突,或修改后还未暂存。
处理方式: 检查冲突标记,确认内容后 git add;再次查看 git status。
MERGE_HEAD exists
原因: 前一次合并仍未结束。
处理方式: 先用 git status 确认状态;继续解决并 merge --continue,或确认后用 git merge --abort 放弃本次合并。
相关文档
官方资料
Git 推送被拒绝
确认远端新增提交与权限问题,再同步分支。
先区分 non-fast-forward 与认证失败。共享分支有新提交时,先获取并审查远端历史;不要直接强制推送覆盖他人工作。
排查步骤
1. 确认分支与上游
git status -sb
git branch -vv预期结果: 看到当前分支、上游和本地是否有未提交改动。
2. 比较本地与远端提交
git fetch origin
git log --oneline --left-right HEAD...origin/<branch>预期结果: 左右两侧标记显示各自独有的提交,能判断是否需要整合远端更新。
3. 整合后重试推送
git merge origin/<branch>
git push origin <branch>预期结果: 先解决可能的合并冲突并运行测试;推送成功后远端包含双方提交。
常见报错
non-fast-forward
原因: 远端分支包含本地没有的提交。
处理方式: 先 fetch 并比较历史,再按团队约定 merge 或 rebase;不要直接 force push。
Permission denied
原因: 账号、凭据或仓库写入权限不匹配。
处理方式: 确认 remote URL、当前身份和仓库权限;修复认证后重试,合并历史不会解决权限问题。
相关文档
官方资料
继续阅读
- Git完整实践与解答
- Git上手与对象
- Git任务与配置