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

В моем репозитории GitLab у меня есть группа с 20 проектами. Я хочу клонировать все проекты сразу. Возможно ли это?

Ответы

Ответ 1

Не совсем, если:

  • у вас есть 21-й проект, который ссылается на остальные 20 как подмодули.
    (в этом случае клона, за которым следует git submodule update --init, будет достаточно для клонирования и проверки всех 20 проектов)

  • или вы каким-то образом перечислите проекты, к которым у вас есть доступ (GitLab API для проектов), и зациклились на этом результате, чтобы клонировать каждый из них (то есть, его можно записать в сценарий, а затем выполнить как одну команду)


С 2015 года Джей Габез упоминает в комментариях (август 2019 года) инструмент gabrie30/ghorg

ghorg позволяет быстро клонировать все организации или репозитории пользователей в один каталог.

Использование:

$ ghorg clone someorg
$ ghorg clone someuser --clone-type=user --protocol=ssh --branch=develop
$ ghorg clone gitlab-org --scm=gitlab --namespace=gitlab-org/security-products
$ ghorg clone --help

Ответ 2

Вот пример в Python 3:

from urllib.request import urlopen
import json
import subprocess, shlex

allProjects     = urlopen("http://[yourServer:port]/api/v4/projects?private_token=[yourPrivateTokenFromUserProfile]&per_page=100000")
allProjectsDict = json.loads(allProjects.read().decode())
for thisProject in allProjectsDict: 
    try:
        thisProjectURL  = thisProject['ssh_url_to_repo']
        command     = shlex.split('git clone %s' % thisProjectURL)
        resultCode  = subprocess.Popen(command)

    except Exception as e:
        print("Error on %s: %s" % (thisProjectURL, e.strerror))

Ответ 3

Существует инструмент под названием myrepos, который управляет несколькими репозиториями контроля версий. Обновление всех репозиториев просто требует одной команды:

mr update

Чтобы зарегистрировать все проекты gitlab в mr, вот небольшой скрипт на python. Требуется установленный пакет python-gitlab:

import os
from subprocess import call
from gitlab import Gitlab

# Register a connection to a gitlab instance, using its URL and a user private token
gl = Gitlab('http://192.168.123.107', 'JVNSESs8EwWRx5yDxM5q')
groupsToSkip = ['aGroupYouDontWantToBeAdded']

gl.auth() # Connect to get the current user

gitBasePathRelative = "git/"
gitBasePathRelativeAbsolut = os.path.expanduser("~/" + gitBasePathRelative)
os.makedirs(gitBasePathRelativeAbsolut,exist_ok=True)

for p in gl.Project():
    if not any(p.namespace.path in s for s in groupsToSkip):
        pathToFolder = gitBasePathRelative + p.namespace.name + "/" + p.name
        commandArray = ["mr", "config", pathToFolder, "checkout=git clone '" + p.ssh_url_to_repo + "' '" + p.name + "'"]
        call(commandArray)

os.chdir(gitBasePathRelativeAbsolut)

call(["mr", "update"])

Ответ 4

Я построил для этого script (завиток, git, jq). Мы используем его, и он работает отлично: https://gist.github.com/JonasGroeger/1b5155e461036b557d0fb4b3307e1e75

Чтобы узнать ваше пространство имен, лучше всего проверить API быстро:

curl "https://domain.com/api/v3/projects?private_token=$GITLAB_PRIVATE_TOKEN"

Там, используйте "namespace.name" как NAMESPACE для вашей группы.

script по существу:

  • Получить все проекты, соответствующие вашему PROJECT_SEARCH_PARAM
  • Получите их path и ssh_url_to_repo

    2,1. Если каталог path существует, cd в него и вызовите git pull

    2,2. Если каталог path не существует, вызовите git clone

Ответ 5

Вот еще один пример сценария bash для клонирования всех репозиториев в группе. Единственная зависимость, которую вам нужно установить - это jq (https://stedolan.github.io/jq/). Просто поместите скрипт в каталог, в который вы хотите клонировать свои проекты. Затем запустите его следующим образом:

./myscript <group name> <private token> <gitlab url>

т.е.

./myscript group1 abc123tyn234 http://yourserver.git.com

Сценарий:

#!/bin/bash
if command -v jq >/dev/null 2>&1; then
  echo "jq parser found";
else
  echo "this script requires the 'jq' json parser (https://stedolan.github.io/jq/).";
  exit 1;
fi

if [ -z "$1" ]
  then
    echo "a group name arg is required"
    exit 1;
fi

if [ -z "$2" ]
  then
    echo "an auth token arg is required. See $3/profile/account"
    exit 1;
fi

if [ -z "$3" ]
  then
    echo "a gitlab URL is required."
    exit 1;
fi

TOKEN="$2";
URL="$3/api/v3"
PREFIX="ssh_url_to_repo";

echo "Cloning all git projects in group $1";

GROUP_ID=$(curl --header "PRIVATE-TOKEN: $TOKEN" $URL/groups?search=$1 | jq '.[].id')
echo "group id was $GROUP_ID";
curl --header "PRIVATE-TOKEN: $TOKEN" $URL/groups/$GROUP_ID/projects?per_page=100 | jq --arg p "$PREFIX" '.[] | .[$p]' | xargs -L1 git clone

Ответ 6

Обновленный скрипт на Python 3, который действительно эффективно выполняет это, используя последние API Gitlab и правильную нумерацию страниц:

import requests
import subprocess, shlex
import os

print('Starting getrepos process..')

key = '12345678901234567890' # your gitlab key
base_url = 'https://your.gitlab.url/api/v4/projects?simple=true&per_page=10&private_token='
url = base_url + key

base_dir = os.getcwd()

while True:
    print('\n\nRetrieving from ' + url)
    response = requests.get(url, verify = False)
    projects = response.json()

    for project in projects:
        project_name = project['name']
        project_path = project['namespace']['full_path']
        project_url = project['ssh_url_to_repo']

        os.chdir(base_dir)
        print('\nProcessing %s...' % project_name)

        try:
            print('Moving into directory: %s' % project_path)
            os.makedirs(project_path, exist_ok = True)
            os.chdir(project_path)
            cmd = shlex.split('git clone --mirror %s' % project_url)
            subprocess.run(cmd)
        except Exception as e:
            print('Error: ' + e.strerror)

    if 'next' not in response.links:
        break

    url = response.links['next']['url'].replace('127.0.0.1:9999', 'your.gitlab.url')


print('\nDone')

Требуется библиотека запросов (для перехода по ссылкам на страницы).

Ответ 7

Если у вас все в порядке с каким-либо приложением оболочки, это клонирует все репозитории, сгруппированные по их идентификатору группы (вам нужен jq и параллельный)

seq 3                                                                           \
| parallel curl -s "'https://[gitlabUrl]/api/v4/projects?page={}&per_page=100&private_token=[privateToken]'
                     | jq '.[] | .ssh_url_to_repo, .name, .namespace.path'" \
| tr -d '"'                                                                 \
| awk '{ printf "%s ", $0; if (NR % 3 == 0) print " " }'                    \
| parallel --colsep ' ' 'mkdir -p {2} && git clone {1} {3}/{2}'

Ответ 8

Один вкладыш с завитком, JQ, TR

for repo in $(curl "https://<your-host>/api/v4/groups/<group_id>?private_token=<your_private_token>" | jq .projects[].ssh_url_to_repo | tr -d '"'); do git clone $repo; done;

Ответ 9

Вы можете обратиться к этому ruby ​​script здесь: https://gist.github.com/thegauraw/da2a3429f19f603cf1c9b3b09553728b

Но вам нужно убедиться, что у вас есть ссылка на организацию gitlab url (которая выглядит так: https://gitlab.example.com/api/v3/, например, организация) и частный токен (который выглядит так: QALWKQFAGZDWQYDGHADS, и вы можете войти: https://gitlab.example.com/profile/account после входа в систему). Также убедитесь, что у вас установлен httparty gem или gem install httparty

Ответ 10

Еще один способ сделать это с Windows "Git Bash", на котором установлены ограниченные пакеты:

#!/bin/bash
curl -o projects.json https://<GitLabUrl>/api/v4/projects?private_token=<YourToken>
i=0
while : ; do
    echo "/$i/namespace/full_path" > jsonpointer
    path=$(jsonpointer -f jsonpointer projects.json 2>/dev/null | tr -d '"')
    [ -z "$path" ] && break
    echo $path
    if [ "${path%%/*}" == "<YourProject>" ]; then
        [ ! -d "${path#*/}" ] && mkdir -p "${path#*/}"
        echo "/$i/ssh_url_to_repo" > jsonpointer
        url=$(jsonpointer -f jsonpointer projects.json 2>/dev/null | tr -d '"')
        ( cd "${path#*/}" ; git clone --mirror "$url" )
    fi
    let i+=1
done 
rm -f projects.json jsonpointer

Ответ 11

Да, это возможно, вот код.

предпосылки:

pip install python-gitlab

#!/usr/bin/python3
import os
import sys
import gitlab
import subprocess

glab = gitlab.Gitlab(f'https://{sys.argv[1]}', f'{sys.argv[3]}')
groups = glab.groups.list()
groupname = sys.argv[2]
for group in groups:
    if group.name == groupname:
        projects = group.projects.list(all=True)

for repo in projects:
    command = f'git clone {repo.ssh_url_to_repo}'
    process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
    output, _ = process.communicate()
    process.wait()

Пример:

  • создать файл .py (например, gitlab-downloader.py)
  • скопируйте и вставьте код сверху
  • в ОС Linux (или OSX) выполните команду chmod +x в файле сценария (например, chmod +x gitlab-downloader.py)
  • запустите его с 3 параметрами: имя хоста Gitlab, имя группы, ваш токен личного доступа (см. https://gitlab.exmaple.com/profile/personal_access_tokens)

Ответ 12

Альтернатива, основанная на ответе Дмитрия - в случае рекурсивного клонирования репозиториев в целое дерево групп.

#!/usr/bin/python3
import os
import sys
import gitlab
import subprocess

glab = gitlab.Gitlab(f'https://{sys.argv[1]}', f'{sys.argv[3]}')
groups = glab.groups.list()
root = sys.argv[2]

def visit(group):
    name = group.name
    real_group = glab.groups.get(group.id)

    os.mkdir(name)
    os.chdir(name) 

    clone(real_group.projects.list(all=True))

    for child in real_group.subgroups.list():
        visit(child)

    os.chdir("../")

def clone(projects):
    for repo in projects:
        command = f'git clone {repo.ssh_url_to_repo}'
        process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
        output, _ = process.communicate()
        process.wait()

glab = gitlab.Gitlab(f'https://{sys.argv[1]}', f'{sys.argv[3]}')
groups = glab.groups.list()
root = sys.argv[2]

for group in groups:
    if group.name == root:
        visit(group)

Ответ 13

Я написал скрипт для извлечения полной базы кода из gitlab для определенной группы.

for pag in {1..3} // number of pages projects has span {per page 20 projects so if you have 50 pages loop should be 1..3}
do
curl -s http://gitlink/api/v4/groups/{groupName}/projects?page=$pag > url.txt
grep -o '"ssh_url_to_repo": *"[^"]*"' url.txt | grep -o '"[^"]*"$' | while read -r line ; do
l1=${line%?}
l2=${l1:1}
echo "$l2"
git clone $l2
done
done