searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

GitLab 工作原理详解

2024-11-12 09:24:50
4
0

GitLab 工作原理详解

1. Git 的数据模型

Git 是一个分布式版本控制系统,其核心数据模型基于对象存储。每个提交(commit)在文件系统上以对象的形式存储,这些对象包括:

  • Blob 对象​:存储文件内容。
  • Tree 对象​:存储目录结构,指向 Blob 对象和子 Tree 对象。
  • Commit 对象​:存储提交信息,包括作者、提交时间、提交信息、父提交等。

1.1 Blob 对象

Blob 对象用于存储文件内容。每个 Blob 对象包含文件的内容,并通过 SHA-1 哈希值唯一标识。

  • 创建 Blob 对象​:当文件被添加到暂存区时,Git 会计算文件内容的 SHA-1 哈希值,并将文件内容存储为 Blob 对象。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 存储​:Blob 对象存储在 .git/objects 目录下,路径为 SHA-1 哈希值的前两位/后38位。例如,文件内容的 SHA-1 哈希值为 abc123...,则存储路径为 .git/objects/ab/c123...

1.2 Tree 对象

Tree 对象用于存储目录结构,指向 Blob 对象和子 Tree 对象。每个 Tree 对象包含目录中的文件和子目录的信息。

  • 创建 Tree 对象​:当文件被添加到暂存区时,Git 会创建一个 Tree 对象,记录当前目录结构。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 存储​:Tree 对象也存储在 .git/objects 目录下,路径为 SHA-1 哈希值的前两位/后38位。例如,Tree 对象的 SHA-1 哈希值为 def456...,则存储路径为 .git/objects/de/f456...

1.3 Commit 对象

Commit 对象用于存储提交信息,包括作者、提交时间、提交信息、父提交等。每个 Commit 对象指向一个 Tree 对象,表示提交时的目录结构。

  • 创建 Commit 对象​:当提交代码时,Git 会创建一个新的 Commit 对象,包含以下信息:

    • 作者信息
    • 提交时间
    • 提交信息
    • 指向当前 Tree 对象的哈希值
    • 指向父 Commit 对象的哈希值
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git commit -m "提交信息"
  • 存储​:Commit 对象也存储在 .git/objects 目录下,路径为 SHA-1 哈希值的前两位/后38位。例如,Commit 对象的 SHA-1 哈希值为 ghi789...,则存储路径为 .git/objects/gh/i789...

2. 本地代码暂存

在 Git 中,代码暂存的过程涉及将文件内容存储为 Blob 对象,并将这些 Blob 对象组织成 Tree 对象。

  • 添加文件到暂存区​:使用 git add 命令将文件内容存储为 Blob 对象,并更新索引文件(.git/index)。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 索引文件​:索引文件(.git/index)记录了暂存区的文件状态,包括文件路径、文件内容的哈希值(SHA-1)等。

3. 代码提交

提交代码时,Git 会创建一个新的 Commit 对象,并将当前的 Tree 对象作为 Commit 对象的树根。

  • 创建 Commit 对象​:提交时,Git 会生成一个新的 Commit 对象,包含以下信息:

    • 作者信息
    • 提交时间
    • 提交信息
    • 指向当前 Tree 对象的哈希值
    • 指向父 Commit 对象的哈希值
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git commit -m "提交信息"
  • 更新分支指针​:提交后,Git 会更新当前分支的指针,使其指向新的 Commit 对象。

4. 分支管理

分支在 Git 中是轻量级的指针,指向某个 Commit 对象。每个分支都有一个独立的指针,记录当前分支的最新提交。

  • 创建分支​:创建分支时,Git 会创建一个新的指针,指向当前分支的最新提交。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git branch <new-branch>
  • 切换分支​:切换分支时,Git 会更新工作目录和索引文件,使其与目标分支的最新提交一致。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git checkout <branch>

5. 冲突解决

冲突发生在多个分支对同一文件的同一部分进行修改时。Git 在合并时会检测冲突,并在冲突文件中插入冲突标记。

  • 冲突标记​:冲突文件中会插入 <<<<<<<, =======, 和 >>>>>>> 标记,分别表示当前分支的修改、分隔符和合并分支的修改。
    plaintext
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    <<<<<<< HEAD 当前分支的修改 ======= 合并分支的修改 >>>>>>> <source-branch>
  • 手动解决冲突​:开发者需要手动编辑冲突文件,删除冲突标记,保留正确的代码。
  • 标记冲突已解决​:解决冲突后,将文件添加到暂存区,标记冲突已解决。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 完成合并​:提交合并后的代码,生成一个新的 Commit 对象。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git commit -m "解决冲突"

6. Merge 和 Rebase

  • Merge​:合并两个分支时,Git 会创建一个新的 Commit 对象,包含两个父 Commit 对象的哈希值。这个新的 Commit 对象称为合并提交。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git merge <source-branch>
    • 合并过程​:
      1. Git 找到两个分支的最近共同祖先(Common Ancestor)。
      2. 比较当前分支和合并分支的差异。
      3. 生成新的 Tree 对象,包含合并后的目录结构。
      4. 创建新的 Commit 对象,包含两个父 Commit 对象的哈希值。
      5. 更新当前分支的指针,使其指向新的 Commit 对象。
  • Rebase​:Rebase 操作将一个分支的更改应用到另一个分支的最新提交上,保持线性的提交历史。Rebase 会创建新的 Commit 对象,覆盖原有的提交历史。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git rebase <base-branch>
    • Rebase 过程​:
      1. Git 找到两个分支的最近共同祖先(Common Ancestor)。
      2. 将当前分支的 Commit 对象从共同祖先开始,逐个应用到目标分支的最新提交上。
      3. 生成新的 Commit 对象,覆盖原有的 Commit 对象。
      4. 更新当前分支的指针,使其指向新的 Commit 对象。

7. 分支对比

  • 本地对比​:使用 git diff 命令对比两个分支的差异。Git 会计算两个分支的最新提交之间的差异,生成差异文件。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git diff <branch1> <branch2>
    • 对比过程​:
      1. Git 找到两个分支的最新 Commit 对象。
      2. 比较两个 Commit 对象的 Tree 对象,生成差异文件。
  • GitLab 界面对比​:在 GitLab 界面中,选择两个分支进行对比,GitLab 会调用 Git 的差异计算功能,生成详细的代码差异。

8. 远程仓库管理

  • 推送代码​:将本地提交的代码推送到远程仓库时,Git 会将新的 Commit 对象和相关的 Tree 对象、Blob 对象推送到远程仓库。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git push <remote> <branch>
    • 推送过程​:
      1. Git 找到本地分支的最新 Commit 对象。
      2. 将新的 Commit 对象、Tree 对象和 Blob 对象推送到远程仓库。
      3. 更新远程分支的指针,使其指向新的 Commit 对象。
  • 拉取代码​:从远程仓库拉取最新的代码到本地时,Git 会下载新的 Commit 对象和相关的 Tree 对象、Blob 对象,并更新本地分支指针。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git pull <remote> <branch>
    • 拉取过程​:
      1. Git 从远程仓库下载最新的 Commit 对象、Tree 对象和 Blob 对象。
      2. 更新本地分支的指针,使其指向新的 Commit 对象。
      3. 如果存在冲突,Git 会提示解决冲突。

9. 代码审查和合并请求

  • 创建合并请求​:在 GitLab 中,创建合并请求时,GitLab 会记录源分支和目标分支的信息,并生成差异文件。其他开发者可以审查这些差异文件,提出修改意见或批准合并。
  • 代码审查​:审查者可以在合并请求页面查看代码差异,添加评论和建议。GitLab 会记录这些评论和建议,帮助开发者改进代码。
  • 合并合并请求​:当合并请求被批准后,GitLab 会执行合并操作,生成新的 Commit 对象,并更新目标分支的指针。

10. 代码保护和权限管理

  • 代码保护​:在 GitLab 中,设置代码保护规则时,GitLab 会记录这些规则,并在推送和合并操作时进行检查。如果操作不符合保护规则,GitLab 会拒绝操作。
  • 权限管理​:GitLab 提供了细粒度的权限管理,可以为不同的用户和组分配不同的权限。权限管理信息存储在 GitLab 的数据库中,用于控制用户对项目的访问和操作。

总结

GitLab 通过 Git 的数据模型和操作机制,提供了强大的代码管理功能。每个提交在文件系统上以对象的形式存储,分支管理通过轻量级的指针实现,合并和冲突解决通过生成新的 Commit 对象和手动编辑冲突文件实现。远程仓库管理通过推送和拉取操作同步代码,代码审查和合并请求通过 GitLab 的界面和后端服务实现。代码保护和权限管理通过规则和数据库记录实现,确保代码的安全和可控。

0条评论
0 / 1000
王****成
1文章数
0粉丝数
王****成
1 文章 | 0 粉丝
王****成
1文章数
0粉丝数
王****成
1 文章 | 0 粉丝
原创

GitLab 工作原理详解

2024-11-12 09:24:50
4
0

GitLab 工作原理详解

1. Git 的数据模型

Git 是一个分布式版本控制系统,其核心数据模型基于对象存储。每个提交(commit)在文件系统上以对象的形式存储,这些对象包括:

  • Blob 对象​:存储文件内容。
  • Tree 对象​:存储目录结构,指向 Blob 对象和子 Tree 对象。
  • Commit 对象​:存储提交信息,包括作者、提交时间、提交信息、父提交等。

1.1 Blob 对象

Blob 对象用于存储文件内容。每个 Blob 对象包含文件的内容,并通过 SHA-1 哈希值唯一标识。

  • 创建 Blob 对象​:当文件被添加到暂存区时,Git 会计算文件内容的 SHA-1 哈希值,并将文件内容存储为 Blob 对象。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 存储​:Blob 对象存储在 .git/objects 目录下,路径为 SHA-1 哈希值的前两位/后38位。例如,文件内容的 SHA-1 哈希值为 abc123...,则存储路径为 .git/objects/ab/c123...

1.2 Tree 对象

Tree 对象用于存储目录结构,指向 Blob 对象和子 Tree 对象。每个 Tree 对象包含目录中的文件和子目录的信息。

  • 创建 Tree 对象​:当文件被添加到暂存区时,Git 会创建一个 Tree 对象,记录当前目录结构。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 存储​:Tree 对象也存储在 .git/objects 目录下,路径为 SHA-1 哈希值的前两位/后38位。例如,Tree 对象的 SHA-1 哈希值为 def456...,则存储路径为 .git/objects/de/f456...

1.3 Commit 对象

Commit 对象用于存储提交信息,包括作者、提交时间、提交信息、父提交等。每个 Commit 对象指向一个 Tree 对象,表示提交时的目录结构。

  • 创建 Commit 对象​:当提交代码时,Git 会创建一个新的 Commit 对象,包含以下信息:

    • 作者信息
    • 提交时间
    • 提交信息
    • 指向当前 Tree 对象的哈希值
    • 指向父 Commit 对象的哈希值
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git commit -m "提交信息"
  • 存储​:Commit 对象也存储在 .git/objects 目录下,路径为 SHA-1 哈希值的前两位/后38位。例如,Commit 对象的 SHA-1 哈希值为 ghi789...,则存储路径为 .git/objects/gh/i789...

2. 本地代码暂存

在 Git 中,代码暂存的过程涉及将文件内容存储为 Blob 对象,并将这些 Blob 对象组织成 Tree 对象。

  • 添加文件到暂存区​:使用 git add 命令将文件内容存储为 Blob 对象,并更新索引文件(.git/index)。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 索引文件​:索引文件(.git/index)记录了暂存区的文件状态,包括文件路径、文件内容的哈希值(SHA-1)等。

3. 代码提交

提交代码时,Git 会创建一个新的 Commit 对象,并将当前的 Tree 对象作为 Commit 对象的树根。

  • 创建 Commit 对象​:提交时,Git 会生成一个新的 Commit 对象,包含以下信息:

    • 作者信息
    • 提交时间
    • 提交信息
    • 指向当前 Tree 对象的哈希值
    • 指向父 Commit 对象的哈希值
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git commit -m "提交信息"
  • 更新分支指针​:提交后,Git 会更新当前分支的指针,使其指向新的 Commit 对象。

4. 分支管理

分支在 Git 中是轻量级的指针,指向某个 Commit 对象。每个分支都有一个独立的指针,记录当前分支的最新提交。

  • 创建分支​:创建分支时,Git 会创建一个新的指针,指向当前分支的最新提交。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git branch <new-branch>
  • 切换分支​:切换分支时,Git 会更新工作目录和索引文件,使其与目标分支的最新提交一致。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git checkout <branch>

5. 冲突解决

冲突发生在多个分支对同一文件的同一部分进行修改时。Git 在合并时会检测冲突,并在冲突文件中插入冲突标记。

  • 冲突标记​:冲突文件中会插入 <<<<<<<, =======, 和 >>>>>>> 标记,分别表示当前分支的修改、分隔符和合并分支的修改。
    plaintext
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    <<<<<<< HEAD 当前分支的修改 ======= 合并分支的修改 >>>>>>> <source-branch>
  • 手动解决冲突​:开发者需要手动编辑冲突文件,删除冲突标记,保留正确的代码。
  • 标记冲突已解决​:解决冲突后,将文件添加到暂存区,标记冲突已解决。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git add <file>
  • 完成合并​:提交合并后的代码,生成一个新的 Commit 对象。
    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git commit -m "解决冲突"

6. Merge 和 Rebase

  • Merge​:合并两个分支时,Git 会创建一个新的 Commit 对象,包含两个父 Commit 对象的哈希值。这个新的 Commit 对象称为合并提交。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git merge <source-branch>
    • 合并过程​:
      1. Git 找到两个分支的最近共同祖先(Common Ancestor)。
      2. 比较当前分支和合并分支的差异。
      3. 生成新的 Tree 对象,包含合并后的目录结构。
      4. 创建新的 Commit 对象,包含两个父 Commit 对象的哈希值。
      5. 更新当前分支的指针,使其指向新的 Commit 对象。
  • Rebase​:Rebase 操作将一个分支的更改应用到另一个分支的最新提交上,保持线性的提交历史。Rebase 会创建新的 Commit 对象,覆盖原有的提交历史。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git rebase <base-branch>
    • Rebase 过程​:
      1. Git 找到两个分支的最近共同祖先(Common Ancestor)。
      2. 将当前分支的 Commit 对象从共同祖先开始,逐个应用到目标分支的最新提交上。
      3. 生成新的 Commit 对象,覆盖原有的 Commit 对象。
      4. 更新当前分支的指针,使其指向新的 Commit 对象。

7. 分支对比

  • 本地对比​:使用 git diff 命令对比两个分支的差异。Git 会计算两个分支的最新提交之间的差异,生成差异文件。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git diff <branch1> <branch2>
    • 对比过程​:
      1. Git 找到两个分支的最新 Commit 对象。
      2. 比较两个 Commit 对象的 Tree 对象,生成差异文件。
  • GitLab 界面对比​:在 GitLab 界面中,选择两个分支进行对比,GitLab 会调用 Git 的差异计算功能,生成详细的代码差异。

8. 远程仓库管理

  • 推送代码​:将本地提交的代码推送到远程仓库时,Git 会将新的 Commit 对象和相关的 Tree 对象、Blob 对象推送到远程仓库。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git push <remote> <branch>
    • 推送过程​:
      1. Git 找到本地分支的最新 Commit 对象。
      2. 将新的 Commit 对象、Tree 对象和 Blob 对象推送到远程仓库。
      3. 更新远程分支的指针,使其指向新的 Commit 对象。
  • 拉取代码​:从远程仓库拉取最新的代码到本地时,Git 会下载新的 Commit 对象和相关的 Tree 对象、Blob 对象,并更新本地分支指针。

    bash
    <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-insert-line1"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-copy-line"></use></svg><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#yunxiao-additive-code-file-line"></use></svg>
    git pull <remote> <branch>
    • 拉取过程​:
      1. Git 从远程仓库下载最新的 Commit 对象、Tree 对象和 Blob 对象。
      2. 更新本地分支的指针,使其指向新的 Commit 对象。
      3. 如果存在冲突,Git 会提示解决冲突。

9. 代码审查和合并请求

  • 创建合并请求​:在 GitLab 中,创建合并请求时,GitLab 会记录源分支和目标分支的信息,并生成差异文件。其他开发者可以审查这些差异文件,提出修改意见或批准合并。
  • 代码审查​:审查者可以在合并请求页面查看代码差异,添加评论和建议。GitLab 会记录这些评论和建议,帮助开发者改进代码。
  • 合并合并请求​:当合并请求被批准后,GitLab 会执行合并操作,生成新的 Commit 对象,并更新目标分支的指针。

10. 代码保护和权限管理

  • 代码保护​:在 GitLab 中,设置代码保护规则时,GitLab 会记录这些规则,并在推送和合并操作时进行检查。如果操作不符合保护规则,GitLab 会拒绝操作。
  • 权限管理​:GitLab 提供了细粒度的权限管理,可以为不同的用户和组分配不同的权限。权限管理信息存储在 GitLab 的数据库中,用于控制用户对项目的访问和操作。

总结

GitLab 通过 Git 的数据模型和操作机制,提供了强大的代码管理功能。每个提交在文件系统上以对象的形式存储,分支管理通过轻量级的指针实现,合并和冲突解决通过生成新的 Commit 对象和手动编辑冲突文件实现。远程仓库管理通过推送和拉取操作同步代码,代码审查和合并请求通过 GitLab 的界面和后端服务实现。代码保护和权限管理通过规则和数据库记录实现,确保代码的安全和可控。

文章来自个人专栏
王某技术分享
1 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0