2012-01-05 90 views
0

希望有人可能知道这种不一致行为的解释。我遇到了公共回购以及我自己的项目回购这个问题,但例如,我会使用Facebook SDK from GitHub克隆和子模块之间的GIt-dir结构差异

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

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

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

这些命令的所有行为都有不同的处理repo结构中第一个目录的原因吗?我误解如何将我的文件存储在回购站内?我想你可以在一些小麻烦的情况下提交这个文件,但我希望能够通过这个约定来使我的回购更容易克隆。

回答

2

基本上没有作为存储库一部分存储的“包装”目录。你期望有一个是误导你的。默认情况下,Git repo只是名为.git的目录。您的沙箱或检出的内容与.git文件夹所在的根位置相同。当您创建一个克隆时,它会自动检出主分支。 .git文件夹和结帐是您的git工作区的实际根目录。

按照惯例,当您使用克隆命令和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的目录。

如果你想有始终是一个叫做回购嵌套所有的源目录,然后你会创造回购这样的:

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回购和检出到该目录中。既然你现在应该明白一个git仓库通常只是.git目录和一个checkout,它应该是显而易见的,为什么该目录不会有一个不同的包装目录。当您使用git submodule add <repo> [<target_dir>]命令时,您基本上命名了子模块应包含的目录。