在 Git 中签出子目录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/180052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Checkout subdirectories in Git?
提问by Annika Backstrom
Is it possible to check out subdirectories of a repository in Git?
是否可以在 Git 中检出存储库的子目录?
Imagine I am setting up a new WordPress installation. I will create two new directories for my plugin and theme customization:
想象一下,我正在设置一个新的 WordPress 安装。我将为我的插件和主题定制创建两个新目录:
wordpress/wp-content/plugins/myplugins/
wordpress/wp-content/themes/mytheme/
wordpress/wp-content/plugins/myplugins/
wordpress/wp-content/themes/mytheme/
I want to maintain these directories via Git. In Subversion, I would accomplish this by having trunk/myplugins/
and trunk/mytheme/
directories and checking out subdirectories. Does Git have a way to accomplish the same task using a single repository?
我想通过 Git 维护这些目录。在Subversion,我想先有做到这一点trunk/myplugins/
和trunk/mytheme/
目录,并检查出子目录。Git 是否有办法使用单个存储库完成相同的任务?
I could just be missing the boat on some Git paradigm, as a long time SVN user with little exposure to Git.
作为一个很少接触 Git 的 SVN 长期用户,我可能只是错过了一些 Git 范式。
Edit:Multiple branchesstoring different content is an interesting way to handle this.
编辑:存储不同内容的多个分支是一种有趣的处理方式。
采纳答案by Collin Anderson
Sparse checkoutsare now in Git 1.7.
Also see the question “Is it possible to do a sparse checkout without checking out the whole repository first?”.
另请参阅问题“是否可以在不先检出整个存储库的情况下进行稀疏检出?”。
Note that sparse checkouts still require you to downloadthe whole repository, even though some of the files Git downloads won't end up in your working tree.
请注意,稀疏检出仍然需要您下载整个存储库,即使 Git 下载的某些文件最终不会出现在您的工作树中。
回答by Aristotle Pagaltzis
There is no real way to do that in git. And if you won't be making changes that affect both trees at once as a single work unit, there is no good reason to use a single repository for both. I thought I would miss this Subversion feature, but I found that creating repositories has so little administrative mental overhead (simply due to the fact that repositories are stored right next to their working copy, rather than requiring me to explicitly pick some place outside of the working copy) that I got used to just making lots of small single-purpose repositories.
在 git 中没有真正的方法可以做到这一点。而且,如果您不打算将两个树作为一个工作单元同时进行更改,那么就没有充分的理由为这两个树使用一个存储库。我以为我会错过这个 Subversion 功能,但我发现创建存储库的管理精神开销非常小(仅仅是因为存储库就存储在它们的工作副本旁边,而不是要求我明确地选择某个位置之外的地方)工作副本),我习惯于制作许多小型的单一用途存储库。
If you insist (or really need it), though, you could make a git repository with just mytheme
and myplugins
directories and symlink those from within the WordPress install.
但是,如果您坚持(或确实需要),您可以创建一个仅包含mytheme
和myplugins
目录的 git 存储库,并在 WordPress 安装中对这些进行符号链接。
MDCore wrote:
MDCore 写道:
making a commit to, e.g., mythemewill increment the revision number for myplugin
对例如mytheme进行提交将增加myplugin的修订号
Note that this is not a concern for git, if you do decide to put both directories in a single repository, because git does away entirely with the concept of monotonically increasing revision numbers of any form.
请注意,如果您决定将两个目录放在一个存储库中,这对于 git 来说不是问题,因为 git 完全摒弃了任何形式的单调增加修订号的概念。
The sole criterion for what things to put together in a single repository in git is whether it constitutes a single unit, ie. in your case whether there are changes where it does not make sense to look at the edits in each directory in isolation. If you have changes where you need to edit files in both directories at once and the edits belong together, they should be one repository. If not, then don't glom them together.
将哪些东西放在 git 中的单个存储库中的唯一标准是它是否构成单个单元,即。在您的情况下,是否存在单独查看每个目录中的编辑没有意义的更改。如果您有更改需要同时编辑两个目录中的文件并且这些编辑属于一起,则它们应该是一个存储库。如果没有,那么不要将它们放在一起。
Git really really wants you to use separate repositories for separate entities.
Git 真的很希望你为不同的实体使用不同的存储库。
Submodules do not address the desire to keep both directories in one repository, because they would actually enforcehaving a separate repository for each directory, which are then brought together in anotherrepository using submodules. Worse, since the directories inside the WordPress install are not direct subdirectories of the same directory and are also part of a hierarchy with many other files, using the per-directory repositories as submodules in a unified repository would offer no benefit whatsoever, because the unified repository would not reflect any use case/need.
子模块没有解决将两个目录都保存在一个存储库中的愿望,因为它们实际上会强制每个目录都有一个单独的存储库,然后使用子模块将它们组合到另一个存储库中。更糟糕的是,由于 WordPress 安装中的目录不是同一目录的直接子目录,而且也是许多其他文件的层次结构的一部分,使用每个目录的存储库作为统一存储库中的子模块将没有任何好处,因为统一的存储库不会反映任何用例/需求。
回答by Travis Stevens
One thing I don't like about sparse checkouts, is that if you want to checkout a subdirectory that is a few directories deep, your directory structure must contain all directories leading to it.
我不喜欢稀疏结帐的一件事是,如果您想结帐一个只有几个目录深的子目录,则您的目录结构必须包含通向它的所有目录。
How I work around this is to clone the repo in a place that is not my workspace and then create a symbolic link in my workspace directory to the subdirectory in the repository. Git works like this quite nicely because things like git status will display the change files relative to your current working directory.
我解决这个问题的方法是在不是我的工作区的地方克隆 repo,然后在我的工作区目录中创建一个符号链接到存储库中的子目录。Git 的工作方式非常好,因为 git status 之类的内容将显示相对于您当前工作目录的更改文件。
回答by Pat Notz
Actually, "narrow" or "partial" or "sparse" checkouts are under current, heavy development for Git. Note, you'll still have the full repository under .git
. So, the other two posts are current for the current state of Git but it lookslike we will be able to do sparse checkouts eventually. Checkout the mailing listsif you're interested in more details -- they're changing rapidly.
实际上,“狭窄的”或“部分的”或“稀疏的”结帐正在为 Git 进行当前的大量开发。请注意,您仍将在.git
. 因此,另外两篇文章是针对 Git 的当前状态的最新文章,但看起来我们最终将能够进行稀疏结帐。 如果您对更多详细信息感兴趣,请查看邮件列表——它们变化很快。
回答by cjs
As your edit points out, you can use two separate branches to store the two separate directories. This does keep them both in the same repository, but you still can't have commits spanning both directory trees. If you have a change in one that requires a change in the other, you'll have to do those as two separate commits, and you open up the possibility that a pair of checkouts of the two directories can go out of sync.
正如您的编辑所指出的,您可以使用两个单独的分支来存储两个单独的目录。这确实将它们保存在同一个存储库中,但是您仍然不能跨两个目录树进行提交。如果您的一个更改需要另一个更改,您必须将它们作为两个单独的提交来执行,并且您打开了两个目录的一对检出可能不同步的可能性。
If you want to treat the pair of directories as one unit, you can use 'wordpress/wp-content' as the root of your repo and use .gitignore file at the top level to ignore everything but the two subdirectories of interest. This is probably the most reasonable solution at this point.
如果您想将这对目录视为一个单元,您可以使用“wordpress/wp-content”作为存储库的根目录,并在顶层使用 .gitignore 文件来忽略除感兴趣的两个子目录之外的所有内容。这可能是目前最合理的解决方案。
Sparse checkouts have been allegedly coming for two years now, but there's still no sign of them in the git development repo, nor any indication that the necessary changes will ever arrive there. I wouldn't count on them.
据称稀疏结帐已经两年了,但在 git 开发库中仍然没有任何迹象,也没有任何迹象表明必要的更改会到达那里。我不会指望他们。
回答by MDCore
You can't checkout a single directory of a repository because the entire repository is handled by the single .git folder in the root of the project instead of subversion's myriad of .svn directories.
您不能检出存储库的单个目录,因为整个存储库由项目根目录中的单个 .git 文件夹处理,而不是 subversion 的无数 .svn 目录。
The problem with working on plugins in a single repository is that making a commit to, e.g., mythemewill increment the revision number for myplugin, so even in subversion it is better to use separate repositories.
在单个存储库中处理插件的问题在于,对例如mytheme进行提交会增加myplugin的修订号,因此即使在 subversion 中,最好使用单独的存储库。
The subversion paradigm for sub-projects is svn:externalswhich translates somewhat to submodulesin git (but not exactly in case you've used svn:externals before.)
子项目的颠覆范式是svn:externals,它在某种程度上转化为git 中的子模块(但不完全是如果您之前使用过 svn:externals。)
回答by W.Perrin
There is an inspiration here. Just utilize shell regex
or git regex
.
这里有一个灵感。只需使用shell regex
或git regex
。
git checkout commit_id */*.bat # *.bat in 1-depth subdir exclude current dir, shell regex
git checkout commit_id '*.bat' # *.bat in all subdir include current dir, git regex
Use quotation to escape shell regex interpretation and pass wildcards to git.
使用引号转义 shell 正则表达式解释并将通配符传递给 git。
The first one is not recursive, only files in 1-depth subdir
. But the second one is recursive.
第一个不是递归的,只有 1-depth 中的文件subdir
。但第二个是递归的。
As for your situation, the following may be enough.
至于您的情况,以下内容可能就足够了。
git checkout master */*/wp-content/*/*
git checkout master '*/wp-content/*'
Just hack the lines as required.
只需根据需要破解线路。
回答by Yuliia Ashomok
You can revert uncommitted changes only to particular file or directory:
您只能将未提交的更改还原到特定文件或目录:
git checkout [some_dir|file.txt]