ghq で管理しているリポジトリを複数選択して消す ghq-unget コマンド書いた

  • 12
    Like
  • 0
    Comment
More than 1 year has passed since last update.

README

ghq-unget.png

ghq get でリポジトリを get できるのは便利だけども便利すぎて色々 get してしまうし、こんなにいらない状態にすぐ陥る。なのでいらないリポジトリを unget するコマンドを書いた。→ソース

ghq-unget

これを実行すると ghq で管理しているリポジトリを peco や何かで絞り込んで削除できる。複数選択したら全部削除する。コミットしていないファイルがあったり push していないブランチがあったりしたら削除前に確認するようになっている。

peco や何かと書いたがデフォルトでは fzf で絞り込むようになっている。こいつのファジーマッチは peco より便利だと常々思っているが、まあそうじゃない人もいると思うので、

FILTER=peco ghq-unget

または

git config --global aux.filter peco
ghq-unget

として好きに設定してほしい。

ghq-unget

ghq-unget
#!/bin/bash

if [[ -z "$FILTER" ]]; then
    FILTER=$(git config --global aux.filter)
    FILTER=${FILTER:-fzf}
fi

ask_yn() {
    local msg=$1
    local yn
    while read -r -p "$msg [yN] " yn; do
        case "$yn" in
            [Yy]*) return 0 ;;
            [Nn]*) return 1 ;;
            "")    return 1 ;;
        esac
    done
}

test_repo_is_clean() {
    local msg
    msg=$(git -c status.color=always status --short)
    if [[ $? = 0 && -z "$msg" ]]; then
        return 0
    else
        printf "\e[31mThe repository is dirty:\e[0m\n"
        echo
        sed 's/^/    /' <<< "$msg"
        echo
        return 1
    fi
}

test_no_unpushed_commits() {
    local msg
    msg=$(git log --branches --not --remotes --simplify-by-decoration --decorate --oneline --color=always)
    if [[ $? = 0 && -z "$msg" ]]; then
        return 0
    else
        printf "\e[31mThere are unpushed commits:\e[0m\n"
        echo
        sed 's/^/    /' <<< "$msg"
        echo
        return 1
    fi
}

rm_each_repo() {
    local fd=$1
    local repo_path
    local ret
    while read -u "$fd" -r repo_path; do
        printf "\e[1;34m> %s\e[0m\n" "$repo_path"
        (
            cd "$repo_path"
            ret=0
            test_repo_is_clean
            ret=$(( ret + $? ))
            test_no_unpushed_commits
            ret=$(( ret + $? ))
            if [[ "$ret" -gt 0 ]]; then
                if ask_yn "Are you sure you want to remove it?"; then
                    rm -rf "$repo_path"
                fi
            else
                rm -rf "$repo_path"
            fi
        )
    done
}

main() {
    rm_each_repo 3 3< <( ghq list -p | "$FILTER" )
}

main