checkout Git中的子目录?

cedebl8k  于 2023-02-02  发布在  Git
关注(0)|答案(9)|浏览(248)

是否可以在Git中 checkout 仓库的子目录?
假设我正在设置一个新的WordPress安装,我将为插件和主题定制创建两个新目录:

  • wordpress/wp-content/plugins/myplugins/
  • wordpress/wp-content/themes/mytheme/

我想通过Git来维护这些目录,在Subversion中,我可以通过trunk/myplugins/trunk/mytheme/目录并 checkout 子目录来完成这个任务,Git有办法用一个仓库来完成同样的任务吗?
我可能只是错过了一些Git范式的船,作为一个长期的SVN用户,几乎没有接触过Git。

编辑:Multiple branches存储不同的内容是一种有趣的处理方法。

gwo2fgha

gwo2fgha1#

稀疏检出为now in Git 1.7
另请参见问题“Is it possible to do a sparse checkout without checking out the whole repository first?“。
注意,稀疏 checkout 仍然需要您 * 下载 * 整个仓库,即使Git下载的一些文件最终不会出现在您的工作树中。

sigwle7e

sigwle7e2#

git clone --filter + git sparse-checkout仅下载所需的文件

例如,仅克隆此测试存储库中子目录small/中的文件:https://github.com/cirosantilli/test-git-partial-clone-big-small

git clone --depth 1 --filter=blob:none --sparse \
  https://github.com/cirosantilli/test-git-partial-clone-big-small
cd test-git-partial-clone-big-small
git sparse-checkout set small

此选项是与远程协议的更新一起添加的,它确实可以防止从服务器下载对象。
我在以下网址中更详细地介绍了这一点:如何只克隆Git仓库的子目录?
测试于2021年1月在git 2.30.0上进行。

8xiog9wr

8xiog9wr3#

在git中没有真实的的方法来实现这一点,如果你不想把两棵树作为一个工作单元来同时进行修改,那么就没有理由使用一个仓库来处理这两棵树,我原以为我会怀念Subversion的这个特性,但是我发现创建仓库只需要很少的管理开销(仅仅是因为仓库存储在工作副本的旁边,而不是要求我显式地选择工作副本之外的某个位置),我习惯于创建大量小型的单一用途仓库。
如果你坚持(或者真的需要),你可以创建一个只有mythememyplugins目录的git仓库,并在WordPress安装中使用符号链接。
MDCore写道:
对例如mytheme进行提交将递增myplugin的修订号
注意,如果你决定把两个目录放在一个仓库中,这不是git要考虑的问题,因为git完全摒弃了单调递增修订号的概念。
在git中,把什么东西放在一个仓库中的唯一标准是它是否构成一个单独的单元,也就是说,在你的例子中,是否有一些修改,孤立地查看每个目录中的编辑内容是没有意义的。如果你有一些修改,你需要同时编辑两个目录中的文件,并且这些编辑内容是属于一起的,那么它们应该是一个仓库。如果没有,那就别把它们混在一起。
Git非常希望你为不同的实体使用不同的仓库。
submodules
子模块并不能满足将两个目录都保存在一个存储库中的愿望,因为它们实际上会强制每个目录都有一个单独的存储库,然后使用子模块将它们放在另一个存储库中。更糟糕的是,由于WordPress安装中的目录并不是同一目录的直接子目录,而且也是与许多其他文件的层次结构的一部分,将每个目录的存储库用作统一存储库中的子模块将不会提供任何益处,因为统一存储库将不会反映任何使用情况/需要。

kfgdxczn

kfgdxczn4#

我不喜欢稀疏 checkout 的一点是,如果您想 checkout 一个只有几个目录深的子目录,那么您的目录结构必须包含指向它的所有目录。
我解决这个问题的方法是在我的工作区以外的地方克隆repo,然后在我的工作区目录中创建一个符号链接,指向repository的子目录。Git这样做很好,因为像git status这样的东西会显示相对于当前工作目录的变更文件。

ecfdbz9o

ecfdbz9o5#

实际上,“narrow”或“partial”或“sparse” checkout 正在Git当前的大量开发中。请注意,您仍然会在.git下拥有完整的存储库。因此,其他两篇文章是Git当前状态的最新文章,但看起来我们最终将能够进行稀疏 checkout 。Checkout the mailing lists如果您对更多细节感兴趣--它们正在快速变化。

mqxuamgl

mqxuamgl6#

正如你的编辑所指出的,你可以使用两个独立的分支来存储两个独立的目录,这样可以将它们保存在同一个仓库中,但是你仍然不能让提交跨越两个目录树,如果你对一个目录树的修改需要对另一个目录树的修改,你必须将它们作为两个独立的提交来完成。并且您打开了两个目录的一对 checkout 可能不同步的可能性。
如果你想把这两个目录当作一个单元,你可以使用'wordpress/wp-content'作为你的repo的根目录,并在顶层使用.gitignore文件来忽略除了两个感兴趣的子目录之外的所有内容,这可能是目前最合理的解决方案。
据说稀疏 checkout 已经出现两年了,但是在git开发回购中仍然没有任何迹象,也没有任何迹象表明必要的更改会出现。

nnt7mjpx

nnt7mjpx7#

你不能 checkout 仓库的一个目录,因为整个仓库是由项目根目录下的一个.git文件夹来管理的,而不是subversion的无数个.svn目录.
在一个仓库中处理插件的问题是,提交到 mytheme 会增加 myplugin 的修订号,所以即使在subversion中,最好使用单独的仓库。
子项目的subversion范例是svn:externals,在git中可以翻译成submodules(但如果你以前用过svn:externals,就不一定了).

qfe3c7zg

qfe3c7zg8#

这里有一个灵感。只需使用shell regexgit 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

使用引号来转义shell正则表达式解释并将通配符传递给git。

第一个不是递归的,只包含深度为1的subdir文件,但第二个是递归的。

对于您的情况,以下内容可能就足够了。

git checkout master */*/wp-content/*/*
git checkout master '*/wp-content/*'

按要求黑掉线路就行了。

s4chpxco

s4chpxco9#

您只能将未提交的更改还原到特定文件或目录:

git checkout [some_dir|file.txt]

相关问题