#!/bin/bash # # Mirror git repository with submodules - recursively # # Usage: # mirror-recursive
[] # strict mode set -euo pipefail IFS=$'\n\t' # Scratch - temp tmpdir=$(mktemp -d -t mirror-recursive-XXXXXXX) function finish { rm -rf "$tmpdir" } trap finish EXIT source $(dirname $(realpath $0))/config source $(dirname $(realpath $0))/gen-mirror-path function progress(){ local progress=${1:-100} echo -n "..$progress%" if [ $progress -eq 100 ] then echo fi } function submoduleDiscovery(){ # main parameters local repo=$1 local gitdir=$(getRepoPath $repo) # depth (empty or prefixed from main script) local depth=${2:-} # temporary path local tmpname=$(getRepoUniq $repo) tmpname=$tmpdir/$tmpname local tmpCommitList=$tmpname.commits local tmpSubmoduleList=$tmpname.submodules # cache paths local cachePath=$(getRepoCache $repo) local cacheCommits=$cachePath/commits-checked local cacheSubmodules=$cachePath/submodules-checked # check, if cache exists [ -d $cachePath ] || mkdir -p $cachePath [ -f $cacheCommits ] || touch $cacheCommits [ -f $cacheSubmodules ] || touch $cacheSubmodules # avoid recursion - if commit list exists # there was activity with this run recently if [ ! -f $tmpCommitList ] then # cache submodules reuse cat $cacheSubmodules > $tmpSubmoduleList echo -n "Discovering submodules of $repo.. " git --git-dir $gitdir log --all $depth --format="%H" | sort > $tmpCommitList # check against cache echo -n "cache check.." comm -13 $cacheCommits $tmpCommitList > $tmpname mv $tmpname $tmpCommitList local commits=$(wc -l $tmpCommitList | cut -d' ' -f1) echo -n "$commits commits" # this can take long time... local processed=0 local nextStamp=$(($(date +"%s") + 3)) while read -r line || [[ -n "$line" ]] do submodule-describe $gitdir $line | cut -f 3 >> $tmpSubmoduleList # progress indication processed=$(($processed + 1)) if [ $(date +"%s") -gt $nextStamp ] then progress $((100*$processed/$commits)) nextStamp=$(($nextStamp + 3)) fi done < $tmpCommitList # finish the bar progress # archive to cache cat $tmpCommitList $cacheCommits > $tmpname sort $tmpname > $cacheCommits sort $tmpSubmoduleList | uniq > $tmpname cat $tmpname > $cacheSubmodules # Recursion++ while read -r submodule || [[ -n "$submodule" ]] do mirror-main-repo $submodule submoduleDiscovery $submodule $depth done < $cacheSubmodules fi } # main repo mainrepo=$1 depth=${2:-} [ -n "$depth" ] && depth="-$depth" # Make first mirror mirror-main-repo $mainrepo submoduleDiscovery $mainrepo $depth