🍵
GitLabで指定したグループ内の全てのリポジトリを一括でcloneする
概要
1個1個丹精込めて手動でcloneすることに限界を感じたので、一括で自分に関連するリポジトリをcloneする
シェルスクリプト
.zshrc
# リポジトリのディレクトリを作成してからcloneする
# 第1引数 URL(https://gitlab.example.com/diaspora/diaspora-client.git)
function git_clone_to_path() {
[[ -z ${commands[git]} ]] \
&& { echo 'git is required'; return 1; }
local repo_path=$(sed 's/[^:]*:\/\/[^\/]*\/\([^\.]*\)\.git/\1/' <<< $1 | xargs dirname)
mkdir -p ${PWD}/${repo_path}
(
cd $2/${repo_path}
[[ -d $(echo $1 | xargs basename | cut -d. -f1) ]] || git clone $1
)
}
# APIがpaginationしているのでページ数を一旦取得
function gitlab_projects_total_pages_by_group_id() {
[[ $# -eq 0 ]] && return 1
local -r total=$(curl -i -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
"https://gitlab.example.com/api/v4/groups/$1/projects?include_subgroups=true&simple=true&per_page=1" \
| grep X-Total: | cut -d' ' -f2 | sed 's/[[:space:]]//')
expr ${total} / 100 + 1
}
# 指定したGroupのリポジトリを全てcloneする
# 第1引数 Group ID(100)
function recursive_git_clone_to_path_by_group_id() {
[[ -z ${commands[git]} ]] \
&& { echo 'git is required'; return 1; }
[[ -z ${commands[jq]} ]] \
&& { echo 'jq is required'; return 1; }
[[ $# -eq 0 ]] && return 1
for i in $(seq $(gitlab_projects_total_pages_by_group_id $1)); do
for repo in $(curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
"https://gitlab.example.com/api/v4/groups/$1/projects?include_subgroups=true&simple=true&per_page=100&page=$i" \
| jq -r '.[].http_url_to_repo'); do
git_clone_to_path $repo
done
done
}
alias rgc='recursive_git_clone_to_path_by_group_id'
$ export GITLAB_TOKEN=xxxxx
$ rgc ${GROUP_ID} ${HOME}/workspace/test
Discussion