git-sync同步所有git库

同步指定目录中所有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.

Bash脚本 git-sync v0.1

#!/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

Bash脚本 git-sync v0.2

#!/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 $@

Bash脚本 git-sync v0.3

#!/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 $@
 TL在Go如何实现oneof语义

Comments