[git]git是如何工作的

164 阅读5分钟

参考网址

juejin.cn/post/734350… 感谢大佬的无私分享

下图是:git的3种状态, 4个核心区域的图形化的描述, 非常的清晰

图片.png

为了更好理解上图的核心内容,我们以代码提交这个过程为例:

  1. 在工作区中进行文件操作,被修改后的文件,状态就会变成 modified;
  2. 执行 git add 命令,文件状态变成 staged,更改的部分会被添加到暂存区;
  3. 执行 git commit 命令,已暂存的文件会被提交到本地仓库,状态变为committed;
  4. 执行 git push,本地仓库的代码会被同步到远程仓库;

上述描述的 4个核心区域,其实都是 Git的一些逻辑结构

git的3种状态

在 Git中,文件有三种状态:modified(已修改)、staged(已暂存,已缓存)、committed(已提交)。

  • 已修改:表示文件在工作区被修改了,但还未进入缓存区;
  • 已暂存:表示在工作区被修改的文件进入了缓存区,即将被提交(git add)
  • 已提交:表示缓存区的数据被提交到本地仓库中(git commit)

4个核心区域

Git 包含 4个核心区域:

  • 工作区: Working Directory

  • 暂存区: Staging Area

  • 本地仓库: Local Repository

  • 远程仓库: Remote Repository

工作区

工作区,顾名思义,就是我们干活的区域,一般是电脑上肉眼可见的目录。

如下图:磁盘上 yuanjava/git-project 目录就是一个工作区。

图片.png

暂存区

暂存区,有点类似于[草稿箱],用 Git 的术语叫做“index(索引)”,本质是一个二进制文件,即 {工作目录}/.git/index,如下图:

图片.png

本地仓库

本地仓库,就是 .git目录,它完整地保存了 git 项目的历史记录,包含了项目的所有文件、提交历史、分支、标签等信息。

通过执行 git init 命令就能在工作区下生成一个 .git目录。

如下图:

图片.png

远程仓库

远程仓库,其实就是代码的远程服务器。

比如:GitHub、GitLab 或自建的服务器。

远程仓库可以被多个开发者访问和操作,允许团队成员协同工作,共享代码并进行版本控制。

git的常用命令

git init

git init 命令的功能如下:

  • 初始化仓库:将当前工作区初始化成一个新的 git仓库;
  • 生成隐藏的 .git目录:其中包含了Git用于跟踪项目历史、版本控制等所需的全部内容。
  • 默认配置:初始化 git仓库时,会生成默认的配置文件(如 .git/config),用于设置 git的行为和属性。

git init 命令执行后,在磁盘上的表现是工作区添加一个.git隐藏目录,该目录包含了一些默认的子目录和文件:

图片.png

git add

‘git add’ 命令是将工作区文件添加到暂存区,实质上是在创建/更新 .git/index 文件,主要的过程为:

  1. 更新暂存区状态:git add 会将工作区中指定的[更新的文件]或[新文件]的当前状态记录到 .git/index 文件中;
  2. 创建/更新索引记录:给被操作的文件生成一个哈希值,并将该文件的元数据(如文件名、文件类型、权限等)保存到 .git/index 文件中;
  3. 暂存文件快照: .git/index 文件会记录每个被暂存的文件的快照信息,用于创建提交时的快照;

如下图,在 test分支的工作区添加一个 test.txt文件,执行‘git add . ’ 命令后会在.git目录下生成一个 index文件,这个就是暂存区的核心。

图片.png

图片.png

git commit

‘git commit’ 命令是将暂存区的内容提交到本地仓库。对.git的修改为:

  1. 更新 .git/objects

在 .git/objects 目录中创建新的对象,这些对象会使用 SHA-1 哈希值作为标识,用于在仓库中唯一标识每个提交对象、树对象和文件对象。

因此,每一次 commit都会在 .git/objects下创建一个目录,目录名为此次提交到哈希值的前两位,如下图:

图片.png

git pull

’git pull’ 命令用于从远程仓库中获取最新的提交,并将它们合并到当前所在的本地分支。

它实际上是 ’git fetch’’git merge’ 两个命令的组合。

  1. 执行 git fetch:

git pull 首先会执行 git fetch 命令,从远程仓库中拉取最新的提交、分支信息和其他更新;

git fetch 不会修改本地工作区的内容,而是将远程仓库的内容下载到本地仓库,更新远程跟踪分支(如 origin/master)指向最新提交;

  1. 执行 git merge:

git pull 接着会执行 git merge 命令,将远程仓库拉取的内容与当前分支进行合并;

如果没有冲突,git 会尝试自动合并更新到当前分支中。如果有冲突,则需要手动解决冲突后再提交;

git fetch(获取)

************’git pull’******** 命令用于从远程仓库中获取最新的提交,并且将代码拉取到本地仓库。** **’git pull’对 .git目录的影响如下:

  1. 更新 .git/refs/remotes/origin 目录,在该目录下创建一个远程分支名的目录,更新或创建远程分支的引用;
  2. 更新.git/FETCH_HEAD 文件中记录最新的 fetch 操作信息;

git merge(合并)

‘git merge’ 命令是指要将哪个分支的内容合并到当前分支。它对 .git目录的影响如下:修改 .git/refs/heads 目录

git push

git push 命令用于将本地分支的提交推送(同步)到远程仓库中。它对 .git目录的影响如下:

  1. 更新 .git/refs/remotes 或 .git/refs/heads

git push 会在 .git/refs/remotes 或 .git/refs/heads 目录下更新或创建远程引用;