Git存储库混乱



昨天我开始学习git。但看到两个相互矛盾的存储库定义,我感到困惑。

1st:存储库是包含您的项目的目录。A.存储库由提交组成。

第二:存储库是项目中的.git文件夹。

这两个语句实际上传达了相同的东西吗?那他们是怎么做的
我看到了.git隐藏文件夹,它肯定不是我的项目。

这两个定义都过于关注存储库在本地文件系统上的样子。

从概念上讲,存储库是受版本控制的文件树。它包含同一项目的不同时间点和不同开发分支的快照(或"提交")。

在本地克隆存储库时,所有内容都包含在一个文件夹中。重建所有不同快照所需的数据都位于.git子文件夹中。文件夹的其余部分代表项目的某个快照,以及您当前对其所做的任何未提交的更改。您可以随时通过"提交"来决定创建新的快照。用户可以通过向远程存储库推送/从远程存储库拉取快照来共享快照。

快照是链接在一起的,所以如果你得到一个快照,你也会递归地得到它所基于的所有其他快照。这允许你检查导致该状态的项目的整个历史。

正如Wim Coenen所说,第二个定义——存储库是.git目录中的东西——专注于组织

但是,从形式上讲,我必须同意第二个定义。剩下的区域——您执行工作的区域——不是存储库本身的一部分。它只是存储库旁边的

原因是.git文件夹中的内容是Git的。你可以看看它,如果你了解Git的内部结构——随着时间的推移,随着Git的发展,它会从一个Git版本变化到另一个版本——你甚至可以直接在这里编辑。但总的来说,你应该把这些东西留给Git自己。

.git文件夹中不是的文件是您的。你可以和他们一起做任何你喜欢的事。Git将在您要求时,从提交开始填写您的工作区域。

因此,简短的版本是您的工作树中工作。这个区域是你的,做任何你喜欢的事。然后在不同的时间点告诉Git:做点什么的东西可以:

  • 将文件从工作树复制到Git的存储库中;或
  • 将文件从Git的存储库复制到您的工作树中;或
  • 做许多其他事情中的一件,比如比较特定的提交,查看过去的提交,调用另一个Git存储库并与之交换提交,等等

如果使用首次在Git 2.5中添加的git worktree命令,您的工作区域和Git的区域之间的区别将变得更加重要,前者不是存储库的一部分。特别是,可以使用git worktree add创建其他工作树。每个这样的工作树都不是在存储库中,事实上,当你完成它时,你可以简单地删除这样一个工作树。

(Git将您的工作区域称为工作树

的工作树Git本身的主要主题是Git存储提交。每个提交依次存储文件。事实上,每次提交都会保存所有文件的完整快照。Git的存储文件使用重复数据消除,因为大多数提交大多与其他提交保存相同版本的文件。它们还以一种特殊的、只读的、仅限Git的格式存储。只有Git才能真正读取这些文件。这就是Git将文件提取到工作树中的原因。

特别奇怪的是,当Git进行新的提交时——这就是你让Git在更新文件后存储更新文件的方式——它从不是你工作树中副本的副本中进行提交!如果你曾经使用过Mercurial,它在其他方面很像Git,这可能有点令人困惑。在Mercurial中,hg commit从工作树中的文件中进行新的提交。这是简单明了的。但是git commit从Git的索引中的文件而不是工作树中的文件进行新的提交。您必须继续使用git add将您更新的任何文件复制回Git的索引中。

因此,Git的索引(Git也将其称为暂存区)是保存您提议的下一次提交的索引。在易于使用的Mercurial中,您的工作树包含您提议的下一次提交。在Git中,建议的下一次提交从匹配当前提交开始。当您更改工作树中的文件时,必须将更改后的文件复制回Git的索引中,以更改建议的下一次提交。

(Git的新提交方法为您提供了灵活性,这在Mercurial中很难实现,但代价是需要大量的git add命令。)

注意:在现代Git中,可以使用git init --separate-git-dir将Git的存储库(.git文件夹)从工作树中分离出来。不过,我不知道有谁在日常工作中使用它。

最新更新