Как клонировать все репо сразу из 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_url
s.
Это немного дополнительная работа, но для 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.
Задний план:
- Документ для входа в интерфейс командной строки GitHub
- Сценарий выше был получен из этого комментария к проблеме
- Причудливый сценарий из другого комментария к выпуску: суть от davegallant
В 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'))]"
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.
Подробно это
- Запрашивает авторизацию (поддерживает 2FA)
- Получает список репозиториев для пользователя / организации через Github API
- Есть ли для этого нумерация страниц, поэтому поддерживается более 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
Таким образом, на практике, если вы хотите клонировать все репо из организации 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 для запуска, например, один раз в день или раз в неделю, и он будет пропускать те, которые клонированы, и вводить новые изменения с момента последнего запуска для всех остальных.