同步指定目录中所有git库的一个简单shell脚本。
$ git sync .
> Found 27 repositories.
> Synching kitex => [# ] 3%
Already up to date.
> Synching kitex finish.
> Synching abcoder => [## ] 6%
Already up to date.
> Synching abcoder finish.
> Synching fastpb => [### ] 9%
Already up to date.
> Synching fastpb finish.
> Synching gopkg => [#### ] 12%
Already up to date.
> Synching gopkg finish.
#!/bin/env bash
#################################
# name: git-sync
# version: v0.1
# auth: alimy (github.com/alimy)
# updated: 2026.02.01
#################################
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
function git_sync() {
progress=$(($3*$5))
if [ $3 -eq $4 ]
then
progress=100
fi
printf "\r> Synching ${RED}$1${NC} => [${GREEN}%-$4s${NC}] %d%%\n" $(printf "%$3s" | tr ' ' '#') $progress
cd $2
git pull
cd $6
printf "> Synching ${RED}$1${NC} finish.\n\n"
}
function do_sync() {
mapfile -d '' -t git_dirs < <(find . -type d -name '*.git' -print0)
# no git dir just return
if [ ${#git_dirs[@]} -eq 0 ]
then
echo "> No repository found."
return 0
fi
repos_count=${#git_dirs[@]}
sync_count=1
sync_step=$((100 / repos_count))
root_dir=$(pwd)
printf "> Found ${GREEN}%d${NC} repositories.\n\n" $repos_count
for repo in ${git_dirs[@]}
do
repo_dir=$(dirname $repo)
repo_name=$(basename $repo_dir)
git_sync $repo_name $repo_dir $sync_count $repos_count $sync_step $root_dir
((sync_count++))
done
}
# main function
work_dir=$(pwd)
cd ${1-.}
do_sync
cd $work_dir
#!/bin/env bash
###########################################
# name: git-sync
# version: v0.2
# auth: alimy (github.com/alimy)
# updated: 2026.02.01
# todo: 优化git库多于32个的场景下的进度条显示;
###########################################
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
function git_sync() {
progress=$(($3*$5))
if [ $3 -eq $4 ]
then
progress=100
fi
printf "\r> Synching ${RED}$1${NC} => [${GREEN}%-$4s${NC}] %d%%\n" $(printf "%$3s" | tr ' ' '#') $progress
cd $2
git pull
cd $6
printf "> Synching ${RED}$1${NC} finish.\n\n"
}
function do_sync() {
opt_args=()
other_args=()
is_prev_opt_arg=0
for arg in "$@"; do
if [[ "$arg" == -* ]]; then
opt_args+=("$arg")
((is_prev_opt_arg++))
else
if (( is_prev_opt_arg == 1 ))
then
opt_args+=("$arg")
((is_prev_opt_arg--))
else
other_args+=("$arg")
fi
fi
done
if (( ${#other_args[@]} == 0 )); then other_args+=("."); fi
mapfile -d '' -t git_dirs < <(find ${other_args[@]} ${opt_args[@]} -type d -name '*.git' -print0)
# no git dir just return
if [ ${#git_dirs[@]} -eq 0 ]
then
echo "> No repository found."
return 0
fi
repos_count=${#git_dirs[@]}
sync_count=1
sync_step=$((100 / repos_count))
root_dir=$(pwd)
printf "> Found ${GREEN}%d${NC} repositories.\n\n" $repos_count
for repo in ${git_dirs[@]}
do
repo_dir=$(dirname $repo)
repo_name=$(basename $repo_dir)
git_sync $repo_name $repo_dir $sync_count $repos_count $sync_step $root_dir
((sync_count++))
done
}
# main function
do_sync $@
#!/bin/env bash
#################################
# name: git-sync
# version: v0.3
# auth: alimy (github.com/alimy)
# updated: 2026.02.03
#################################
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
function git_sync() {
printf "\r> Synching ${RED}$1${NC} (${GREEN}$3${NC}/$4)\n"
cd $2
git pull
cd $5
printf "> Synching ${RED}$1${NC} finish.\n\n"
}
function do_sync() {
opt_args=()
other_args=()
is_prev_opt_arg=0
for arg in "$@"; do
if [[ "$arg" == -* ]]; then
opt_args+=("$arg")
((is_prev_opt_arg++))
else
if (( is_prev_opt_arg == 1 ))
then
opt_args+=("$arg")
((is_prev_opt_arg--))
else
other_args+=("$arg")
fi
fi
done
if (( ${#other_args[@]} == 0 )); then other_args+=("."); fi
mapfile -d '' -t git_dirs < <(find ${other_args[@]} ${opt_args[@]} -type d -name '*.git' -print0)
# no git dir just return
if [ ${#git_dirs[@]} -eq 0 ]
then
echo "> No repository found."
return 0
fi
repos_count=${#git_dirs[@]}
sync_count=1
root_dir=$(pwd)
printf "> Found ${GREEN}%d${NC} repositories.\n\n" $repos_count
for repo in ${git_dirs[@]}
do
repo_dir=$(dirname $repo)
repo_name=$(basename $repo_dir)
git_sync $repo_name $repo_dir $sync_count $repos_count $root_dir
((sync_count++))
done
}
# main function
do_sync $@