diff --git a/_vcsh b/_vcsh
index c77f2afb082c0e1d1d595723ee011bde18972c6a..47dbd9e69a9582540c563cfc27c0362fc046d453 100644
--- a/_vcsh
+++ b/_vcsh
@@ -47,6 +47,10 @@ function _vcsh-pull () {
 	_nothing
 }
 
+function _vcsh-push () {
+	_nothing
+}
+
 function _vcsh-rename () {
 	(( CURRENT == 2 )) && __vcsh_repositories
 	(( CURRENT == 3 )) && _message "new repository name"
diff --git a/doc/hooks b/doc/hooks
index 5547131cddc8c625e095bf13789833ac403a7fd6..1a93fda674a49e1c20e84be0a3b78b46a89a164e 100644
--- a/doc/hooks
+++ b/doc/hooks
@@ -1,9 +1,13 @@
 Available hooks are:
-pre-command
-post-command
-pre-enter
-post-enter
-pre-run
-post-run
-pre-upgrade
-post-upgrade
+* pre-command
+* post-command
+* pre-enter
+* post-enter
+* pre-pull
+* post-pull
+* pre-push
+* post-push
+* pre-run
+* post-run
+* pre-upgrade
+* post-upgrade
diff --git a/doc/vcsh.1.ronn b/doc/vcsh.1.ronn
index 1592d077ff9d36dfb6b56504a8fae7a8c6227a2e..ee13b7f4005d5b34360fd14980a6606511eb0db1 100644
--- a/doc/vcsh.1.ronn
+++ b/doc/vcsh.1.ronn
@@ -23,6 +23,8 @@ vcsh(1) - Version Control System for $HOME - multiple Git repositories in $HOME
 
 `vcsh` pull
 
+`vcsh` push
+
 `vcsh` rename <repo> <newname>
 
 `vcsh` run <repo> <shell command>
@@ -103,6 +105,9 @@ an interactive user.
 * pull:
   Pull from all vcsh remotes.
 
+* push:
+  Push to all vcsh remotes.
+
 * rename:
   Rename a repository.
 
diff --git a/vcsh b/vcsh
index 2764d3df219d3141b80ee2dab777f0d29bdcd04f..e64ca0b936247983b4f203cd6f283f553070d322 100755
--- a/vcsh
+++ b/vcsh
@@ -101,6 +101,7 @@ help() {
    list-tracked-by \\
         <repo>          List files tracked by a repository
    pull                 Pull from all vcsh remotes
+   push                 Push to vcsh remotes
    rename <repo> \\
           <newname>     Rename repository
    run <repo> \\
@@ -234,6 +235,17 @@ pull() {
 	hook post-pull
 }
 
+push() {
+	hook pre-push
+	for VCSH_REPO_NAME in $(list); do
+		echo -n "$VCSH_REPO_NAME: "
+		export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git"
+		use
+		git push
+	done
+	hook post-push
+}
+
 rename() {
 	git_dir_exists
 	[ -d "$GIT_DIR_NEW" ] && fatal "'$GIT_DIR_NEW' exists" 54
@@ -341,7 +353,8 @@ elif [ "$1" = 'delete' ]           ||
 	[ "$VCSH_COMMAND" = 'write-gitignore' ]
 elif [ "$1" = 'list' ] ||
      [ "$1" = 'list-tracked' ] ||
-     [ "$1" = 'pull' ]; then
+     [ "$1" = 'pull' ] ||
+     [ "$1" = 'push' ]; then
 	export VCSH_COMMAND="$1"
 elif [ -n "$2" ]; then
 	export VCSH_COMMAND='run'