Redian新闻
>
一些被忽略的 Git 知识 | Linux 中国

一些被忽略的 Git 知识 | Linux 中国

科技
 
导读:尽管我曾认为自己对 Git 非常了解,但像往常一样,当我尝试解释某事的时候,我又学到一些新东西。   
本文字数:4189,阅读时长大约:5分钟

我一直在慢慢地撰写关于 Git 工作原理的文章。尽管我曾认为自己对 Git 非常了解,但像往常一样,当我尝试解释某事的时候,我又学到一些新东西。

现在回想起来,这些事情都不算太令人吃惊,但我以前并没有清楚地思考过它们。

事实是:

◈ “索引”、“暂存区” 和 -cached 是一回事
◈ 隐匿文件就是一堆提交
◈ 并非所有引用都是分支或标签
◈ 合并提交不是空的

下面我们来详细了解这些内容。

“索引”、“暂存区” 和 -cached 是一回事

当你运行 git add file.txt,然后运行 git status,你会看到类似以下的输出:

  1. $ git add content/post/2023-10-20-some-miscellaneous-git-facts.markdown
  2. $ git status
  3. Changes to be committed:
  4. (use "git restore --staged <file>..." to unstage)
  5. 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/refs/stash 目录下)。

让我们将此博客文章隐匿起来,然后查看 stash 引用的日志:

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

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

  1. $ git show 2ff2c273 --stat
  2. commit 2ff2c273357c94a0087104f776a8dd28ee467769
  3. Author: Julia Evans <julia@jvns.ca>
  4. Date: Fri Oct 20 14:49:20 2023 -0400
  5. index on main: c6ee55ed wip
  6. content/post/2023-10-20-some-miscellaneous-git-facts.markdown | 40 ++++++++++++++++++++++++++++++++++++++++

毫不意外,它包含了这篇博客文章。这很合理!

实际上,git stash 会创建两个独立的提交:一个是索引提交,另一个是你尚未暂存的改动提交。这让我感到很振奋,因为我一直在开发一款工具,用于快照和恢复 Git 仓库的状态(也许永远不会发布),而我提出的设计与 Git 的隐匿实现非常相似,所以我对自己的选择感到满意。

显然 stash 中的旧提交存储在 reflog 中。

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

Git 文档中经常泛泛地提到 “引用”,这使得我有时觉得很困惑。就个人而言,我在 Git 中处理 “引用” 的 99% 时间是指分支或 HEAD,而剩下的 1% 时间是指标签。事实上,我以前完全不知道任何不是分支、标签或 HEAD 的引用示例。

但现在我知道了一个例子—— stash 是一种引用,而它既不是分支也不是标签!所以这太酷啦!

以下是我博客的 Git 仓库中的所有引用(除了 HEAD):

  1. $ find .git/refs -type f
  2. .git/refs/heads/main
  3. .git/refs/remotes/origin/HEAD
  4. .git/refs/remotes/origin/main
  5. .git/refs/stash

人们在本帖回复中提到的其他一些参考资料:

◈ refs/notes/*,来自 git notestylercipriani.com
◈ refs/pull/123/head 和 refs/pull/123/head`` 用于 GitHub 拉取请求(可通过 git fetch origin refs/pull/123/merge` 获取)
◈ refs/bisect/*,来自 git bisect

合并提交不是空的

这是一个示例 Git 仓库,其中我创建了两个分支 x 和 y,每个分支都有一个文件(x.txt 和 y.txt),然后将它们合并。让我们看看合并提交。

  1. $ git log --oneline
  2. 96a8afb (HEAD -> y) Merge branch 'x' into y
  3. 0931e45 y
  4. 1d8bd2d (x) x

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

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

但是,如果我单独比较合并提交与其两个父提交之间的差异,你会发现当然差异:

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

现在回想起来,合并提交并不是实际上“空的”(它们是仓库当前状态的快照,就像任何其他提交一样),这一点似乎很明显,只是我以前从未思考为什么它们看起来为空。

显然,这些合并差异为空的原因是合并差异只显示冲突 —— 如果我创建一个带有合并冲突的仓库(一个分支在同一文件中添加了 x,而另一个分支添加了 y),然后查看我解决冲突的合并提交,它看起来会像这样:

  1. $ git show HEAD
  2. commit 3bfe8311afa4da867426c0bf6343420217486594
  3. Merge: 782b3d5 ac7046d
  4. Author: Julia Evans <julia@jvns.ca>
  5. Date: Fri Oct 20 15:29:06 2023 -0400
  6. Merge branch 'x' into y
  7. diff --cc file.txt
  8. index 975fbec,587be6b..b680253
  9. --- a/file.txt
  10. +++ b/file.txt
  11. @@@ -1,1 -1,1 +1,1 @@@
  12. - y
  13. -x
  14. ++z

这似乎是在告诉我,一个分支添加了 x,另一个分支添加了 y,合并提交通过将 z 替代冲突解决了它。但在前面的示例中,没有冲突,所以 Git 并未显示任何差异。

(感谢 Jordi 告诉我合并差异的工作原理)

先这样吧

些写到这里吧,也许我将在学到更多 Git 知识时撰写另一篇关于 Git 的知识的博客文章。

(题图:MJ/03bfecc3-944e-47a0-a4fd-575293d2ba92)


via: https://jvns.ca/blog/2023/10/20/some-miscellaneous-git-facts/

作者:Julia Evans 选题:lujun9972 译者:KaguyaQiang 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

LCTT 译者 :KaguyaQiang
🌟
翻译: 1.0 篇
|
贡献: 2 天
2023-10-24
2023-10-25
https://linux.cn/lctt/KaguyaQiang
欢迎遵照 CC-BY-SA 协议规定转载,
如需转载,请在文章下留言 “转载:公众号名称”,
我们将为您添加白名单,授权“转载文章时可以修改”。


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
老年艾滋蔓延,被忽略的性需求Linux 如何挽救老旧电脑(和地球) | Linux 中国如何在 Linux 中扩展 Veritas 文件系统(VxFS) | Linux 中国Vojtux:针对视力障碍用户改造 Linux | Linux 中国Fedora Linux Flatpak 九月推荐应用 | Linux 中国Mageia 9 发布:搭载 Linux 内核 6.4,支持 PulseAudio | Linux 中国在基于 Arm 的 Thinkpad X13S 笔记本上运行 Linux | Linux 中国Arch Linux 下全面使用 Wayland 的配置指南 | Linux 中国在 Linux 文件系统中使用 attr 添加扩展属性 | Linux 中国Linux 黑话解释:Linux 中的 Super 键是什么? | Linux 中国中原被忽略的宝藏小城,连续8年上榜“中国宜居城市”,太适合反向旅行!Linus Torvalds:Linux 内核中的 Rust、AI 和疲劳的维护者 | Linux 中国记一次和犹太人谈生意的经历 (下)红色日记 11.22-30将手机作为你的 Linux 桌面的摄像头和麦克风 | Linux 中国如何在 Linux 中查找映射到 VxVM 磁盘的 SAN LUN | Linux 中国八月25日共军飞机继续绕台湾飞行Linux 爱好者线下沙龙:LLUG 2023 深圳 - 活动预告 | Linux 中国如何在 Linux 中映射 SAN LUN、磁盘和文件系统 | Linux 中国澳洲报税截止时间只剩两周!这项易被忽略的物品也可扣税Librem 11:Purism 推出注重隐私的 Linux 平板电脑 | Linux 中国选择题:DUKE vs. GIT(州外学费), CS专业一个被忽略的事实:工资水平是由什么决定的?Linux Lite 6.6 发布:更新了欢迎应用和图标主题 | Linux 中国在 Linux 的 VirtualBox 中从 USB 驱动器启动 | Linux 中国澳洲报税截止时间只剩两周!逾期或罚$1500!这项易被忽略的物品也可扣税最被忽略的糖水大省,花样凭什么多过广东?首款 Linux 游戏本?!Tuxedo 推出 Linux 游戏本 Sirius 16《星级男人通鉴》第20章 平安夜的陷阱Linux 上的最佳白板应用程序 | Linux 中国10 个在 Linux 终端中生成有趣的 ASCII 字符画的工具 | Linux 中国桃源在心Linux 爱好者线下沙龙:LLUG 2023 深圳硬核来袭 | Linux 中国Linux 下“Hello World”的幕后发生了什么 | Linux 中国如何在 Linux 中注释 PDF | Linux 中国你好,我是筚(bì)篥( lì)!
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。