如何从GitHub一次克隆所有回购?

num*_*s1x 82 git github git-clone

我有一个公司GitHub帐户,我想备份其中的所有存储库,计算可能为自动化目的创建的任何新内容.我希望这样的事情:

git clone git@github.com:company/*.git 
Run Code Online (Sandbox Code Playgroud)

或类似的工作,但它似乎不喜欢那里的通配符.

有没有办法在Git克隆然后拉出一切假设一个人有适当的权限?

Ric*_*Vel 250

使用 GitHub CLI 的简单脚本(无 API 密钥)

\n

这是使用官方 GitHub CLI 工具的简单解决方案gh- 不需要 API 密钥,并且可以处理多达 4,000 个私有存储库。

\n

仅限第一次:使用私人存储库登录gh,然后按照提示操作:

\n
gh auth login\n
Run Code Online (Sandbox Code Playgroud)\n

现在您可以在新文件夹下克隆任意数量的存储库./myorgname。替换myorgname为您的组织名称:

\n
gh repo list myorgname --limit 4000 | while read -r repo _; do\n  gh repo clone "$repo" "$repo"\ndone\n
Run Code Online (Sandbox Code Playgroud)\n

默认限制为 30。

\n

这应该适用于 Mac 或 Linux。

\n

对于 Windows:

\n\n

设置

\n

要获取GitHub CLI 工具

\n\n

面向未来:当 GitHub API 发生变化时,GitHub CLI 工具将得到长期支持。由于这个原因,这里的一些旧答案不再起作用。

\n

可选:更新现有结账

\n

要更新磁盘上已有的存储库文件夹以及克隆新的存储库,脚本需要检查 的故障gh repo clone,如下所示:

\n
gh repo list myorgname --limit 1000 | while read -r repo _; do\n  gh repo clone "$repo" "$repo" -- -q 2>/dev/null || (\n    cd "$repo"\n    # Handle case where local checkout is on a non-main/master branch\n    # - ignore checkout errors because some repos may have zero commits, \n    #\xc2\xa0so no main or master\n    git checkout -q main 2>/dev/null || true\n    git checkout -q master 2>/dev/null || true\n    git pull -q\n  )\ndone\n
Run Code Online (Sandbox Code Playgroud)\n

尖端

\n
    \n
  • 不想在./myorgname文件夹中创建存储库?删除第二个"$repo"参数以gh repo clone在当前目录中创建它们
  • \n
\n

过滤结果:

\n
    \n
  • --no-archived- 省略存档存储库
  • \n
  • --source- 仅显示非分叉
  • \n
\n

提示:处理数千个存储库

\n

该脚本可与多达约 4,000 个存储库配合使用 - 请参阅@Ryan Fisher下面的评论,并评论您的结果。

\n

gh repo list命令使用 GitHub Search API,在返回许多结果时会分页。可搜索的存储库数量限制为 4,000 个。

\n

要解决任何限制:

\n
    \n
  • 检查gh repo list命令是否返回您期望的结果
  • \n
  • 确保您省略了存档和分叉的存储库
  • \n
  • 请参阅gh repo list --help按语言、主题等进行过滤
  • \n
\n

或者,您可以使用不同的答案(基于 API 请求)来替换命令gh repo list或整个脚本。

\n

提示:更快地克隆许多存储库

\n

如果您要克隆大量存储库,则可以使用GNUparallel加速此脚本。

\n
gh repo list <ORG_NAME> --limit <LIMIT> --json nameWithOwner --jq \'.[].nameWithOwner\' | \\\n   parallel -j<JOBS> gh repo clone\n
Run Code Online (Sandbox Code Playgroud)\n

这使用gh\ 的内部jq库,而不是独立的jq.

\n

如果您使用上面的“更新现有结帐”选项,则需要将其合并到上面的脚本中 - 也许将循环内容放入bash -c "..."下的单独命令中parallel

\n

您还可以使用xargs -P并行克隆存储库 - 请参阅此答案

\n

背景

\n\n

  • IMO 是一个很好的解决方案。我花了早上的大部分时间来做这件事(使用“gh”编写解决方案),因为我没能转到答案的第二页。我希望这能得到投票,这样其他人就不会再犯同样的错误。 (12认同)
  • 到目前为止,最容易实施的解决方案。 (6认同)
  • 这个解决方案非常干净。我想知道是否也可以轻松地实现为每个存储库拉下所有远程分支。 (4认同)
  • @TaylorD.Edmiston 请参阅[此答案](/sf/ask/4738961/)了解克隆所有分支的方法,并使用`gitbranch-a ` 去见他们。普通的“git clone”确实包含远程跟踪分支。您可以在主脚本的 `gh repo clone` 之后添加命令,如下所示: `( cd "$repo" &amp;&amp; COMMANDS_HERE )` - 括号创建一个子 shell 来限制 `cd` 的范围。注意“git push” - 默认情况下它将推送所有分支:[comment](/sf/ask/4738961/#comment975098_72156) (2认同)
  • PowerShell 版本[此处](https://gist.github.com/KarsonAlford/f26f1bcca772d9ac6a76d8594155f923#file-clone-all-repos) (2认同)

Erd*_* Ay 101

Windows和所有UNIX/LINUX系统上,使用Git Bash任何其他终端,替换YOURUSERNAME为您的用户名并使用:

CNTX={users|orgs}; NAME={username|orgname}; PAGE=1
curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" |
  grep -e 'git_url*' |
  cut -d \" -f 4 |
  xargs -L1 git clone
Run Code Online (Sandbox Code Playgroud)

设置CNTX=usersNAME=yourusername下载所有存储库.设置CNTX = orgs和NAME = yourorgname,以下载组织的所有存储库.

最大页面大小为100,因此您必须使用正确的页码多次调用此页面以获取所有存储库(设置CNTX=orgs为您要下载的所需页码).

这是一个执行上述操作的shell脚本:https://gist.github.com/erdincay/4f1d2e092c50e78ae1ffa39d13fa404e

  • 纯粹的bash解决方案,最简单的.为了您的信息,这个bash代码几乎可以在任何*nix环境,Linux,Cygwin,Mingw中执行,当然Gitbash实际上是像其他人一样的终端仿真. (3认同)
  • 我从来不知道curl在windows上的git bash中工作过!让这更容易,谢谢. (3认同)
  • 请更新答案(2019 年 2 月):根据 GitHub API v3,您的 curl 应该转到 /orgs/ORGNAME/repos。也可能包含 API v3 的链接:https://developer.github.com/v3/ 另外对于私有存储库,您需要添加 curl -u "username",然后 curl 会询问您一次密码。否则工作得很好!:))) (3认同)
  • 这只会获取公共回购,而不是私人和内部回购。 (3认同)
  • 这不适用于组织,因此它不会直接回答问题。[这个答案](/sf/answers/2296211781/) 来自 Kenorb 确实可以处理组织,并且也适用于多达 1000 个存储库 - 对我来说效果更好。 (2认同)
  • 带认证: curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&amp;per_page=100&amp;access_token=$ACCESS_TOKEN" | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone (2认同)
  • 更新来自 dimitry hevkoplyas 评论 /sf/ask/1370371971/#comment96219716_32833411。developer.github.com/v3 在尝试 curl 时返回 301 状态。使用这个 bash 命令 curl -u "{username}" "https://api.github.com/orgs/{org}/repos?page=1&amp;per_page=100" | grep -o 'git@[^"]*' | xargs -L1 git clone 100% 有效 (2认同)
  • 这只下载公共存储库,还是也下载私人存储库? (2认同)

Tho*_*ley 41

我不认为这样做是可能的.您最好的办法是使用API​​查找并遍历组织的存储库列表.

试试这个:

  • 通过转到帐户设置 - >应用程序创建API令牌
  • 拨打电话: http://${GITHUB_BASE_URL}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN}
  • 响应将是JSON对象数组.每个对象都将包含有关该组织下的一个存储库的信息.我认为在您的情况下,您将专门寻找该ssh_url物业.
  • 然后git clone每个人ssh_url.

这是一些额外的工作,但GitHub必须有适当的身份验证.

  • 根据 GitHub:请改用授权 HTTP 标头,因为不推荐使用“access_token”查询参数。如果您无法控制的应用程序正在使用此令牌,请注意它可能会因此弃用而停止工作。 (3认同)
  • 啊,我误会你了。我以为是企业帐户。而不是`https://github.com/api/v3/`,试试`https://api.github.com/`。 (2认同)
  • 而且我不确定您的特定公司是如何设置的,但是如果它是“用户”而不是“组织”,那么您将需要使用 `/users/${COMPANY}/repos` 路径而不是`/orgs/${COMPANY}/repos`。 (2认同)
  • 如果您更喜欢使用 cli [ghorg](https://github.com/gabrie30/ghorg) 将为您完成此任务 (2认同)

ken*_*orb 29

组织存储库

要从组织中克隆所有回购,请尝试以下shell one-liner:

GHORG=company; curl "https://api.github.com/orgs/$GHORG/repos?per_page=1000" | grep -o 'git@[^"]*' | xargs -L1 git clone
Run Code Online (Sandbox Code Playgroud)

用户存储库

使用Git存储库URL克隆所有内容:

GHUSER=CHANGEME; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -o 'git@[^"]*' | xargs -L1 git clone
Run Code Online (Sandbox Code Playgroud)

克隆所有使用克隆URL:

GHUSER=CHANGEME; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -w clone_url | grep -o '[^"]\+://.\+.git' | xargs -L1 git clone
Run Code Online (Sandbox Code Playgroud)

这是一个有用的shell函数,可以添加到用户的启动文件中(使用curl+ jq):

# Usage: gh-clone-user (user)
gh-clone-user() {
  curl -sL "https://api.github.com/users/$1/repos?per_page=1000" | jq -r '.[]|.clone_url' | xargs -L1 git clone
}
Run Code Online (Sandbox Code Playgroud)

私人仓库

如果您需要克隆私人仓库,您可以在标头中添加授权令牌,如:

-H 'Authorization: token <token>'
Run Code Online (Sandbox Code Playgroud)

或者在param(?access_token=TOKEN)中传递它,例如:

curl -s "https://api.github.com/users/$GHUSER/repos?access_token=$GITHUB_API_TOKEN&per_page=1000" | grep -w clone_url | grep -o '[^"]\+://.\+.git' | xargs -L1 git clone
Run Code Online (Sandbox Code Playgroud)

另一种方法是type=private在配置API密钥后使用.

查看另一个示例:


提示:
- 要提高速度,请通过hub-P(xargs= 4个进程)指定参数来设置并行进程数.
- 如果您需要提高GitHub限制,请尝试通过指定API密钥进行身份验证.
- 添加-P4到递归到已注册的子模块,并更新其中的任何嵌套子模块.

  • per_page=1000 最大为 100 (5认同)

sea*_*vis 19

这个要点在命令行的一行中完成任务:

curl -s https://api.github.com/orgs/[your_org]/repos?per_page=200 | ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]} ]}'
Run Code Online (Sandbox Code Playgroud)

替换[your_org]为您组织的名称.并per_page在必要时设置您的.

更新:

正如ATutorMe所提到的,根据GitHub文档,最大页面大小为100 .

如果您有超过100个repos,则必须page在您的URL中添加一个参数,然后您可以为每个页面运行该命令.

curl -s "https://api.github.com/orgs/[your_org]/repos?page=2&per_page=100" | ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]} ]}'
Run Code Online (Sandbox Code Playgroud)

注意:默认per_page参数是30.


shu*_*vro 19

仍然是2024 年的最佳解决方案:

首先,安装这个。

gh extension install matt-bartel/gh-clone-org
Run Code Online (Sandbox Code Playgroud)

然后这是一个非常简单的命令来实现这一点

gh clone-org my_org_name
Run Code Online (Sandbox Code Playgroud)

Github CLI现在有一个扩展HERE。第一个命令取自此处。

此扩展有助于按组织名称克隆和更新现有存储库。

这是从Github CLI问题列表中建议的


Pur*_*lex 11

使用Github CLI和一些脚本来克隆命名空间下的所有(公共或私有)存储库

gh repo list OWNER --limit 1000 | awk '{print $1; }' | xargs -L1 gh repo clone
Run Code Online (Sandbox Code Playgroud)

其中OWNER可以是您的用户名或组织名称。

  • 这就是这里 - 迄今为止最简单和最新的方法 (2认同)

Kir*_*rby 8

所以,我也会添加我的答案。:)(我发现这很简单)

获取列表(我使用过“magento”公司):

curl -si https://api.github.com/users/magento/repos | grep ssh_url | cut -d '"' -f4
Run Code Online (Sandbox Code Playgroud)

使用clone_url而不是ssh_url使用HTTP访问。

所以,让我们克隆它们!:)

curl -si https://api.github.com/users/magento/repos | \
    grep ssh_url | cut -d '"' -f4 | xargs -i git clone {}
Run Code Online (Sandbox Code Playgroud)

如果您要获取私有仓库 - 只需添加 GET 参数 ?access_token=YOURTOKEN


Gar*_*n S 6

我发现@seancdavis 提供的要点中的评论非常有帮助,尤其是因为像原始海报一样,我想同步所有存储库以便快速访问,但其中绝大多数是私有的。

curl -u [[USERNAME]] -s https://api.github.com/orgs/[[ORGANIZATION]]/repos?per_page=200 |
  ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]} ]}'
Run Code Online (Sandbox Code Playgroud)

将 [[USERNAME]] 替换为您的 github 用户名,将 [[ORGANIZATION]] 替换为您的 Github 组织。输出(JSON 存储库元数据)将传递给一个简单的 ruby​​ 脚本:

# bring in the Ruby json library
require "json"

# read from STDIN, parse into ruby Hash and iterate over each repo
JSON.load(STDIN.read).each do |repo|
  # run a system command (re: "%x") of the style "git clone <ssh_url>"
  %x[git clone #{repo["ssh_url"]} ]
end
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案对我来说非常有效。实际上,我所需要的只是将我所有的个人帐户存储库克隆到我的新本地机器上。设置新工作站非常方便。注意:要做到这一点,我必须将 `.../orgs/[[organization]]/repos...` 更改为 `.../users/[[username]]/repos...`。现在我可以快速将我的所有工作导入到不同的本地机器上。**谢谢!** (2认同)

Fil*_*lip 6

这是一个Python解决方案:

curl -s https://api.github.com/users/org_name/repos?per_page=200 | python -c $'import json, sys, os\nfor repo in json.load(sys.stdin): os.system("git clone " + repo["clone_url"])'
Run Code Online (Sandbox Code Playgroud)

将 org_name 替换为您希望下载其存储库的组织或用户的名称。在 Windows 中,您可以在 Git Bash 中运行它。如果它找不到 python(不在你的 PATH 等中),我找到的最简单的解决方案是用实际 Python 可执行文件的路径替换 python,例如:/c/ProgramData/Anaconda3/python 用于 Anaconda 安装视窗 10。

  • 最好的选择!感谢你 (2认同)

Cor*_*ein 5

转到帐户设置 - >应用程序并创建API密钥
然后在下面的脚本中插入API密钥,github实例URL和组织名称

#!/bin/bash

# Substitute variables here
ORG_NAME="<ORG NAME>"
ACCESS_TOKEN="<API KEY>"
GITHUB_INSTANCE="<GITHUB INSTANCE>

URL="https://${GITHUB_INSTANCE}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN}"

curl ${URL} | ruby -rjson -e 'JSON.load(STDIN.read).each {|repo| %x[git clone #{repo["ssh_url"]} ]}'
Run Code Online (Sandbox Code Playgroud)

将其保存在chmod u+x文件中,然后运行它.

感谢Arnaud的红宝石代码.


小智 5

这个 python one-liner 将满足您的需求。它:

  • 检查 github 以获取您的可用存储库
  • 对于每个,进行系统调用 git clone

    python -c "import json, urllib, os; [os.system('git clone ' + r['ssh_url']) for r in json.load(urllib.urlopen('https://api.github.com/orgs/<<ORG_NAME>>/repos?per_page=200'))]"
    
    Run Code Online (Sandbox Code Playgroud)

  • 对于 python3 使用 -&gt; `python -c "import json, urllib.request, os; [os.system('git clone ' + r['clone_url']) for r in json.load(urllib.request.urlopen(' https://api.github.com/orgs/&lt;&lt;ORG_NAME&gt;&gt;/repos?per_page=200'))]"` (2认同)

muh*_*urk 5

我用 Python3 和 Github APIv3 做了一个脚本

https://github.com/muhasturk/gitim

赶紧跑

./gitim
Run Code Online (Sandbox Code Playgroud)


小智 5

curl -s https://api.github.com/orgs/[GITHUBORG_NAME]/repos | grep clone_url | awk -F '":' '{ print $2 }' | sed 's/\"//g' | sed 's/,//' | while read line; do git clone "$line"; done
Run Code Online (Sandbox Code Playgroud)

  • 请为您的解决方案添加解释。这样其他有类似问题的人将能够更容易地理解您的解决方案! (3认同)
  • 一个细节是需要传递页码,如`?page=2`。 (2认同)

归档时间:

查看次数:

63531 次

最近记录:

6 年 前