我的Git存储库在根目录下有两个子目录:
/finisht
/static
当这是在SVN中时,/finisht在一个地方签出,而/static在其他地方签出了,如下所示:
svn co svn+ssh://admin@domain.example/home/admin/repos/finisht/static static
有没有办法用Git做到这一点?
我的Git存储库在根目录下有两个子目录:
/finisht
/static
当这是在SVN中时,/finisht在一个地方签出,而/static在其他地方签出了,如下所示:
svn co svn+ssh://admin@domain.example/home/admin/repos/finisht/static static
有没有办法用Git做到这一点?
当前回答
如果要克隆gitclone--不签出<REPOSTORY_URL>cd<REPOSTORY_NAME>现在,设置您希望拉入工作目录的特定文件/目录:git稀疏检出集<PATH_TO_A_SPECIFIC_DIRECTORY_OR_FILE_TO_PULL>然后,您应该将工作目录重新设置为您希望提取的提交。例如,我们将其重置为默认的origin/master的HEAD提交。git reset—硬头如果您想gitinit然后远程添加初始化git远程添加原点<REPOSTORY_URL>现在,设置您希望拉入工作目录的特定文件/目录:git稀疏检出集<PATH_TO_A_SPECIFIC_DIRECTORY_OR_FILE_TO_PULL>最后一次提交:git拉动原点主机
注:如果您想将另一个目录/文件添加到工作目录,可以这样做:git稀疏签出添加<PATH_TO_ANOTHER_SPECIFIC_DIRECTORY_OR_FILE_TO_PULL>如果要将所有存储库添加到工作目录,请执行以下操作:git稀疏签出添加*如果要清空工作目录,请执行以下操作:git稀疏签出集为空
如果需要,可以通过运行以下命令来查看已指定的跟踪文件的状态:
git status
如果要退出稀疏模式并克隆所有存储库,应运行:
git sparse-checkout set *
git sparse-checkout set init
git sparse-checkout set disable
其他回答
您正在尝试做的是所谓的稀疏签出,这一功能是在Git1.7.0(2012年2月)中添加的。执行稀疏克隆的步骤如下:
mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>
这将使用远程设备创建一个空的存储库,并获取所有对象,但不会检出它们。然后执行以下操作:
git config core.sparseCheckout true
现在,您需要定义要实际检出的文件/文件夹。这是通过在.git/info/spease checkout中列出它们来完成的,例如:
echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout
最后但同样重要的是,使用远程状态更新空回购:
git pull origin master
现在,文件系统上的一些/dir和另一个/sub/tree的文件将被“检出”(这些路径仍然存在),而没有其他路径。
您可能想看一下扩展教程,可能应该阅读有关稀疏签出和读取树的官方文档。
作为一项功能:
function git_sparse_clone() (
rurl="$1" localdir="$2" && shift 2
mkdir -p "$localdir"
cd "$localdir"
git init
git remote add -f origin "$rurl"
git config core.sparseCheckout true
# Loops over remaining args
for i; do
echo "$i" >> .git/info/sparse-checkout
done
git pull origin master
)
用法:
git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"
请注意,这仍然会从服务器下载整个存储库–只有签出的大小减小了。目前,仅克隆一个目录是不可能的。但如果您不需要存储库的历史记录,至少可以通过创建浅层克隆来节省带宽。有关如何结合浅层克隆和稀疏检出的信息,请参阅下面的udondan答案。
截至Git 2.25.0(2020年1月),Git中添加了一个实验性稀疏校验命令:
git sparse-checkout init
# same as:
# git config core.sparseCheckout true
git sparse-checkout set "A/B"
# same as:
# echo "A/B" >> .git/info/sparse-checkout
git sparse-checkout list
# same as:
# cat .git/info/sparse-checkout
这将克隆特定文件夹并删除所有与之无关的历史记录。
git clone --single-branch -b {branch} git@github.com:{user}/{repo}.git
git filter-branch --subdirectory-filter {path/to/folder} HEAD
git remote remove origin
git remote add origin git@github.com:{user}/{new-repo}.git
git push -u origin master
上面有很多好的想法和脚本。我情不自禁地将它们组合成一个bash脚本,并提供帮助和错误检查:
#!/bin/bash
function help {
printf "$1
Clones a specific directory from the master branch of a git repository.
Syntax:
$(basename $0) [--delrepo] repoUrl sourceDirectory [targetDirectory]
If targetDirectory is not specified it will be set to sourceDirectory.
Downloads a sourceDirectory from a Git repository into targetdirectory.
If targetDirectory is not specified, a directory named after `basename sourceDirectory`
will be created under the current directory.
If --delrepo is specified then the .git subdirectory in the clone will be removed after cloning.
Example 1:
Clone the tree/master/django/conf/app_template directory from the master branch of
git@github.com:django/django.git into ./app_template:
\$ $(basename $0) git@github.com:django/django.git django/conf/app_template
\$ ls app_template/django/conf/app_template/
__init__.py-tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl
Example 2:
Clone the django/conf/app_template directory from the master branch of
https://github.com/django/django/tree/master/django/conf/app_template into ~/test:
\$ $(basename $0) git@github.com:django/django.git django/conf/app_template ~/test
\$ ls test/django/conf/app_template/
__init__.py-tpl admin.py-tpl apps.py-tpl migrations models.py-tpl tests.py-tpl views.py-tpl
"
exit 1
}
if [ -z "$1" ]; then help "Error: repoUrl was not specified.\n"; fi
if [ -z "$2" ]; then help "Error: sourceDirectory was not specified."; fi
if [ "$1" == --delrepo ]; then
DEL_REPO=true
shift
fi
REPO_URL="$1"
SOURCE_DIRECTORY="$2"
if [ "$3" ]; then
TARGET_DIRECTORY="$3"
else
TARGET_DIRECTORY="$(basename $2)"
fi
echo "Cloning into $TARGET_DIRECTORY"
mkdir -p "$TARGET_DIRECTORY"
cd "$TARGET_DIRECTORY"
git init
git remote add origin -f "$REPO_URL"
git config core.sparseCheckout true
echo "$SOURCE_DIRECTORY" > .git/info/sparse-checkout
git pull --depth=1 origin master
if [ "$DEL_REPO" ]; then rm -rf .git; fi
您仍然可以使用svn:
svn export https://admin@domain.example/home/admin/repos/finisht/static static --force
到“gitclone”子目录,然后到“gitpull”子目录。
(并非旨在提交和推送。)
我不知道是否有人成功拉取了特定目录,这是我的经验:gitclone--filter=blob:none--singlebranch<repo>,下载对象时立即取消,输入repo,然后gitcheckoutorigin/master<dir>,忽略错误(sha1),输入dir,对每个子目录重复签出(使用新的dir)。我设法以这种方式快速获取源文件