diff --git a/_vcsh b/_vcsh
index d6850ce36004ab7432bc19cf93d7ef1dae85aff1..c6efe6fdc4b41fd25ce4feb8a678297f4f329149 100644
--- a/_vcsh
+++ b/_vcsh
@@ -8,6 +8,7 @@ _arguments \
 		enter\:"Enter repo; spawn new \$SHELL"
 		init\:"init & clone from repo"
 		list\:"list all repos"
+		rename\:"rename repo"
 		run\:"run command on repo"
 		seed-gitignore\:"seed .gitignore.d/foo from git ls-files"
 		setup\:"set up repo with recommended settings"
diff --git a/doc/error_codes.md b/doc/error_codes.md
index e6636442c8ef069c4ea4515c486674ec2a957026..70496b5683622c9db1aefc66f608197a923d16f9 100644
--- a/doc/error_codes.md
+++ b/doc/error_codes.md
@@ -4,8 +4,6 @@
 * 11: Could not enter $GIT_WORK_TREE
 * 12: No repository found
 * 13: Required directory exists but is not a directory
-* 14: Could not create directory
-* 15: Could not create file
 * 16: Potentially harmful operation aborted
 * 17: Files that would be overwritten exist; fix manually
 
@@ -13,5 +11,7 @@
 * 51: Could not create file
 * 52: Could not move directory
 * 53: Could not move file
+* 54: Directory exists
+* 55: File exists
 
 * 99: Error code reserved for actions that should never happen
diff --git a/doc/vcsh.1.ronn b/doc/vcsh.1.ronn
index b348f923d918a208f6f80ff4d6f1ae314089416a..21ded83e85117c8752fee7fb22b22c586133f745 100644
--- a/doc/vcsh.1.ronn
+++ b/doc/vcsh.1.ronn
@@ -15,6 +15,8 @@ vcsh(1) - manage and sync config files via git
 
 `vcsh` list
 
+`vcsh` rename <repo> <newname>
+
 `vcsh` run <repo> <command>
 
 `vcsh` seed-gitignore <repo>
@@ -62,6 +64,9 @@ A sample configuration for `vcsh` and `mr` can be found at
 * list:
   List all local vcsh repositories.
 
+* rename:
+  Rename a repository.
+
 * run:
   Run command with <$GIT_DIR> and <$GIT_WORK_TREE> set. Allows you to run any
   and all commands without any restrictions. Use with care.
diff --git a/vcsh b/vcsh
index cfcb42abe107222d9a0f3135f824b78d854f4749..7d1f5aaca2d663b25fe6aceb099d467db863d14b 100755
--- a/vcsh
+++ b/vcsh
@@ -16,6 +16,8 @@ help() {
    enter                Enter repository; spawn new $SHELL
    init <repo>          Initialize a new repository
    list                 List all repositories
+   rename <repo> \\
+          <newname>     Rename repository
    run <repo> \\
        <command>        Use this repository
 
@@ -91,6 +93,10 @@ enter() {
 	$SHELL
 }
 
+git_dir_exists() {
+	[ -d "$GIT_DIR" ] || fatal "no repository found for '$VCSH_REPO_NAME'" 12
+}
+
 init() {
 	[ ! -e "$GIT_DIR" ] || fatal "'$GIT_DIR' exists" 10
 	export GIT_WORK_TREE="$HOME"
@@ -106,6 +112,13 @@ list() {
 	done
 }
 
+rename() {
+	git_dir_exists
+	[ -d "$GIT_DIR_NEW" ] && fatal "'$GIT_DIR_NEW' exists" 54
+	mv -f "$GIT_DIR" "$GIT_DIR_NEW" || fatal "Could not mv '$GIT_DIR' '$GIT_DIR_NEW'" 52
+
+}
+
 run() {
 	use
 	$VCSH_EXTERNAL_COMMAND
@@ -153,9 +166,7 @@ setup() {
 }
 
 use() {
-	if [ ! -d "$GIT_DIR" ]; then
-		fatal "no repository found for '$VCSH_REPO_NAME'" 12
-	fi
+	git_dir_exists
 	export GIT_WORK_TREE="$(git config --get core.worktree)"
 	export VCSH_DIRECTORY="$VCSH_REPO_NAME"
 }
@@ -170,14 +181,17 @@ if [ "$1" = 'clone' ]; then
 elif [ "$1" = 'delete' ] ||
      [ "$1" = 'enter' ] ||
      [ "$1" = 'init' ] ||
+     [ "$1" = 'rename' ] ||
      [ "$1" = 'run' ] ||
      [ "$1" = 'seed-gitignore' ] ||
      [ "$1" = 'setup' ]; then
-	[ -z $2 ] && fatal "$1: please specify repository to work on" 1
-	[ "$1" = 'run' -a -z "$3" ] && fatal "$1: please specify a command" 1
+	[ -z $2 ]                      && fatal "$1: please specify repository to work on" 1
+	[ "$1" = 'rename' -a -z "$3" ] && fatal "$1: please specify a target name" 1
+	[ "$1" = 'run' -a -z "$3" ]    && fatal "$1: please specify a command" 1
 	export VCSH_COMMAND="$1"
 	export VCSH_REPO_NAME="$2"
 	export GIT_DIR="$VCSH_BASE/$VCSH_REPO_NAME.git"
+	[ "$VCSH_COMMAND" = 'rename' ]         && export GIT_DIR_NEW="$VCSH_BASE/$3.git"
 	[ "$VCSH_COMMAND" = 'run' ] && shift 2 && export VCSH_EXTERNAL_COMMAND="$@"
 	[ "$VCSH_COMMAND" = 'seed-gitignore' ] && export VCSH_COMMAND='seed_gitignore'
 elif [ "$1" = 'list' ]; then