繁体   English   中英

如何从 GitHub 克隆所有存储库(包括私有存储库)?

[英]How to clone all repos (including private repos) from GitHub?

我正在尝试一次将我的所有存储库克隆到我的计算机上,所有这些都是私有的。 我尝试了无数的单行脚本和脚本(即,这里这里的),但它们都不起作用。

最初我会收到关于 JSON 无法解析响应的错误,我最终意识到这是因为响应是空的,因为我没有公共存储库。 当我创建一个测试公共 repo 时,它会返回一个 JSON 对象,其中包含该特定 repo 的信息,但没有私有 repo。 据我了解,我需要将我的用户名和访问令牌都传递给 GitHub,其中访问令牌是在Settings > Developer settings > Personal access tokens生成的。

我尝试了以下两种格式均无济于事:

curl -i -u [[USERNAME]]:[[TOKEN]] -s https://api.github.com/users/[[USERNAME]]/repos?per_page=100 [[...]]

curl -i -u [[USERNAME]] -s https://api.github.com/users/[[USERNAME]]/repos?per_page=100&access_token=[[TOKEN]] [[...]]

接下来的[[...]]部分是各种代码片段,如上面链接中的代码片段。 我相信这些部分很好,因为它们克隆公共存储库没有任何问题,而问题在于我无法看到我的私人存储库,尽管有访问令牌。 重要的是要注意,当您生成访问令牌时,您定义了它可以做什么的范围,并且我已经定义了对所有内容的完全访问权限,包括repo ,这应该授予它对私有 repos 的控制权。

此外,有时当我尝试上面的命令时,我会得到以下响应:

 HTTP/1.1 401 Unauthorized
Server: GitHub.com
Date: Fri, 13 Oct 2017 08:08:01 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 93
Status: 401 Unauthorized
X-GitHub-Media-Type: github.v3; format=json
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 41
X-RateLimit-Reset: 1507884238
Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none'
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block
X-Runtime-rack: 0.060685
X-GitHub-Request-Id: D038:4E67:1349CC:2CB494:59E07461

{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v3"
}

尽管知道我的凭据很好。

有谁知道我出了什么问题? 我已经绕着这个圈子跑了几个小时,结果空空如也。

好吧,经过几天的随机 SO 帖子/要点和 API 文档的拖钓,我想通了。 突破尤其来自这篇文章,因为问题在于我如何构建我的 GET 请求。 虽然它本身没有任何问题,但有两种方法可以解决,一种有效,一种无效,而且 GitHub 没有记录这一点,请看图¯\_(ツ)_/¯

这是一个格式正确的curl命令,用于获取用户的所有(公共和私有)存储库:

curl -iH "Authorization: token [[TOKEN]]" https://api.github.com/user/repos

[[TOKEN]] 部分应该是您的 OAuth 令牌。 要生成它,请阅读此处,或执行以下摘要:

  • 在 GitHub 上,转到Settings > Developer settings > Personal access tokens
  • 单击Generate new token
  • 给它一个描述并确保选中repo旁边的框(它会自动检查 repo 下的所有子类别,这很好)
  • 单击Save并复制下一页上的令牌字符串,这是您唯一一次看到它,应将其视为密码或私钥(如果丢失,您可以随时删除令牌并生成新令牌)

-i标志包括请求标头。 这里要寻找的两个重要的事情是:

  • 在您看到的标题中大约有 10 个项目X-OAuth-Scopes: repo 这告诉您传递的令牌具有哪些范围。 它可以不仅仅是repo ,但至少有repo
  • 标题中的下一个条目是X-Accepted-OAuth-Scopes: 这是您正在执行的操作所需的范围。 要查询 repo 信息,没有列出任何范围,但实际克隆 repos 的下一个命令将需要repo范围

后面的授权字符串需要-H标志

现在,要克隆所有存储库,请使用这个单行命令。 这里的这个要点有很多代码片段可以在 php、ruby、python 等中实现这一点,但我个人喜欢 bash 解决方案:

for i in `curl -H "Authorization: token [[TOKEN]]" https://api.github.com/user/repos?per_page=100 | grep ssh_url | cut -d ':' -f 2-3|tr -d '",'`; do git clone $i; done

关于上述内容的一些注意事项:

  • 默认情况下,它会要求您输入每个 repo 的密码。 这可能会很烦人,所以在运行命令之前(或者您可以使用Ctrl+C取消命令然后执行此操作),运行以下命令将您的 SSH 密钥添加到您的ssh-agenteval "$(ssh-agent -s)" ssh-add -t 1h ~/.ssh/path/to/ssh/key
  • 如果您尝试这样做,但对于组织而不是用户,请查看我在上面发布的 gist 链接以获取更多示例
  • 如果您尝试使用超过 100 个 repos 执行此操作,请使用page参数,如下所示: ?page=1&per_page=100 (请注意,API 最多支持 100,因此任何超过 100 的数字都是没有意义的,并且会静默失败)

编辑:我自己在使用逻辑代码的 Ruby 版本时想出了一些额外的东西,如果您(作为用户)是多个组织的一部分并且不想从其中一些组织下载存储库,您可以通过指定与组织名称匹配的字符串来创建黑名单。 例如,我想编写我有权访问的所有存储库,但我不想克隆“Google”或“Twitter”中的存​​储库:

curl -H "Authorization: token [[TOKEN]]" https://api.github.com/user/repos?per_page=100 | ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]}] unless repo["full_name"].include? "Google" or repo["full_name"].include? "Twitter"}'

尝试这样的事情(它使用jq仅获取 ssh_url 以便您可以克隆存储库):

GITHUB="https://api.github.com/user/repos?per_page=100&type=owner"
for repo in $(curl -s -u user:token ${GITHUB} | jq -r '.[] | .ssh_url')
do
   git clone --mirror ${repo}
done

使用 curl 时,您需要像传递密码一样传递令牌(基本身份验证)

curl -u user:token

检查 GitHub 页面上的“其他身份验证方法

我编写了一个命令行工具来执行此操作,称为github-dl

使用它(假设你已经安装了 nodejs)

npx github-dl -d test wires

这会将所有 repo 从wires克隆到test目录中。

详细地说,它

  1. 要求身份验证(支持 2FA)
  2. 通过 Github API 获取用户/组织的 repos 列表
  3. 是否为此进行分页,因此支持 100 多个 repo

它实际上并没有克隆存储库,而是编写一个.txt文件,您可以将其传递给xargs进行克隆。

几乎是原生支持 w/ Github CLI

  1. 下载Github CLI

  2. 登录

    gh auth login
  3. 列出 repos 并通过管道进入克隆命令

    重击

    gh repo list <userName> --limit 999 --json name --jq ".[]|.name" \ | xargs -L1 gh repo clone

    电源外壳

    gh repo list <userName> --limit 999 --json name --jq ".[]|.name" | ForEach-Object { gh repo clone $_ }

进一步阅读如何从 GitHub 一次克隆所有 repos?

如果您想从一个组织中克隆所有存储库,您可以使用以下代码。

gh repo list ORGNAME  --limit 999 --json name --jq ".[]|.name" | xargs printf -- 'ORGNAME/%s\n' | xargs -L1 gh repo clone

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM