如何将git仓库的子目录检出到当前目录?

12

有一个远程代码库,其目录结构为:

-directory1
    -file1_1
    -file1_2
    ...
-directory2
    -file2_1
    -file2_2
    ...

我在 Web 托管上有一个自定义名称的文件夹,比如说 "/path/public_html"。

我该如何在 Web 托管上设置 Git ,以便让我的 "public_html" 跟踪远程仓库中的子目录 "directory2"?

换句话说,我想在 Web 托管上执行某种形式的 Git 命令,并将 public_html 更新为 "directory2" 的最新内容。如果有帮助,我不介意从 Web 托管推回到仓库。

4个回答

13

您不能直接克隆directory2的内容,只能克隆directory2和其内容,这意味着你的磁盘上始终有一个directory2/文件夹。

如果您想在public_html中查看directory2的内容(而不是public_html/directory2/...),则需要创建符号链接。

话虽如此,您仍然可以只克隆和检出directory2文件夹,而不是完整的repo,具体方法请参考“是否可能进行稀疏检出而无需先检出整个存储库?”中所述。

即:

git init /a/path
cd /a/path
git config core.sparseCheckout true
git remote add -f origin /url/remote/repo
echo "directory2/" > .git/info/sparse-checkout
git checkout [branchname] # ex: master

这将创建一个名为a/path/directory2的文件夹,然后您的public_html可以使用symlink链接到它。

如果在public_html中存在directory2文件夹不会困扰您,那么您可以在public_html中重复上述命令,而不是在a/path中执行。


6
如何在主机上克隆整个代码库并使用目录间的符号链接:public_html -> directory2

我希望能找到一个不那么混乱的解决方案,但还是谢谢你。我会记住这个想法的。 - Gleb Varenov
你可以使用稀疏检出来克隆特定的目录,详情请参考 https://git-scm.com/docs/git-read-tree#_sparse_checkout。我认为这比上述方法更加复杂。 - shahaf
符号链接是最简单、最明显的解决方案。唯一考虑其他选项的原因是如果你的空间非常有限,而且你的 Git 存储库中有很多其他无用的东西。(在这种情况下,你应该真正考虑拆分你的存储库) - Jonathan Hall

4
这是一项简单的git read-tree工作。在任何地方在网络服务器上创建一个裸的git存储库。保持部署目录中内容的清单,使用类似以下的pre-receive处理更新:
#!/bin/sh
while read old new ref; do [[ $ref = refs/heads/deploy ]] && {
    export GIT_INDEX_FILE=$GIT_DIR/deployment-manifest
    export GIT_WORK_TREE=/path/public-html
    git read-tree -um `git write-tree` $new:directory2 || exit 1
}; done

然后将需要部署到 web 服务器的内容推送到部署分支,例如:git push server master:deploy

git read-tree 加载索引(即清单,在工作树中放置哪些文件的列表),从存储在仓库对象数据库中的任何树。它会将你指定的树读入到索引中。它是 checkout、reset 和 merge 的幕后工作者,例如使用 -um 选项更新 checkout 或快进合并所需的工作树。你可以保留任何想要的索引,用于任何你想要的内容。方便包装器只保留一个索引,用于一组特定的内容,并始终更新名为 HEAD 的引用以与其配合的任何内容相匹配,但这纯粹是惯例。

注意,如果通过此方式部署的某个文件已更改,则在此处执行 git read-tree 并进行推送时,将失败,因为 git 不会覆盖你未告知的内容。


我总是忘记那种命令(read-tree here):+1 - VonC
我真的不理解这个答案。噢,好吧。 相较于稀疏检出和符号链接,有什么优势?我看到您将实际的repo保留在Web服务器上与/path/public-html分离,但此后的事情变得混沌不清。我应该如何编写deployment-manifest? 更新Web服务器文件以匹配远程repo的命令是什么?我认为'git pull'不够用。 - Gleb Varenov
这些命令已经实现了你想要的功能,请查看编辑。优点是:你可以得到你想要的内容,放在你想要的位置。 - jthill
抱歉。虽然我很欣赏这个答案的创意,但我还是把赏金给了一个我能够实际使用的答案,即使它不是完美的。我尝试着实现你的解决方案,但我无法让它工作。我在 web 服务器上创建了一个仓库,用 git init 分配了远程,并将你提供的代码保存到一个名为 'script.sh' 的文件中。我运行了脚本,它等待一些输入,我不确定接下来该怎么做。 - Gleb Varenov
1
你说的是什么语气?我并没有任何冒犯你的意思。pre-receive 的含义确实让我困惑了。直到你指出来并且我搜索了一下,才明白你的意思。之前我并不知道 git hooks。请不要太在意,我很感激你花时间和精力提供这个解决方案。只是我之前已经明确表示我不够了解,无法理解它。 - Gleb Varenov

2

我不关心从Web托管推回到存储库

在这种情况下,您可以使用归档命令。类似于以下内容:

git archive --remote=remote_repo --format=tar branch_name  path/to/directory2 > /path/public_html/dir2.tar && cd /path/public_html && tar xvf dir2.tar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接