diff --git a/.gitignore b/.gitignore
index 0bbc648ecf5649a931c7ccaac5c9374b699758ab..330a4d17845bd53588bf80ee9f787650b2dced6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 /gitlab-shell/
+/gitlab-shell
 /.ssh/
 /gitlab-satellites/
 /repositories/
@@ -53,3 +54,4 @@
 /gitaly/
 /gitlab-workhorse/config.toml
 /gitlab-workhorse/.cache
+/go-gitlab-shell
diff --git a/Makefile b/Makefile
index 71086817449e0987a08ca698311f3b5517fc68d6..d903b739aace023e5e4eb82874a8f8866b432683 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
 gitlab_repo = https://gitlab.com/gitlab-org/gitlab-ce.git
 gitlab_shell_repo = https://gitlab.com/gitlab-org/gitlab-shell.git
+gitlab_shell_clone_dir = go-gitlab-shell/src/gitlab.com/gitlab-org/gitlab-shell
 gitlab_workhorse_repo = https://gitlab.com/gitlab-org/gitlab-workhorse.git
 gitlab_workhorse_clone_dir = gitlab-workhorse/src/gitlab.com/gitlab-org/gitlab-workhorse
 gitaly_repo = https://gitlab.com/gitlab-org/gitaly.git
@@ -59,10 +60,14 @@ bundler:
 
 # Set up gitlab-shell
 
-gitlab-shell-setup: gitlab-shell/.git gitlab-shell/config.yml bundler .gitlab-shell-bundle gitlab-shell/.gitlab_shell_secret
+gitlab-shell-setup: symlink-gitlab-shell ${gitlab_shell_clone_dir}/.git gitlab-shell/config.yml bundler .gitlab-shell-bundle gitlab-shell/.gitlab_shell_secret
+	if [ -x gitlab-shell/bin/compile ] ; then gitlab-shell/bin/compile; fi
 
-gitlab-shell/.git:
-	git clone ${gitlab_shell_repo} gitlab-shell
+symlink-gitlab-shell:
+	support/symlink-gitlab-shell gitlab-shell ${gitlab_shell_clone_dir}
+
+${gitlab_shell_clone_dir}/.git:
+	git clone ${gitlab_shell_repo} ${gitlab_shell_clone_dir}
 
 gitlab-shell/config.yml:
 	sed -e "s|/home/git|${gitlab_development_root}|"\
diff --git a/support/symlink-gitlab-shell b/support/symlink-gitlab-shell
new file mode 100755
index 0000000000000000000000000000000000000000..995bd1c082a549ec20b473552b7b303d04359d4e
--- /dev/null
+++ b/support/symlink-gitlab-shell
@@ -0,0 +1,21 @@
+#!/usr/bin/env ruby
+
+require 'fileutils'
+require 'time'
+
+def main(symlink, target)
+  return if File.symlink?(symlink)
+
+  if File.exist?(symlink)
+    # there is an old directory at the symlink location
+    FileUtils.mv(symlink, "#{symlink}.#{Time.now.iso8601}")
+  end
+
+  FileUtils.ln_s(target, symlink)
+end
+
+if ARGV.count != 2
+  abort "Usage: #{$0} SYMLINK TARGET"
+end
+
+main(*ARGV)