从GitHub远程仓库导出Git

65

我想从Github远程仓库导出,而不是将其克隆。类似于svn export,我不想带有.git文件夹。我可以通过克隆并删除.git文件夹来解决这个问题。我想知道是否有更简便的方法?

我在某处读到可以使用git archive来实现这一点。

但是我遇到了以下错误...

$ git archive --format=tar --remote=git@github.com:xxx/yyy.git master | tar -xf -

Invalid command: 'git-upload-archive 'xxx/yyy.git''
You appear to be using ssh to clone a git:// URL.
Make sure your core.gitProxy config option and the
GIT_PROXY_COMMAND environment variable are NOT set.
fatal: The remote end hung up unexpectedly

任何帮助都将是极好的。谢谢。


可能是Do a "git export" (like "svn export")?的重复问题。 - Andre Figueiredo
你可能会对这里提到的获取zip API感兴趣:https://dev59.com/nWsy5IYBdhLWcg3wsQJj - russau
2021年10月:命令行gh repo archive <repository>可以帮助您:请参见下面的答案 - VonC
10个回答

68

由于 GitHub 支持 Subversion,您可以使用 svn export 命令获取项目但不包括任何版本控制文件:

svn export https://github.com/user/project/trunk

注意URL格式:

  • 基本URL是https://github.com/
  • USERNAME/PROJECTNAME,不包括.git
  • 在末尾添加/trunk

这样您就可以获得分支和子目录。

这将创建一个带有导出文件的目录。不可能直接创建tar / zip,您必须进行两个步骤(导出+ zip)。这是svn export本身的限制。

正如@Jon指出的那样,默认情况下,这将在名为trunk的目录中创建导出。如果您喜欢,可以指定不同的名称:

svn export https://github.com/username/projectname/trunk projectname

你可以使用这种技术来导出项目中的任何子目录。 例如,如果你只想要 some/path,可以执行以下操作:

svn export https://github.com/username/projectname/trunk/some/path local-dir-name

您也可以从分支和标签中获取路径。端点https://github.com/username/projectname完全像一个具有常规布局的Subversion存储库一样工作,因此您会在https://github.com/username/projectname/branches找到分支,在https://github.com/username/projectname/tags中找到标签。

在意外导出大型内容之前,最好先检查路径的内容。您可以使用svn ls来执行此操作,例如:

svn ls https://github.com/username/projectname/

通常这应该给你:

branches/
tags/
trunk/
你可以通过迭代地探索存储库来实现这一点。

1
我没有svn/git,也不打算安装。我只想要子目录。我该怎么办? - Mark Jeronimus
@MarkJeronimus 如果我知道如何在没有 svn 的情况下完成它,我会那样回答...不幸的是我不知道 :( 所以你要么使用 GitHub 自己的下载功能下载整个存储库,要么安装 svn 来使用此技巧。 - janos
谢谢分享。但是我们有多确定这不是在后台下载整个仓库?我刚刚使用它从一个大型仓库中获取了一个小文件,但命令需要几分钟才能完成。 - Oliver Pearmain
@OliverPearmain 在一个历史悠久的相当大的代码库中,我发现在执行 time svn export repo/trunk/pathtime git clone --bare repo 时有很大的差异。(我添加了 --bare 选项以消除创建工作树所需的额外时间。) - janos
是的,这个可行... URL格式非常棘手。你需要使用的URL并不是实际的URL。即使你的“trunk”被称为“master”,你也需要使用你描述的格式。这是我永远无法挽回的几个小时 ;) - John
我没有svn/git,也没有计划安装它们。我只想要子目录。我该怎么办?你可以使用Selenium来启动一个网络浏览器,然后编写代码来浏览代码库,并通过Web界面逐个下载每个子目录。这应该很简单。 - undefined

18
对于我来说至少是未知的原因,GitHub不支持这个
We don’t support people running git-archive against our servers.

似乎有点傻,因为通过SVN你可以做到,但是...我给@Janos' answer点了赞。

9

如果您的目标是限制与服务器交换的信息量,您是否考虑使用--depthclone命令?尽管如此,您仍需要删除(大大减少的).git子目录:

git clone --depth=1 git@github.com:xxx/yyy.git && rm -rf yyy/.git

好主意。如果我能够“导出”它,那就更好了 :) - Adrian Gunawan

8
如果你只对从GitHub导出感兴趣,那么他们提供了下载tarballs的机制。例如:https://github.com/torvalds/linux/downloads。即使它说“此存储库没有任何下载内容。”,你仍然可以使用按钮下载主分支的tarball。或者查看此链接以获取与标签相关联的tarball列表:https://github.com/torvalds/linux/tags。这对于任何GitHub存储库都适用,而不仅仅是Linux内核。

1
如果它适用于任何Git存储库而不仅仅是GitHub,那将非常有用。 - anatoly techtonik
什么按钮?我怀疑这个功能可能已经消失了。 - pjz
下载和上传已被废弃:https://github.blog/2012-12-12-goodbye-uploads/ - Joseph Sheedy

5
如果您需要对已命名的提交(即分支和标签)进行操作,则可以使用git clone --depth=1结合git archive。值得注意的是,git clone --depth=1会克隆所有分支和标签的顶部提交记录,而不仅仅是master。因此,在进行这样的浅层克隆之后,您可以进入本地目录并执行git archive --format=tar tag_to_be_exported。所以如果您想导出标签release1.1
git clone --depth=1 git@github.com:xxx/yyy.git
cd yyy
git archive --format=tar release1.1 -o release1.1.tar

所以,除非您需要导出未命名的提交ID,否则这可能是一个不错的解决方案。


1
有趣的是你提到了“所有分支和标签”的话题。确实,一个人可能想要在一个巨大的仓库中导出一个轻量级分支。然而,在我的git(1.9.1)中,man git-clone有选项--[no-]single-branch,“仅克隆导致单个分支末端的历史记录”,“使用--depth选项创建浅克隆时,默认情况下是这样的,除非给出--no-single-branch以获取靠近所有分支末端的历史记录。” - Stéphane Gourichon
@StéphaneGourichon 是的,自从这个答案发布以来,默认值已经改变了:https://dev59.com/kHI-5IYBdhLWcg3wlpeW#9920956 - xverges

1

1

我之前也遇到过同样的问题,据我所知,这似乎只适用于Bitbucket,例如:

ysim:~/repos$ git archive --format=tar --prefix=alembic/ --remote=ssh://git@bitbucket.org/zzzeek/alembic.git master | tar -xf -
ysim:~/repos$ ls
alembic

但是我找到了一个使用wget的GitHub解决方法 - 因此在新的GitHub界面中,您会发现右侧边栏底部有一个名为“Download ZIP”的按钮;右键单击它并复制链接地址。

Download ZIP

接下来,在命令行中执行以下操作(我从这里得到了灵感):
wget -qO- -O tmp.zip <zipball url> && unzip tmp.zip && rm tmp.zip

这将解压缩到一个名为repo-master/的目录中。

如果您愿意,还可以在.gitconfig中对其进行别名设置,以便您无需记住/键入所有内容,例如:

export = "! f() { wget -qO- -O tmp.zip \"$1\" && unzip tmp.zip && rm tmp.zip; }; f"

所以你可以在终端中这样做:

ysim:~/repos$ git export https://github.com/ysim/verbinski/archive/master.zip
ysim:~/repos$ ls
verbinski-master

您可以在URL的末尾放置.tar.gz而不是.zip - Johan Boulé

0

实现这一目标的一种方法是使用GIT提供的SVN支持。

以root身份执行一次性操作的步骤(适用于CentOS)如下:

yum install git

yum install subversion

要执行选择性导出,应使用以下语法:

svn export  <git repository>/<source folder> <empty target folder>  --no-auth-cache --force --username <active directory username>

如果在提示保存密码时不使用参数--no-auth-cache,请出于安全原因输入"no",否则密码将以未加密的形式保存。

从GIT标记转换为SVN标记时,应用以下映射规则: 将"tree/master"替换为"trunk"表示主分支 将"tree/branch_name"替换为"branches/branch_name"表示分支

这适用于文件和目录。


0

如果您需要在Github上获取提交的tarball,我认为这是最简单的方法:

假设您的存储库名称为 https://github.com/arielgabizon/librustzcash

并且提交ID为 4be41ca6160c16abfd983c8c878b6ea04105b224

只需在浏览器中输入以下地址 https://github.com/arielgabizon/librustzcash/archive/4be41ca6160c16abfd983c8c878b6ea04105b224.tar.gz

至少在Google Chrome上,它将开始下载文件。


-6

对于一个 普通 的导出:

$ git archive master | tar -x -C /path/to/destination

对于一个 zip 压缩文件:

$ git archive --format zip --output /path/to/destination/file.zip master

当然,为了使其工作,您首先需要在本地克隆它,这方面没有简单的方法。


@AdrianGunawan 你无法直接从GitHub导出它,你需要先在本地克隆它。在你克隆它之后,master指的是分支名称。 - Marvin Pinto
3
因为忽略了问题的核心,与标题陈述不符,所以被踩了。 - danorton

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