湖州站内优化seo公司,杭州网站建设q479185700惠,字画网站建设,成立网站建设公司要求好吧#xff0c;我想你们中的大多数人每天都或多或少地使用 git#xff0c;但是您是否研究过 git 创建的 .git 文件夹中的内容#xff1f;本文[1]我们将一起探索一下#xff0c;了解里面到底发生了什么。 ❝ git 在基本层面上只是一堆通过文件名相互链接的文本文件。 ❞ in… 好吧我想你们中的大多数人每天都或多或少地使用 git但是您是否研究过 git 创建的 .git 文件夹中的内容本文[1]我们将一起探索一下了解里面到底发生了什么。 ❝ git 在基本层面上只是一堆通过文件名相互链接的文本文件。 ❞ init 众所周知我们从 git init 开始我们的 git 之旅。这给出了我们现在可能已经习惯的信息特别是如果你开始并放弃了很多副项目。 Initialized empty Git repository in /home/meain/dev/src/git-talk/.git/ 让我们看看目前 .git 存储库中有什么。 $ tree .git.git├── config├── HEAD├── hooks│ └── prepare-commit-msg.msample├── objects│ ├── info│ └── pack└── refs ├── heads └── tags 它似乎创建了一堆文件和文件夹。这些都是什么让我们一一回顾一下。 config 是一个文本文件其中包含当前存储库的 git 配置。如果你仔细研究它你会看到你的存储库的一些基本设置如作者、文件模式等。 HEAD 包含存储库的当前头。根据您设置的“默认”分支它将是 refs/heads/master 或 refs/heads/main 或您设置的任何其他分支。正如您可能已经猜到的这指向您可以在下面看到的 refs/heads 文件夹并指向一个名为 master 的文件该文件目前还不存在。该文件主文件仅在您第一次提交后才会显示。 hooks 包含可以在 git 执行任何操作之前/之后运行的任何脚本。 objects包含 git 对象即存储库中有关文件、提交等的数据。 refs 存储引用指针。 refs/heads 包含指向分支的指针refs/tags 包含指向标签的。 add 现在您已经了解 .git 中的初始文件集是什么让我们执行第一个操作将某些内容添加到 .git 目录中。让我们创建一个文件并添加它我们还没有提交它。 echo meain.io filegit add file 这会执行以下操作 --- init 2024-07-02 15:14:00.584674816 0530 add 2023-07-02 15:13:53.869525054 0530 -3,7 3,10 ├── HEAD ├── hooks │ └── prepare-commit-msg.msample├── index ├── objects│ ├── 4c│ │ └── 5b58f323d7b459664b5d3fb9587048bb0296de │ ├── info │ └── pack └── refs 如您所见这会导致两个主要变化。它修改的第一件事是索引文件。索引存储有关当前暂存内容的信息。这用于表示名为 file 的文件已添加到索引中。 第二个也是更重要的变化是在其中添加了一个新文件夹objects/4c和一个文件5b58f323d7b459664b5d3fb9587048bb0296de。 文件里有什么 这是我们详细了解 git 如何存储内容的地方。让我们首先看看其中存在哪些类型的数据。 $ file .git/objects/5c/5b58f323d7b459664b5d3fb9587048bb0296de.git/objects/4c/5b58f323d7b459664b5d3fb9587048bb0296de: zlib compressed data 嗯但是 zlib 压缩数据是什么 $ zlib-flate -uncompress .git/objects/4c/5b58f323d7b459664b5d3fb9587048bb0296deblob 9\0meain.io 看起来它包含我们执行 git add 的名为 file 的文件的类型、大小和数据。在本例中数据表明它是一个大小为 9 的 blob内容是 meain.io。 文件名是什么 嗯好问题。它来自于内容的sha1。如果您获取 zlib 压缩数据并通过 sha1sum 进行管道传输您将获得文件名。 $ zlib-flate -uncompress .git/objects/4c/5b58f323d7b459664b5d3fb9587048bb0296de|sha1sum4c5b58f323d7b459664b5d3fb9587048bb0296de git 获取要写入的内容的 sha1获取前两个字符在本例中为 4c创建一个文件夹然后使用其余部分作为文件名。 git 从前两个字符创建文件夹以确保单个对象文件夹下没有太多文件。 向 git cat 文件问好 事实上由于这是 git 中比较重要的部分之一因此 git 还有一个管道命令来查看对象的内容。您可以使用 git cat-file其中 -t 表示类型-s 表示大小-p 表示内容。 $ git cat-file -t 4c5b58f323d7b459664b5d3fb9587048bb0296deblob$ git cat-file -s 4c5b58f323d7b459664b5d3fb9587048bb0296de9$ git cat-file -p 4c5b58f323d7b459664b5d3fb9587048bb0296demeain.io commit 现在我们知道添加文件时会发生什么变化让我们通过提交将其提升到一个新的水平。 $ git commit -m Initial commit[master (root-commit) 4c201df] Initial commit 1 file changed, 1 insertion() create mode 100644 file 以下是发生的变化 --- init 2024-07-02 15:14:00.584674816 0530 commit 2023-07-02 15:33:28.536144046 0530 -1,11 1,25 .git├── COMMIT_EDITMSG ├── config ├── HEAD ├── hooks │ └── prepare-commit-msg.msample ├── index├── logs│ ├── HEAD│ └── refs│ └── heads│ └── master ├── objects│ ├── 3c│ │ └── 201df6a1c4d4c87177e30e93be1df8bfe2fe19 │ ├── 4c │ │ └── 5b58f323d7b459664b5d3fb9587048bb0296de│ ├── 62│ │ └── 901ec0eca9faceb8fe0a9870b9b6cde75a9545 │ ├── info │ └── pack └── refs ├── heads │ └── master └── tags 哇看来有很多变化。让我们一一浏览它们。第一个是新文件 COMMIT_EDITMSG。顾名思义它包含最后的提交消息。 如果您在不带 -m 标志的情况下运行 git commit 命令那么 git 获取提交消息的方式是使用 COMMIT_EDITMSG 文件打开编辑器让用户编辑提交消息一旦用户更新并退出编辑器git 使用文件的内容作为提交消息。 它还添加了一个全新的文件夹日志。这是 git 记录存储库中所有提交更改的一种方式。您将能够在此处看到所有引用和 HEAD 的提交更改。 对象目录也进行了一些更改但我希望您首先查看 refs/heads 目录其中我们现在有文件 master.txt。您可能已经猜到这是对 master 分支的引用。让我们看看里面有什么。 $ cat refs/heads/master3c201df6a1c4d4c87177e30e93be1df8bfe2fe19 看起来它指向新对象之一。我们知道如何观察物体让我们这样做吧。 $ git cat-file -t 3c201df6a1c4d4c87177e30e93be1df8bfe2fe19commit$ git cat-file -p 3c201df6a1c4d4c87177e30e93be1df8bfe2fe19tree 62902ec0eca9faceb8fe0a9870b9b6cde75a9545author Abin Simon mailmeain.io 1688292123 0530committer Abin Simon mailmeain.io 1688292123 0530Initial commit 你也可以这样做 git cat-file -t refs/heads/master 嗯看起来那是一种新的对象。这似乎是一个提交对象。提交对象的内容告诉我们它包含一个哈希值为 62902ec0eca9faceb8fe0a9870b9b6cde75a9545 的树对象它看起来像我们提交时添加的另一个对象。提交对象还包含有关作者和提交者是谁的信息在本例中都是我。最后还显示了此提交的提交消息是什么。 现在让我们看看树对象包含什么。 $ git cat-file -t 62902ec0eca9faceb8fe0a9870b9b6cde75a9545tree$ git cat-file -p 62901ec0eca9faceb8fe0a9870b9b6cde75a9545100644 blob 4c5b58f323d7b459664b5d3fb9587048bb0296de file 树对象将以其他树和 blob 对象的形式包含工作目录的状态。在本例中由于我们只有一个名为 file 的文件因此您只会看到一个对象。如果您看到的话该文件指向我们执行 git add 文件时添加的原始对象。 这是更成熟的仓库的树的样子。更多的树对象用于从提交对象链接的树对象内部来表示文件夹。 $ git cat-file -p 2e5e84c3ee1f7e4cb3f709ff5ca0ddfc259a8d04100644 blob 3cf56579491f151d82b384c211cf1971c300fbf8 .dockerignore100644 blob 02c348c202dd41f90e66cfeb36ebbd928677cff6 .gitattributes040000 tree ab2ba080c4c3e4f2bc643ae29d5040f85aca2551 .github100644 blob bdda0724b18c16e69b800e5e887ed2a8a210c936 .gitignore100644 blob 3a592bc0200af2fd5e3e9d2790038845f3a5cf9b CHANGELOG.md100644 blob 71a7a8c5aacbcaccf56740ce16a6c5544783d095 CODE_OF_CONDUCT.md100644 blob f433b1a53f5b830a205fd2df78e2b34974656c7b LICENSE100644 blob 413072d502db332006536e1af3fad0dce570e727 README.md100644 blob 1dd7ed99019efd6d872d5f6764115a86b5121ae9 SECURITY.md040000 tree 918756f1a4e5d648ae273801359c440c951555f9 build040000 tree 219a6e58af53f2e53b14b710a2dd8cbe9fea15f5 design040000 tree 5810c119dd4d9a1c033c38c12fae781aeffeafc1 docker040000 tree f09c5708676cdca6562f10e1f36c9cfd7ee45e07 src040000 tree e6e1595f412599d0627a9e634007fcb2e32b62e5 website change 让我们对文件进行更改看看它是如何工作的。 $ echo blog.meain.io file$ git commit -am Use blog link[master 68ed5aa] Use blog link 1 file changed, 1 insertion(), 1 deletion(-) 它的作用如下 --- commit 2024-07-02 15:33:28.536144046 0530 update 2023-07-02 15:47:20.841154907 0530 -17,6 17,12 │ │ └── 5b58f323d7b459664b5d3fb9587048bb0296de │ ├── 62 │ │ └── 901ec0eca9faceb8fe0a9870b9b6cde75a9545│ ├── 67│ │ └── ed5aa2372445cf2249d85573ade1c0cbb312b1│ ├── 8a│ │ └── b377e2f9acd9eaca12e750a7d3cb345065049e│ ├── e5│ │ └── ec63cd761e6ab9d11e7dc2c4c2752d682b36e2 │ ├── info │ └── pack └── refs 好吧我们添加了 3 个新对象。其中之一是包含文件新内容的 blob 对象一个是树对象最后一个是提交对象。 让我们从 HEAD 或 refs/heads/master 再次追踪它们。 $ git cat-file -p refs/heads/mastertree 9ab377e2f9acd9eaca12e750a7d3cb345065049eparent 3c201df6a1c4d4c87177e30e93be1df8bfe2fe19author Abin Simon mailmeain.io 1688292975 0530committer Abin Simon mailmeain.io 1688292975 0530Use blog link$ git cat-file -p 9ab377e2f9acd9eaca12e750a7d3cb345065049e100644 blob e5ec63cd761e6ab9d11e7dc2c4c2752d682b36e2 file$ git cat-file -p e6ec63cd761e6ab9d11e7dc2c4c2752d682b36e2blog.meain.io 那些关注的人可能已经注意到提交对象现在有一个名为parent的附加键它链接到先前的提交因为此提交是在先前的提交之上创建的。 branch 我们是时候创建一个分支了。让我们使用 git branch fix-url 来做到这一点。 --- update 2024-07-02 15:47:20.841154907 0530branch 2023-07-02 15:55:25.165204941 0530-27,5 28,6 │ └── pack└── refs├── heads│ ├── fix-url│ └── master└── tags这会在 refs/heads 文件夹下添加一个新文件其中文件作为分支名称内容作为最新提交的 id。 $ cat .git/refs/heads/fix-url68ed5aa2372445cf2249d85573ade1c0cbb312b1 这几乎就是创建分支的全部内容。 git 中的分支确实很便宜。标签的行为方式也相同只不过它们是在 refs/tags 下创建的。 在logs目录下也添加了一个文件用于存储类似于master分支的提交历史数据。 检查分支 在 git 中签出是指 git 获取提交的树对象并更新工作树中的文件以匹配其中记录的状态。在这种情况下由于我们从 master 切换到 fix-url两者都指向相同的提交和底层树对象因此 git 在工作树中没有任何事情可做。 git checkout fix-url 当您在 .git 中进行签出时发生的唯一变化是 .git/HEAD 文件现在将指向 fix-url。 $ cat .git/HEADref: refs/heads/fix-url 如果我们在这里做出commit。我需要这个来展示稍后合并的作用。 $ echo https://blog.meain.iofile$ git commit -am Fix url 合并 主要有3种合并方式。 最简单也是最容易的就是快进合并。在这种情况下您只需更新一个分支指向另一个分支指向的提交。这几乎涉及将 refs/heads/fix-url 中的哈希复制到 refs/heads/master。 第二个是变基合并。在这种情况下我们首先将更改应用到 main 当前一次指向一个提交的内容之上然后执行类似于快进合并的操作。 最后一种是使用单独的合并提交来合并两个分支。这有点不同因为它的提交对象中有两个父条目。我们将在最后进一步讨论这一点。 首先让我们看看合并之前的图表是什么样子的。 git log --graph --oneline --all* 42c6318 (fix-url) Fix url* 67ed5aa (HEAD - master) Use blog link* 3c201df Initial commit 现在执行合并 $ git merge fix-url # updates refs/heads/master to the hash in refs/heads/fix-url$ git log --graph --oneline --all* 42c6318 (HEAD - master) (fix-url) Fix url* 67ed5aa Use blog link* 3c201df Initial commit push 现在我们已经使用本地 git 存储库一段时间了让我们看看推送它时会发生什么。什么正在发送到另一端的 git 存储库 为了展示这一点首先让我创建另一个 git 存储库它可以用作此存储库的远程。 $ mkdir git-talk-2$ cd git-talk-2 git init --bare$ cd ../git-talk git remote add origin ../git-talk-2 现在push $ git push origin master 让我们看看我们的仓库发生了什么变化。 --- branch 2023-07-02 15:55:25.165204941 0530 remote 2023-07-02 17:41:05.170923141 0530 -22,12 29,18 │ ├── e5 │ │ └── ec63cd761e6ab9d11e7dc2c4c2752d682b36e2 │ ├── info │ └── pack ├── ORIG_HEAD └── refs ├── heads │ ├── fix-url │ └── master ├── remotes │ └── origin │ └── master └── tags 它添加了一个新的 refs/remotes 来存储有关不同remote中所有可用内容的信息。 但是什么会被发送到另一个 git 存储库呢它是对象中和引用下的所有内容。这就是其他 git 实例获取整个 git 历史记录所需的全部内容。 Reference [1] Source: https://blog.meain.io/2023/what-is-in-dot-git/ 本文由 mdnice 多平台发布