Gt - dir克隆和子模块之间的结构差异

时间:2012-01-05 20:01:42

标签: git version-control

希望有人可能知道这种不一致行为的解释。我和公共回购以及我自己的项目回购都有这个问题,但是例如我会使用Facebook SDK from GitHub

如果我克隆这个repo,它会检入一个名为php-sdk的文件夹。这是非常值得期待的,尽管GitHub上的repo文件列表没有显示这个文件夹。

如果我把它作为另一个项目中的子模块克隆出来(对于像这样的SDK来说这是一个非常常见的操作)我只是将文件夹的内容直接输出到我选择的目录中。

我也遇到过这样的情况:当我将所有项目文件包装在目录中并将其提交到repo中时,克隆时有时不会出现此结构(与上面的子模块示例输出相同。) .git目录的名称前缀似乎改变了这一点,但对子模块命令的结果没有任何影响。

这些命令在处理repo结构中的第一个目录时是否都有不同的行为?我是否误解了如何将文件存储在回购中?我想你可以提出这个小麻烦,但我希望得到这些约定,使我的回购更友好的克隆。

1 个答案:

答案 0 :(得分:2)

基本上没有'wrap'目录作为存储库的一部分存储。你对这一点的期望是误导你的。默认情况下,Git repo只是名为.git的目录。您的沙箱或签出的东西放置在.git文件夹所在的同一根级别。进行克隆时,它会自动检出主分支。 .git文件夹和结帐是git工作区的实际根目录。

按照惯例,当您使用clone和git submodule add命令时,Git通常会推断出一个名称并为您的工作区创建一个目录。它将创建目录,然后放置git repo(该.git文件夹),然后将主分支文件签出到其中。但是,您可以指定git clone <repo> .git clone <repo> <target_dir>,Git会将您的仓库的根目录放在任何您想要的位置。

所以,如果您创建了这样的回购:

mkdir repo.git
cd repo.git
git init
touch foo
git add foo
git commit -m "Initial commit"

稍后使用git clone repo.git克隆它时,只会将其放入名为repo的子目录中,该子目录具有名为foo的文件和目录.git。但是,repo是根签出目录,而不是当前目录(你可以告诉它,因为它将有一个.git目录)。您运行克隆的目录将不是存储.git或结帐目录的目录。如果你想要那样做git clone <repo> .然后你会看到名为foo的文件和一个名为.git的目录,而没有名为repo的目录。

如果你想要一个名为repo的目录,那么嵌套所有的源代码就可以像这样创建一个repo:

mkdir repo.git
cd repo.git
git init
mkdir repo
cd repo
touch foo
git add foo
git commit -m "Initial commit"

然后,当您使用git clone <uri>/repo.git克隆它时,您将拥有一个名为repo的目录,其中包含目录.git和一个名为repo的目录,其中包含foo文件。在我看来,这是一个间接层,可能很麻烦(我知道,我做过......一次)。

子模块是主仓库中的一个条目,只是一个目录,在某个结账时包含另一个git仓库。当你初次启动并更新子模块时,它基本上只是创建主repo为子模块保留的目录,然后将整个git repo和checkout提取到该目录中。既然您现在应该了解git repo通常只是.git目录并且旁边有一个checkout,那么很明显为什么该目录也不会有不同的包装目录。您基本上命名了当您使用git submodule add <repo> [<target_dir>]命令时子模块应该包装的目录。