Git Clone:只看文件,好吗?

hgc7kmma  于 2023-01-01  发布在  Git
关注(0)|答案(9)|浏览(266)

我想克隆一个GIT存储库,但不想克隆到.git目录。换句话说,我只想克隆文件。有办法做到吗?
git clone --no-checkout所做的与我想要的完全相反(只给了我.git目录)。
我试图为一个 * 远程 * repo而不是本地repo这样做,这意味着这不是“How to do a “git export” (like “svn export”)“的副本(即使解决方案最终可能是相同的)。

zbq4xfa0

zbq4xfa01#

与您要查找的内容最接近的git命令是**git archive**。
参见备份使用git的项目:它将在一个存档中包括所有文件(如果你正在使用git-archive-all脚本,则包括子模块)
然后,您可以在任何地方使用该存档,只返回文件,而不返回.git目录。

git archive --remote=<repository URL> | tar -t

如果您只需要第一级的文件夹和文件:

git archive --remote=<repository URL> | tar -t --exclude="*/*"

要仅列出远程存储库的第一级文件夹:

git archive --remote=<repository URL> | tar -t --exclude="*/*" | grep "/"

注意:does not work for GitHub (not supported)
因此,您需要to clone (shallow to quicken the clone step), and then archive locally

git clone --depth=1 git@github.com:xxx/yyy.git
cd yyy
git archive --format=tar aTag -o aTag.tar

另一种选择是进行浅克隆(如下所述),但将. git文件夹放在其他位置。

git --git-dir=/path/to/another/folder.git clone --depth=1 /url/to/repo

repo文件夹将只包含文件,而不包含.git
注意:git --git-dircommand git的一个选项,而不是git clone
更新Git 2.14.X/2.15(2017年第四季度):它将确保避免添加空文件夹
"git archive",尤其是与pathspec一起使用时,在输出中存储了一个空目录,尽管Git本身从未这样做过。
此问题已解决。
参见René Scharfe (``)commit 4318094(2017年9月12日)。
建议人:Jeff King ( peff ).
(由Junio C Hamano -- gitster --合并至commit 62b1cb7,2017年9月25日)

archive:不添加空目录到存档

虽然git不跟踪空目录,但git archive可能会被骗将一些空目录归档。
虽然对象数据库支持这种情况,但它不能在索引中表示,因此不太可能出现。
由于git不支持空目录,因此它们也不应该被写入归档文件。
如果确实需要一个空目录,则可以通过在其中放置一个空.gitignore文件来跟踪和归档该目录。

fjaof16o

fjaof16o2#

git archive --format=tar --remote=<repository URL> HEAD | tar xf -

取自here

zfciruhq

zfciruhq3#

您可以创建浅克隆以仅获取最后几个修订版本:

git clone --depth 1 git://url

然后删除.git目录或使用git archive导出树。

vsmadaxz

vsmadaxz4#

为什么不执行一次克隆,然后删除.git目录,这样就只剩下一个裸工作副本呢?
编辑:事实上,为什么要使用clone?当你说你想要一个git repo,但没有.git目录时,这有点令人困惑。如果你的意思是你只想要树的某个状态的副本,那么为什么不在shell中执行cp -R,而不是git clone,然后删除.git

yftpprvb

yftpprvb5#

git checkout -f

还有另一种方法可以做到这一点,即把repo从工作树中分离出来。
如果你需要定期更新这些无git的git文件,这个方法很有用。例如,我需要 checkout 源文件并构建工件,然后将工件复制到另一个repo中,以便部署到服务器,我也会在将源代码推送到服务器时使用它,我希望源代码 checkout 并构建到www目录中。
我们将创建两个文件夹,一个存放git,一个存放工作文件:

mkdir workingfiles
mkdir barerepo.git

初始化一个裸git存储库:

cd barerepo.git
git --bare init

然后创建一个post-receive钩子:

touch hooks/post-receive
chmod ug+x hooks/post-receive

在您喜爱的编辑器中编辑接收后信息:

GIT_WORK_TREE=/path/to/workingfiles git checkout -f
# optional stuff:
cd down/to/some/directory
[do some stuff]

将此添加为远程:

git remote add myserver ssh://user@host:/path/to/barerepo.git

现在,每次你推到这个空的repo,它都会把工作树 checkout 到/workingfiles/,但是/workingfiles/本身不受版本控制;在/workingfiles/中运行git status会给予错误fatal: Not a git repository (or any parent up to mount point /data)。这只是普通文件。
与其他解决方案不同,rm -r .git命令是不需要的,所以如果/workingfiles/是其他git repo,你不必担心这个命令会删除其他repo的git文件。

6ie5vjzr

6ie5vjzr6#

完全不需要使用git,只需要在URL(source)后面添加“/zipball/master/”即可。

下载中

这个解决方案最接近github页面上的“下载ZIP”按钮。一个优点是没有.git目录。另一个-它下载单个ZIP文件,而不是一个一个地下载每个文件,这会产生巨大的差异。它可以通过wget从命令行完成:wget -O "$(basename $REPO_URL)".zip "$REPO_URL"/zipball/master/。唯一的问题是,一些仓库可能根本没有master分支。如果是这种情况,URL中的“master”应该替换为适当的分支。

拉开拉链

一旦ZIP存在,最终解压缩的目录名可能仍然是相当奇怪和意外的。要解决这个问题,名称可以通过这个脚本提取,并mv-ed到basename的URL。最终script.sh可能看起来像这样(evals处理空格):

#Script for downloading from github. If no BRANCH_NAME is given, default is "master".
#usage: script.sh URL [BRANCH_NAME]
__repo_name__='basename "$1"'
__repo_name__="$(eval $__repo_name__)"
__branch__="${2:-master}"
#downloading
if [ ! -e ./"$__repo_name__"".zip" ] ; then
wget -O "$__repo_name__"".zip" "$1""/zipball/$__branch__/"
fi
#unpacking and renaming
if [ ! -e ./"$__repo_name__" ] ; then
unzip "$__repo_name__"".zip" && 
__dir_name__="$(unzip -qql $__repo_name__.zip | sed -r '1 {s/([ ]+[^ ]+){3}\s+//;q}')" &&
rm "$__repo_name__"".zip" &&
mv "$__dir_name__" "$__repo_name__"
fi

保持

这种方法应该可以“只访问文件”,并且非常适合于对小型存储库进行快速的一次性访问。
但是,如果源代码相当大,并且更新的唯一可能性是下载并重建所有源代码,则(据我所知)没有可能更新.git-less目录,因此必须再次下载完整的repo。那么最好的解决方案是--正如VonC已经解释的--坚持使用浅拷贝git clone --depth 1 $REPO_URL。但接下来呢?“检查更新”请参阅link,更新请参阅类似wiki的answer

31moq8wy

31moq8wy7#

git --work-tree=/tmp/files_without_dot_git clone --depth=1 \
  https://git.yourgit.your.com/myawesomerepo.git \
  /tmp/deleteme_contents_of_dot_git

/tmp中的两个目录都是动态创建的,不需要预先创建。

omqzjyyz

omqzjyyz8#

听起来你只是想要一份源代码的副本。如果是这样,为什么不直接复制目录并从副本中排除.git目录呢?

fnvucqvd

fnvucqvd9#

只需克隆它,然后删除.git文件夹

相关问题