Как клонировать все репо сразу из GitHub?

У меня есть учетная запись GitHub компании, и я хочу создать резервные копии всех репозиториев внутри, учитывая все новое, что может быть создано в целях автоматизации. Я надеялся что-то вроде этого:

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

или подобное сработало бы, но там, похоже, не понравился шаблон.

Есть ли способ в Git клонировать, а затем извлечь все, если у вас есть соответствующие разрешения?

49 ответов

Решение

Я не думаю, что это возможно сделать так. Лучше всего найти и просмотреть список репозиториев Организации с помощью API.

Попробуй это:

  • Создайте токен API, перейдя в Настройки аккаунта -> Приложения
  • Сделайте звонок: http://${GITHUB_BASE_URL}/api/v3/orgs/${ORG_NAME}/repos?access_token=${ACCESS_TOKEN}
  • Ответом будет массив объектов JSON. Каждый объект будет содержать информацию об одном из хранилищ в рамках этой Организации. Я думаю, что в вашем случае вы будете искать специально для ssh_url имущество.
  • затем git clone каждый из тех ssh_urls.

Это немного дополнительная работа, но для GitHub необходимо иметь правильную аутентификацию.

Вот простое решение с использованием официального инструмента GitHub CLI, gh:

      # 1. Login with gh for private repos, and follow prompts
gh auth login

# 2.  Replace myorgname with your org name
# Clone up to 1000 repos under `./myorgname` folder
gh repo list myorgname --limit 1000 | while read -r repo _; do
  gh repo clone "$repo" "$repo"
done

Чтобы получить инструмент GitHub CLI :

  • Mac - brew install gh
  • Linux / Windows - см. Руководство по установке выше, они также хорошо поддерживаются.

Инструмент GitHub CLI будет поддерживаться в течение длительного времени по мере изменения GitHub API.

Задний план:

В 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

Установите CNTX=users и NAME=yourusername, чтобы загрузить все ваши репозитории. Установите CNTX=orgs и NAME=yourorgname, чтобы загрузить все репозитории вашей организации.

Максимальный размер страницы составляет 100, поэтому вам нужно несколько раз позвонить по этому номеру, чтобы получить все ваши репозитории (установлено PAGE на нужный номер страницы, которую вы хотите скачать).

Вот Shell-скрипт для shell-скрипта, который выполняет вышеуказанное: https://gist.github.com/erdincay/4f1d2e092c50e78ae1ffa39d13fa404e

Организация хранилищ

Чтобы клонировать все репозитории из вашей организации, попробуйте следующую однострочную оболочку:

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

Репозитории пользователей

Клонирование всех с использованием URL репозитория Git:

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

Клонирование всех с использованием 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

Вот полезная функция оболочки, которую можно добавить в файлы запуска пользователя (используя 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

Другой способ заключается в использовании 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, максимальный размер страницы составляет 100, в соответствии с документацией GitHub.

Если у вас более 100 репо, вам нужно будет добавить 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"]} ]}'

Примечание: по умолчанию per_page параметр 30 ,

Для тех, кто приедет сюда в 2022 году:

Сначала установите это

      gh extension install matt-bartel/gh-clone-org

Тогда вот довольно простая команда для достижения этого

      gh clone-org my_org_name

теперь имеет расширение ЗДЕСЬ. Первая команда взята отсюда.

Это расширение помогает клонировать и обновлять существующие репозитории по имени организации.

Предлагается изGithub CLIсписок вопросов ЗДЕСЬ

если вы используете Github CLI https://cli.github.com, вы можете использовать следующий скрипт:

gh repo list {ORG_NAME} | awk '{print $1; }' | xargs -L1 gh repo clone

Итак, я тоже добавлю свой ответ.:) (я нашел это просто)

Список выборок (я использовал компанию "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

Зайдите в Настройки аккаунта -> Приложение и создайте ключ API
Затем вставьте ключ API, URL-адрес экземпляра github и название организации в приведенный ниже скрипт

#!/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 файл, затем запустите его.

Спасибо Арно за код рубина.

Я нашел, что комментарий в гисте @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, а [[ОРГАНИЗАЦИЯ]] - на свою организацию в 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

Вот решение 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"])'

Замените org_name названием организации или пользователя, репозитории которых вы хотите загрузить. В Windows вы можете запустить это в Git Bash. В случае, если он не может найти python (не в вашем PATH и т. Д.), Самым простым решением, которое я нашел, является замена python на путь к фактическому исполняемому файлу Python, например: /c/ProgramData/Anaconda3/python для установки Anaconda в Windows 10.

Этот 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'))]"
    

Я сделал скрипт с Python3 и Github APIv3

https://github.com/muhasturk/gitim

Просто беги

./gitim
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

Я попробовал некоторые из приведенных выше команд и инструментов, но решил, что они слишком хлопотны, поэтому я написал для этого еще один инструмент командной строки под названием github-dl,

Чтобы использовать его (при условии, что у вас установлен nodejs)

npx github-dl -d /tmp/test wires

Это получит список всех репо от wires и запишите информацию в test каталог, используя данные авторизации (user/pass), которые вы предоставляете в CLI.

Подробно это

  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, поэтому должно быть легко приспособиться к вашим потребностям

Клонируйте все ваши репозитории, не являющиеся форками:

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 команда сложна, потому что имя репозитория gists - это хэши, поэтому эта команда объединяет все имена файлов в имя репо


Вы можете произвольно фильтровать JSON, используя jq

установить: sudo apt-get install jq

В приведенном выше примере я отфильтровал вилки, используя это:curl ... | jq -r 'map(select(.fork == false))' ...- полезно для того, чтобы не клонировать репозитории, в которых вы делали случайные запросы на вытягивание

jq поддерживает некоторые очень продвинутые функции.man jq твой друг


Вы можете пройти аутентификацию с помощью curl -u "username" ... для доступа к частным репозиториям


URL-адреса API Guthub

  • Ваши репозитории (требуется аутентификация): 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 для репозиториев

Таким образом, на практике, если вы хотите клонировать все репо из организации 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

Простое решение:

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

Более простой способ — использовать github cli для получения URL-адреса ssh и клонирования с помощью команды git.

      gh repo list --json sshUrl --jq '.[].sshUrl' | xargs -n1 git clone

Для этого также есть очень полезный модуль npm. Он может не только клонировать, но и извлекать (для обновления данных, которые у вас уже есть).

Вы просто создаете конфигурацию так:

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

и делать gitall clone например. Или же gitall pull

Теперь мы можем использовать gh, и он параллельно клонирует 5 репозиториев.

      export org=<org|gh-handle>
gh repo list $org | cut -f1 | xargs -n 1 -P 5 gh repo clone

Для более параллельной задачи мы можем увеличить -P 5 до любого желаемого числа.

В случае, если кто-то ищет решение для 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() }
}

Другой сценарий оболочки с комментариями, который клонирует все репозитории (публичные и частные) от пользователя:

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

Создайте псевдоним / func для bash в своем ~/.bashrc file

Я решил это для своей команды, создав псевдоним / bash func в моем ~/.bashrc file

шаги

откройте терминал или оболочку Linux и откройте свой ~/.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, а затем закройте терминал - вам нужно сделать это, иначе новая функция не будет инициализирована:

откройте новый терминал и попробуйте:

CloneAll <your_github_org_name>

пример: если ваш личный URL-адрес репозитория github называется 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

Надеюсь это поможет!:)

Чтобы клонировать все ваши собственные частные и общедоступные репозитории, просто создайте новый токен доступа с доступом к репозиториям и используйте его:

(замените свой токен доступа и имя пользователя)

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.

Вы можете получить список репозиториев, используя 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

Обновление от 2023 года:

если вы хотите упростить и использовать http_url, а не ssh_url или без каких-либо накладных сложных решений, используйте это простое: замените USERNAME на имя, которое вы хотели бы:

      curl -s https://api.github.com/users/{USERNAME}/repos?per_page=100 | jq -r ".[].clone_url" | xargs -L1 git clone

максимальное значение per_page равно 100, как в документе Github. если вы хотите больше, подумайте о создании цикла итераций.

Я хотел предложить еще один вариант, который может быть проще некоторых скриптов, размещенных здесь. — это инструмент командной строки, который можно использовать для клонирования всех репозиториев организации из GitHub, как описано на этой странице .

      mergestat "SELECT clone('https://github.com/mergestat/'|| name) AS path FROM github_org_repos('mergestat')" -v --clone-dir my-dir

Это не основная цель инструмента, а полезный побочный эффект того, что он делает (это способ запрашивать репозитории git с помощью SQL). Полное раскрытие, я являюсь сопровождающим / создателем, но хотел поделиться здесь, поскольку это довольно частый вариант использования / вопрос, который мы получаем от пользователей, и я надеюсь mergestatможет предложить простое решение.

Если у вас есть список репозиториев в этом списке, то этот сценарий оболочки работает:

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

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

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

do

   echo $user"$i"

   git clone $user"$i"

done 

Вы можете использовать такой инструмент, как GitHub Archive, который позволяет вам клонировать / извлекать публичные и частные личные репозитории, репозитории организаций и объекты с помощью одного простого инструмента.

Что касается автоматизации, вы можете настроить GitHub Archive для запуска, например, один раз в день или раз в неделю, и он будет пропускать те, которые клонированы, и вводить новые изменения с момента последнего запуска для всех остальных.

Источник: https://github.com/Justintime50/github-archive

Другие вопросы по тегам