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

时间:2013-10-24 21:12:29

标签: git github git-clone

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

git clone git@github.com:company/*.git 

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

Git中是否有一种方法可以克隆,然后在假设有一个具有适当权限的情况下拉出所有内容?

35 个答案:

答案 0 :(得分:89)

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

git describe

设置YOURUSERNAMECNTX={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 = orgs和NAME = yourorgname,以下载组织的所有存储库。

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

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

答案 1 :(得分:36)

我认为不可能这样做。您最好的办法是使用API​​查找并循环浏览组织的存储库列表。

试试这个:

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

这是一项额外的工作,但GitHub需要进行适当的身份验证。

答案 2 :(得分:25)

组织存储库

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

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

使用克隆网址克隆所有内容:

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

另一种方法是在配置API密钥后使用hub

点击此处查看另一个示例:

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

答案 3 :(得分:19)

This gist在命令行的一行中完成任务:

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所提到的,最大页面大小为100,according to the GitHub docs

如果您有超过100个repos,则必须在网址中添加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

答案 4 :(得分:5)

转到帐户设置 - &gt;应用并创建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获取ruby代码。

答案 5 :(得分:4)

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

获取列表(我已使用&#34; magento&#34;公司):

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

答案 6 :(得分:3)

我在the gist @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"]} ]}'

将您的github用户名和[[ORGANIZATION]]替换为[[USERNAME]]与您的Github组织。输出(JSON repo元数据)将传递给一个简单的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

答案 7 :(得分:2)

我用Python3和Github APIv3制作了一个脚本

https://github.com/muhasturk/gitim

跑步

./gitim

答案 8 :(得分:1)

因此,在实践中,如果您要克隆与FOO匹配的组织BAR的所有回购,您可以使用下面的单行,这需要jq和常见的cli应用

curl 'https://api.github.com/orgs/FOO/repos?access_token=SECRET' |
  jq '.[] |
  .ssh_url' |
  awk '/BAR/ {print "git clone " $0 " & "}' |
  sh

答案 9 :(得分:1)

这是一种获取用户所有要点的方法,该方法考虑了 github 的新 api 和分页规则...

用法:

python3 gist.py bgoonz

此外……每个克隆都将成为它自己的存储库,这可能会占用您驱动器上的大量内存……您可以使用以下方法递归删除 git 存储库:


find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} +

如果您想将它们全部克隆到您现有的存储库中...请确保在运行此命令时您不在存储库的最外层文件夹中,否则它会像删除一样不加选择地删除您的 .git 文件夹将删除属于要点的那些。

语言:Python

#!/usr/bin/env python3

import os
import sys
import json
import hashlib
import requests

from subprocess import call
from concurrent.futures import ThreadPoolExecutor as PoolExecutor

def download_all_from_user(user: str):
    
    next_page = True
    page = 1
    
    while next_page:
        
        url = f"https://api.github.com/users/{user}/gists?page={page}"
        
        response = requests.get(url)

        if not len(response.json()):
            next_page = False
        else:
            page += 1

        download_all(response.json())

def download_all(gists: list):
    with PoolExecutor(max_workers=10) as executor:
        for _ in executor.map(download, gists):
            pass

def download(gist):
    
    target = gist["id"] + hashlib.md5(gist["updated_at"].encode('utf-8')).hexdigest()
    
    call(["git", "clone", gist["git_pull_url"], target])

    description_file = os.path.join(target, "description.txt")
    
    with open(description_file, "w") as f:
        f.write(f"{gist['description']}\n")

# Run

user = sys.argv[1]

download_all_from_user(user)

答案 10 :(得分:1)

当我想快速克隆所有存储库时,我会这样做:

set

答案 11 :(得分:1)

这是使用 PowerShell 的 windows 版本

$name="facebook" #either username or org_name

$api_url="https://api.github.com/users/$($name)/repos?per_page=200"

$repos=Invoke-WebRequest -UseBasicParsing -Uri $api_url |ConvertFrom-Json

foreach ($repo in $repos)
{
  Write-Host  "Cloning via SSH URL  $($repo.ssh_url)"
  git clone $repo.ssh_url
}

答案 12 :(得分:1)

在您的~/.bashrc file中创建bash别名/功能

我为团队解决了这个问题,方法是在~/.bashrc file中创建别名/ bash函数。

步骤

打开终端或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

希望这会有所帮助! :)

答案 13 :(得分:1)

简单的解决方案:

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

答案 14 :(得分:1)

我已经创建了一个pip模块来执行此操作。适用于Windows,Linux和OSX。

https://github.com/zeusofjuice/starclone

可以使用以下方法克隆您的存储库:

starclone <user> 

可以从帮助文件或自述文件中指定一些标志。

答案 15 :(得分:1)

这个蟒蛇单行将满足您的需求。它:

  • 检查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'))]"
    

答案 16 :(得分:1)

执行此操作还有一个非常有用的npm module。它既可以克隆,也可以拉(也可以更新已有的数据)。

您只需创建如下配置:

[{
   "username": "BoyCook",
   "dir": "/Users/boycook/code/boycook",
   "protocol": "ssh"
}]

并以gitall clone为例。或gitall pull

答案 17 :(得分:1)

如果有人在寻找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() }
}

答案 18 :(得分:0)

对于组织机构,您可以使用私有存储库进行访问:

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密码即可。

答案 19 :(得分:0)

您可以使用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

答案 20 :(得分:0)

这是Python解决方案:

//get from file folder path
let _usersToBeCreated = GetUsers('./uploads/employees.xlsx');


//get file from above then loop through the file
function GetUsers(filename)
{
  let _users =[];
  const xlsxFile = require('read-excel-file/node');
  xlsxFile(filename).then((rows) => {
 
  rows.forEach(element => {
        let _user={
          username :element[0],
          lastName :element[1],
          firstName :element[2],
          email :element[3],
             }
            _users.push(_user);
          });
    })
  return _users;
}

//adding all users aafter loopin through excel file and creating the list one by one
usersToBeCreated.forEach((v)=>{
      CreateKCUser(v);
    })



//get file path from anugalr file browswer then read that excel file using nodejs method
let _usersToBeCreated = exports.findFilePath(filename);


exports.getfilename= (req, res) => {
  console.log(data)
  res.send(data);
  filename = data;


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

答案 21 :(得分:0)

您可以使用GitHub Archive之类的工具,使您可以通过一个简单的工具克隆/提取公共和私人个人仓库,组织仓库以及摘要。

关于自动化,您可以将GitHub Archive设置为每天或每周运行一次,例如,它将跳过克隆的副本,并自上次运行所有其他版本以来引入新更改。 / p>

来源:https://github.com/Justintime50/github-archive

答案 22 :(得分:0)

要克隆所有自己的私有和公共存储库,只需生成一个具有存储库访问权限的新访问令牌,并使用此令牌即可:

(用您自己的访问令牌和用户名替换)

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键即可。

答案 23 :(得分:0)

"""
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']}...")

答案 24 :(得分:0)

克隆所有非fork的存储库:

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

任意过滤JSON

安装:sudo apt-get install jq

在上面的示例中,我使用以下方法过滤了curl ... | jq -r 'map(select(.fork == false))' ...-对于不克隆您提出临时请求的存储库很有用 < / p>

jq 支持一些非常高级的功能。 man jq是你的朋友


您可以通过curl -u "username" ... 进行身份验证以访问私有存储库


Guthub的API网址

  • 您的存储库(需要身份验证): 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

Github API Docs for repos

答案 25 :(得分:0)

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

答案 26 :(得分:0)

另一个带有注释的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

答案 27 :(得分:0)

尽管您可以在12:00-24:00中指定,但这里流行的答案并未考虑到Github API仅最多返回100个存储库。如果要克隆的Github组织包含超过100个存储库,则必须遵循API响应中的页面链接。

我写了CLI tool to do just that

per_page

这会将clone-github-org -o myorg 组织中的所有存储库克隆到当前工作目录。

答案 28 :(得分:0)

  

我尝试了上面的一些命令和工具,但认为它们太麻烦了,所以我编写了另一个命令行工具github-dl

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

npx github-dl -d /tmp/test wires

这将使用您在CLI上提供的授权详细信息(用户/密码)从wires获取所有存储库的列表,并将信息写入test目录。

详细

  1. 请求身份验证(支持2FA)
  2. 通过Github API获取用户/组织的仓库清单
  3. 为此进行分页,因此支持超过100个回购

它实际上并没有克隆存储库,而是编写了一个.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,所以应该很容易适应您的需求

答案 29 :(得分:0)

自5月19日起更新

将此bash命令用于组织(包括私人回购)

curl -u "{username}" "https://api.github.com/orgs/{org}/repos?page=1&per_page=100" | grep -o 'git@[^"]*' | xargs -L1 git clone

答案 30 :(得分:0)

您可以使用开源工具来克隆一堆github存储库:https://github.com/artiomn/git_cloner

示例:

git_cloner --type github --owner octocat --login user --password user https://my_bitbucket

使用api.github.com中的JSON API。 您可以在github文档中看到代码示例: https://developer.github.com/v3/

或者那里:

https://github.com/artiomn/git_cloner/blob/master/src/git_cloner/github.py

答案 31 :(得分:0)

我创建了一个示例批处理脚本。您可以从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

答案 32 :(得分:0)

要仅使用访问密钥克隆私有存储库,并且已安装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;

答案 33 :(得分:0)

如果您在这样的列表中有存储库列表,则此shell脚本有效:

user="https://github.com/user/"

declare -a arr=("repo1", "repo2")

for i in "${arr[@]}"

do

   echo $user"$i"

   git clone $user"$i"

done 

答案 34 :(得分:0)

一个Python3解决方案,包括通过Link标题进行详尽的分页。

先决条件:

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])

然后,您可以使用xargsparallel和:cat repolist | parallel -I% hub clone %