文章目录Git 本地仓库从 git init 到第一次提交一、什么是 Git 仓库二、创建一个本地仓库三、git init 到底做了什么四、认识 .git 目录1. config2. HEAD3. hooks4. objects5. refs五、配置 Git 用户名和邮箱1. 全局配置和当前仓库配置2. 查看 Git 配置3. 删除 Git 配置六、工作区、暂存区和版本库1. 工作区2. 暂存区3. 版本库七、git add 和 git commit从暂存到提交1. git add2. git commit3. 第一次提交文件4. 一次提交多个文件八、查看提交历史总结Git 本地仓库从 git init 到第一次提交上一篇主要整理了 Git 为什么存在以及它能解决什么问题。从这一篇开始就正式进入 Git 的实际操作。学习 Git 时最先要掌握的不是分支也不是远程仓库而是本地仓库。因为 Git 的很多操作本质上都是围绕本地仓库展开的。只有先理解本地仓库、工作区、暂存区、版本库之间的关系后面学习add、commit、reset、branch、merge才不会觉得乱。一、什么是 Git 仓库在 Git 中仓库可以理解为一个被 Git 管理起来的项目目录。普通目录只是普通目录Git 不会自动管理它。只有当一个目录被初始化成 Git 仓库后Git 才会开始追踪这个目录中的文件变化。比如有一个目录gitcode如果它只是一个普通目录那么你在里面新增、修改、删除文件Git 并不会记录这些变化。想让 Git 管理这个目录需要先进入这个目录然后执行gitinit执行完成后这个目录就变成了一个 Git 本地仓库。简单来说Git 仓库 一个被 Git 接管并可以进行版本管理的目录。二、创建一个本地仓库先创建一个用于练习的目录。Linux / Git Bash 中可以这样写mkdirgitcodecdgitcode查看当前所在目录pwd然后执行初始化命令gitinit执行成功后通常会看到类似输出Initialized empty Git repositoryinxxxxx这句话的意思是Git 已经在当前目录下初始化了一个空仓库。这里有两个重点git init要在你希望管理的目录中执行初始化完成后当前目录下会多出一个隐藏目录.git。可以查看隐藏文件ls-a可能会看到其中.git就是 Git 仓库真正的核心。三、git init 到底做了什么很多人刚开始使用 Git 时只知道git init是初始化仓库但不清楚它具体做了什么。其实git init最重要的动作就是在当前目录下创建一个.git隐藏目录。这个.git目录里面保存了 Git 管理版本所需要的各种数据。也就是说真正让一个普通目录变成 Git 仓库的并不是目录名字也不是里面有多少代码而是它内部出现了.git目录。可以理解为普通目录 ↓ 执行 git init 带有 .git 目录的 Git 仓库如果把.git目录删掉这个目录就不再是 Git 仓库了。当然正常情况下不要手动修改或删除.git目录。因为 Git 的版本信息、提交记录、分支引用等内容都保存在里面。随便改.git目录很容易把仓库弄坏。四、认识 .git 目录初始化仓库后可以看一下.git目录里面大概有什么。在 Linux / Git Bash 中可以使用tree .git如果没有安装tree也可以使用ls.git看看我的一个刚初始化的.git目录中通常会包含类似这些内容.git/ ├── branches ├── config ├── description ├── HEAD ├── hooks ├── info ├── objects └── refs这些目录和文件后面都会逐渐接触到。现在先建立一个整体印象。1. configconfig保存当前仓库的配置信息。比如这个仓库单独使用的用户名、邮箱、远程仓库地址等都可能写在这里。2. HEADHEAD可以先理解为一个指针。它指向当前所在的分支后面学习分支时会频繁遇到它。刚开始可以先记住HEAD 和“当前版本”“当前分支”有关。3. hookshooks目录保存 Git 钩子脚本。钩子可以在某些 Git 操作前后自动执行脚本比如提交前检查代码格式。刚入门时暂时不用深究。4. objectsobjects是 Git 保存对象数据的地方。提交、文件内容、目录结构等底层数据最终都会以对象的形式保存在这里。5. refsrefs保存引用信息。比如分支、标签本质上都和refs有关。后面学习分支和标签时会继续展开。现在不需要一开始就把.git里的所有内容背下来只需要知道.git是 Git 仓库的核心里面保存了 Git 进行版本管理所需的全部信息。五、配置 Git 用户名和邮箱Git 安装完成后通常需要先配置用户名和邮箱。这是因为Git 的每一次提交都会记录提交者信息。如果不配置提交时可能会报错或者 Git 会使用不符合预期的默认身份。常用配置命令如下gitconfig--globaluser.nameYour Namegitconfig--globaluser.emailemailexample.com实际使用时把内容换成自己的信息gitconfig--globaluser.namezhangsangitconfig--globaluser.emailzhangsanexample.com这里的--global表示全局配置。也就是说这台电脑上当前用户下的所有 Git 仓库默认都会使用这个用户名和邮箱。1. 全局配置和当前仓库配置Git 配置有不同作用范围最常见的是两种全局配置当前仓库配置带--global的配置属于全局配置gitconfig--globaluser.namezhangsangitconfig--globaluser.emailzhangsanexample.com这种配置会影响当前用户下的所有 Git 仓库。如果平时都是用同一个身份提交代码使用全局配置最方便。如果不加--global就是当前仓库配置gitconfig user.namelisigitconfig user.emaillisiexample.com这种配置只对当前仓库生效。需要注意的是执行当前仓库配置时一般要在 Git 仓库目录中执行。比如有些场景下可能希望公司项目使用公司邮箱个人项目使用个人邮箱。这时就可以全局配置一个默认身份再在某个具体仓库中单独覆盖配置。例如先配置全局身份gitconfig--globaluser.namezhangsangitconfig--globaluser.emailpersonalexample.com然后在公司项目仓库中单独配置邮箱gitconfig user.emailworkexample.com这样这个公司项目就会使用workexample.com而其他仓库仍然使用全局邮箱。如果一个配置同时存在全局配置和当前仓库配置当前仓库配置优先级更高。2. 查看 Git 配置查看当前 Git 配置可以使用gitconfig-l可能会看到类似内容user.namezhangsan user.emailzhangsanexample.com如果只想查看某一项配置可以写gitconfig user.namegitconfig user.email如果想查看全局配置可以写gitconfig--globaluser.namegitconfig--globaluser.email3. 删除 Git 配置删除配置可以使用--unset。删除全局用户名gitconfig--global--unsetuser.name删除全局邮箱gitconfig--global--unsetuser.email删除当前仓库配置时不加--globalgitconfig--unsetuser.namegitconfig--unsetuser.email六、工作区、暂存区和版本库理解 Git必须先理解三个区域工作区暂存区版本库这三个概念非常关键。很多 Git 命令看起来难其实是因为没有弄清楚文件到底处在哪个区域。1. 工作区工作区就是我们平时真正编辑文件的目录。比如当前项目目录是gitcode那么这个目录中除.git以外的大部分内容都可以理解为工作区。你写代码、改文档、新增文件都是在工作区中完成的。例如gitcode/ ├── ReadMe ├── main.c └── src/这些文件就是我们能直接看到、直接编辑的内容。工作区的特点是可以直接编辑可以新增文件可以删除文件文件变化不一定已经被 Git 保存为版本。也就是说文件出现在工作区不代表它已经被 Git 版本管理起来了。2. 暂存区暂存区英文叫stage或index。它是工作区和版本库之间的中间区域。当执行gitaddReadMe这个操作并不是直接把文件提交到版本库而是先把文件修改放到暂存区。可以把暂存区理解为下一次提交前的准备区。你可以先把多个文件陆续放进暂存区然后一次性提交gitaddfile1gitaddfile2gitaddfile3gitcommit-madd three files虽然执行了三次git add但最后只执行了一次git commit。原因就是git commit提交的是暂存区中的内容。暂存区一般对应.git/index文件所以暂存区有时也被叫作索引区。3. 版本库版本库也叫仓库英文是repository。对于一个 Git 项目来说.git目录就是 Git 的版本库核心。版本库中保存了提交历史文件快照分支信息标签信息Git 配置对象数据。工作区是我们编辑文件的地方版本库是 Git 保存历史版本的地方。如果某个文件只是被复制到了项目目录中但没有执行git add和git commit那么它还没有真正进入版本库。所以可以记住这句话新建文件只是进入工作区执行git add后进入暂存区执行git commit后才进入版本库。七、git add 和 git commit从暂存到提交刚开始学习 Git 时很容易把git add和git commit混在一起。其实它们的职责不同git add 把工作区中的修改加入暂存区 git commit 把暂存区中的内容提交到本地仓库1. git addgit add的作用是把工作区中的修改加入暂存区。常见用法gitaddReadMe添加多个文件gitaddfile1 file2 file3添加某个目录gitaddsrc添加当前目录下所有变化gitadd.2. git commitgit commit的作用是把暂存区中的内容提交到本地仓库。常见用法gitcommit-m提交说明这里的-m后面要跟提交信息。提交信息非常重要不要随便写成gitcommit-mupdate这种信息后面看起来基本没有意义。更推荐写清楚本次提交做了什么例如gitcommit-madd ReadMe file或者gitcommit-mfix login error message好的提交说明能让后面查看历史记录时更容易理解项目变化。3. 第一次提交文件下面完整走一遍第一次提交文件的流程。先在仓库目录中创建一个ReadMe文件vimReadMe写入内容hello git hello git如果不使用vim也可以用其他编辑器创建这个文件。查看文件内容catReadMe输出hello git hello git此时ReadMe只是工作区中的一个文件还没有进入 Git 仓库。先添加到暂存区gitaddReadMe然后提交到本地仓库gitcommit-mcommit my first file我这里演示的是我之前的socket编程的代码提交成功后可能会看到类似输出[master(root-commit)c614289]commit my firstfile1filechanged,2insertions()create mode100644ReadMe这段输出可以简单理解为当前提交发生在master分支这是当前仓库的第一次提交所以有root-commit本次提交 ID 的前几位是c614289有 1 个文件发生变化新增了 2 行内容创建了一个新文件ReadMe。这里的master是分支名。不同 Git 版本或不同平台中默认分支名也可能是main。如果看到的是main也不用奇怪本质是一样的。4. 一次提交多个文件Git 支持多次git add然后一次git commit。例如创建三个文件touchfile1 file2 file3分别加入暂存区gitaddfile1gitaddfile2gitaddfile3最后一次性提交gitcommit-madd three files可能会看到类似输出[master 23807c5]addthree files3files changed,0insertions(),0deletions(-)create mode100644file1 create mode100644file2 create mode100644file3这说明三个文件被作为同一次提交保存到了版本库中。这里也能看出暂存区的作用暂存区可以帮我们组织下一次提交要包含哪些内容。不是所有工作区修改都必须一次提交。我们可以选择一部分修改加入暂存区再提交这一部分内容。这个习惯在真实开发中非常重要。八、查看提交历史提交完成后可以使用git log查看历史提交记录哎暴露邮箱了懒得打码了。工作邮箱而已欢迎大家学习交流。gitlog示例输出commit 23807c536969cd886c4fb624b997ca575756eed6(HEAD -master)Author: zhangsanzhangsanexample.comDate: Sat May611:27:3220230800addthree files commit c61428926f3853d4ec6dde904415b0e6c1dabcc6 Author: zhangsanzhangsanexample.comDate: Sat May611:25:5020230800 commit my firstfile从日志中可以看到每次提交都有一个commit id每次提交都有作者信息每次提交都有时间每次提交都有提交说明最新提交一般显示在最上面。其中commit id是 Git 为每次提交生成的唯一标识。后面做版本回退时经常会用到它。HEAD - master表示当前HEAD指向master分支而master分支当前指向这次提交。现在不需要完全理解 HEAD 和分支的细节只要先知道git log可以查看仓库的提交历史。总结这一篇从零开始整理了 Git 本地仓库的基本使用流程。主要内容包括如何使用git init创建本地仓库.git目录的作用Git 用户名和邮箱配置全局配置和当前仓库配置的区别工作区、暂存区、版本库三个核心区域git add和git commit的关系如何完成第一次文件提交如何一次提交多个文件如何使用git log查看提交历史。到这里已经可以完成最基本的本地提交操作了。下一篇继续围绕文件状态展开重点整理Git 如何识别文件新增和修改如何查看当前仓库状态git status怎么读git diff如何查看文件差异为什么提交前一定要检查修改内容。