GIt - 克隆和子模块之间的目录结构差异
希望有人知道这种不一致行为的解释。我在公共存储库以及我自己的项目存储库中都遇到了这个问题,但为了举例,我将使用 来自 GitHub 的 Facebook SDK。
如果我克隆这个存储库,它会检出到一个名为 php-sdk 的文件夹中。尽管 GitHub 上列出的存储库文件没有显示此文件夹,但这几乎是可以预料到的。
如果我将其克隆为另一个项目中的子模块(这对于像这样的 SDK 来说是一个非常常见的操作),我只需将文件夹的内容直接输出到我选择的目录中。
我还遇到过这样的情况:当我将所有项目文件包装在一个目录中并将其提交到存储库中时,克隆时它有时不会出现在该结构中(与上面的子模块示例的输出相同。) 更改名称前缀.git 目录的 似乎改变了这一点,但对子模块命令的结果没有任何影响。
这些命令在处理存储库结构中的第一个目录时表现不同,是否有原因?我是否误解了如何将文件存储在存储库中?我想您可以在轻微的麻烦下归档此文件,但我很乐意获得此约定,以使我的存储库更适合克隆。
Hoping someone might know the explanation for this inconsistent behavior. I have had this problem both with public repos as well as my own project repos, but for example's sake I'll use the Facebook SDK from GitHub.
If I clone this repo, it checks out into a folder called php-sdk. This is pretty much to be expected, although the repo file listing at GitHub doesn't show this folder.
If I clone it out as a submodule in another project (which would be a pretty common operation for an SDK like this) I just get the contents of the folder directly outputted into the directory I choose.
I have also had it happen that when I wrap all my project files in a directory and commit it into the repo, it sometimes doesn't come out in this structure when cloned (same output as the submodule example above.) Changing the name prefix of the .git
dir seems to change this, but does not have any effect on the outcome of the submodule command.
Is there a reason these commands all behave differently handling the first directory in the repo structure? Am I misunderstanding how to store my files inside a repo? I guess you could file this under minor nuisance, but I would love to get the conventions for this to make my repos more friendly for cloning.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基本上没有“包装”目录存储为存储库的一部分。你对存在的期望正在误导你。默认情况下,Git 存储库只是名为
.git
的目录。您的沙箱或签出的内容放置在.git
文件夹所在的同一根级别。当您进行克隆时,它会自动检查主分支。 .git 文件夹和 checkout 是 git 工作区的实际根目录。按照惯例,当您使用克隆和 git submodule add 命令时,Git 通常会推断出名称并为您的工作区创建一个目录。它将创建目录,然后放置 git 存储库(. 或
.git
文件夹),然后将主分支文件检出到其中。但是,您可以指定 git clonegit clone;
和 Git 会将您的存储库的根目录放置在您想要的任何位置并签出。因此,如果您创建了这样的存储库:
当您稍后使用 git clone repo.git 克隆它时,按照惯例,它只会被放入名为. 然后您将只看到名为
repo
的子目录中,该子目录具有文件名为foo
和目录.git
。但是,repo 是根签出目录,而不是当前目录(您可以看出,因为其中会有一个 .git 目录)。您运行克隆的目录不会是存储.git
或 checkout 目录的目录。如果您愿意,您可以执行 git clonefoo
的文件和名为.git
的目录,而没有名为 repo 的目录。如果您希望始终有一个名为 repo 的目录,其中嵌套所有源代码,那么您可以像这样创建存储库:
然后,当您仅使用 git clone/repo.git 克隆它时> 您将有一个名为
repo
的目录,其中包含一个目录.git
和一个名为repo
的目录,其中包含 foo 文件。在我看来,这是一个可能很麻烦的间接层(我知道,我做过......一次)。子模块是主存储库中的一个条目,只是一个目录,其中在某个结账时包含另一个 git 存储库。当您第一次初始化和更新子模块时,它基本上只是创建主存储库为子模块保留的目录,然后获取整个 git 存储库并签出到该目录中。既然您现在应该明白 git 存储库通常只是 .git 目录和旁边的签出目录,那么很明显为什么该目录中不会有不同的包装目录。当您使用 git submodule add时,您基本上指定了子模块应包装在哪个目录中。 [] 命令。
Basically there is no 'wrapping' directory stored as part of the repository. Your expectations that there is one is what is misleading you. A Git repo is just, by default, the directory called
.git
. Your sandbox, or the stuff that is checked out, is placed at the same root level that the.git
folder is located. When you make a clone it automatically checks out the master branch. The .git folder and the checkout is the actual root of your git workspace.By convention, Git will normally infer a name and create a directory for your workspace when you use the clone and
git submodule add
command. It will create the directory and then it places the git repo (that.git
folder) and then checkout the master branch files into it. However, you could specifygit clone <repo> .
orgit clone <repo> <target_dir>
and Git will place the root of your repo and checkout anywhere you want.So if you created a repo like this:
When you clone it later with
git clone repo.git
it is only by convention it is put into a subdirectory calledrepo
that has a file calledfoo
and a directory.git
. However, repo is the root checkout directory, not the current directory (you can tell because it will have a.git
directory in it). The directory you ran clone from will NOT be the directory that stores the.git
or checkout directory. If you wanted that you would dogit clone <repo> .
and then you would see just the file calledfoo
and a directory called.git
and no directory called repo.If you want there always to be a directory called repo nesting all the source in then you would of created the repo like this:
Then when you clone it by just using
git clone <uri>/repo.git
you'll have a directory calledrepo
that contains a directory.git
and a directory calledrepo
that has the foo file. In my opinion this is a layer of indirection that can be cumbersome (I know, I did it...once).Submodule's are an entry in the main repo as simply a directory which contains another git repo at a certain checkout. When you init and update the submodule the first time it is basically just creating the directory reserved for the submodule by the main repo and then fetches that whole git repo and checkout into that directory. Since you should understand now that a git repo is just normally the .git directory and a checkout along side it it should be obvious why that directory would not also have a different wrapping directory in it. You basically named what directory the submodule should wrap in when you use the
git submodule add <repo> [<target_dir>]
command.