diff --git a/_vcsh b/_vcsh index 73a04a59dcb16d8451d8d941eaf311f2fcaac18a..3022c6125d6a4a82db9697ee76a5f7c229d12f95 100644 --- a/_vcsh +++ b/_vcsh @@ -23,6 +23,10 @@ function _vcsh-enter () { (( CURRENT == 2 )) && __vcsh_repositories } +function _vcsh-foreach () { + _dispatch git git +} + function _vcsh-help () { _nothing } @@ -96,6 +100,7 @@ function _vcsh () { "commit:commit in all repositories" "delete:delete an existing repository" "enter:enter repository; spawn new <\$SHELL>" + "foreach:execute for all repos" "help:display help" "init:initialize an empty repository" "list:list all local vcsh repositories" diff --git a/doc/vcsh.1.ronn b/doc/vcsh.1.ronn index 2bf8a77ebd8c394d58a402e78b916af39ed4d197..d5ee0dc53861d6346b74a64e8932d6e97c375076 100644 --- a/doc/vcsh.1.ronn +++ b/doc/vcsh.1.ronn @@ -11,6 +11,8 @@ vcsh(1) - Version Control System for $HOME - multiple Git repositories in $HOME `vcsh` enter <repo> +`vcsh` foreach [-g] <git command> + `vcsh` help `vcsh` init <repo> @@ -98,6 +100,11 @@ an interactive user. * enter: Enter repository; spawn new <$SHELL>. +* foreach: + Execute git command for every vcsh repository. + + `-g`: Execute in general context. + * help: Display help. diff --git a/vcsh b/vcsh index afed6eb33abbcc16885365cd560095a3eeb94a9d..06f6c331edabbdc6ea2360f54e84ea0d65bf768e 100755 --- a/vcsh +++ b/vcsh @@ -106,6 +106,8 @@ help() { commit Commit in all repositories delete <repo> Delete an existing repository enter <repo> Enter repository; spawn new instance of \$SHELL + foreach [<-g>] + <git command> Execute a command for every repository help Display this help text init <repo> Initialize a new repository list List all repositories @@ -216,6 +218,27 @@ enter() { hook post-enter } +foreach() { + hook pre-foreach + + # We default to prefixing `git` to all commands passed to foreach, but + # allow running in general context with -g + command_prefix=git + while getopts "g" flag; do + if [ x"$1" = x'-g' ]; then + unset command_prefix + fi + shift 1 + done + for VCSH_REPO_NAME in $(list); do + echo "$VCSH_REPO_NAME:" + GIT_DIR=$VCSH_REPO_D/$VCSH_REPO_NAME.git; export GIT_DIR + use + $command_prefix "$@" + done + hook post-foreach +} + git_dir_exists() { [ -d "$GIT_DIR" ] || fatal "no repository found for '$VCSH_REPO_NAME'" 12 } @@ -558,6 +581,9 @@ elif [ x"$VCSH_COMMAND" = x'delete' ] || [ x"$VCSH_COMMAND" = x'rename' ] && { VCSH_REPO_NAME_NEW=$3; export VCSH_REPO_NAME_NEW; GIT_DIR_NEW=$VCSH_REPO_D/$VCSH_REPO_NAME_NEW.git; export GIT_DIR_NEW; } [ x"$VCSH_COMMAND" = x'run' ] && shift 2 +elif [ x"$VCSH_COMMAND" = x'foreach' ]; then + [ -z "$2" ] && fatal "$VCSH_COMMAND: please specify a command" 1 + shift 1 elif [ x"$VCSH_COMMAND" = x'commit' ] || [ x"$VCSH_COMMAND" = x'list' ] || [ x"$VCSH_COMMAND" = x'list-tracked' ] ||