使用稀疏签出更改存储库目录结构
使用 Git 1.7.0 中新的稀疏签出功能,是否可以像在 SVN 中那样获取子目录的内容?我找到了 这个示例,但它保留了完整目录结构。想象一下,我只想要“perl”目录的内容,而不需要名为“perl”的实际目录。
-- 编辑 --
示例:
我的 git 存储库包含以下路径
repo/.git/
repo/perl/
repo/perl/script1.pl
repo/perl/script2.pl
repo/images/
repo/images/image1.jpg
repo/images/image2.jpg
repo/doc/
repo/doc/readme.txt
repo/doc/help.txt
我想要的是能够从上面的存储库生成此布局:
repo/.git/
repo/script1.pl
repo/script2.pl
但是,使用当前的稀疏结帐功能,它似乎是只能得到
repo/.git/
repo/perl/script1.pl
repo/perl/script2.pl
这不是我想要的。
With the new sparse checkout feature in Git 1.7.0, is it possible to just get the contents of a subdirectory like how you can in SVN? I found this example, but it preserves the full directory structure. Imagine that I just wanted the contents of the 'perl' directory, without an actual directory named 'perl'.
-- EDIT --
Example:
My git repository contains the following paths
repo/.git/
repo/perl/
repo/perl/script1.pl
repo/perl/script2.pl
repo/images/
repo/images/image1.jpg
repo/images/image2.jpg
repo/doc/
repo/doc/readme.txt
repo/doc/help.txt
What I want is to be able to produce from the above repository this layout:
repo/.git/
repo/script1.pl
repo/script2.pl
However with the current sparse checkout feature, it seems like it is only possible to get
repo/.git/
repo/perl/script1.pl
repo/perl/script2.pl
which is NOT what I want.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您仍然需要克隆整个存储库,其中包含所有文件。您可以使用
--depth
标志仅检索有限数量的历史记录。克隆存储库后,读取树技巧会将存储库的“视图”限制为仅位于 .git/info/sparse-checkout 文件中的文件或目录。
我编写了一个快速脚本来帮助管理稀疏性,因为目前它有点不友好:
如果将此脚本另存为 git-sparse.sh 到通过调用 git 报告的路径中 - -exec-path,那么您可以运行
git稀疏foo/ bar/
来仅“签出”foo和bar目录,或者git稀疏'*'
重新找回一切。You still need to clone the whole repository, which will have all the files. You could use the
--depth
flag to only retrieve a limited amount of history.Once the repository is cloned, the read-tree trick limits your "view" of the repository to only those files or directories that are in the
.git/info/sparse-checkout
file.I wrote a quick script to help manage the sparseness, since at the moment it is a bit unfriendly:
If you save this script as
git-sparse.sh
into the path reported by callinggit --exec-path
, then you can rungit sparse foo/ bar/
to only "checkout" the foo and bar directories, orgit sparse '*'
to get everything back again.简短的回答是否定的。 Git 将所有文件视为一个单元。
我建议您将存储库分解为逻辑块。一个单独的 Perl、图像和文档。如果您还需要维护 uber 存储库样式,您可以创建一个由 子模块 组成的存储库。
The short answer is no. Git sees all files as a single unit.
What I recommend is that you break down you repositories into logical chunks. A separate one for perl, images, and docs. If you also needed to maintain the uber repo style you can create a repo made up of Submodules.
现在,无需详细说明为什么要这样做,您的问题可以(可能)通过符号链接/快捷方式轻松解决。
回答这个问题 - 不,并且有一个有意义的理由。即使使用“稀疏结帐”,也会下载存储库的整个历史记录。为了澄清为什么这是必要的 - 否则跟踪重命名的文件将是一个令人头疼的事情。想象一下,您将文件
/repo_root/asd/file1.cpp
移动到/repo_root/fgh/file1.cpp
- 现在,如果您只下载了/repo_root/fgh
deltas,你不会知道 file1.cpp。所以这意味着您必须下载所有增量。但这样你就有了一个完整的存储库;不仅仅是它的一个文件夹,因此/rero_root/fgh
文件夹本身并不是一个存储库。当你签出时,这可能听起来并不重要,但是当你提交时,git 可能不知道足够的信息来正常工作。解决方法:如果你真的愿意,你可以创建一个以这种方式调用 git-checkout 的脚本(对于 sh shell,Windows 的批处理应该不难生成):
这里是第一个参数是要签出的分支,第二个 - 存储库当前所在的文件夹,第三个 - 您想要真正使用的子目录,第四个 - 您想要将其复制到的位置。
警告:我的shell技能几乎没有,所以测试后使用这个。重新创建该脚本的相反内容应该不难,即复制回内容,以便可以将其提交到存储库。
Now without plunging into detail about why would you want to do this, your problem can be (probably) easily solved by a symlink/shortcut.
To answer the question - no, and with a meaningful reason. The whole history of the repo is downloaded even with a 'sparse checkout'. To clarify why this is necessary - otherwise tracking renamed files would be a pain in the ...neck. Imagine you move the file
/repo_root/asd/file1.cpp
to/repo_root/fgh/file1.cpp
- now if you had only downloaded/repo_root/fgh
deltas, you won't know about file1.cpp. So this means you must download all deltas. But then you have a full repository; not just a folder cut of it, therefore just the/rero_root/fgh
folder is not a repo itself. This might not sound important when you checkout, but when you commit, git might not know enough to work alright.Workaround: If you really want to, you can create a script that calls git-checkout in such a manner (for the sh shell, batch for windows should not be hard to produce):
Here the first argument is the branch to checkout, the second - the folder where the repo is currently present, the third - the subdir you want to really use, and the fourth - the location to which you want it copied.
Warning: my shell skills are almost non-existent, so use this after testing. It should not be hard to recreate the reverse of this script, that copies back stuff, so that it can be committed to the repo.
richq 的答案很接近,但漏掉了一步。您需要显式启用稀疏结账:
这篇博文清楚地概述了所有步骤:
richq's answer was close, but it missed a step. You need to explicitly enable sparse checkout:
This blog post has all the steps outlined clearly:
git filter-branch --subdirectory-filter
是您所需要的,请参阅将子目录分离(移动)到单独的 Git 存储库。这是一个用于执行此操作的小 bash 脚本。
这将首先制作原始存储库的工作副本,然后使用子目录过滤器过滤分支以获得您想要的内容。
对于问题中的示例,
git-subdir.sh repo perl
可以工作。git filter-branch --subdirectory-filter
is what you need, see Detach (move) subdirectory into separate Git repository.Here is a little bash script to do that.
This will first make a working copy of the original repo, then filter branch using subdirectory filter to you get what you want.
Use for the example in the question,
git-subdir.sh repo perl
would work.您可以尝试 braid - 它会跟踪遥控器,同时将它们与路径匹配。
https://github.com/evilchelu/braid/wiki
You can try braid - it tracks remotes while matching them to a path.
https://github.com/evilchelu/braid/wiki
看来您想要做的是重命名目录树,以便您的文件最终位于不同的位置。在我看来,您要求做的是代码/项目管理的反模板,有两个方面:模块分类(java 节点下的 java 位,perl 节点下的 perl),以及拥有一个包含不同位置文件的项目从开发人员可视化它们的地方。由于 git 维护目录内容的哈希值以查看更改的内容,因此这也会破坏 git。
戴蒙·雷德尔
It appears what you are trying to do is rename the directory tree such that your files end up in a different place. It appears to me that what you are asking to do is an anti-template for code/project management on two counts: categorization of modules (java bits under java node, perl under perl node), and having a project with files in different locations from where the developer visualizes them. Since git maintains hashes of directory contents to see what is changed, this also breaks git as such.
Daemeon Reiydelle