
简介一份面向Web开发入门者及需要掌握版本控制技能的开发者的Git学习笔记聚焦Git仓库初始化与本地常用操作系统讲解Git分布式架构、快速与完整性特点、历史记录与回滚作用并与SVN等集中式版本控制系统作了命令级对比。文档结合git init、git add、git commit、git config等命令详细演示了在空目录中创建新仓库、将现有项目目录转换为Git仓库、配置全局与局部用户信息的具体操作并针对工作区、暂存区与提交的关系给出了实践示例便于在本地项目起步阶段快速建立规范版本管理流程。资源为docx格式共1个文件压缩包总大小约26KB轻量便携可直接阅读。已有114人学习浏览适合想从零入门Git、理顺本地仓库操作链的读者。使用后可以独立完成仓库搭建、文件跟踪、状态检查与提交归档等操作为后续分支合并、远程协作打下基础。1. Git 本地仓库不是“存文件”是给改代码留后悔药写代码最难受的不是报错而是改了一下午发现思路错了想退回上午那个能跑的版本却找不到任何痕迹。Git 的本地仓库就是干这个的在你电脑上维护一份完整版本历史让每次提交、每次分支都有据可查。标题里的“Git 初始化与本地仓库操作”指的就是从安装 Git、git init 建立仓库到提交文件、查看历史、管理分支这一整套不依赖服务器的动作。它适合一个人开发、还没上团队协作的初学者也是把版本管理跑通的最小闭环。把这套动作练熟你就有了写代码的后悔药——随便折腾总能找回上一个能用的版本。2. 从零装 Git 到第一次 git init环境、身份与仓库骨架2.1 三端 git 安装与第一道验证装完先看 git --version很多人拿到 Git 第一步不是装环境而是先去找可视化工具。我建议反过来先装好命令行 Git把 git 命令跑通再决定要不要套图形界面。因为无论你之后用 VS Code 的源代码管理、SourceTree 还是 JetBrains 系列底层调用的都是这套命令行 Git。命令行能跑通图形界面才能不踩“库初始化失败”“项目初始化错误”这类环境问题。常见做法是按操作系统分开装平台安装方式日常操作终端Windows下载 Git for Windows 安装包一路默认选项即可Git BashmacOSbrew install git或官网 pkg 包TerminalLinuxsudo apt install gitDebian/Ubuntu、yum install gitCentOSTerminalWindows 上我一般默认选 Git for Windows装完开始菜单里会出现 Git Bash。它模拟了一套 Linux 风格 shell补全、路径、换行处理都更顺手。不建议在 cmd 或 PowerShell 里硬用 gitWindows 原生命令行对单引号、通配符的处理和 Git 期望的行为不一致遇到奇怪报错很难排查。装完第一道验证不是打开界面而是在终端里执行git --version如果输出git version 2.xx.x这样的信息说明安装成功。这一步能过滤掉大部分“装完不知道怎么进环境”的困惑。如果提示command not found多半是安装时没把 git 加进 PATH或者装完没有重开终端。重开终端再看一次不行就检查安装选项里“Add to PATH”是否勾选。2.2 git init仓库是怎么“长”出来的环境就绪后初始化本地仓库只需要一条命令。我一般会先建一个专门的项目目录再进去执行初始化避免把仓库建在乱七八糟的目录里。演示完整过程mkdir my-project # 建项目目录 cd my-project # 进入目录 git init # 初始化本地仓库 ls -la .git # 查看仓库骨架git init会在当前目录生成一个.git子目录这就是整个本地仓库的本体里面存着提交对象、分支指针、配置信息和钩子脚本。HEAD记录当前所在分支config存仓库级配置objects存提交和文件内容对象refs存分支和标签指针。初学者不需要逐项理解但要知道一条原则.git目录坏了版本历史就悬了日常别去手动删里面的文件。注意git init 只负责“建仓库”不会自动提交任何文件也不会把当前目录已有的文件纳入版本管理。如果你在一个写了一半的项目目录里执行 git initgit 只会安静地把仓库建好然后等你用 git add 和 git commit 把文件装进去。这跟很多人印象里“初始化就是建好完整项目”不一样是新手常见的理解偏差。这一步不产生任何系统级初始化动作纯粹是给当前目录挂上一套版本管理外壳。想确认当前目录是否已经是仓库可以用git rev-parse --is-inside-work-tree输出true说明在仓库内。这个命令在排查“明明执行了 git 却提示 not a git repository”时很好用一般是目录进错了或者仓库建在了上级目录。2.3 提交前必须配置身份user.name 与 user.email 的作用范围仓库建好先别急着提交。Git 要求每次提交带作者身份没配置就提交会直接报错提示Please tell me who you are。常见做法是用全局配置一次性设好后续所有仓库默认继承git config --global user.name 你的名字 git config --global user.email youexample.com git config --listgit config --list会列出当前生效的全部配置用来验证是否写进去了。如果看到user.name和user.email说明身份配置完成。这里有个细节user.email 不一定要用真实邮箱但要填一个长期能用的地址将来接远程托管平台时这个邮箱最好和平台账号一致否则提交记录里的头像和账号关联不上看着很别扭。配置的作用范围分三档--system作用整台机器所有用户--global作用当前系统用户的所有仓库--local只作用当前仓库。默认不写参数时git config 操作的是--local。我一般习惯把姓名、邮箱这种通用信息放--global把某个仓库特有的配置放--local这样换项目时不会被上一份工作的名字污染提交记录。这就是一套最精简的 git 安装及配置流程后面所有仓库都会继承这套身份配置。排查配置被“覆盖”时git config --list --show-origin很有用它会列出每条配置来自哪个配置文件直接看出是全局配置生效还是仓库配置把全局值盖掉了。这个命令在处理“我明明设置了用户名提交时却显示别人的名字”这类玄学问题时比挨个文件翻快得多。身份配置完成后初始化本地仓库的最小闭环就是装 Git、git init、配身份。到这里还没涉及远程仓库git clone、git remote 这些命令都属于“连远端”阶段等真正需要和远程协作时再学也不迟。本地这套动作跑顺后面接远程仓库时会自然得多。3. 本地仓库的日常循环status、add、commit 与 log3.1 先拆黑匣子工作区、暂存区、仓库三块地怎么协作Git 本地仓库的文件状态不是“改了/没改”二元制而是三块区域之间的流转工作区、暂存区、仓库。工作区就是你磁盘上看到的真实文件暂存区是一个中间缓冲区git add 把工作区的改动装进去仓库是.git目录里存储的已提交版本。commit 的动作是把暂存区的内容固化成一次版本快照写进仓库。把这个模型想成“草稿箱”最好懂文件先在工作区改改完用 git add 放进草稿箱确认没问题后 git commit 正式发出去。很多人第一次用 Git 会直接跳步改完文件就 commit结果发现 commit 什么都没记录就是因为没先 add。这不是 Git 的缺陷而是设计上故意把“改”和“提交”分开让你在提交前有检查的机会。三块区域的边界状态直接影响后续命令的输出。文件可能处于未跟踪、已暂存、已修改、已提交四种状态。搞不清这些状态你只会在 git status 的输出里来回猜。这也是我把 status 放在所有操作前面讲的原因它是一面镜子能直接告诉你文件现在站在哪块区域。3.2 git status读不懂状态就动手早晚翻车在项目里新建一个 README 文件然后跑一次 status是最直观的入门方式echo # demo README.md git status输出里 README.md 会出现在 Untracked files 段落意思是这个文件还没被 Git 跟踪。此时它只在工作区git 知道它的存在但不知道它属于版本历史。执行git status -s得到紧凑格式?? README.md??表示未跟踪。紧凑模式在文件多的时候特别好用不会刷满屏。如果文件已经被跟踪且修改过status 会显示 Changes not staged for commit意思是工作区有改动但这改动还没进暂存区。此时git diff能看具体改了哪些行。如果文件已暂存但还没提交会显示 Changes to be committed此时git diff --cached能看暂存区里将要提交的内容。我见过不少新手每次提交前不看 status直接 add 全部文件然后 commit结果把临时文件、日志文件一起提交进去仓库越来越脏。养成提交前先git status看一眼的习惯能避免绝大多数“提交了不该提交的东西”的后悔场景。这不是技巧是纪律。3.3 git add 的三种写法与撤销暂存git add 是决定“哪些改动进入这次提交”的动作写法不同口径不同git add README.md # 精确加一个文件 git add . # 加当前目录下所有改动 git add *.md # 加所有匹配 .md 后缀的改动git add .最常见也最容易出事它会一次性把所有改动都装进暂存区包括你不想提交的调试输出文件。我一般建议在文件数量少或明确知道改动范围时用精确文件路径改动多时先git status扫一遍确认没有可疑文件后再git add .。git add *.md这种通配符写法适合批量操作同一类型文件注意它遵循 shell 的通配规则不是 git 自己的过滤规则。如果 add 加错了撤销暂存用git restore --staged README.mdgit restore --staged把文件从暂存区移回工作区文件内容保持不变。注意不要用老教程里的git reset HEAD file来干这件事功能类似但 restore 语义更清晰也更符合现代 Git 的操作习惯。撤销暂存后git status 会把它重新归到未暂存或未跟踪的段落这时候再重新 add 正确文件就行。3.4 git commit 与 git log提交历史的“记账本”暂存区准备好后提交操作本身很简单git commit -m docs: 添加项目说明 git log --oneline --graph-m后面跟提交信息。提交信息是给未来的自己看的我习惯用动词开头比如 fix: 修复登录按钮失效、feat: 新增导出功能、docs: 补充部署说明。前缀用来区分改动类型在 log 里扫一眼就能看出项目演进脉络。如果提交时忘写-mGit 会打开一个编辑器让你输入信息在 Git Bash 里默认可能是 Vim新手容易卡在“不知道怎么保存退出”。要么记住 Vim 的:wq退出要么老老实实每次都带-m。git log --oneline --graph是查看提交历史的常用姿势--oneline把每次提交压成一行哈希加信息--graph用字符画出分支走向。对一个本地仓库来说看到整洁的提交历史说明前面 add 和 commit 的节奏是对的。想看某次提交具体改了什么用git diff HEAD~1对比上一次提交用git diff HEAD --stat只看改了哪些文件。这些都是本地操作不会影响任何远端完全可以放心试。这个章的节奏很关键status 看状态add 选内容diff 检查commit 固化log 回顾。按这个循环走本地仓库的基本盘就稳了。4. 分支与本地仓库管理一切操作先开分支心里不慌4.1 分支是平行世界创建、切换、查看本地仓库操作里分支是最能体现 Git 优势的部分。分支可以理解为平行世界在 feature 分支上随便折腾不影响主分支的稳定版本。创建并切换分支git branch feature-login # 创建分支 git checkout -b feature-login # 创建并切换分支 git branch -v # 查看本地所有分支和最近提交git checkout -b是创建分支最顺手的写法一步完成“创建切换”。git branch -v会列出本地分支和各自指向的提交方便确认当前在哪个分支上。当前分支用git branch输出里的*号标识也可以用git status第一行查看。有个习惯值得从一开始就养成改代码之前先确认自己在哪个分支不要在 main 分支上直接写新功能。创建分支的默认基准是当前 HEAD。新仓库第一次提交后Git 默认分支名在较新版本里是 main早期版本是 master如果你本地的默认分支名和团队不一致可以用git branch -m main master改名。这里不展开只是提醒你看到分支名不同时别觉得是出错了。现代 Git 也推荐用git switch替代checkout做分支切换git switch -c等价于git checkout -b。老教程多用 checkout两个都能用我习惯按老命令讲因为网上存量资料里 checkout 出现频率高你看到旧命令能看懂就行。分支本质上是一个指向提交的指针创建分支就是新建一个指针成本极低几乎不占空间。所以“开分支”这件事在本地仓库里应该被当成零成本操作来用每做一个独立需求、独立修复都可以先开一个分支做完再合并回去。等你需要处理多个并行改动时这个习惯能帮你避免“改到一半发现另一个需求也要改同一个文件”的狼狈。4.2 git merge合并结果和一次经典冲突处理合并分支用git merge。常见做法是切回接收方分支再合并进来git checkout main git merge feature-login如果两个分支改动互不干扰merge 会直接成功Git 自动生成一次合并提交log 里能看到分支汇入的痕迹。如果两个分支改了同一个文件的同一区域就会产生冲突。冲突时 Git 不会自动帮你定夺而是把冲突标记写进文件 HEAD 当前分支的内容 feature-login 分支的内容 feature-login看到这种标记不用慌手动编辑文件决定留下哪部分删掉冲突标记然后git add index.html git commitmerge 后提交的是“合并结果”不是冲突文件本身。冲突体验第一次总是有点吓人但处理几次就熟Git 把两边的差异原样摆出来你当裁判决定谁留下或都保留。处理冲突的关键是别慌也别用git checkout -- .把整个目录重置那样会把另一边的改动一起丢掉。如果 merge 到一半发现合错了或者冲突太多不想手动处理可以用git merge --abort取消合并回到 merge 之前的状态。这是一个很实用的后悔药别硬着头皮合完才后悔。合并前我会习惯先确认当前分支和工作区状态git status显示工作区干净再 merge。否则带着未提交的改动去 merge容易把状态搅乱出现“合并完我改动不见了”的错觉。这个习惯能避开大多数本地仓库里的灰色问题。4.3 本地仓库的后悔药reset、restore、stash 怎么选本地仓库操作里最常被问“我操作错了怎么回退”的就是 reset 和 stash 这套。reset 三个模式有明确差异命令作用工作区暂存区git reset --soft HEAD~1撤销提交保留保留git reset --mixed HEAD~1撤销提交默认保留清空git reset --hard HEAD~1撤销提交清空清空HEAD~1表示当前提交的上一次。--soft只是撤销了提交动作改动都还在暂存区里适合“提交后发现漏了东西”。--mixed是默认行为提交被撤销改动退回工作区适合“提交早了还想再改改”。--hard会把提交、暂存区、工作区一起恢复到指定版本工作区里未提交的改动会永久丢失。这条命令是真正意义上的翻车点用之前一定要确认工作区没有要保留的东西。注意reset --hard 会清空工作区未提交的改动执行前先 git status 确认。restore 系列则更细粒度git restore --staged撤销暂存git restore file把工作区文件恢复到暂存区或 HEAD 的版本。它不会移动 HEAD只针对单个文件比 reset 安全得多。日常“改错了一个文件想还原”第一反应应该是 restore而不是 reset。restore 和 reset 的分工可以用一句话记restore 是“改了某文件要还原”reset 是“提交历史的回退”。restore 操作的是工作区和暂存区的文件内容reset 操作的是 HEAD 指针和提交历史。改坏一个文件第一反应应该是 restore提交错了要撤销才轮到 reset。临时要切换分支但手头改动还没做完就用 stash 把工作区暂时存起来git stash push -m 登录功能做到一半 git stash list git stash popgit stash push把工作区改动打包存进 stash 列表git stash pop再把最近一次 stash 弹回工作区。存的时候带-m写清备注否则 stash list 里全是匿名条目过几天根本分不清哪条是哪条。stash 的定位是暂存不是长期保存放太久不处理和分支混在一起容易造成混乱。5. 本地仓库操作避坑5 个真实踩过的“玄学”这一章整理 5 个在本地仓库操作里高频出现的疑难杂症每一个都是我实际踩过或帮人排过的。它们看起来像代码问题本质上都是状态、配置或环境问题。5.1 现象.gitignore 明明写了规则文件还是被提交原因.gitignore 只对“未被跟踪”的文件生效。如果文件已经 git add 过它已经在 Git 的跟踪列表里之后在 .gitignore 里补规则不会把已跟踪文件踢出去。这是整个 gitignore 问题里最常见的误解很多人以为写进去就自动被忽略结果提交后文件还是进了仓库。解决把已跟踪文件从索引移除保留工作区文件git rm --cached file git add .gitignore git commit -m chore: 停止跟踪不需要的文件git rm --cached只删除索引记录不删磁盘文件。处理后文件进入未跟踪状态.gitignore 规则才开始生效。.gitignore 的规则本身不难build/忽略整个目录*.log忽略后缀!important.log表示例外保留。注意例外规则只有在父目录没被忽略时才有效。建议规则从简单开始按需补充不要一开始抄一大份通用的容易把该提交的文件也忽略掉。新项目一开始就把该忽略的目录写进 .gitignore比如临时文件、构建产物、IDE 配置比事后补救省心得多。5.2 现象Windows 下只改一行代码git status 显示整个文件都变了原因换行符。Windows 用 CRLFLinux/macOS 用 LF。Git 默认会把仓库里的 LF 在检出时转成 CRLF提交时再转回 LF。如果同一文件里既有 CRLF 又有 LF或 core.autocrlf 配置不一致git 会把整个文件的换行符差异当成内容差异于是只加了一行却显示“整个文件被改”。这是我在 Windows 上踩过的血泪经验属于典型的跨平台换行符翻车。解决Windows 上统一设置core.autocrlf true仓库内部统一存 LFgit config --global core.autocrlf truemacOS/Linux 一般设input检出时转 LF提交时不转。更彻底的做法是在仓库根目录加.gitattributes文件写上* textauto让 Git 自动按文本类型处理换行。验证某个文件到底是内容变了还是换行符变了可以用git diff --ignore-space-at-eol看排除行尾差异后的结果如果排除后没有实际内容差异那基本就是换行符的锅调整 autocrlf 配置后重新提交即可。注意历史文件已经混入 CRLF 的仓库不要一次性做全量转换否则一次提交会带上大量无关改动要转换就单独安排一次格式化提交并在提交信息里写清楚避免污染历史。5.3 现象commit 提交后才想改注释或者发现漏了一个文件原因提交已经生成但还没推送到远程本地仓库范围内其实完全有后悔余地。犯错的不是“写错注释”而是不知道本地提交可以安全改写。解决用 git commit --amend 修正上一次提交git commit --amend -m 修正后的注释 git add forgotten.txt git commit --amend --no-edit-m会替换原提交信息--no-edit表示保持原注释不变只补充文件。amend 的本质是生成一次新提交替换旧的提交所以提交的哈希会变。在本地仓库里这样做没有任何风险但如果提交已经推送到远程就不要用 amend 去改公共历史否则别人 pull 下来会看到分叉历史。这个原则要记住本地随便改远程需谨慎。另外 amend 只能修补最近一次提交如果想改更早的提交就需要 rebase 这类会重写历史的操作本地仓库里能做但那是一个更大的话题。先把 amend 用熟它覆盖了八成的“刚提交就后悔”场景。5.4 现象git stash list 是空的但明明记得自己存过东西原因stash 是跟着仓库走的不存在跨仓库的 stash。换了一个目录执行 git stash list自然什么都看不到还有一种可能是 stash pop 时被弹出后又因为后续操作被覆盖或丢弃。stash 列表清空了不代表数据立刻消失但抢救窗口比较短。解决先确认在正确的仓库目录下执行git stash list。如果确实弹丢了可以尝试用git fsck --no-reflogs找悬空提交git fsck --no-reflogs | grep commitgit fsck会列出仓库里没有被引用但仍存在于对象库里的提交对象配合git log查看这些悬空提交的内容找回 stash 或误删分支的场景都能救回来。这个命令有点冷门但它是 Git 本地仓库在数据层面最后的兜底值得记下来。为了避免 stash 找不到我一般随手就 pop不在 stash 里囤东西。stash 的用途是“临时避让”不是“第二份工作区”长期不用的改动应该开一个分支放进去而不是一直压在 stash 里。5.5 现象Git Bash 突然报 git open /dev/null or dup failed原因在 Windows 上长时间开着大量编辑器、终端和 Git 进程时文件句柄耗尽会出现这个错误另一种常见情况是当前终端所在的目录已被删除Git 无法创建临时文件。这个报错信息看着像代码问题实际上跟代码没有任何关系属于运行环境层面的句柄问题。解决先关掉不用的编辑器、多余的 Git Bash 窗口cd到一个真实存在的目录里再重开终端执行 git 命令。这个报错在 Git Bash 里偶发在 cmd 里一般不出现遇到先看是不是终端卡死重开一个干净的 Git Bash 窗口往往直接解决。频繁出现就考虑升级 Git for Windows 版本新版对 Windows 句柄管理更稳。别浪费时间去查代码或改仓库配置这个坑和运行状态有关不是仓库数据问题。6. 用 git reflog 找回“以为删掉的提交”本地仓库的底线验证前面讲的 reset、restore、stash 说到底都是“还没彻底丢”的操作。真正让人心里没底的场景是reset --hard 之后连 log 里都看不到了是不是就没了答案是不一定。Git 还有一个记录所有 HEAD 移动痕迹的机制叫 reflog。它记录的是 HEAD 在本地仓库里的每一次变动即使提交被 reset 掉reflog 里还留着那个提交的哈希。演示一下完整找回流程echo v1 app.txt git add app.txt git commit -m app v1 git reset --hard HEAD~1 # 模拟误操作app.txt 没了 git reflog # 找到 app v1 对应的哈希 git cherry-pick hash # 把那次提交恢复到当前分支git reflog输出里能看到HEAD{0}、HEAD{1}这样的条目每条对应一次 HEAD 移动。“app v1”这次提交虽然从 log 里消失了但 reflog 里还留着它的哈希用git cherry-pick把这个提交的改动在当前分支上重新生成一次文件就回来了。cherry-pick 的作用是把指定提交的改动应用到当前分支相当于“把丢掉的改动捡回来”。注意reflog 条目默认保留 90 天执行 git gc 会按配置清理。所以发现误删之后越早动手找回成功率越高隔几个月再想来处理数据可能真的被回收了。我不建议把 reflog 当常规操作天天用但它存在的意义是让你敢在一个本地仓库里放手实验只要没跑 git gc多数误操作都有后悔药。我现在养成的习惯是每天下班前在项目目录里跑一次git status看一眼有没有改到一半没提交的文件提交前再用git diff HEAD快速检查一遍改了什么。这个习惯帮我省掉了大量“我昨天改的呢”的找补时间。Git 本地仓库这套东西真正的价值不在于命令多熟而在于养成一种“改动有记录、回退有依据”的工作方式。希望帮到你。本文还有配套的精品资源点击获取