Git 基础知识,完整指南

2025-05-27

Git 基础知识,完整指南

如果您已经每天使用Git,但想要很好地理解 Git基础知识,那么这篇文章适合您。

在这里,您将有机会真正了解Git 架构以及添加、检出、重置、提交、合并、变基、挑选、拉取、推送标记等命令的内部工作原理。

不要让 Git 控制你,而是学习 Git 基础知识并掌握 Git

做好准备,关于 Git 的完整指南即将开始。


💡 首先要做的事情

您必须在阅读这篇文章的同时进行练习。

接下来,让我们首先创建一个名为的新项目git-101,然后使用以下命令初始化一个 git 存储库git init



$ mkdir git-101
$ cd git-101


Enter fullscreen mode Exit fullscreen mode

Git CLI 提供两种类型的命令:

  • plumbing ,由用户输入高级命令时 Git 在后台内部使用的低级命令组成

  • ceramic,这是Git 用户常用的高级命令

在本指南中,我们将了解管道命令与我们日常使用的瓷器命令之间的关系。


⚙️ Git 架构

在包含 Git 存储库的项目中,我们可以检查 Git 组件:



$ ls -F1 .git/

HEAD
config
description
hooks/
info/
objects/
refs/


Enter fullscreen mode Exit fullscreen mode

我们将重点关注以下几个主要方面:

  • .git/对象/

  • .git/refs

让我们详细分析一下每个组件


💾 对象数据库

使用 UNIX 工具find我们可以看到文件夹的结构.git/objects



$ find .git/objects

.git/objects
.git/objects/pack
.git/objects/info


Enter fullscreen mode Exit fullscreen mode

在 Git 中,所有内容都保存在.git/objects结构中,即Git 对象数据库

我们可以在 Git 中持久化哪些内容?所有内容

🤔等待!

这怎么可能呢?

通过使用哈希函数

🔵 哈希救援

哈希函数 将任意动态大小的数据映射到固定大小的值。通过这种方式,我们可以存储/持久化任何内容,因为最终值的大小始终相同

哈希函数的错误实现很容易导致冲突,其中两个不同的动态大小数据可能映射到相同的固定大小的最终哈希。

SHA-1是哈希函数的一个众所周知的实现,它通常是安全的并且几乎不会发生冲突。

让我们以字符串的散列为例my precious



$ echo -e "my precious" | openssl sha1
fa628c8eeaa9527cfb5ac39f43c3760fe4bf8bed


Enter fullscreen mode Exit fullscreen mode

注意:如果您使用的是 Linux,则可以使用命令 sha1sum代替OpenSSL

🔵 比较内容的差异

良好的散列一种安全的做法,我们无法知道原始值,即进行逆向工程。

如果我们想知道值是否已更改,我们只需将值包装到哈希函数中,然后我们就可以比较差异:



$ echo -e "my precious" | openssl sha1
fa628c8eeaa9527cfb5ac39f43c3760fe4bf8bed

$ echo -e "no longer my precious" | openssl sha1
2e71c9ae2ef57194955feeaa99f8543ea4cd9f9f


Enter fullscreen mode Exit fullscreen mode

如果哈希值不同,那么我们可以假设值已经改变

你能发现这里的机会吗?用SHA-1来存储数据,然后通过比较哈希值来追踪所有内容,怎么样?

这正是 Git 内部所做的🤯。

🔵 Git 和 SHA-1

Git 使用 SHA-1 生成所有内容的哈希值并将其存储在.git/objects文件夹中。就这么简单!

管道命令完成hash-object以下工作:



$ echo "my precious" | git hash-object --stdin
8b73d29acc6ae79354c2b87ab791aecccf51701f


Enter fullscreen mode Exit fullscreen mode

我们来比较一下OpenSSL版本:



$ echo -e "my precious" | openssl sha1
fa628c8eeaa9527cfb5ac39f43c3760fe4bf8bed


Enter fullscreen mode Exit fullscreen mode

哎呀……完全不一样。这是因为 Git在内容大小和分隔符前面添加了一个特定的单词。Git 把这个单词称为对象类型\0

是的,Git 对象有类型。我们首先要研究的是blob 对象

🔵 blob 对象

例如,当我们向命令发送字符串“my precious”时hash-object,Git 会将该模式添加{object_type} {content_size}\0到 SHA-1 函数的前面,以便:



blob 12\0myprecious


Enter fullscreen mode Exit fullscreen mode

然后:



$ echo -e "blob 12\0my precious" | openssl sha1
8b73d29acc6ae79354c2b87ab791aecccf51701f

$ echo "my precious" | git hash-object --stdin
8b73d29acc6ae79354c2b87ab791aecccf51701f


Enter fullscreen mode Exit fullscreen mode

耶! 🎉

🔵 将 Blob 存储在数据库中

但是命令hash-object本身不会持久化到.git/objects文件夹中。我们应该添加选项-w,这样对象就会被持久化:



$ echo "my precious" | git hash-object --stdin -w
8b73d29acc6ae79354c2b87ab791aecccf51701f

$ find .git/objects
...
.git/objects/8b
.git/objects/8b/73d29acc6ae79354c2b87ab791aecccf51701f

### Or, simply
$ find .git/objects -type f
.git/objects/8b/73d29acc6ae79354c2b87ab791aecccf51701f


Enter fullscreen mode Exit fullscreen mode

第一个对象

🔵 读取 blob 的原始内容

我们已经知道,由于加密原因,无法从其散列版本中读取原始内容。

🤔 好的,但是请稍等。

Git 如何知道原始值

它使用哈希作为指向值的键,该值是原始内容本身,使用名为Zlib的压缩算法压缩内容并将其存储在对象数据库中,从而节省存储空间

管道命令完成以下工作:定一个键,膨胀压缩数据,从而获得原始内容:cat-file



$ git cat-file -p 8b73d29acc6ae79354c2b87ab791aecccf51701f
my precious


Enter fullscreen mode Exit fullscreen mode

如果你猜对了,Git 是一个键值数据库

诺SQL

🔵 推广 blob

当使用 Git 时,我们希望处理内容并与其他人共享

通常,在处理完各种文件/blob 之后,我们准备共享它们并在最终作品上签名

换句话说,我们需要对 Blob 进行分组、提升和添加元数据。这个过程如下:

  1. 将 Blob 添加到暂存区

  2. 将舞台区域中的所有 blob分组为树形结构

  3. 树结构添加元数据(作者姓名、日期、语义信息)

让我们详细看看上述步骤

🔵 阶段区域,索引

plumbing命令允许向舞台update-index区域添加一个 blob 并为其命名:



$ git update-index \
    --add \
    --cacheinfo 100644 \
    8b73d29acc6ae79354c2b87ab791aecccf51701f \
    index.txt


Enter fullscreen mode Exit fullscreen mode
  • --add:将 blob 添加到舞台,也称为索引

  • --cacheinfo:用于注册尚未在工作目录中的文件

  • 散列

  • index.txt:索引中 blob 的名称

git 索引

Git 将索引存储在哪里?



$ cat .git/index

DIRCsҚjT¸zQp    index.txtÆ
                          7CJVVÙ


Enter fullscreen mode Exit fullscreen mode

但它不是人类可读的,它是使用 Zlib 压缩的。

我们可以根据需要向索引添加任意数量的 blob,例如:



$ git update-index {sha-1} f1.txt
$ git update-index {sha-1} f2.txt


Enter fullscreen mode Exit fullscreen mode

将 blob 添加到索引后,我们可以将它们分组为准备提升的树结构。

🔵 树对象

当使用plumbing命令时write-treeGit 将对添加到索引的所有 blob 进行分组,并在文件夹中创建另一个对象.git/objects



$ git write-tree
3725c9e313e5ae764b2451a8f3b1415bf67cf471


Enter fullscreen mode Exit fullscreen mode

检查.git/objects文件夹,注意已创建了一个新对象:



$ find .git/objects

### The new object
.git/objects/37
.git/objects/37/25c9e313e5ae764b2451a8f3b1415bf67cf471

### The blob previously created
.git/objects/8b
.git/objects/8b/73d29acc6ae79354c2b87ab791aecccf51701f


Enter fullscreen mode Exit fullscreen mode

让我们使用以下方法来检索原始值cat-file以便更好地理解:



### Using the option -t, we get the object type
$ git cat-file -t 3725c9e313e5ae764b2451a8f3b1415bf67cf471
tree

$ git cat-file -p 3725c9e313e5ae764b2451a8f3b1415bf67cf471
100644 blob 8b73d29acc6ae79354c2b87ab791aecccf51701f index.txt


Enter fullscreen mode Exit fullscreen mode

这是一个有趣的输出,它与返回原始内容的blob 有很大不同

在树对象中,Git 返回所有添加到索引的对象



100644 blob 8b73d29acc6ae79354c2b87ab791aecccf51701f index.txt


Enter fullscreen mode Exit fullscreen mode
  • 100644:缓存信息

  • blob:对象类型

  • 散列

  • blob 名称

树对象

一旦推广完成,就需要向树中添加一些元数据,以便我们可以声明作者的姓名、日期等。

🔵 提交对象

管道命令接收一棵树commit-tree一条提交消息并在.git/objects文件夹中创建另一个对象:



$ git commit-tree 3725c -m 'my precious commit'
505555f4f07d90ae14a0f2e67cba7f7b9af539ee


Enter fullscreen mode Exit fullscreen mode

它是什么样的物体?



$ find .git/objects
...
.git/objects/50
.git/objects/50/5555f4f07d90ae14a0f2e67cba7f7b9af539ee

### cat-file
$ git cat-file -t 505555f4f07d90ae14a0f2e67cba7f7b9af539ee
commit


Enter fullscreen mode Exit fullscreen mode

它的价值又如何呢?



$ git cat-file -p 505555f4f07d90ae14a0f2e67cba7f7b9af539ee

tree 3725c9e313e5ae764b2451a8f3b1415bf67cf471
author leandronsp <leandronsp@example.com> 1678768514 -0300
committer leandronsp <leandronsp@example.com> 1678768514 -0300

my precious commit


Enter fullscreen mode Exit fullscreen mode
  • tree 3725c引用树对象

  • 作者/提交者

  • 提交消息我的珍贵提交

提交树

🤯 我的天哪!我是不是看出什么规律了?

此外,提交可以引用其他提交:



$ git commit-tree 3725c -p 50555 -m 'second commit'
5ea578a41333bae71527db537072534a199a0b67


Enter fullscreen mode Exit fullscreen mode

该选项-p允许引用父提交



$ git cat-file -p 5ea578a41333bae71527db537072534a199a0b67

tree 3725c9e313e5ae764b2451a8f3b1415bf67cf471
parent 505555f4f07d90ae14a0f2e67cba7f7b9af539ee
author leandronsp <leandronsp@gmail.com> 1678768968 -0300
committer leandronsp <leandronsp@gmail.com> 1678768968 -0300

second commit


Enter fullscreen mode Exit fullscreen mode

我们可以看到,给定一个具有父级的提交,我们可以递归地遍历所有提交遍历它们的所有树,直到到达最终的 blob

一个潜在的解决方案:



$ git cat-file -p <first-commit-sha1>
$ git cat-file -p <first-commit-tree-sha1>
$ git cat-file -p <first-commit-parent-sha1>
$ git cat-file -p <parent-commit-sha1>
...


Enter fullscreen mode Exit fullscreen mode

等等。好了,你说到了重点。

🔵 救援日志

瓷器 命令git log解决了这个问题,通过遍历所有提交、它们的父母和树,让我们了解我们工作的时间表



$ git log 5ea57

commit 5ea578a41333bae71527db537072534a199a0b67
Author: leandronsp <leandronsp@gmail.com>
Date:   Mon Mar 13 22:42:48 2023 -0300

    second commit

commit 505555f4f07d90ae14a0f2e67cba7f7b9af539ee
Author: leandronsp <leandronsp@gmail.com>
Date:   Mon Mar 13 22:35:14 2023 -0300

    my precious commit


Enter fullscreen mode Exit fullscreen mode

🤯 天啊!

Git 是一个巨大但轻量级的键值图数据库!

🔵 Git 图表

在 Git 中,我们可以操作图形中的指针等对象

git 图表

  • Blob是数据/文件快照

  • 是一串斑点或另一棵树

  • 提交参考树和/或其他提交,添加元数据

这真是太棒了。但是在命令sha1中使用git log可能会很麻烦。

那么给哈希表命名怎么样?输入“引用”


Git 参考

参考资料位于.git/refs文件夹中:



$ find .git/refs

.git/refs/
.git/refs/heads
.git/refs/tags


Enter fullscreen mode Exit fullscreen mode

🔵 为提交命名

我们可以将任何提交哈希与位于中的任意名称关联起来.git/refs/heads,例如:



echo 5ea578a41333bae71527db537072534a199a0b67 > .git/refs/heads/test


Enter fullscreen mode Exit fullscreen mode

现在,让我们git log使用新的引用来发出问题:



$ git log test

commit 5ea578a41333bae71527db537072534a199a0b67
Author: leandronsp <leandronsp@gmail.com>
Date:   Mon Mar 13 22:42:48 2023 -0300

    second commit

commit 505555f4f07d90ae14a0f2e67cba7f7b9af539ee
Author: leandronsp <leandronsp@gmail.com>
Date:   Mon Mar 13 22:35:14 2023 -0300

    my precious commit


Enter fullscreen mode Exit fullscreen mode

更好的是,Git 提供了管道命令update-ref,因此我们可以使用它来更新提交与引用的关联:



$ git update-ref refs/heads/test 5ea578a41333bae71527db537072534a199a0b67


Enter fullscreen mode Exit fullscreen mode

听起来很熟悉,嗯?是的,我们正在谈论分支

🔵 分支

分支是指向特定提交的引用。

由于分支代表update-ref命令,因此提交哈希可以随时更改,即分支引用是可变的

分支

让我们暂时思考一下git log不带参数的函数是如何工作的:



$ git log

fatal: your current branch 'main' does not have any commits yet


Enter fullscreen mode Exit fullscreen mode

🤔 嗯……

Git 如何知道我当前的分支是“主”分支

🔵 头部

HEAD 引用位于.git/HEAD。它是一个指向头引用(分支)的单个文件:



$ cat .git/HEAD

ref: refs/heads/main


Enter fullscreen mode Exit fullscreen mode

类似地,使用瓷器命令:



$ git branch
* main


Enter fullscreen mode Exit fullscreen mode

使用管道命令symbolic-ref,我们可以操纵HEAD 指向哪个分支



$ git symbolic-ref HEAD refs/heads/test

### Check the current branch
$ git branch
* test


Enter fullscreen mode Exit fullscreen mode

就像在分支上一样,我们可以随时update-ref使用 HEAD 进行更新。symbolic-ref

符号引用

在下图中,我们将 HEAD 从分支更改为修复分支:

更新头

如果没有参数,该git log命令将遍历当前分支(HEAD)引用的根提交:



$ git log

commit 5ea578a41333bae71527db537072534a199a0b67 (HEAD -> test)
Author: leandronsp <leandronsp@gmail.com>
Date:   Tue Mar 14 01:42:48 2023 -0300

    second commit

commit 505555f4f07d90ae14a0f2e67cba7f7b9af539ee
Author: leandronsp <leandronsp@gmail.com>
Date:   Tue Mar 14 01:35:14 2023 -0300

    my precious commit


Enter fullscreen mode Exit fullscreen mode

到目前为止,我们学习了 Git 的架构和主要组件,以及管道命令,它们是更底层的命令。

是时候将所有这些知识与我们日常使用的瓷器命令联系起来了。


🍽️ 瓷器命令

Git 带来了更多高级命令,我们可以使用这些命令,而无需直接操作对象和引用。

这些命令被称为瓷器命令

🔵 git 添加

git add命令将工作目录中的文件作为参数,将它们作为 blob 保存到数据库中并将它们添加到索引中

git 添加

简而言之,git add

  1. hash-object对每个文件参数运行

  2. update-index对每个文件参数运行

🔵 git 提交

git commit以消息作为参数,将之前添加到索引的所有文件分组并创建一个提交对象

首先,它运行write-tree

提交写入树

然后,它运行commit-tree

提交提交树



$ git commit -m 'another commit'

[test b77b454] another commit
 1 file changed, 1 deletion(-)
 delete mode 100644 index.txt


Enter fullscreen mode Exit fullscreen mode

🕸️ 在 Git 中操作指针

以下瓷器命令被广泛使用,它们在后台操纵Git 引用。

假设我们刚刚克隆了一个项目,其中HEAD指向主分支,而主分支又指向提交C1

git 克隆

我们如何从当前 HEAD创建另一个新分支并将HEAD 移动到这个新分支

🔵 git checkout

通过使用git checkout-b选项,Git 将从当前分支(HEAD)创建一个新分支,并将 HEAD 移动到这个新分支。



### HEAD
$ git branch
* main

### Creates a new branch "fix" using the same reference SHA-1
#### of the current HEAD
$ git checkout -b fix
Switched to a new branch 'fix'

### HEAD
$ git branch
* fix
main


Enter fullscreen mode Exit fullscreen mode

哪个管道命令负责移动 HEAD?没错,就是symbolic-ref

git checkout -b 修复

之后,我们在修复分支上做一些新的工作,然后执行git commit,这将添加一个名为C3的新提交:

git 提交

通过运行git checkout,我们可以在不同的分支之间切换 HEAD:

git checkout 终极版

有时,我们可能想要移动分支指向的提交

我们已经知道管道命令update-ref可以做到这一点:



$ git update-ref refs/heads/fix 356c2


Enter fullscreen mode Exit fullscreen mode

瓷器语言,让我向你介绍git reset

🔵 git 重置

git reset ceramic命令内部运行update-ref,因此我们只需执行:



$ git reset 356c2


Enter fullscreen mode Exit fullscreen mode

但是 Git 如何知道要移动哪个分支呢?git reset 会移动 HEAD 指向的分支

git 重置

如果修订版本之间存在差异怎么办?通过使用reset,Git 会移动指针,但会将所有差异保留在暂存区(索引)中。



$ git reset b77b


Enter fullscreen mode Exit fullscreen mode

检查git status



$ git status

On branch fix
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        another.html
        bye.html
        hello.html

nothing added to commit but untracked files present (use "git add" to track)


Enter fullscreen mode Exit fullscreen mode

修订提交在 修复分支 中发生更改,所有差异都 移至索引

那么,如果我们想重置并丢弃所有差异,该怎么办呢?只需传递选项--hard

git reset hard

通过使用git reset --hard,修订之间的任何差异都将被丢弃,并且不会出现在索引中

💡 关于移动分支的黄金建议

如果我们想在另一个分支上执行管道 update-ref,则无需像git reset中那样检出分支。

我们可以进行 git branch -f source target改:



$ git branch -f main b77b


Enter fullscreen mode Exit fullscreen mode

它在源分支中执行了操作。让我们检查一下主分支指向git reset --hard哪个提交:



$ git log main --pretty=oneline -n1
b77b454a9a507f839880879a895ac4f241177a28 (main) another commit


Enter fullscreen mode Exit fullscreen mode

另外,我们确认修复分支仍然指向369cd提交:



$ git log fix --pretty=oneline -n1
369cd96b1f1ef6fa7de1ff2ed12e15be979dcffa (HEAD -> fix, test) add files


Enter fullscreen mode Exit fullscreen mode

我们执行了“git reset”,但没有移动 HEAD

git 分支 -f

并不罕见,我们不想移动分支指针,而是想将特定的提交应用到当前分支

满足cherry-pick

🔵 git cherry-pick

使用ceramic git cherry-pick,我们可以对当前分支应用任意提交。

请考虑以下场景:

场景 42

  • 要点至 C3 - C2 - C1

  • 固定点至 C5 - C4 - C2 - C1

  • HEAD指向修复

修复分支中,我们缺少主分支所引用的C3 提交

我们可以通过运行来应用它git cherry-pick C3

精选A

注意:

  • C3提交将被克隆到名为C3'的新提交中

  • 这个新的提交将引用 C5 提交

  • 修复将移动指针至 C3'

  • HEAD 一直指向修复

应用更改后,图表将显示如下:

挑选B

不过,还有另一种移动分支指针的方法。它包括应用另一个分支的任意提交,并在需要时合并差异

你没错,我们这里讨论的是git merge 。

🔵 git 合并

让我们描述以下场景:

另一种情况

  • 要点至 C3 - C2 - C1

  • 固定点至 C4 - C3 - C2 - C1

  • HEAD 指向主

我们希望将修复分支应用到当前(主)分支,也就是执行git merge fix

请注意,修复分支包含属于主分支(C3 - C2 - C1)的所有提交,主分支之前只有一个提交(C4)。

在这种情况下,主分支将被“转发”,指向与修复分支相同的提交。

这种合并称为快进,如下图所示:

快进

当无法快进时

有时,我们的树状结构 current 状态不允许快进。例如以下场景:

场景 44

这就是当合并分支(上面例子中的修复分支)缺少来自当前分支(主分支)的一个或多个提交时的情况: C3 提交

因此,快进是不可能的

但是,为了使合并成功,Git 执行了一种称为Snapshotting的技术,该技术由以下步骤组成。

首先,Git 查找两个分支的下一个公共父级,在此示例中为C2提交。

合并共同父级

其次,Git对目标C3 提交分支进行快照:

目标快照

第三,Git对源C5 提交分支进行快照:

源快照

最后,Git 自动创建一个提交合并(C6),并将其分别指向两个父级:C3(目标)和 C5(源):

合并提交

您是否想过为什么您的 Git 树会显示一些自动创建的提交?

毫无疑问,这个合并过程被称为三向合并

三路合并

接下来,让我们探索另一种无法快进的合并技术,但 Git 不会进行快照和自动提交合并,而是在源分支之上应用差异

是的,这就是git rebase

🔵 git rebase

请考虑以下图像:

场景 55

  • 要点至 C3 - C2 - C1

  • 固定点至 C5 - C4 - C2 - C1

  • HEAD 指向修复

我们希望通过执行以下命令将主分支rebasegit rebase main到 fix 分支。但是git rebase是如何工作的呢?

👉 git reset

首先,Git 执行git reset main,其中 fix 分支将指向相同的主分支指针:C3 - C2 - C1

重新基准:重置

目前,C5 - C4 提交没有引用

👉 git cherry-pick

其次,Git 执行git cherry-pick C5到当前分支:

重新设置:cherry-pick

请注意,在挑选过程中,挑选的提交会被克隆,因此最终的哈希值会发生变化:C5 - C4 变成 C5' - C4'

经过 cherry-pick 之后,我们可能会出现以下情况:

rebase-cherry-pick-b

👉再次重置 git

最后,Git 将执行git reset C5',因此修复分支指针将从C3 移动到 C5'

重新定基过程已完成。

重新设置:完成

到目前为止,我们一直在使用本地分支,也就是我们自己的机器上。现在是时候学习如何使用远程分支了,这些分支与互联网上的远程仓库同步


🌐 远程分支

要使用远程分支,我们必须使用ceramic命令将远程分支添加到我们的本地存储库git remote



$ git remote add origin git@github.com/myaccount/myrepo.git


Enter fullscreen mode Exit fullscreen mode

遥控器位于.git/refs/remotes以下文件夹中:



$ find .git/refs
...
.git/refs/remotes/origin
.git/refs/remotes/origin/main


Enter fullscreen mode Exit fullscreen mode

🔵 从远程下载

我们如何将远程分支与本地分支同步?

Git 提供了两个步骤

👉 git fetch

通过使用瓷器,Git 将下载远程分支并将其与名为 origin/maingit fetch origin main的新本地分支(也称为上游分支)同步。

拿来

👉 git 合并

在获取并同步上游分支后,我们可以执行,git merge origin/main并且由于上游位于我们本地分支之前,Git 将安全地应用快进合并

获取合并 ff

然而,fetch + merge 可能会重复,因为我们每天会多次同步本地/远程分支。

但今天是我们的幸运日,Git 提供了git pull瓷器命令,可以代表我们执行 fetch + merge。

👉 git pull

使用git pull,Git 将执行 fetch(将远程与上游分支同步),然后将上游分支合并到本地分支。

git pull

好的,我们已经了解了如何从远程拉取/下载更改。那么,如何将本地更改发送到远程呢?

🔵 上传到远程

Git 提供了一个名为的瓷器命令git push

👉 git push

执行git push origin main将首先将更改上传到远程:

按A

然后,Git 会将上游origin/main与本地main分支合并:

推B

在推送过程结束时,我们得到以下图像:

推端

在哪里:

  • 远程已更新(本地更改已推送至远程)

  • C4 要点

  • 起点/要点至 C4

  • HEAD 指向主

🔵 为提交赋予不可变的名称

到目前为止,我们了解到分支只是对提交的可变引用,这就是为什么我们可以随时移动分支指针。

然而,Git 还提供了一种提供不可变引用的方法,这些引用的指针不能改变(除非删除它们并再次创建它们)。

例如,当我们想要标记/标记已准备好发布某些生产版本的提交时,不可变引用很有用。

是的,我们正在谈论标签

👉 git 标签

使用 ceramicgit tag命令,我们可以为提交命名,但不能执行重置或任何其他会改变指针的命令。

git 标签

它对于发布版本控制非常有用。标签位于以下.git/refs/tags文件夹中:



$ find .git/refs

...
.git/refs/tags
.git/refs/tags/v1.0


Enter fullscreen mode Exit fullscreen mode

如果我们想改变标签指针,我们必须删除它并创建另一个同名的标签指针。


💡 Git 引用日志

最后但同样重要的是,有一个名为的命令git reflog可以保存我们在本地存储库中所做的所有更改。



$ git reflog

369cd96 (HEAD -> fix, test) HEAD@{0}: reset: moving to main
b77b454 (main) HEAD@{1}: reset: moving to b77b
369cd96 (HEAD -> fix, test) HEAD@{2}: checkout: moving from main to fix
369cd96 (HEAD -> fix, test) HEAD@{3}: checkout: moving from fix to main
369cd96 (HEAD -> fix, test) HEAD@{4}: checkout: moving from main to fix
369cd96 (HEAD -> fix, test) HEAD@{5}: checkout: moving from fix to main
369cd96 (HEAD -> fix, test) HEAD@{6}: checkout: moving from main to fix
369cd96 (HEAD -> fix, test) HEAD@{7}: checkout: moving from test to main
369cd96 (HEAD -> fix, test) HEAD@{8}: checkout: moving from main to test
369cd96 (HEAD -> fix, test) HEAD@{9}: checkout: moving from test to main
369cd96 (HEAD -> fix, test) HEAD@{10}: commit: add files
b77b454 (main) HEAD@{11}: commit: another commit
5ea578a HEAD@{12}:


Enter fullscreen mode Exit fullscreen mode

如果我们想在 Git 时间线上来回切换,它就非常有用。和reset、cherry-pick 等类似的工具一样,它也是掌握 Git 的强大工具。


总结

多么漫长的旅程啊!

这篇文章有点太长了,但我可以表达我认为理解 Git 的重要主题。

我希望您在阅读本文后能够更加自信地使用 Git,解决合并/变基过程中的日常冲突和痛苦情况。

在Twitter上关注我并查看我的网站博客leandronsp.com,我在那里也撰写了一些技术文章。

干杯!

文章来源:https://dev.to/leandronsp/git-fundamentals-a-complete-guide-do7
PREV
node_modules 问题
NEXT
更好的代码审查实践