如何从GitHub克隆所有转发(包括私人转发)



我正试图一次将我的所有转发克隆到我的计算机上,所有这些都是私有的。我已经尝试了无数的单行线和脚本(即这里和这里的),但都不起作用。

最初,我会收到JSON无法解析响应的错误,我最终意识到这是因为响应是空的,因为我没有公共repo。当我测试公共回购时,它会返回一个JSON对象,其中包含特定回购的信息,但没有私有回购的信息。据我所知,我需要将我的用户名和访问令牌都传递给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,它应该授予它对私人回购的控制权。

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

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帖子/Gist和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信息,没有列出任何作用域,但实际克隆repo的下一个命令将需要repo作用域

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

现在,要克隆所有的repo,请使用这一行命令。这里的要点有许多代码片段可以在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

关于以上的一些注意事项:

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

EDIT:我在自己使用Ruby版本的逻辑代码时想出了一些额外的东西,如果你(作为用户)是多个组织的一部分,不想从其中一些组织下载转发,你可以通过指定与组织名称匹配的字符串来创建黑名单。例如,我想对我可以访问的所有转发进行编码,但我不想在"谷歌"或"推特"中克隆转发:

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"}'

这几乎是通过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
    

    PowerShell

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

进一步阅读:如何从GitHub一次克隆所有转发?

试试这样的方法(它使用jq只获取ssh_url,这样你就可以克隆repo):

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

这将把wires中的所有repo克隆到test目录中。

详细来说,它是

  1. 请求身份验证(支持2FA)
  2. 通过Github API获取用户/组织的转发列表
  3. 为此进行分页,因此支持100多个回购

它实际上并没有克隆repo,而是编写一个.txt文件,您可以将该文件传递到xargs中进行克隆。

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

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

使用gh进行身份验证

gh auth login;

下载组织拥有的所有公共和私人回购

gh repo list ORGNAME -L 999 --json nameWithOwner --jq '.[].nameWithOwner'| xargs -L1 gh repo clone

最新更新