GIt - 克隆和子模块之间的目录结构差异

发布于 2024-12-25 06:38:24 字数 538 浏览 0 评论 0原文

希望有人知道这种不一致行为的解释。我在公共存储库以及我自己的项目存储库中都遇到了这个问题,但为了举例,我将使用 来自 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江湖正好 2025-01-01 06:38:24

基本上没有“包装”目录存储为存储库的一部分。你对存在的期望正在误导你。默认情况下,Git 存储库只是名为 .git 的目录。您的沙箱或签出的内容放置在 .git 文件夹所在的同一根级别。当您进行克隆时,它会自动检查主分支。 .git 文件夹和 checkout 是 git 工作区的实际根目录。

按照惯例,当您使用克隆和 git submodule add 命令时,Git 通常会推断出名称并为您的工作区创建一个目录。它将创建目录,然后放置 git 存储库(.git 文件夹),然后将主分支文件检出到其中。但是,您可以指定 git clone. 或 git clone; 和 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 或 checkout 目录的目录。如果您愿意,您可以执行 git clone. 然后您将只看到名为 foo 的文件和名为 .git 的目录,而没有名为 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/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 specify git clone <repo> . or git 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:

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

When you clone it later with git clone repo.git it is only by convention it is put into a subdirectory called repo that has a file called foo 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 do git clone <repo> . and then you would see just the file called foo 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:

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

Then when you clone it by just using git clone <uri>/repo.git you'll have a directory called repo that contains a directory .git and a directory called repo 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文