diff --git a/spec/support/generate-seed-repo-rb b/spec/support/generate-seed-repo-rb
new file mode 100755
index 0000000000000000000000000000000000000000..7335f74c0e95799777e9b671b5cbeb740394db1d
--- /dev/null
+++ b/spec/support/generate-seed-repo-rb
@@ -0,0 +1,162 @@
+#!/usr/bin/env ruby
+# 
+# # generate-seed-repo-rb
+# 
+# This script generates the seed_repo.rb file used by lib/gitlab/git
+# tests. The seed_repo.rb file needs to be updated anytime there is a
+# Git push to https://gitlab.com/gitlab-org/gitlab-git-test.
+# 
+# Usage:
+# 
+#   ./spec/support/generate-seed-repo-rb > spec/support/seed_repo.rb
+# 
+# 
+
+require 'erb'
+require 'tempfile'
+
+SOURCE = 'https://gitlab.com/gitlab-org/gitlab-git-test.git'.freeze
+SCRIPT_NAME = 'generate-seed-repo-rb'.freeze
+REPO_NAME = 'gitlab-git-test.git'.freeze
+
+def main
+  Dir.mktmpdir do |dir|
+    unless system(*%W[git clone --bare #{SOURCE} #{REPO_NAME}], chdir: dir)
+      abort "git clone failed"
+    end
+    repo = File.join(dir, REPO_NAME)
+    erb = ERB.new(DATA.read)
+    erb.run(binding)
+  end
+end
+
+def capture!(cmd, dir)
+  output = IO.popen(cmd, 'r', chdir: dir) { |io| io.read }
+  raise "command failed with #{$?}: #{cmd.join(' ')}" unless $?.success?
+  output.chomp
+end
+
+main
+
+__END__
+# This file is generated by <%= SCRIPT_NAME %>. Do not edit this file manually.
+#
+# Seed repo:
+<%= capture!(%w{git log --format=#\ %H\ %s}, repo) %>
+
+module SeedRepo
+  module BigCommit
+    ID               = "913c66a37b4a45b9769037c55c2d238bd0942d2e".freeze
+    PARENT_ID        = "cfe32cf61b73a0d5e9f13e774abde7ff789b1660".freeze
+    MESSAGE          = "Files, encoding and much more".freeze
+    AUTHOR_FULL_NAME = "Dmitriy Zaporozhets".freeze
+    FILES_COUNT      = 2
+  end
+
+  module Commit
+    ID               = "570e7b2abdd848b95f2f578043fc23bd6f6fd24d".freeze
+    PARENT_ID        = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9".freeze
+    MESSAGE          = "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>\n".freeze
+    AUTHOR_FULL_NAME = "Dmitriy Zaporozhets".freeze
+    FILES            = ["files/ruby/popen.rb", "files/ruby/regex.rb"].freeze
+    FILES_COUNT      = 2
+    C_FILE_PATH      = "files/ruby".freeze
+    C_FILES          = ["popen.rb", "regex.rb", "version_info.rb"].freeze
+    BLOB_FILE        = %{%h3= @key.title\n%hr\n%pre= @key.key\n.actions\n  = link_to 'Remove', @key, :confirm => 'Are you sure?', :method => :delete, :class => \"btn danger delete-key\"\n\n\n}.freeze
+    BLOB_FILE_PATH   = "app/views/keys/show.html.haml".freeze
+  end
+
+  module EmptyCommit
+    ID               = "b0e52af38d7ea43cf41d8a6f2471351ac036d6c9".freeze
+    PARENT_ID        = "40f4a7a617393735a95a0bb67b08385bc1e7c66d".freeze
+    MESSAGE          = "Empty commit".freeze
+    AUTHOR_FULL_NAME = "Rémy Coutable".freeze
+    FILES            = [].freeze
+    FILES_COUNT      = FILES.count
+  end
+
+  module EncodingCommit
+    ID               = "40f4a7a617393735a95a0bb67b08385bc1e7c66d".freeze
+    PARENT_ID        = "66028349a123e695b589e09a36634d976edcc5e8".freeze
+    MESSAGE          = "Add ISO-8859-encoded file".freeze
+    AUTHOR_FULL_NAME = "Stan Hu".freeze
+    FILES            = ["encoding/iso8859.txt"].freeze
+    FILES_COUNT      = FILES.count
+  end
+
+  module FirstCommit
+    ID               = "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863".freeze
+    PARENT_ID        = nil
+    MESSAGE          = "Initial commit".freeze
+    AUTHOR_FULL_NAME = "Dmitriy Zaporozhets".freeze
+    FILES            = ["LICENSE", ".gitignore", "README.md"].freeze
+    FILES_COUNT      = 3
+  end
+
+  module LastCommit
+    ID               = <%= capture!(%w[git show -s --format=%H HEAD], repo).inspect %>.freeze
+    PARENT_ID        = <%= capture!(%w[git show -s --format=%P HEAD], repo).split.last.inspect %>.freeze
+    MESSAGE          = <%= capture!(%w[git show -s --format=%s HEAD], repo).inspect %>.freeze
+    AUTHOR_FULL_NAME = <%= capture!(%w[git show -s --format=%an HEAD], repo).inspect %>.freeze
+    FILES            = <%=
+      parents = capture!(%w[git show -s --format=%P HEAD], repo).split
+      merge_base = parents.size > 1 ? capture!(%w[git merge-base] + parents, repo) : parents.first
+      capture!( %W[git diff --name-only #{merge_base}..HEAD --], repo).split("\n").inspect
+    %>.freeze
+    FILES_COUNT      = FILES.count
+  end
+
+  module Repo
+    HEAD = "master".freeze
+    BRANCHES = %w[
+<%=   capture!(%W[git for-each-ref --format=#{'  ' * 3}%(refname:strip=2) refs/heads/], repo) %>
+    ].freeze
+    TAGS = %w[
+<%=   capture!(%W[git for-each-ref --format=#{'  ' * 3}%(refname:strip=2) refs/tags/], repo) %>
+    ].freeze
+  end
+
+  module RubyBlob
+    ID = "7e3e39ebb9b2bf433b4ad17313770fbe4051649c".freeze
+    NAME = "popen.rb".freeze
+    CONTENT = <<-eos.freeze
+require 'fileutils'
+require 'open3'
+
+module Popen
+  extend self
+
+  def popen(cmd, path=nil)
+    unless cmd.is_a?(Array)
+      raise RuntimeError, "System commands must be given as an array of strings"
+    end
+
+    path ||= Dir.pwd
+
+    vars = {
+      "PWD" => path
+    }
+
+    options = {
+      chdir: path
+    }
+
+    unless File.directory?(path)
+      FileUtils.mkdir_p(path)
+    end
+
+    @cmd_output = ""
+    @cmd_status = 0
+
+    Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
+      @cmd_output << stdout.read
+      @cmd_output << stderr.read
+      @cmd_status = wait_thr.value.exitstatus
+    end
+
+    return @cmd_output, @cmd_status
+  end
+end
+    eos
+  end
+end
diff --git a/spec/support/seed_repo.rb b/spec/support/seed_repo.rb
index 99a500bbbb1b5faa5bf26c5fc34dfedacbe7d854..cfe7fc980a881107a6b1063741f7113686d89158 100644
--- a/spec/support/seed_repo.rb
+++ b/spec/support/seed_repo.rb
@@ -1,4 +1,8 @@
+# This file is generated by generate-seed-repo-rb. Do not edit this file manually.
+#
 # Seed repo:
+# 4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6 Merge branch 'master' into 'master'
+# 0e1b353b348f8477bdbec1ef47087171c5032cd9 adds an executable with different permissions
 # 0e50ec4d3c7ce42ab74dda1d422cb2cbffe1e326 Merge branch 'lfs_pointers' into 'master'
 # 33bcff41c232a11727ac6d660bd4b0c2ba86d63d Add valid and invalid lfs pointers
 # 732401c65e924df81435deb12891ef570167d2e2 Update year in license file
@@ -94,7 +98,12 @@ module SeedRepo
       master
       merge-test
     ].freeze
-    TAGS = %w[v1.0.0 v1.1.0 v1.2.0 v1.2.1].freeze
+    TAGS = %w[
+      v1.0.0
+      v1.1.0
+      v1.2.0
+      v1.2.1
+    ].freeze
   end
 
   module RubyBlob