From 71dc3b30449a4574455ff7eb9c390e30ad52ac4a Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 15 Dec 2016 16:01:03 -0500 Subject: fix (wip) --- git-mirror | 86 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 30 deletions(-) (limited to 'git-mirror') diff --git a/git-mirror b/git-mirror index d9e1932..113379a 100755 --- a/git-mirror +++ b/git-mirror @@ -5,6 +5,8 @@ # terms of the Do What The Fuck You Want To Public License, Version 2, # as published by Sam Hocevar. See the COPYING file for more details. +# Depends 4.4+, as it uses the '-d' flag to 'mapfile'. +# # Depends on the 'gitget' and 'libremessages' commands. On Parabola # GNU/Linux-libre, those are the 'gitget' and 'librelib' packages, # respectively. @@ -12,8 +14,7 @@ # For other systems, they both live at: # https://git.parabola.nu/packages/libretools.git/ -set -o pipefail -set -e +set -o pipefail -euE . libremessages usage() { @@ -27,18 +28,16 @@ main() { fi declare -g cfg_file="$1" - local r=0 while read -r repo; do - handle-repo "$repo" || r=$? + handle-repo "$repo" done < <(cfg-list-repos) - return $r } handle-repo() { [[ $# == 1 ]] || panic local repo=$1 - local local upstream downstreams downstream r=0 - + local local upstream downstreams downstream + # read configuration local="$(cfg-get "repo.$repo.local")" upstream="$(cfg-get "repo.$repo.upstream")" || true @@ -46,7 +45,7 @@ handle-repo() { # download if [[ -n "$upstream" ]]; then - download "$upstream" "$local" + download "$repo" "$upstream" "$local" fi # ensure that $local exists @@ -54,25 +53,29 @@ handle-repo() { # upload for downstream in "${downstreams[@]}"; do - upload "$local" "$downstream" || r=$? + upload "$repo" "$local" "$downstream" done - - return $r } download() { [[ $# == 3 ]] || panic local repo=$1 - local remote=$2 + local _remote=$2 local local=$3 + local IFS='&' + local remote=${_remote%%#*} + local params=(${_remote#"$remote"}) + # download the repository local url + url="$(remote "$remote" pull-url)" - gitget -f -n "$repo" "$url" "$local" + gitget -f -n "$repo" bare "$url" "$local" # download the metadata - remote "$remote" get-meta > "$local/git-mirror.tmp" - git config --file "$local/config" --rename-section git-mirror git-mirror-bak + msg2 "Fetching metadata for repo '%s'" "$repo" + get-meta "$remote" > "$local/git-mirror.tmp" + git config --file "$local/config" --rename-section git-mirror git-mirror-bak 2>/dev/null || true local IFS='=' while read -r key val; do git config --file "$local/config" --add git-mirror."$key" "$val" @@ -81,20 +84,19 @@ download() { git config --file "$local/config" --remove-section git-mirror-bak } -upload() { - [[ $# == 2 ]] || panic - local local=$1 - local remote=${2%%#*} - local IFS='&' - local params=(${2#"$remote"}) +upload() ( + [[ $# == 3 ]] || panic + local repo=$1 + local local=$2 + local remote=$3 # push metadata - { - printf '%q ' set-meta "${remote#*:}" - git config --file "$local/config" --get-regexp '^git-mirror[.]' -z|sed -z 's/ /=/'|xargs -0r printf '%q ' - printf '%q ' "${params[@]}" - } | account "${remote%%:*}" + msg2 "Pushing metadata for repo '%s'" "$repo" + local meta + mapfile -d '' meta < <(git config --file "$local/config" -z --get-regexp '^git-mirror[.]'|sed -z 's/ /=/') + set-meta "$remote" "${meta[@]}" # push repository + msg2 "Pushing repo '%s'" "repo" local repo_mode repo_mode=$(remote "$remote" repo-mode) if [[ $repo_mode == passive ]]; then @@ -102,6 +104,30 @@ upload() { push_url="$(remote "$remote" push-url)" cd "$local" && git push --mirror "$push_url" fi +) + +get-meta() ( + [[ $# = 1 ]] || panic + local _remote=$1 + + local IFS='&' + local remote=${_remote%%#*} + local params=(${_remote#"$remote"}) + + remote "$remote" get-meta + [[ ${#params[@]} = 0 ]] || printf '%s\n' "${params[@]}" +) + +set-meta() { + [[ $# -ge 1 ]] || panic + local _remote=$1 + local args=("${@:2}") + + local IFS='&' + local remote=${_remote%%#*} + local params=(${_remote#"$remote"}) + + remote "$remote" set-meta "${args[@]}" "${params[@]}" } # Spawn an 'account.type' helper. It will read commands from stdin. @@ -109,11 +135,11 @@ account() { [[ $# == 1 ]] || panic local account=$1 - local account_type - account_type="$(cfg-get "account.$account.type")" + local type + type="$(cfg-get "account.$account.type")" { - cfg --list -z|sed -zn "s=^account[.]$account[.]=config =p"|grep -z -v '^type='|xargs -r0 printf '%s\n' + cfg --list|sed -n "s=^account[.]$account[.]==p"|grep -v '^type='|xargs -r printf 'config %q\n' cat } | git mirror-"$type" "$account" } @@ -146,7 +172,7 @@ cfg-get-all() { cfg-list-repos() { [[ $# == 0 ]] || panic - cfg --name-only --get-regexp '^repo[.].*[.].*$' -z|sed -z -e 's|^repo[.]||' -e 's|[.][^.]*$||'|sort -zu|xargs -r0 printf '%s\n' + cfg --name-only -z --get-regexp '^repo[.].*[.].*$' |sed -z -e 's|^repo[.]||' -e 's|[.][^.]*$||'|sort -zu|xargs -r0 printf '%s\n' } main "$@" -- cgit v1.2.3