我有一个公司GitHub帐户,我想备份其中的所有存储库,以考虑可能出于自动化目的而创建的所有新内容。我希望是这样的:
git clone git@github.com:company/*.git
或类似的方法可行,但似乎不喜欢通配符。
Git中是否有一种方法可以进行克隆,然后假定拥有适当的权限就提取所有内容?
我有一个公司GitHub帐户,我想备份其中的所有存储库,以考虑可能出于自动化目的而创建的所有新内容。我希望是这样的:
git clone git@github.com:company/*.git
或类似的方法可行,但似乎不喜欢通配符。
Git中是否有一种方法可以进行克隆,然后假定拥有适当的权限就提取所有内容?
Answers:
我认为不可能那样做。最好的选择是使用API查找并遍历组织的存储库列表。
试试这个:
http://${GITHUB_BASE_URL}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN}
ssh_url
物业。git clone
每个ssh_url
。这需要一些额外的工作,但是GitHub必须具有正确的身份验证。
curl -i https://github.com/api/v3/orgs/company/repos?access_token=<token>
https://github.com/api/v3/
,请尝试https://api.github.com/
。
/users/${COMPANY}/repos
路径而不是/orgs/${COMPANY}/repos
。
access_token
query参数。如果您无法控制此应用正在使用此令牌,请注意,由于此弃用该令牌可能会停止工作。
在Windows和所有UNIX / LINUX系统上,使用Git Bash或任何其他Terminal,用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
CNTX=users
和NAME=yourusername
,以下载所有存储库。CNTX=orgs
和NAME=yourorgname
,以下载组织的所有存储库。最大页面大小为100,因此您必须使用正确的页面编号多次调用此页面,以获取所有存储库(设置PAGE
为要下载的所需页面编号)。
这是执行上述操作的Shell脚本:https : //gist.github.com/erdincay/4f1d2e092c50e78ae1ffa39d13fa404e
要从您的组织克隆所有回购协议,请尝试使用以下shell一线式:
GHORG=company; curl "https://api.github.com/orgs/$GHORG/repos?per_page=1000" | grep -o 'git@[^"]*' | xargs -L1 git clone
使用Git存储库URL克隆所有内容:
GHUSER=CHANGEME; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -o 'git@[^"]*' | xargs -L1 git clone
使用克隆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
这是有用的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
}
如果需要克隆私有存储库,则可以在标头中添加授权令牌,例如:
-H 'Authorization: token <token>'
或将其传递到参数(?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
笔记:
type=private
到您的查询字符串中。hub
在配置API密钥后使用。也可以看看:
提示:
-为了提高速度,请通过-P
为xargs
(-P4
= 4个进程)指定参数来设置并行进程数。
-如果您需要提高GitHub限制,请尝试通过指定API密钥进行身份验证。
-添加--recursive
以递归到已注册的子模块中,并更新其中的任何嵌套子模块。
该要点可以在命令行的一行中完成任务:
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"]} ]}'
替换[your_org]
为您的组织名称。并per_page
根据需要设置。
更新:
如ATutorMe所述,根据GitHub docs,最大页面大小为100 。
如果您有超过100个存储库,则必须page
在网址中添加一个参数,然后才能为每个页面运行该命令。
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"]} ]}'
注意:默认per_page
参数是30
。
转到帐户设置->应用程序并创建一个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"]} ]}'
将其保存在chmod u+x
文件中,然后运行它。
感谢Arnaud提供了红宝石代码。
因此,我也将添加我的答案。:)(我发现很简单)
获取列表(我使用过“ magento”公司):
curl -si https://api.github.com/users/magento/repos | grep ssh_url | cut -d '"' -f4
使用clone_url
而不是ssh_url
使用HTTP访问。
因此,让我们全部克隆它们!:)
curl -si https://api.github.com/users/magento/repos | \
grep ssh_url | cut -d '"' -f4 | xargs -i git clone {}
如果您要获取私有存储库-只需添加GET参数 ?access_token=YOURTOKEN
我发现提供的要点 @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"]} ]}'
将[[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
.../orgs/[[organization]]/repos...
为.../users/[[username]]/repos...
。现在,我可以将所有工作快速导入到不同的本地计算机。谢谢!
这个python一线客可满足您的需求。它:
对于每个,进行系统调用 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'))]"
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
?page=2
。
简单的解决方案:
NUM_REPOS=1000
DW_FOLDER="Github_${NUM_REPOS}_repos"
mkdir ${DW_FOLDER}
cd ${DW_FOLDER}
for REPO in $(curl https://api.github.com/users/${GITHUB_USER}/repos?per_page=${NUM_REPOS} | awk '/ssh_url/{print $2}' | sed 's/^"//g' | sed 's/",$//g') ; do git clone ${REPO} ; done
我尝试了上面的一些命令和工具,但认为它们太麻烦了,因此我编写了另一个命令行工具来执行此操作,称为
github-dl
。
要使用它(假设您已经安装了nodejs)
npx github-dl -d /tmp/test wires
这将使用您在CLI上提供的授权详细信息(用户/密码)从中获取所有存储库的列表wires
并将信息写入test
目录。
详细来说
它实际上并没有克隆存储库,而是编写了一个.txt
您可以传递xargs
来进行克隆的文件,例如:
cd /tmp/test
cat wires-repo-urls.txt | xargs -n2 git clone
# or to pull
cat /tmp/test/wires-repo-urls.txt | xargs -n2 git pull
也许这对您有用;只是几行JS,所以应该很容易适应您的需求
还有一个非常有用的npm模块可以执行此操作。它不仅可以克隆,还可以拉(以更新您已经拥有的数据)。
您只需像这样创建配置:
[{
"username": "BoyCook",
"dir": "/Users/boycook/code/boycook",
"protocol": "ssh"
}]
并gitall clone
例如。要么gitall pull
如果有人在寻找Windows解决方案,则可以使用PowerShell中的一个小功能来解决问题(如果不是事实,我需要它可以与代理一起使用,也可以与代理一起使用,可以是oneliner / alias)。
function Unj-GitCloneAllBy($User, $Proxy = $null) {
(curl -Proxy $Proxy "https://api.github.com/users/$User/repos?page=1&per_page=100").Content
| ConvertFrom-Json
| %{ $_.clone_url }
# workaround git printing to stderr by @wekempf aka William Kempf
# https://github.com/dahlbyk/posh-git/issues/109#issuecomment-21638678
| %{ & git clone $_ 2>&1 }
| % { $_.ToString() }
}
另一个带有注释的shell脚本,可从用户克隆所有存储库(公共和私有):
#!/bin/bash
USERNAME=INSERT_USERNAME_HERE
PASSWORD=INSERT_PASSWORD_HERE
# Generate auth header
AUTH=$(echo -n $USERNAME:$PASSWORD | base64)
# Get repository URLs
curl -iH "Authorization: Basic "$AUTH https://api.github.com/user/repos | grep -w clone_url > repos.txt
# Clean URLs (remove " and ,) and print only the second column
cat repos.txt | tr -d \"\, | awk '{print $2}' > repos_clean.txt
# Insert username:password after protocol:// to generate clone URLs
cat repos_clean.txt | sed "s/:\/\/git/:\/\/$USERNAME\:$PASSWORD\@git/g" > repos_clone.txt
while read FILE; do
git clone $FILE
done <repos_clone.txt
rm repos.txt & rm repos_clone.txt
~/.bashrc file
我通过在我的别名中创建别名/ bash函数来为团队解决了这个问题 ~/.bashrc file
打开终端或linux shell并打开您的~/.bashrc file
:
sudo nano ~/.bashrc
添加此功能:
CloneAll() {
# Make the url to the input github organization's repository page.
ORG_URL="https://api.github.com/orgs/${1}/repos?per_page=200";
# List of all repositories of that organization (seperated by newline-eol).
ALL_REPOS=$(curl -s ${ORG_URL} | grep html_url | awk 'NR%2 == 0' \
| cut -d ':' -f 2-3 | tr -d '",');
# Clone all the repositories.
for ORG_REPO in ${ALL_REPOS}; do
git clone ${ORG_REPO}.git;
done
}
保存并关闭〜/ .bashrc文件,然后关闭终端-您需要执行此操作,否则新的func将不会初始化:
打开新的终端并尝试一下:
CloneAll <your_github_org_name>
例:如果您的个人github回购URL被称为https://github.com/awesome-async,则命令为
CloneAll awesome-async
的 per_page=200
在第一变量的末尾ORG_URL
设置将克隆回购的数量,所以要特别注意那些:
ORG_URL="https://api.github.com/orgs/${1}/repos?per_page=200"; <---- make sure this is what you want
希望这可以帮助!:)
...repos?page=${2}&per_page=100";
您可以使用来获取存储库列表,curl
然后使用bash循环遍历该列表:
GIT_REPOS=`curl -s curl https://${GITHUB_BASE_URL}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN} | grep ssh_url | awk -F': ' '{print $2}' | sed -e 's/",//g' | sed -e 's/"//g'`
for REPO in $GIT_REPOS; do
git clone $REPO
done
您可以使用开源工具克隆一堆github仓库:https : //github.com/artiomn/git_cloner
例:
git_cloner --type github --owner octocat --login user --password user https://my_bitbucket
使用中的JSON API api.github.com
。您可以在github文档中查看代码示例:https :
//developer.github.com/v3/
或那里:
https://github.com/artiomn/git_cloner/blob/master/src/git_cloner/github.py
要仅克隆私有存储库,给定访问密钥,给定python 3和请求模块,请执行以下操作:
ORG=company; ACCESS_KEY=0000000000000000000000000000000000000000; for i in $(python -c "import requests; print(' '.join([x['ssh_url'] for x in list(filter(lambda x: x['private'] ,requests.get('https://api.github.com/orgs/$ORG/repos?per_page=1000&access_token=$ACCESS_KEY').json()))]))"); do git clone $i; done;
一个Python3解决方案,其中包括通过Link
Header进行详尽的分页。
先决条件:
import json
import requests
from requests.auth import HTTPBasicAuth
import links_from_header
respget = lambda url: requests.get(url, auth=HTTPBasicAuth('githubusername', 'githubtoken'))
myorgname = 'abc'
nexturl = f"https://api.github.com/orgs/{myorgname}/repos?per_page=100"
while nexturl:
print(nexturl)
resp = respget(nexturl)
linkheads = resp.headers.get('Link', None)
if linkheads:
linkheads_parsed = links_from_header.extract(linkheads)
nexturl = linkheads_parsed.get('next', None)
else:
nexturl = None
respcon = json.loads(resp.content)
with open('repolist', 'a') as fh:
fh.writelines([f'{respconi["full_name"]}\n' for respconi in respcon])
然后,您可以使用xargs
或并行和:cat repolist | parallel -I% hub clone %
如果您在这样的列表中有存储库列表,则此shell脚本有效:
user="https://github.com/user/"
declare -a arr=("repo1", "repo2")
for i in "${arr[@]}"
do
echo $user"$i"
git clone $user"$i"
done
我创建了一个示例批处理脚本。您可以从github.com下载所有私有/公共存储库。下载存储库后,它将自动转换为zip文件。
@echo off
setlocal EnableDelayedExpansion
SET "username=olyanren"
SET "password=G....."
set "mypath=%cd%\"
SET "url=https://%username%:%password%@github.com/%username%/"
FOR /F "tokens=* delims=" %%i in (files.txt) do (
SET repo=%%i
rmdir /s /q !repo!
git clone "!url!!repo!.git"
cd !repo!
echo !mypath!
git archive --format=zip -o "!mypath!!repo!.zip" HEAD
cd ..
)
注意:files.txt文件应仅包含存储库名称,例如:
repository1
repository2
尽管您可以在其中指定什么,但此处的主流答案并未考虑到Github API最多只会返回100个存储库。 per_page
。如果要克隆的Github组织包含超过100个存储库,则必须遵循API响应中的分页链接。
我写了一个CLI工具来做到这一点:
clone-github-org -o myorg
这会将myorg
组织中的所有存储库克隆到当前工作目录。
对于组织,您可以使用私有存储库访问:
curl -u <YOUR_GITHUB_USERNAME> -s https://api.github.com/orgs/<ORG_NAME>/repos?per_page=200 | ruby -rubygems -e ’require “json”; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo[“html_url”]} ]}'
它使用html_url
,因此您不需要access_token
在提示时输入github密码。
curl -u "username" https://api.github.com/user/repos\?page\=1\&per_page\=100 |
jq -r 'map(select(.fork == false)) | .[] | .ssh_url' |
xargs -L1 git clone
curl https://api.github.com/users/username/gists\?page\=1\&per_page\=100 |
jq -r ".[] | .git_pull_url +\" '\" + (.files|keys|join(\"__\") + \"'\")" |
xargs -L1 git clone
该jq
命令很复杂,因为要点的存储库名称是散列,因此该命令将所有文件名连接为存储库名称
jq
安装: sudo apt-get install jq
在上面的示例中,我使用以下方法滤除了分叉:curl ... | jq -r 'map(select(.fork == false))' ...
- 对于不克隆发出临时请求请求的存储库很有用
jq支持一些非常高级的功能。man jq
是你的朋友
curl -u "username" ...
访问私有存储库https://api.github.com/user/repos\?page\=1\&per_page\=100
https://api.github.com/users/other_username/repos\?page\=1\&per_page\=100
https://api.github.com/orgs/orgname/repos\?page\=1\&per_page\=100
"""
Clone all public Github Repos
https://developer.github.com/v3/repos/#list-repositories-for-a-user
"""
import urllib.request, base64
import json
import os
def get_urls(username):
url = f"https://api.github.com/users/{username}/repos?per_page=200"
request = urllib.request.Request(url)
result = urllib.request.urlopen(request)
return json.load(result)
if __name__ == "__main__":
for r in get_urls("MartinThoma"):
if not os.path.isdir(r["name"]):
print(f"Clone {r['name']}...")
os.system("git clone " + r["ssh_url"])
else:
print(f"SKIP {r['name']}...")
要克隆所有自己的私有和公共存储库,只需生成一个具有存储库访问权限的新访问令牌,并使用此令牌:
(替换为您自己的访问令牌和用户名)
for line in $(curl https://api.github.com/user/repos?access_token=ACCESS_TOKEN_HERE | grep -o "git@github.com:YOUR_USER_NAME/[^ ,\"]\+");do git clone $line;done
这将克隆当前文件夹中的所有存储库
这是一个小小的bash程序,您可以将其粘贴到终端中,然后按Enter