【git系列】git中的那些迷惑的术语以及概念详解

引子

连着写了几篇关于git的文章,满满对git有了更深入的了解。但是git里面还是有很多术语让人困惑。下面我逐一解释下。

当我们把它们搞清楚后就发现,没那么难懂,心里作用占了很大一部分。

事实是:

1)"索引"、"暂存区"和"-缓存"都是同一件事

2)存储是一堆提交

3)并非所有引用都是分支或标签

4)合并提交不为空

这四条让我们挨个看看。

"索引"、"暂存区"和"-缓存"都是同一件事

当您运行git add file.txt,然后运行git status,您会看到类似这样的内容:

$ git add content/post/2023-10-20-some-miscellaneous-git-facts.markdown
$ git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   content/post/2023-10-20-some-miscellaneous-git-facts.markdown

人们通常称之为"**暂存文件"**或"将文件添加到暂存区"。

当您使用 暂存文件时git add,git 会在后台将该文件添加到其对象数据库(在 中.git/objects)并更新名为 的文件.git/index以引用新添加的文件。

在 Git 中,这个"暂存区"实际上有 3 个不同的名称。它们都指的是同一个东西(文件.git/index):

git diff --cached
git diff --staged
文件.git/index

你看是不是该早点认识这个问题

git stash 是一堆提交

当我运行git stash存储更改时,我总是对这些更改实际上去了哪里感到有些困惑。事实证明,当您运行 时git stash,git 会对您的更改进行一些提交,并使用名为stash(in .git/refs/stash) 的引用标记它们。

我们先把这篇博文藏起来,看一下stash引用的日志:

$ git log stash --oneline
6cb983fe (refs/stash) WIP on main: c6ee55ed wip
2ff2c273 index on main: c6ee55ed wip
... some more stuff

现在我们可以查看提交2ff2c273以查看其包含的内容:

$ git show 2ff2c273  --stat
commit 2ff2c273357c94a0087104f776a8dd28ee467769
Author: Julia Evans <julia@jvns.ca>
Date:   Fri Oct 20 14:49:20 2023 -0400

    index on main: c6ee55ed wip

 content/post/2023-10-20-some-miscellaneous-git-facts.markdown | 40 ++++++++++++++++++++++++++++++++++++++++

不出所料,它包含这篇博文。怎么样,懂了吧

git stash实际上会创建 2 个单独的提交:一个用于索引,另一个用于尚未暂存的更改。我发现这有点令人振奋,因为我一直在开发一种快照和恢复 git 存储库状态的工具(我可能会也可能不会发布),并且我想出了一个非常相似的设计,所以这让我对我的选择感到更放心。

显然,存储中的较早提交存储在 reflog 中。

并非所有引用都是 branches 或 tags

Git 的文档经常以通用的方式提及"引用",有时我觉得有点困惑。就我个人而言,当我在 Git 中处理"引用"时,99% 的时间它是一个分支或HEAD,另外 1% 的时间它是一个标签。实际上,我不知道任何不是分支或标签或的引用示例HEAD。

但现在我知道了一个例子------stash是一个引用,它不是一个分支或标签!这很有意思吧。

以下是我博客的 git 仓库中的所有参考资料(除 外HEAD):

$ find .git/refs -type f
.git/refs/heads/main
.git/refs/remotes/origin/HEAD
.git/refs/remotes/origin/main
.git/refs/stash

大家在讨论这篇文章时提到的其他一些参考资料:

refs/notes/*, 从 git notes
refs/pull/123/head和 `refs/pull/123/head用于 GitHub 拉取请求(您可以通过 获取git fetch origin refs/pull/123/merge)
refs/bisect/*, 从git bisect

merge commits 不为空

这里有一个 简单的 git repo,我在其中创建了两个分支x和y,每个分支包含 1 个文件(x.txt和y.txt),然后合并了它们。让我们看看合并提交。

$ git log --oneline

96a8afb (HEAD -> y) Merge branch 'x' into y

0931e45 y

1d8bd2d (x) x

如果我运行git show 96a8afb,提交看起来是"空的":没有差异!

git show 96a8afb
commit 96a8afbf776c2cebccf8ec0dba7c6c765ea5d987 (HEAD -> y)
Merge: 0931e45 1d8bd2d
Author: Julia Evans <julia@jvns.ca>
Date:   Fri Oct 20 14:07:00 2023 -0400

    Merge branch 'x' into y

但是,如果我分别将合并提交与其两个父提交进行比较,您就会发现存在差异:

$ git diff 0931e45 96a8afb   --stat
 x.txt | 1 +
 1 file changed, 1 insertion(+)
$ git diff 1d8bd2d 96a8afb   --stat
 y.txt | 1 +
 1 file changed, 1 insertion(+)

现在想想, merge提交实际上并不是"空的"(它们是存储库当前状态的快照,就像任何其他提交一样),但我从未想过为什么它们看起来是空的。

显然这些merge差异为空的原因是合并差异仅显示冲突- 如果我创建一个具有合并冲突的 repo(添加一个分支x并将另一个分支添加y到同一个文件),并显示我解决冲突的合并提交,它看起来像这样:

$ git show HEAD
commit 3bfe8311afa4da867426c0bf6343420217486594
Merge: 782b3d5 ac7046d
Author: Julia Evans <julia@jvns.ca>
Date:   Fri Oct 20 15:29:06 2023 -0400

    Merge branch 'x' into y

diff --cc file.txt
index 975fbec,587be6b..b680253
--- a/file.txt
+++ b/file.txt
@@@ -1,1 -1,1 +1,1 @@@
- y
 -x
++z

这个提示在告诉我,一个分支添加了x,另一个分支添加了y,而merge提交通过放入z 解决了冲突问题。但在前面的例子中,没有冲突,所以 Git 根本没有显示差异。

相关推荐
贩卖纯净水.2 小时前
白月光git
git·github
爱吃瓜的猹z6 小时前
git reset 几点疑问
git·源代码管理
悟空201612 小时前
001、Git开发流程规范
git
Li小李同学Li12 小时前
git学习【持续更新中。。。】
git·学习·elasticsearch
晨春计14 小时前
【git】
android·linux·git
念幽15 小时前
Git常用命令
git
benben04416 小时前
Photoshop使用方法大全
git
ou.cs16 小时前
git 删除远程分支的几种写法
git
atlanteep16 小时前
Linux·权限与工具-git与gdb
linux·git