web-dev-qa-db-fra.com

Comment cloner tous les repos à la fois depuis GitHub?

J'ai un compte d'entreprise GitHub et je souhaite sauvegarder tous les référentiels qu'il contient, en tenant compte de tout élément nouveau susceptible d'être créé à des fins d'automatisation. J'espérais quelque chose comme ça:

git clone [email protected]:company/*.git 

ou similaire pourrait fonctionner, mais il ne semble pas aimer le joker ici. 

Existe-t-il un moyen dans Git de cloner puis de tout extraire en supposant que l’on dispose des autorisations appropriées?

61
numb3rs1x

Je ne pense pas qu'il soit possible de le faire de cette façon. Votre meilleur choix est de rechercher et de parcourir la liste des référentiels d'une organisation à l'aide de l'API.

Essaye ça:

  • Créez un jeton d'API en allant dans Paramètres du compte -> Applications
  • Appeler à: http://${GITHUB_BASE_URL}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN}
  • La réponse sera un tableau d'objets JSON. Chaque objet comprendra des informations sur l'un des référentiels de cette organisation. Je pense que dans votre cas, vous chercherez spécifiquement la propriété ssh_url.
  • Puis git clone chacun de ces ssh_urls.

C'est un peu de travail supplémentaire, mais il est nécessaire que GitHub dispose d'une authentification appropriée.

34
Thomas Kelley

Sur Windows et tous les systèmes UNIX/LINUX, en utilisant Git Bash ou tout autre terminal, remplacez YOURUSERNAME par votre nom d'utilisateur et utilisez:

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

Définissez CNTX=users et NAME=yourusername pour télécharger tous vos référentiels. Définissez CNTX = orgs et NAME = votrenom pour télécharger tous les référentiels de votre organisation.

La taille maximale de la page est de 100; vous devez donc appeler plusieurs fois avec le bon numéro de page pour obtenir tous vos référentiels (définissez PAGE sur le numéro de page que vous souhaitez télécharger).

Voici un script Shell qui effectue ce qui précède: https://Gist.github.com/erdincay/4f1d2e092c50e78ae1ffa39d13fa404e

78
Erdinc Ay

Référentiels d'organisation

Pour cloner tous les repos de votre organisation, essayez l'un des doublons Shell suivants:

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

Référentiels utilisateurs

Cloner tout en utilisant les URL du référentiel Git:

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

Tout cloner en utilisant l'URL de clonage:

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

Voici la fonction Shell utile qui peut être ajoutée aux fichiers de démarrage de l'utilisateur (à l'aide de 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
}

Dépôts privés

Si vous devez cloner le dépôt privé, vous pouvez ajouter jeton d'autorisation dans votre en-tête, comme suit:

-H 'Authorization: token <token>'

ou le passer dans le param (?access_token=TOKEN), par exemple:

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

Une autre méthode consiste à utiliser hub après avoir configuré votre clé API.

Vérifiez un autre exemple ici:


Astuces:
- Pour augmenter la vitesse, définissez le nombre de processus parallèles en spécifiant le paramètre -P pour xargs (-P4 = 4 processus).
- Si vous devez augmenter les limites de GitHub, essayez de vous authentifier en spécifiant votre clé API.
- Ajoutez --recursive pour recurse dans les sous-modules enregistrés et mettez à jour tous les sous-modules imbriqués.

23
kenorb

This Gist accomplit la tâche en une ligne sur la ligne de commande:

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

Remplacez [your_org] par le nom de votre organisation. Et définissez votre per_page si nécessaire.

METTRE À JOUR:

Comme ATutorMe l'a mentionné, la taille maximale de la page est de 100, selon les documents GitHub .

Si vous avez plus de 100 repos, vous devrez ajouter un paramètre page à votre URL et vous pourrez exécuter la commande pour chaque 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"]} ]}'

Remarque: le paramètre par défaut per_page est 30.

19
seancdavis

Allez dans Paramètres du compte -> Application et créez une clé API
Ensuite, insérez la clé d'API, l'URL de l'instance github et le nom de l'organisation dans le script ci-dessous

#!/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"]} ]}'

Enregistrez cela dans un fichier, chmod u+x le fichier, puis exécutez-le.

Merci à Arnaud pour le code Ruby.

5
Cory Klein

J’ai trouvé un commentaire dans the Gist @seancdavis très utile, en particulier parce que, comme pour l’affiche originale, je voulais synchroniser tous les dépôts pour un accès rapide, même si la grande majorité était privée.

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

Remplacez [[USERNAME]] par votre nom d'utilisateur github et par [[ORGANIZATION]] par votre organisation Github. La sortie (métadonnées de rapport JSON) sera transmise à un simple script 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
3
Garren S

J'ai fait un script avec Python3 et Github APIv3

https://github.com/muhasturk/gitim

Juste courir

./gitim
2
muhasturk

J'ai essayé quelques-unes des commandes et des outils ci-dessus, mais j'ai décidé qu'ils étaient trop compliqués. J'ai donc écrit un autre outil en ligne de commande appelé github-dl .

Pour l'utiliser (en supposant que vous avez installé nodejs)

_npx github-dl -d /tmp/test wires
_

Cela obtiendrait une liste de tous les dépôts de wires et écrirait des informations dans le répertoire test, en utilisant les détails de l'autorisation (utilisateur/passe) que vous avez fournis sur la CLI.

En détail, ça

  1. Demande d'authentification (prend en charge 2FA)
  2. Obtient la liste des dépôts pour l'utilisateur/org via l'API Github
  3. Est-ce que la pagination pour cela, donc plus de 100 pensions prises en charge

En fait, il ne clone pas le dépôt, mais écrit plutôt un fichier _.txt_ que vous pouvez passer dans xargs pour effectuer le clonage, par exemple:

_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
_

Peut-être que cela vous est utile. il ne s'agit que de quelques lignes de JS, il devrait donc être facile de s'adapter à vos besoins

2
wires

Donc, je vais aussi ajouter ma réponse. :) (j'ai trouvé c'est simple)

Aller chercher la liste (j'ai utilisé la compagnie "magento"):

curl -si https://api.github.com/users/magento/repos | grep ssh_url | cut -d '"' -f4

Utilisez clone_url à la place de ssh_url pour utiliser l'accès HTTP.

Alors, clonons-les tous! :)

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

Si vous voulez récupérer un dépôt privé, ajoutez simplement le paramètre GET ?access_token=YOURTOKEN

2
Kirby

Ce one-liner en python fera ce dont vous avez besoin. Il:

  • vérifie github pour votre repos disponible
  • pour chacun, fait un appel système à 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'))]"
    
1
Evren Ozkan

J'ai créé un module pip pour le faire. Fonctionne sous Windows, Linux et OSX. 

https://github.com/zeusofjuice/starclone

Peut cloner votre repo en utilisant:

starclone <user> 

Vous pouvez spécifier quelques indicateurs à partir du fichier d’aide ou du fichier README. 

1
samdixon

Si vous recherchez une solution Windows, voici une petite fonction de PowerShell qui vous permettra de résoudre le problème (pourrait être un onglet ou un alias si ce n’est le fait que j’ai besoin de travailler avec et sans proxy).

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() }
}
1

Ainsi, en pratique, si vous souhaitez cloner toutes les mises en pension de l'organisation FOO qui correspondent à BAR, vous pouvez utiliser l'un des doublons ci-dessous, qui nécessite jq et des utilitaires cli communs.

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

Il existe également un module npm très utile pour le faire. Il peut non seulement cloner, mais aussi tirer (pour mettre à jour les données que vous avez déjà).

Vous venez de créer une configuration comme ceci:

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

et faire gitall clone par exemple. Ou gitall pull

1

Si vous avez une liste de référentiels dans une liste comme celle-ci, alors ce script Shell fonctionne:

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

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

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

do

   echo $user"$i"

   git clone $user"$i"

done 
0

Vous pouvez obtenir une liste des référentiels en utilisant curl, puis parcourir cette liste avec une boucle 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
0
Sriram Mageswaran

Solution simple:

NUM_REPOS=1000
DW_FOLDER="Github_${NUM_REPOS}_repos"
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
0
Antonio Feitosa

Pour cloner uniquement les pensions privées, à partir d'une clé d'accès, d'un module python 3 et de requêtes installé:

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;
0
ubugnu

Une solution Python3 incluant une pagination exhaustive via Link Header.

Conditions préalables:


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

Ensuite, vous pouvez utiliser xargs ou parallel and: cat repolist | parallel -I% hub clone %

0
Jose Alban

Les réponses actuelles ne tiennent pas compte du fait que l'API Github ne renverra qu'un maximum de 100 référentiels malgré ce que vous pouvez spécifier dans per_page. Si vous clonez une organisation Github avec plus de 100 référentiels, vous devrez suivre les liens de pagination dans la réponse de l'API.

J'ai écrit un outil CLI pour faire exactement cela :

clone-github-org -o myorg

Cela va cloner tous les référentiels de l'organisation myorg dans le répertoire de travail actuel.

0
Chad

J'ai créé un exemple de script de lot. Vous pouvez télécharger tous les référentiels privés/publics à partir de github.com. Une fois le référentiel téléchargé, il est automatiquement converti en fichier 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 ..
)

Remarque: Le fichierfiles.txtne doit contenir que des noms de référentiel tels que: 

repository1
repository2
0
olyanren

Mise à jour du 19 mai

utiliser cette commande bash pour une organisation (repo privé inclus)

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

Un autre script Shell avec des commentaires qui clone tous les dépôts (publics et privés) d'un utilisateur:

#!/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
0
hlorand