Git 存储库混乱
Posted
技术标签:
【中文标题】Git 存储库混乱【英文标题】:Git repository confusion 【发布时间】:2020-09-14 17:52:29 【问题描述】:昨天我开始学习 git。但是看到两个相互矛盾的存储库定义,我感到很困惑。
第一个:存储库是包含您的项目的目录。一种 存储库由提交组成。
第二个:存储库是项目中的 .git 文件夹。
这两个陈述实际上传达了同样的东西吗?那么他们是怎么做到的呢? 我已经看到了 .git 隐藏文件夹,这肯定不是我的项目。
【问题讨论】:
【参考方案1】:这两个定义都过于关注存储库在本地文件系统上的样子。
从概念上讲,存储库是版本控制的文件树。它包含不同时间点和同一项目的不同开发分支的快照(或“提交”)。
在本地克隆存储库时,所有内容都包含在一个文件夹中。重建所有不同快照所需的数据位于 .git 子文件夹中。文件夹的其余部分代表项目的某个快照,以及您当前对其进行的任何未提交的更改。在任何时候,您都可以决定通过“提交”来创建新快照。用户可以通过向远程存储库推/拉快照来共享快照。
快照链接在一起,所以如果你得到一个,那么你也递归地得到它所基于的所有其他快照。这使您可以检查导致该状态的项目的整个历史。
【讨论】:
【参考方案2】:作为Wim Coenen put it,第二个定义——存储库是.git
目录中的东西——侧重于组织。
但是,从形式上讲,我必须同意第二个定义。剩下的区域——你进行工作的区域——不是存储库本身的一部分。它只是在存储库旁边。
原因是.git
文件夹内的东西是Git 的。你可以看看它,如果你了解 Git 的内部结构——随着 Git 的发展,随着时间的推移,它会从一个 Git 版本变化到另一个版本——你甚至可以直接在此处编辑内容。但总的来说,你应该把这些东西留给 Git 自己。
.git
文件夹中不的文件是你的。你可以对他们做任何你喜欢的事情。当您提出要求时,Git 会填充您的工作区域。
那么,简短的版本是你在你的工作树中工作。这个区域是你的,随心所欲。然后在不同的时间点告诉 Git:做某事。那某物可以:
将工作树中的文件复制到 Git 的存储库中;或 将文件从 Git 的存储库复制到您的工作树;或 做许多其他事情之一,例如比较特定的提交、查看过去的提交、调用 另一个 Git 存储库并与之交换提交等等。如果您使用git worktree
命令,那么您的 工作区(不属于存储库的一部分)和 Git 的实际保存存储库的区域之间的区别会变得更加重要,首先在 Git 2.5 中添加。特别是,您可以使用git worktree add
创建额外的工作树。每个这样的工作树都不在存储库中,事实上,当你完成它时,你可以简单地删除这样的工作树。
(Git 将您的工作区称为工作树或工作树。这就是为什么添加新工作树的命令是git worktree add
。)
Git 本身的主题是 Git 存储 commits。每个提交依次存储文件。实际上,每个提交都包含 所有 文件的完整快照。 Git 的存储文件使用重复数据删除,因为大多数提交大多持有与其他提交相同的文件版本。它们还以特殊的、只读的、仅限 Git 的格式存储。只有 Git 可以真正读取这些文件。这就是 Git 将文件提取到您的工作树的原因。
特别奇怪的部分是,当 Git 进行新提交时——这是你让 Git 存储更新文件的方式,在你更新它们之后——它会从 不是的副本中生成它们> 你的工作树中的副本!如果你曾经使用过 Mercurial,它在其他方面很像 Git,这可能有点令人费解。在 Mercurial 中,hg commit
从工作树中的文件进行新的提交。这是简单明了的。但是git commit
从 Git index 中的文件而不是工作树中的文件进行新提交。您必须继续使用 git add
将您更新的所有文件复制回 Git 的索引中。
因此,Git 的 index(Git 也将其称为 暂存区)是保存您提议的下一次提交的内容。在易于使用的 Mercurial 中,您的工作树包含您提议的下一次提交。在 Git 中,提议的下一个提交开始与当前提交匹配。当您更改工作树中的文件时,您必须将更改的文件复制回 Git 的索引,以更改建议的下一次提交。
(Git 进行新提交的方法为您提供了在 Mercurial 中难以实现的灵活性,但代价是需要大量 git add
命令。)
注意:在现代 Git 中,可以使用 git init --separate-git-dir
将 Git 的存储库(.git
文件夹)从您的工作树中分离出来。不过,我不知道有谁在日常工作中使用它。
【讨论】:
谢谢。这是一个非常详细且相对简单的解释。 为什么很多人把仓库称为项目目录本身? @Sharandeep:你得问他们?,但我认为这是一种心理混淆:因为git clone
创建了一个新项目目录,然后在该项目目录中创建.git
目录,它“感觉”项目和存储库是一回事。从某种意义上说,它们是:这是一个带有存储库的项目。但是因为它们可以分开(例如git init --separate-git-dir
),它们确实不是相同的。它们只是由一个git clone
命令创建的——如果你使用git clone
。
请注意,如果您自己创建项目目录,用文件填充它,并在考虑提交之前做一些初步工作,然后只然后运行git init
,它不会“感觉”Git“拥有”项目目录。但是当你使用git clone
制作项目目录时,它“感觉不一样”。
感谢您的建议和建议?以上是关于Git 存储库混乱的主要内容,如果未能解决你的问题,请参考以下文章