From ef968fd0c8a61d63283e9f7aba4a07809d87bc16 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 21 Mar 2013 22:22:21 +0200
Subject: [PATCH 01/83] fix commit-description css on commit.show

---
 app/assets/stylesheets/sections/commits.scss | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss
index 0df39298c89..1e564188892 100644
--- a/app/assets/stylesheets/sections/commits.scss
+++ b/app/assets/stylesheets/sections/commits.scss
@@ -413,3 +413,9 @@
   padding: 4px;
   background-color: #EEE;
 }
+
+.commit-description {
+  background: none;
+  border: none;
+  margin: 0;
+}
-- 
GitLab


From 0e4b2395a9612d67255f5101452a2e79334c4352 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 22 Mar 2013 15:08:02 +0200
Subject: [PATCH 02/83] Fix lines and line numbers being squashed in File ->
 blame

---
 app/views/blame/show.html.haml | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/app/views/blame/show.html.haml b/app/views/blame/show.html.haml
index 36d81e6af38..62516266536 100644
--- a/app/views/blame/show.html.haml
+++ b/app/views/blame/show.html.haml
@@ -38,9 +38,11 @@
                   - current_line += 1
                 - else
                   - lines.each do |line|
-                    = current_line
+                    :preserve
+                      #{current_line}
                     - current_line += 1
             %td.lines
               %pre
                 - lines.each do |line|
-                  = line
+                  :preserve
+                    #{line}
-- 
GitLab


From 5c49cf6ca170aba7646f53d02130c79c0c4470a6 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 22 Mar 2013 15:11:16 +0200
Subject: [PATCH 03/83] fix blame view head nav

---
 app/views/blame/_head.html.haml | 9 ++-------
 app/views/blame/show.html.haml  | 2 +-
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/app/views/blame/_head.html.haml b/app/views/blame/_head.html.haml
index ef9e6c9c532..3a883829562 100644
--- a/app/views/blame/_head.html.haml
+++ b/app/views/blame/_head.html.haml
@@ -1,7 +1,2 @@
-%ul.nav.nav-tabs
-  %li
-    = render partial: 'shared/ref_switcher', locals: {destination: 'tree', path: params[:path]}
-  = nav_link(controller: :refs) do
-    = link_to 'Source', project_tree_path(@project, @ref)
-  %li.pull-right
-    = render "shared/clone_panel"
+%div.tree-ref-holder
+  = render 'shared/ref_switcher', destination: 'tree', path: params[:path]
diff --git a/app/views/blame/show.html.haml b/app/views/blame/show.html.haml
index 62516266536..f85dde6dbbf 100644
--- a/app/views/blame/show.html.haml
+++ b/app/views/blame/show.html.haml
@@ -3,7 +3,7 @@
 #tree-holder.tree-holder
   %ul.breadcrumb
     %li
-      %span.arrow
+      %i.icon-angle-right
       = link_to project_tree_path(@project, @ref) do
         = @project.name
     - @tree.breadcrumbs(6) do |link|
-- 
GitLab


From 0c7f426037db668fbd9ad11376b4db0007baafce Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 22 Mar 2013 18:52:25 +0200
Subject: [PATCH 04/83] fix xss issue in blame

---
 app/views/blame/show.html.haml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/views/blame/show.html.haml b/app/views/blame/show.html.haml
index f85dde6dbbf..b2a45ef5303 100644
--- a/app/views/blame/show.html.haml
+++ b/app/views/blame/show.html.haml
@@ -38,11 +38,11 @@
                   - current_line += 1
                 - else
                   - lines.each do |line|
-                    :preserve
-                      #{current_line}
+                    = current_line
+                    \
                     - current_line += 1
             %td.lines
               %pre
                 - lines.each do |line|
-                  :preserve
-                    #{line}
+                  = line
+                  \
-- 
GitLab


From 017c19bbe4e9098e161b8cc0e866d644e7d3ae95 Mon Sep 17 00:00:00 2001
From: Koen Punt <koen@koenpunt.nl>
Date: Mon, 25 Mar 2013 12:00:57 +0100
Subject: [PATCH 05/83] Fixed type

---
 doc/install/installation.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/install/installation.md b/doc/install/installation.md
index 69d3b186b32..a0ff9a26870 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -1,6 +1,6 @@
 This installation guide was created for Debian/Ubuntu and tested on it. Please read [`doc/install/requirements.md`](./requirements.md) for hardware and platform requirements.
 
-This installation guide is recommended to set up a production server. If you want a development environment please use the [Vargrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) since it makes it much easier to set up all the dependencies for integration testing.
+This installation guide is recommended to set up a production server. If you want a development environment please use the [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) since it makes it much easier to set up all the dependencies for integration testing.
 
 **Important Note:**
 The following steps have been known to work.
-- 
GitLab


From 6a09b21df677e5115f46d3e52ffaf553f4276f85 Mon Sep 17 00:00:00 2001
From: Oluf Lorenzen <fink.github.com@mafia-server.net>
Date: Thu, 28 Mar 2013 18:53:26 +0100
Subject: [PATCH 06/83] switch gitlab-shell to correct version
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

a gitlab:check does say that you need v1.1.0 of gitlab-shell...
---
 doc/install/installation.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/install/installation.md b/doc/install/installation.md
index a0ff9a26870..853a6e78364 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -106,6 +106,11 @@ GitLab Shell is a ssh access and repository management software developed specia
     git clone https://github.com/gitlabhq/gitlab-shell.git
 
     cd gitlab-shell
+    
+    # switch to right version for v5.0
+    git checkout v1.1.0
+    git checkout -b v1.1.0
+    
     cp config.yml.example config.yml
 
     # Edit config and replace gitlab_url
-- 
GitLab


From 34136d381fe733e7465700a043c7a3a27c8c0ec6 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Sat, 30 Mar 2013 13:14:19 +0200
Subject: [PATCH 07/83] Use latest gitlab-grit fork to prevent gollum override
 gitlab-grit. Fixes issues related to gpg signed commits and other fixes from
 gitlab/grit fork

---
 Gemfile      |  3 ++-
 Gemfile.lock | 20 +++++++++++---------
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/Gemfile b/Gemfile
index 7f92cb75d30..494f331ef2a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -22,7 +22,8 @@ gem 'omniauth-twitter'
 gem 'omniauth-github'
 
 # Extracting information from a git repository
-gem "gitlab-grit", '~> 1.0.0', require: 'grit'
+# Since gollum requires grit we cannot use gitlab-grit gem name any more. Use grit instead
+gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: 'c15e2758ec75f99230cd0fbcc9110bf932c0bf05'
 gem 'grit_ext', '~> 0.6.2'
 
 # Ruby/Rack Git Smart-HTTP Server Handler
diff --git a/Gemfile.lock b/Gemfile.lock
index 4de5c893ff8..7b779dbcad9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -23,6 +23,16 @@ GIT
       activerecord (>= 2.3.0)
       rake (>= 0.8.7)
 
+GIT
+  remote: https://github.com/gitlabhq/grit.git
+  revision: c15e2758ec75f99230cd0fbcc9110bf932c0bf05
+  ref: c15e2758ec75f99230cd0fbcc9110bf932c0bf05
+  specs:
+    grit (2.5.0)
+      diff-lcs (~> 1.1)
+      mime-types (~> 1.15)
+      posix-spawn (~> 0.3.6)
+
 GIT
   remote: https://github.com/gitlabhq/raphael-rails.git
   revision: cb2c92a040b9b941a5f1aa1ea866cc26e944fe58
@@ -166,10 +176,6 @@ GEM
     github-markup (0.7.5)
     gitlab-grack (1.0.0)
       rack (~> 1.4.1)
-    gitlab-grit (1.0.0)
-      diff-lcs (~> 1.1)
-      mime-types (~> 1.15)
-      posix-spawn (~> 0.3.6)
     gitlab-pygments.rb (0.3.2)
       posix-spawn (~> 0.3.6)
       yajl-ruby (~> 1.1.0)
@@ -194,10 +200,6 @@ GEM
     grape-entity (0.2.0)
       activesupport
       multi_json (>= 1.3.2)
-    grit (2.5.0)
-      diff-lcs (~> 1.1)
-      mime-types (~> 1.15)
-      posix-spawn (~> 0.3.6)
     grit_ext (0.6.2)
       charlock_holmes (~> 0.6.9)
     growl (1.0.3)
@@ -521,7 +523,6 @@ DEPENDENCIES
   github-linguist (~> 2.3.4)
   github-markup (~> 0.7.4)
   gitlab-grack (~> 1.0.0)
-  gitlab-grit (~> 1.0.0)
   gitlab-pygments.rb (~> 0.3.2)
   gitlab_meta (= 5.0)
   gitlab_omniauth-ldap (= 1.0.2)
@@ -530,6 +531,7 @@ DEPENDENCIES
   gon
   grape (~> 0.3.1)
   grape-entity (~> 0.2.0)
+  grit (~> 2.5.0)!
   grit_ext (~> 0.6.2)
   growl
   guard-rspec
-- 
GitLab


From 8b761574bd629cf5a6ddb0e169fff019d55ad415 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Sat, 30 Mar 2013 16:37:41 +0200
Subject: [PATCH 08/83] fix gollum

---
 Gemfile      | 2 +-
 Gemfile.lock | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Gemfile b/Gemfile
index 494f331ef2a..e1e5bba238f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -23,7 +23,7 @@ gem 'omniauth-github'
 
 # Extracting information from a git repository
 # Since gollum requires grit we cannot use gitlab-grit gem name any more. Use grit instead
-gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: 'c15e2758ec75f99230cd0fbcc9110bf932c0bf05'
+gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: 'c40a32432616a07fa7fc3c32c24ab73ad6a9718f'
 gem 'grit_ext', '~> 0.6.2'
 
 # Ruby/Rack Git Smart-HTTP Server Handler
diff --git a/Gemfile.lock b/Gemfile.lock
index 7b779dbcad9..9614a07c5fa 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -25,8 +25,8 @@ GIT
 
 GIT
   remote: https://github.com/gitlabhq/grit.git
-  revision: c15e2758ec75f99230cd0fbcc9110bf932c0bf05
-  ref: c15e2758ec75f99230cd0fbcc9110bf932c0bf05
+  revision: c40a32432616a07fa7fc3c32c24ab73ad6a9718f
+  ref: c40a32432616a07fa7fc3c32c24ab73ad6a9718f
   specs:
     grit (2.5.0)
       diff-lcs (~> 1.1)
-- 
GitLab


From 7850171af3ea4fb24638169eddbc72cbb8e2ea8a Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 1 Apr 2013 20:55:49 +0200
Subject: [PATCH 09/83] Init public gitlab fork

---
 app/controllers/application_controller.rb | 18 +++++
 app/controllers/keys_controller.rb        |  3 +
 app/controllers/profiles_controller.rb    |  1 +
 app/models/ability.rb                     | 16 ++++-
 app/models/project.rb                     |  4 ++
 app/models/user.rb                        | 13 +++-
 app/views/layouts/_head_panel.html.haml   | 80 +++++++++++++----------
 app/views/projects/_new_form.html.haml    |  6 +-
 app/views/shared/_clone_panel.html.haml   | 11 +++-
 9 files changed, 110 insertions(+), 42 deletions(-)

diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 32b1246601d..79fdfa1d397 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -20,8 +20,26 @@ class ApplicationController < ActionController::Base
     log_exception(exception)
     render "errors/not_found", layout: "errors", status: 404
   end
+ 
+  def current_user
+    super || guest_user
+  end
+
+  def authenticate_user!(*args)
+    current_user.present? || super(*args)
+  end
+
+  def reject_guest!
+    if current_user.is_guest?
+      redirect_to new_user_session_path
+    end
+  end
 
   protected
+  
+  def guest_user
+    User.find_by_username!('guest');
+  end
 
   def log_exception(exception)
     application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
diff --git a/app/controllers/keys_controller.rb b/app/controllers/keys_controller.rb
index 1a25d834e12..5f0504e5f0f 100644
--- a/app/controllers/keys_controller.rb
+++ b/app/controllers/keys_controller.rb
@@ -1,5 +1,8 @@
 class KeysController < ApplicationController
   layout "profile"
+
+  before_filter :reject_guest! 
+
   respond_to :js, :html
 
   def index
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 6fa114a4194..684f0e85485 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -1,6 +1,7 @@
 class ProfilesController < ApplicationController
   include ActionView::Helpers::SanitizeHelper
 
+  before_filter :reject_guest! 
   before_filter :user
   layout 'profile'
 
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 41f7127403c..405b90b2330 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -39,6 +39,9 @@ class Ability
 
       elsif team.guests.include?(user)
         rules << project_guest_rules
+
+      elsif project.is_public?
+        rules << project_anon_and_download_rules
       end
 
       if project.owner == user
@@ -48,7 +51,7 @@ class Ability
       rules.flatten
     end
 
-    def project_guest_rules
+    def project_anon_rules
       [
         :read_project,
         :read_wiki,
@@ -58,6 +61,17 @@ class Ability
         :read_team_member,
         :read_merge_request,
         :read_note,
+      ]
+    end
+
+    def project_anon_and_download_rules
+      project_anon_rules + [
+        :download_code
+      ]
+    end
+
+    def project_guest_rules
+      project_anon_rules + [
         :write_project,
         :write_issue,
         :write_note
diff --git a/app/models/project.rb b/app/models/project.rb
index b13b2918652..1aee6306baa 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -203,6 +203,10 @@ class Project < ActiveRecord::Base
     self.id
   end
 
+  def is_public?
+    self.public
+  end  
+
   def issues_labels
     issues.tag_counts_on(:labels)
   end
diff --git a/app/models/user.rb b/app/models/user.rb
index c73353bf032..3ff57984e67 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -236,6 +236,7 @@ class User < ActiveRecord::Base
   def authorized_projects
     project_ids = users_projects.pluck(:project_id)
     project_ids = project_ids | owned_projects.pluck(:id)
+    project_ids = project_ids | public_projects.pluck(:id) 
     Project.where(id: project_ids)
   end
 
@@ -250,6 +251,10 @@ class User < ActiveRecord::Base
                   (projects.namespace_id IS NULL AND projects.creator_id = :user_id)",
                   namespaces: namespaces.map(&:id), user_id: self.id)
   end
+  
+  def public_projects
+    Project.where("projects.public = true")
+  end
 
   # Team membership in authorized projects
   def tm_in_authorized_projects
@@ -260,12 +265,16 @@ class User < ActiveRecord::Base
     admin
   end
 
+  def is_guest?
+    username == 'guest'
+  end
+
   def require_ssh_key?
-    keys.count == 0
+    !is_guest? && keys.count == 0
   end
 
   def can_change_username?
-    Gitlab.config.gitlab.username_changing_enabled
+    !is_guest? && Gitlab.config.gitlab.username_changing_enabled
   end
 
   def can_create_project?
diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 8f6873e1dfc..f7f6c1ab4a7 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -1,35 +1,45 @@
-%header.navbar.navbar-static-top.navbar-gitlab
-  .navbar-inner
-    .container
-      %div.app_logo
-        %span.separator
-        = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do
-          %h1 GITLAB
-        %span.separator
-      %h1.project_name= title
-      %ul.nav
-        %li
-          = render "layouts/search"
-        %li
-          = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do
-            %i.icon-globe
-        - if current_user.is_admin?
-          %li
-            = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do
-              %i.icon-cogs
-        - if current_user.can_create_project?
-          %li
-            = link_to new_project_path, title: "Create New Project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project'  do
-              %i.icon-plus
-        %li
-          = link_to profile_path, title: "My Profile", class: 'has_bottom_tooltip', 'data-original-title' => 'Your profile'  do
-            %i.icon-user
-        %li
-          = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout'  do
-            %i.icon-signout
-        %li
-          = link_to current_user, class: "profile-pic" do
-            = image_tag gravatar_icon(current_user.email, 26)
-
-
-= render "layouts/init_auto_complete"
+%header.navbar.navbar-static-top.navbar-gitlab
+  .navbar-inner
+    .container
+      %div.app_logo
+        %span.separator
+        = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do
+          %h1 GITLAB
+        %span.separator
+      %h1.project_name= title
+      %ul.nav
+        %li
+          = render "layouts/search"
+        %li
+          = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do
+            %i.icon-globe
+        - unless current_user.is_guest?
+          - if current_user.is_admin?
+            %li
+              = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do
+                %i.icon-cogs
+          - if current_user.can_create_project?
+            %li
+              = link_to new_project_path, title: "Create New Project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project'  do
+                %i.icon-plus
+        %li.separator
+        %li
+          - if current_user.is_guest?
+            = link_to profile_path, title: "Login", class: 'has_bottom_tooltip', 'data-original-title' => 'Login'  do
+              %i.icon-user
+            %li
+              = link_to "#{request.url}/users/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
+                %i.icon-briefcase
+          - else
+            %li
+              = link_to profile_path, title: "My Profile", class: 'has_bottom_tooltip', 'data-original-title' => 'Your profile'  do
+                %i.icon-user
+            %li
+              = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout'  do
+                %i.icon-signout
+            %li
+              = link_to current_user, class: "profile-pic" do
+                = image_tag gravatar_icon(current_user.email, 26)
+
+
+= render "layouts/init_auto_complete"
diff --git a/app/views/projects/_new_form.html.haml b/app/views/projects/_new_form.html.haml
index b6503636890..c93b82c930a 100644
--- a/app/views/projects/_new_form.html.haml
+++ b/app/views/projects/_new_form.html.haml
@@ -31,7 +31,11 @@
         URL must be clonable
 
   %p.padded
-    New projects are private by default. You choose who can see the project and commit to repository.
+    .clearfix
+      = f.label :public do
+        Make this project visible to the public
+      .input
+        = f.check_box :public, { :checked => 'checked' }, true, nil
   %hr
 
   - if current_user.can_create_group?
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index bd9ca729352..d627b3945ea 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -1,4 +1,9 @@
 .input-prepend.project_clone_holder
-  %button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
-  %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
-  = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge", readonly: true
+  - if current_user.can?(:push_code, @project)
+    %button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
+    %button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
+    = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge"
+  - else
+    %button{class: "btn", :"data-clone" => @project.ssh_url_to_repo} SSH
+    %button{class: "btn active", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
+    = text_field_tag :project_clone, @project.http_url_to_repo, class: "one_click_select input-xxlarge"
-- 
GitLab


From a00520afa5599d6b067e3d7d47a8850df0362927 Mon Sep 17 00:00:00 2001
From: GitLab <gitlab@localhost>
Date: Tue, 2 Apr 2013 20:27:54 +0200
Subject: [PATCH 10/83] Public GitLab documentation

---
 README.md | 148 ++++++++++--------------------------------------------
 1 file changed, 26 insertions(+), 122 deletions(-)
 mode change 100644 => 100755 README.md

diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index b04d7eb9e20..ba9abcb55b5
--- a/README.md
+++ b/README.md
@@ -1,141 +1,45 @@
-## GitLab: self hosted Git management software
+# Public GitLab
 
-![logo](https://raw.github.com/gitlabhq/gitlabhq/master/public/gitlab_logo.png)
+## Presentation
 
-### GitLab allows you to
- * keep your code secure on your own server
- * manage repositories, users and access permissions
- * communicate through issues, line-comments and wiki pages
- * perform code review with merge requests
+Public GitLab is a fork of the official GitLab software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects).
 
-### GitLab is
+By public I mean:
 
-* powered by Ruby on Rails
-* completely free and open source (MIT license)
-* used by 10.000 organizations to keep their code secure
+  * Allow anonymous users to browse your repository.
+  * Allow anonymous users to download your code (not only by `git clone`).
+  * Allow anonymous users to register and submit issues.
 
-### Code status
+With these features, GitLab can be a self-hosted Github competitor.
 
-* [![build status](http://ci.gitlab.org/projects/1/status?ref=master)](http://ci.gitlab.org/projects/1?ref=master) ci.gitlab.org (master branch)
+_Disclaimer_: I do not provide any support on GitLab itself. I'm only contribute on the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
 
-* [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) travis-ci.org (master branch)
+You should also be aware that **Public GitLab** only applies to the lastest [`stable`](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/) release branch. `master` branch on this repo have high chance to be broken.
 
-* [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.png)](https://codeclimate.com/github/gitlabhq/gitlabhq)
+## Installation
 
-* [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
+During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part "_6. GitLab - Clone the Source_". 
 
-* [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
+### Clone the Source
 
-### Resources
+    # Clone GitLab repository
+    sudo -u git -H git clone http://git.hoa.ro/arthur/public-gitlab.git gitlab
 
-* GitLab.org community site: [Homepage](http://gitlab.org) [Screenshots](http://gitlab.org/screenshots/) [Blog](http://blog.gitlab.org/) [Demo](http://demo.gitlabhq.com/users/sign_in)
+    # Go to gitlab dir
+    cd /home/git/gitlab
 
-* GitLab.com commercial services: [Homepage](http://blog.gitlab.com/) [GitLab Cloud](http://blog.gitlab.com/cloud/) [Subscription](http://blog.gitlab.com/subscription/) [Consultancy](http://blog.gitlab.com/consultancy/) [Blog](http://blog.gitlab.com/blog/)
+    # Checkout to stable release
+    sudo -u git -H git checkout 5-0-stable
 
-* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server
+### Add guest user
 
-### Requirements
+Connect to your database, and execute the following SQL command:
 
-* Ubuntu/Debian**
-* ruby 1.9.3
-* MySQL
-* git
-* gitlab-shell
-* redis
+    insert into users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
+    values ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
 
-** More details are in the [requirements doc](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/requirements.md)
+### Allow signup 
 
-### Installation
+In the file ~/gitlab/config/gitlab.yml, uncomment:
 
-#### For production
-
-Follow the installation guide for production server.
-
-* [Installation guide for latest stable release (4.2)](https://github.com/gitlabhq/gitlabhq/blob/4-2-stable/doc/install/installation.md) - **Recommended**
-
-* [Installation guide for the current master branch (5.0)](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
-
-
-#### For development
-
-If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working sandboxed and with all dependencies.
-
-* [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm)
-
-### Starting
-
-1. The Installation guide contains instructions to download an init script and run that on boot. With the init script you can also start GitLab
-
-        sudo service gitlab start
-
-  or
-
-        sudo /etc/init.d/gitlab restart
-
-2. Start it with [Foreman](https://github.com/ddollar/foreman) in development mode
-
-        bundle exec foreman start -p 3000
-
- or start it manually
-
-        bundle exec rails s
-        bundle exec rake sidekiq:start
-
-### Running the tests
-
-* Seed the database
-
-        bundle exec rake db:setup RAILS_ENV=test
-        bundle exec rake db:seed_fu RAILS_ENV=test
-
-* Run all tests
-
-        bundle exec rake gitlab:test
-
-* Rspec unit and functional tests
-
-        bundle exec rake spec
-
-* Spinach integration tests
-
-        bundle exec rake spinach
-
-### Getting help
-
-* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide)
-
-* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq)
-
-* [Feedback and suggestions forum](http://gitlab.uservoice.com/forums/176466-general)
-
-* [Support subscription](http://blog.gitlab.com/subscription/)
-
-* [Consultancy](http://blog.gitlab.com/consultancy/)
-
-### New versions and the API
-
-Each month on the 22th a new version is released together with an upgrade guide.
-
-* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/wiki)
-
-* [Roadmap](https://github.com/gitlabhq/gitlabhq/blob/master/ROADMAP.md)
-
-### Other documentation
-
-* [GitLab API](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/README.md)
-
-* [Rake tasks](https://github.com/gitlabhq/gitlabhq/tree/master/doc/raketasks)
-
-* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes)
-
-### Getting in touch
-
-* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md)
-
-* [Core team](https://github.com/gitlabhq?tab=members)
-
-* [Contributors](https://github.com/gitlabhq/gitlabhq/graphs/contributors)
-
-* [Leader](https://github.com/randx)
-
-* [Contact page](http://gitlab.org/contact/)
+    signup_enabled: true
\ No newline at end of file
-- 
GitLab


From bf819790e93a567e232cb9696b31cf67893af311 Mon Sep 17 00:00:00 2001
From: GitLab <gitlab@localhost>
Date: Tue, 2 Apr 2013 20:30:27 +0200
Subject: [PATCH 11/83] Revert "Public GitLab documentation"

This reverts commit a00520afa5599d6b067e3d7d47a8850df0362927.
---
 README.md | 148 ++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 122 insertions(+), 26 deletions(-)
 mode change 100755 => 100644 README.md

diff --git a/README.md b/README.md
old mode 100755
new mode 100644
index ba9abcb55b5..b04d7eb9e20
--- a/README.md
+++ b/README.md
@@ -1,45 +1,141 @@
-# Public GitLab
+## GitLab: self hosted Git management software
 
-## Presentation
+![logo](https://raw.github.com/gitlabhq/gitlabhq/master/public/gitlab_logo.png)
 
-Public GitLab is a fork of the official GitLab software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects).
+### GitLab allows you to
+ * keep your code secure on your own server
+ * manage repositories, users and access permissions
+ * communicate through issues, line-comments and wiki pages
+ * perform code review with merge requests
 
-By public I mean:
+### GitLab is
 
-  * Allow anonymous users to browse your repository.
-  * Allow anonymous users to download your code (not only by `git clone`).
-  * Allow anonymous users to register and submit issues.
+* powered by Ruby on Rails
+* completely free and open source (MIT license)
+* used by 10.000 organizations to keep their code secure
 
-With these features, GitLab can be a self-hosted Github competitor.
+### Code status
 
-_Disclaimer_: I do not provide any support on GitLab itself. I'm only contribute on the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
+* [![build status](http://ci.gitlab.org/projects/1/status?ref=master)](http://ci.gitlab.org/projects/1?ref=master) ci.gitlab.org (master branch)
 
-You should also be aware that **Public GitLab** only applies to the lastest [`stable`](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/) release branch. `master` branch on this repo have high chance to be broken.
+* [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) travis-ci.org (master branch)
 
-## Installation
+* [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.png)](https://codeclimate.com/github/gitlabhq/gitlabhq)
 
-During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part "_6. GitLab - Clone the Source_". 
+* [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
 
-### Clone the Source
+* [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
 
-    # Clone GitLab repository
-    sudo -u git -H git clone http://git.hoa.ro/arthur/public-gitlab.git gitlab
+### Resources
 
-    # Go to gitlab dir
-    cd /home/git/gitlab
+* GitLab.org community site: [Homepage](http://gitlab.org) [Screenshots](http://gitlab.org/screenshots/) [Blog](http://blog.gitlab.org/) [Demo](http://demo.gitlabhq.com/users/sign_in)
 
-    # Checkout to stable release
-    sudo -u git -H git checkout 5-0-stable
+* GitLab.com commercial services: [Homepage](http://blog.gitlab.com/) [GitLab Cloud](http://blog.gitlab.com/cloud/) [Subscription](http://blog.gitlab.com/subscription/) [Consultancy](http://blog.gitlab.com/consultancy/) [Blog](http://blog.gitlab.com/blog/)
 
-### Add guest user
+* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server
 
-Connect to your database, and execute the following SQL command:
+### Requirements
 
-    insert into users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
-    values ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+* Ubuntu/Debian**
+* ruby 1.9.3
+* MySQL
+* git
+* gitlab-shell
+* redis
 
-### Allow signup 
+** More details are in the [requirements doc](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/requirements.md)
 
-In the file ~/gitlab/config/gitlab.yml, uncomment:
+### Installation
 
-    signup_enabled: true
\ No newline at end of file
+#### For production
+
+Follow the installation guide for production server.
+
+* [Installation guide for latest stable release (4.2)](https://github.com/gitlabhq/gitlabhq/blob/4-2-stable/doc/install/installation.md) - **Recommended**
+
+* [Installation guide for the current master branch (5.0)](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
+
+
+#### For development
+
+If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working sandboxed and with all dependencies.
+
+* [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm)
+
+### Starting
+
+1. The Installation guide contains instructions to download an init script and run that on boot. With the init script you can also start GitLab
+
+        sudo service gitlab start
+
+  or
+
+        sudo /etc/init.d/gitlab restart
+
+2. Start it with [Foreman](https://github.com/ddollar/foreman) in development mode
+
+        bundle exec foreman start -p 3000
+
+ or start it manually
+
+        bundle exec rails s
+        bundle exec rake sidekiq:start
+
+### Running the tests
+
+* Seed the database
+
+        bundle exec rake db:setup RAILS_ENV=test
+        bundle exec rake db:seed_fu RAILS_ENV=test
+
+* Run all tests
+
+        bundle exec rake gitlab:test
+
+* Rspec unit and functional tests
+
+        bundle exec rake spec
+
+* Spinach integration tests
+
+        bundle exec rake spinach
+
+### Getting help
+
+* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide)
+
+* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq)
+
+* [Feedback and suggestions forum](http://gitlab.uservoice.com/forums/176466-general)
+
+* [Support subscription](http://blog.gitlab.com/subscription/)
+
+* [Consultancy](http://blog.gitlab.com/consultancy/)
+
+### New versions and the API
+
+Each month on the 22th a new version is released together with an upgrade guide.
+
+* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/wiki)
+
+* [Roadmap](https://github.com/gitlabhq/gitlabhq/blob/master/ROADMAP.md)
+
+### Other documentation
+
+* [GitLab API](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/README.md)
+
+* [Rake tasks](https://github.com/gitlabhq/gitlabhq/tree/master/doc/raketasks)
+
+* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes)
+
+### Getting in touch
+
+* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md)
+
+* [Core team](https://github.com/gitlabhq?tab=members)
+
+* [Contributors](https://github.com/gitlabhq/gitlabhq/graphs/contributors)
+
+* [Leader](https://github.com/randx)
+
+* [Contact page](http://gitlab.org/contact/)
-- 
GitLab


From 4a8f79fcd9a8087edaacddce5133328c694cc16d Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Tue, 2 Apr 2013 20:36:56 +0200
Subject: [PATCH 12/83] Public GitLab documentation

---
 README.md | 148 ++++++++++--------------------------------------------
 1 file changed, 26 insertions(+), 122 deletions(-)

diff --git a/README.md b/README.md
index b04d7eb9e20..ba9abcb55b5 100644
--- a/README.md
+++ b/README.md
@@ -1,141 +1,45 @@
-## GitLab: self hosted Git management software
+# Public GitLab
 
-![logo](https://raw.github.com/gitlabhq/gitlabhq/master/public/gitlab_logo.png)
+## Presentation
 
-### GitLab allows you to
- * keep your code secure on your own server
- * manage repositories, users and access permissions
- * communicate through issues, line-comments and wiki pages
- * perform code review with merge requests
+Public GitLab is a fork of the official GitLab software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects).
 
-### GitLab is
+By public I mean:
 
-* powered by Ruby on Rails
-* completely free and open source (MIT license)
-* used by 10.000 organizations to keep their code secure
+  * Allow anonymous users to browse your repository.
+  * Allow anonymous users to download your code (not only by `git clone`).
+  * Allow anonymous users to register and submit issues.
 
-### Code status
+With these features, GitLab can be a self-hosted Github competitor.
 
-* [![build status](http://ci.gitlab.org/projects/1/status?ref=master)](http://ci.gitlab.org/projects/1?ref=master) ci.gitlab.org (master branch)
+_Disclaimer_: I do not provide any support on GitLab itself. I'm only contribute on the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
 
-* [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) travis-ci.org (master branch)
+You should also be aware that **Public GitLab** only applies to the lastest [`stable`](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/) release branch. `master` branch on this repo have high chance to be broken.
 
-* [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.png)](https://codeclimate.com/github/gitlabhq/gitlabhq)
+## Installation
 
-* [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
+During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part "_6. GitLab - Clone the Source_". 
 
-* [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
+### Clone the Source
 
-### Resources
+    # Clone GitLab repository
+    sudo -u git -H git clone http://git.hoa.ro/arthur/public-gitlab.git gitlab
 
-* GitLab.org community site: [Homepage](http://gitlab.org) [Screenshots](http://gitlab.org/screenshots/) [Blog](http://blog.gitlab.org/) [Demo](http://demo.gitlabhq.com/users/sign_in)
+    # Go to gitlab dir
+    cd /home/git/gitlab
 
-* GitLab.com commercial services: [Homepage](http://blog.gitlab.com/) [GitLab Cloud](http://blog.gitlab.com/cloud/) [Subscription](http://blog.gitlab.com/subscription/) [Consultancy](http://blog.gitlab.com/consultancy/) [Blog](http://blog.gitlab.com/blog/)
+    # Checkout to stable release
+    sudo -u git -H git checkout 5-0-stable
 
-* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server
+### Add guest user
 
-### Requirements
+Connect to your database, and execute the following SQL command:
 
-* Ubuntu/Debian**
-* ruby 1.9.3
-* MySQL
-* git
-* gitlab-shell
-* redis
+    insert into users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
+    values ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
 
-** More details are in the [requirements doc](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/requirements.md)
+### Allow signup 
 
-### Installation
+In the file ~/gitlab/config/gitlab.yml, uncomment:
 
-#### For production
-
-Follow the installation guide for production server.
-
-* [Installation guide for latest stable release (4.2)](https://github.com/gitlabhq/gitlabhq/blob/4-2-stable/doc/install/installation.md) - **Recommended**
-
-* [Installation guide for the current master branch (5.0)](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
-
-
-#### For development
-
-If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working sandboxed and with all dependencies.
-
-* [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm)
-
-### Starting
-
-1. The Installation guide contains instructions to download an init script and run that on boot. With the init script you can also start GitLab
-
-        sudo service gitlab start
-
-  or
-
-        sudo /etc/init.d/gitlab restart
-
-2. Start it with [Foreman](https://github.com/ddollar/foreman) in development mode
-
-        bundle exec foreman start -p 3000
-
- or start it manually
-
-        bundle exec rails s
-        bundle exec rake sidekiq:start
-
-### Running the tests
-
-* Seed the database
-
-        bundle exec rake db:setup RAILS_ENV=test
-        bundle exec rake db:seed_fu RAILS_ENV=test
-
-* Run all tests
-
-        bundle exec rake gitlab:test
-
-* Rspec unit and functional tests
-
-        bundle exec rake spec
-
-* Spinach integration tests
-
-        bundle exec rake spinach
-
-### Getting help
-
-* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide)
-
-* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq)
-
-* [Feedback and suggestions forum](http://gitlab.uservoice.com/forums/176466-general)
-
-* [Support subscription](http://blog.gitlab.com/subscription/)
-
-* [Consultancy](http://blog.gitlab.com/consultancy/)
-
-### New versions and the API
-
-Each month on the 22th a new version is released together with an upgrade guide.
-
-* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/wiki)
-
-* [Roadmap](https://github.com/gitlabhq/gitlabhq/blob/master/ROADMAP.md)
-
-### Other documentation
-
-* [GitLab API](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/README.md)
-
-* [Rake tasks](https://github.com/gitlabhq/gitlabhq/tree/master/doc/raketasks)
-
-* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes)
-
-### Getting in touch
-
-* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md)
-
-* [Core team](https://github.com/gitlabhq?tab=members)
-
-* [Contributors](https://github.com/gitlabhq/gitlabhq/graphs/contributors)
-
-* [Leader](https://github.com/randx)
-
-* [Contact page](http://gitlab.org/contact/)
+    signup_enabled: true
\ No newline at end of file
-- 
GitLab


From 1825ce7e28d073d2b0a0e7b90fe7420aa1e27671 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Wed, 3 Apr 2013 07:32:31 +0200
Subject: [PATCH 13/83] README

---
 README.md | 102 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 57 insertions(+), 45 deletions(-)

diff --git a/README.md b/README.md
index ba9abcb55b5..00f48286d4e 100644
--- a/README.md
+++ b/README.md
@@ -1,45 +1,57 @@
-# Public GitLab
-
-## Presentation
-
-Public GitLab is a fork of the official GitLab software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects).
-
-By public I mean:
-
-  * Allow anonymous users to browse your repository.
-  * Allow anonymous users to download your code (not only by `git clone`).
-  * Allow anonymous users to register and submit issues.
-
-With these features, GitLab can be a self-hosted Github competitor.
-
-_Disclaimer_: I do not provide any support on GitLab itself. I'm only contribute on the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
-
-You should also be aware that **Public GitLab** only applies to the lastest [`stable`](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/) release branch. `master` branch on this repo have high chance to be broken.
-
-## Installation
-
-During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part "_6. GitLab - Clone the Source_". 
-
-### Clone the Source
-
-    # Clone GitLab repository
-    sudo -u git -H git clone http://git.hoa.ro/arthur/public-gitlab.git gitlab
-
-    # Go to gitlab dir
-    cd /home/git/gitlab
-
-    # Checkout to stable release
-    sudo -u git -H git checkout 5-0-stable
-
-### Add guest user
-
-Connect to your database, and execute the following SQL command:
-
-    insert into users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
-    values ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
-
-### Allow signup 
-
-In the file ~/gitlab/config/gitlab.yml, uncomment:
-
-    signup_enabled: true
\ No newline at end of file
+# Public GitLab
+
+## Presentation
+
+Public GitLab is a fork of the official GitLab software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects).
+
+By public I mean:
+
+  * Allow anonymous users to browse your repository.
+  * Allow anonymous users to download your code (not only by `git clone`).
+  * Allow anonymous users to register and submit issues.
+
+With these features, GitLab can be a self-hosted Github competitor.
+
+_Disclaimer_: I do not provide any support on GitLab itself. I'm only contribute on the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
+
+You should also be aware that **Public GitLab** only applies to the lastest [stable](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/) release branch. `master` branch on this repo have high chance to be broken.
+
+## Installation
+
+During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
+
+**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](http://git.hoa.ro/arthur/public-gitlab/repository/archive?ref=5-0-stable).
+
+### Clone the Source
+
+    # Clone GitLab repository
+    sudo -u git -H git clone http://git.hoa.ro/arthur/public-gitlab.git gitlab
+
+    # Go to gitlab dir
+    cd /home/git/gitlab
+
+    # Checkout to stable release
+    sudo -u git -H git checkout 5-0-stable
+
+### Add guest user
+
+Connect to your database, and execute the following SQL command:
+
+    insert into users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
+    values ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+
+### Allow signup (optional)
+
+In the file ~/gitlab/config/gitlab.yml, uncomment:
+
+    signup_enabled: true
+
+Note: Keep in mind that if you do not allow signup, guest wouldn't be able to report issues. 
+
+If you do not want guest users to create projects on your GitLab installation, set `default_projects_limit: 0` in `config/gitlab.yaml`.
+
+## License
+
+Public GitLab is distributed under the [same license](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/LICENSE) as the original sofware.
+
+This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
\ No newline at end of file
-- 
GitLab


From 2f6fb4f51223ebe18430103914d0155d9f5be24c Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Wed, 3 Apr 2013 18:11:57 +0200
Subject: [PATCH 14/83] PostgreSQL script added.

---
 pgl/pgl_script_mysql.sql    |  1 +
 pgl/pgl_script_postgres.sql | 53 +++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100755 pgl/pgl_script_mysql.sql
 create mode 100755 pgl/pgl_script_postgres.sql

diff --git a/pgl/pgl_script_mysql.sql b/pgl/pgl_script_mysql.sql
new file mode 100755
index 00000000000..fa2769589c0
--- /dev/null
+++ b/pgl/pgl_script_mysql.sql
@@ -0,0 +1 @@
+-- NOT SUPPORTED YET
diff --git a/pgl/pgl_script_postgres.sql b/pgl/pgl_script_postgres.sql
new file mode 100755
index 00000000000..4dff5bbca5f
--- /dev/null
+++ b/pgl/pgl_script_postgres.sql
@@ -0,0 +1,53 @@
+INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
+VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+
+INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
+VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)');
+
+CREATE FUNCTION pgl_create_user_team_rs() RETURNS trigger
+LANGUAGE plpgsql
+AS $$
+	DECLARE m_user_team_id integer;
+	DECLARE m_projects_id integer;
+	BEGIN
+		m_user_team_id := 0;
+		SELECT "id" INTO m_user_team_id
+		  	FROM "user_teams" p
+		WHERE p.name = 'pgl_reporters'
+		LIMIT 1;
+
+		FOR m_projects_id IN SELECT project_id FROM user_team_project_relationships WHERE user_team_id = m_user_team_id LOOP
+			INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
+			VALUES (NEW.id, m_projects_id, now(), now(), 20);
+		END LOOP;
+
+		INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());
+		RETURN new;
+	END;
+$$;
+CREATE TRIGGER pgl_new_user AFTER INSERT ON users FOR EACH ROW EXECUTE PROCEDURE pgl_create_user_team_rs();
+
+CREATE FUNCTION pgl_create_project_team_rs() RETURNS trigger
+LANGUAGE plpgsql
+AS $$
+	DECLARE m_user_team_id integer;
+	DECLARE m_users_id integer;
+	BEGIN
+		IF NEW.public = 't' THEN	
+			m_user_team_id := 0;
+			SELECT "id" INTO m_user_team_id
+			  	FROM "user_teams" p
+			WHERE p.name = 'pgl_reporters'
+			LIMIT 1;
+
+			FOR m_users_id IN SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id  LOOP
+				INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
+				VALUES (m_users_id, NEW.id, now(), now(), 20);
+			END LOOP;
+
+			INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());			
+		END IF;
+		RETURN new;
+	END;
+$$;
+CREATE TRIGGER pgl_new_project AFTER INSERT ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_create_project_team_rs();
-- 
GitLab


From 907a8f42a2224dc8ec796717213bf02388c1c364 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 4 Apr 2013 11:10:09 +0300
Subject: [PATCH 15/83] 5.0.1

---
 CHANGELOG | 3 +++
 VERSION   | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG b/CHANGELOG
index 62792fcf5a6..dbe60f4650b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+v 5.0.1
+  - Fixed issue with gitlab-grit being overrided by grit
+
 v 5.0.0
   - Replaced gitolite with gitlab-shell
   - Removed gitolite-related libraries
diff --git a/VERSION b/VERSION
index 0062ac97180..6b244dcd696 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.0.0
+5.0.1
-- 
GitLab


From 093517b79beee2ee86292b33b386f2d6f511df6f Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Fri, 5 Apr 2013 11:54:24 +0200
Subject: [PATCH 16/83] Init MySQL syntax

---
 pgl/pgl_script_mysql.sql | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/pgl/pgl_script_mysql.sql b/pgl/pgl_script_mysql.sql
index fa2769589c0..ffa36d3e0cb 100755
--- a/pgl/pgl_script_mysql.sql
+++ b/pgl/pgl_script_mysql.sql
@@ -1 +1,29 @@
--- NOT SUPPORTED YET
+-- NOT SUPPORTED YET
+
+/* -- MySQL wants something like that
+DROP TRIGGER IF EXISTS pgl_new_user;
+delimiter //
+
+CREATE TRIGGER pgl_new_user 
+AFTER INSERT ON users FOR EACH ROW
+BEGIN
+    DECLARE m_user_team_id integer;
+	SELECT @m_user_team_id:=id FROM user_teams WHERE name = "pgl_reporters";
+	DECLARE m_projects_id integer;
+	DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = m_user_team_id;
+	
+
+	OPEN cur;
+        ins_loop: LOOP
+            FETCH cur INTO m_projects_id;
+            IF done THEN
+                LEAVE ins_loop;
+            END IF;
+            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
+            VALUES (NEW.id, m_projects_id, now(), now(), 20);
+        END LOOP;
+    CLOSE cur;
+
+    INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());
+END//
+DELIMITER ;*/
\ No newline at end of file
-- 
GitLab


From 7f4b4dcaecbb0974eb93568913593cb907d25421 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 6 Apr 2013 05:59:02 +0200
Subject: [PATCH 17/83] Update mysql (still not working)

---
 pgl/pgl_script_mysql.sql | 68 +++++++++++++++++++++++-----------------
 1 file changed, 39 insertions(+), 29 deletions(-)

diff --git a/pgl/pgl_script_mysql.sql b/pgl/pgl_script_mysql.sql
index ffa36d3e0cb..5682a593d9e 100755
--- a/pgl/pgl_script_mysql.sql
+++ b/pgl/pgl_script_mysql.sql
@@ -1,29 +1,39 @@
--- NOT SUPPORTED YET
-
-/* -- MySQL wants something like that
-DROP TRIGGER IF EXISTS pgl_new_user;
-delimiter //
-
-CREATE TRIGGER pgl_new_user 
-AFTER INSERT ON users FOR EACH ROW
-BEGIN
-    DECLARE m_user_team_id integer;
-	SELECT @m_user_team_id:=id FROM user_teams WHERE name = "pgl_reporters";
-	DECLARE m_projects_id integer;
-	DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = m_user_team_id;
-	
-
-	OPEN cur;
-        ins_loop: LOOP
-            FETCH cur INTO m_projects_id;
-            IF done THEN
-                LEAVE ins_loop;
-            END IF;
-            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
-            VALUES (NEW.id, m_projects_id, now(), now(), 20);
-        END LOOP;
-    CLOSE cur;
-
-    INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());
-END//
-DELIMITER ;*/
\ No newline at end of file
+-- NOT SUPPORTED YET
+
+INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
+VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+
+INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
+VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)');
+
+ -- MySQL wants something like that
+DROP TRIGGER IF EXISTS pgl_new_user;
+delimiter //
+
+CREATE TRIGGER pgl_new_user 
+AFTER INSERT ON users FOR EACH ROW
+BEGIN
+    DECLARE m_user_team_id integer;
+    DECLARE done INT DEFAULT FALSE;
+	DECLARE m_projects_id integer;
+    SELECT id INTO m_user_team_id FROM user_teams WHERE name = "pgl_reporters";
+	DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters"); 
+    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+
+    -- SET @m_user_team_id := (SELECT id FROM user_teams WHERE name = "pgl_reporters");
+
+	OPEN cur;
+        ins_loop: LOOP
+            FETCH cur INTO m_projects_id;
+            IF done THEN
+                LEAVE ins_loop;
+            END IF;
+
+            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
+            VALUES (NEW.id, m_projects_id, now(), now(), 20);
+        END LOOP;
+    CLOSE cur;
+
+    INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());
+END//
+DELIMITER ;
\ No newline at end of file
-- 
GitLab


From 93bd688abeb3c81cf6232d702e8f6266797826ac Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 8 Apr 2013 13:27:33 +0300
Subject: [PATCH 18/83] Update pgl_script_mysql.sql

---
 pgl/pgl_script_mysql.sql | 53 ++++++++++++++++++++++++++++++++--------
 1 file changed, 43 insertions(+), 10 deletions(-)

diff --git a/pgl/pgl_script_mysql.sql b/pgl/pgl_script_mysql.sql
index 5682a593d9e..35dfe49f01b 100755
--- a/pgl/pgl_script_mysql.sql
+++ b/pgl/pgl_script_mysql.sql
@@ -1,6 +1,6 @@
 -- NOT SUPPORTED YET
 
-INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
+INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin )
 VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
 
 INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
@@ -10,30 +10,63 @@ VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username =
 DROP TRIGGER IF EXISTS pgl_new_user;
 delimiter //
 
-CREATE TRIGGER pgl_new_user 
+CREATE TRIGGER pgl_new_user
 AFTER INSERT ON users FOR EACH ROW
 BEGIN
-    DECLARE m_user_team_id integer;
-    DECLARE done INT DEFAULT FALSE;
-	DECLARE m_projects_id integer;
+    DECLARE m_user_team_id integer;    
     SELECT id INTO m_user_team_id FROM user_teams WHERE name = "pgl_reporters";
-	DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters"); 
+
+    DECLARE m_projects_id integer;
+    DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = m_user_team_id;
+    
+    DECLARE done INT DEFAULT FALSE;
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
 
     -- SET @m_user_team_id := (SELECT id FROM user_teams WHERE name = "pgl_reporters");
 
-	OPEN cur;
+    OPEN cur;
         ins_loop: LOOP
             FETCH cur INTO m_projects_id;
             IF done THEN
                 LEAVE ins_loop;
             END IF;
 
-            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
+            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access)
             VALUES (NEW.id, m_projects_id, now(), now(), 20);
         END LOOP;
     CLOSE cur;
 
-    INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());
+    INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());
+END//
+DELIMITER ;
+
+DROP TRIGGER IF EXISTS pgl_new_user;
+delimiter //
+
+CREATE TRIGGER pgl_new_project
+AFTER INSERT ON users FOR EACH ROW
+BEGIN
+    DECLARE m_user_team_id integer;    
+    SELECT id INTO m_user_team_id FROM user_teams WHERE name = "pgl_reporters";
+
+    DECLARE m_users_id integer;
+    DECLARE cur CURSOR FOR SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id;
+    
+    DECLARE done INT DEFAULT FALSE;
+    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+
+    OPEN cur;
+        ins_loop: LOOP
+            FETCH cur INTO m_users_id;
+            IF done THEN
+                LEAVE ins_loop;
+            END IF;
+
+            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access)
+            VALUES (m_users_id, NEW.id, now(), now(), 20);
+        END LOOP;
+    CLOSE cur;
+
+    INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());            
 END//
-DELIMITER ;
\ No newline at end of file
+DELIMITER ;
-- 
GitLab


From 0e8cc2400fb36483a66a5e42e33ce0f79d0db2f2 Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Thu, 11 Apr 2013 20:55:52 +0200
Subject: [PATCH 19/83] MySQL is now working

---
 pgl/pgl_script_mysql.sql | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/pgl/pgl_script_mysql.sql b/pgl/pgl_script_mysql.sql
index 35dfe49f01b..061e5dbc234 100755
--- a/pgl/pgl_script_mysql.sql
+++ b/pgl/pgl_script_mysql.sql
@@ -1,28 +1,19 @@
--- NOT SUPPORTED YET
-
 INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin )
 VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
 
 INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
 VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)');
 
- -- MySQL wants something like that
 DROP TRIGGER IF EXISTS pgl_new_user;
 delimiter //
 
 CREATE TRIGGER pgl_new_user
 AFTER INSERT ON users FOR EACH ROW
 BEGIN
-    DECLARE m_user_team_id integer;    
-    SELECT id INTO m_user_team_id FROM user_teams WHERE name = "pgl_reporters";
-
-    DECLARE m_projects_id integer;
-    DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = m_user_team_id;
-    
     DECLARE done INT DEFAULT FALSE;
-    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-
-    -- SET @m_user_team_id := (SELECT id FROM user_teams WHERE name = "pgl_reporters");
+    DECLARE m_projects_id integer;
+    DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters");
+    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 
 
     OPEN cur;
         ins_loop: LOOP
@@ -36,23 +27,22 @@ BEGIN
         END LOOP;
     CLOSE cur;
 
-    INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());
+    INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());
 END//
+
 DELIMITER ;
 
-DROP TRIGGER IF EXISTS pgl_new_user;
+DROP TRIGGER IF EXISTS pgl_new_project;
+
 delimiter //
 
 CREATE TRIGGER pgl_new_project
-AFTER INSERT ON users FOR EACH ROW
+AFTER INSERT ON projects FOR EACH ROW
 BEGIN
-    DECLARE m_user_team_id integer;    
-    SELECT id INTO m_user_team_id FROM user_teams WHERE name = "pgl_reporters";
-
     DECLARE m_users_id integer;
-    DECLARE cur CURSOR FOR SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id;
-    
     DECLARE done INT DEFAULT FALSE;
+
+    DECLARE cur CURSOR FOR SELECT user_id FROM user_team_user_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters");
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
 
     OPEN cur;
@@ -67,6 +57,6 @@ BEGIN
         END LOOP;
     CLOSE cur;
 
-    INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());            
+    INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());            
 END//
 DELIMITER ;
-- 
GitLab


From 05033fa4cee2045d5ea8bf560b81d29992d4652c Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Thu, 11 Apr 2013 21:03:57 +0200
Subject: [PATCH 20/83] Trying to fix signup

---
 app/views/layouts/_head_panel.html.haml | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index f7f6c1ab4a7..9e4663f1ad2 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -27,9 +27,10 @@
           - if current_user.is_guest?
             = link_to profile_path, title: "Login", class: 'has_bottom_tooltip', 'data-original-title' => 'Login'  do
               %i.icon-user
-            %li
-              = link_to "#{request.url}/users/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
-                %i.icon-briefcase
+            - if Gitlab.config.gitlab.signup_enabled?
+              %li
+                = link_to "#{request.host_with_port}/users/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
+                  %i.icon-briefcase
           - else
             %li
               = link_to profile_path, title: "My Profile", class: 'has_bottom_tooltip', 'data-original-title' => 'Your profile'  do
-- 
GitLab


From 6df4a4511b45eb303d0fc331e9d3073c7de06558 Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Thu, 11 Apr 2013 21:07:20 +0200
Subject: [PATCH 21/83] Bug fix on signup

---
 app/views/layouts/_head_panel.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 9e4663f1ad2..54a2b3480c0 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -27,7 +27,7 @@
           - if current_user.is_guest?
             = link_to profile_path, title: "Login", class: 'has_bottom_tooltip', 'data-original-title' => 'Login'  do
               %i.icon-user
-            - if Gitlab.config.gitlab.signup_enabled?
+            - if Gitlab.config.gitlab.signup_enabled
               %li
                 = link_to "#{request.host_with_port}/users/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
                   %i.icon-briefcase
-- 
GitLab


From a234823e11e7025c0d5a2b5d67304e47e7f283b6 Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Thu, 11 Apr 2013 21:11:04 +0200
Subject: [PATCH 22/83] Fixing link

---
 app/views/layouts/_head_panel.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 54a2b3480c0..85124e95868 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -29,7 +29,7 @@
               %i.icon-user
             - if Gitlab.config.gitlab.signup_enabled
               %li
-                = link_to "#{request.host_with_port}/users/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
+                = link_to "#{request.protocol}#{request.host}:#{request.port}/users/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
                   %i.icon-briefcase
           - else
             %li
-- 
GitLab


From 7c367dd8ef72b994fbb4018e92f5cf9a7ba94ba9 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Thu, 11 Apr 2013 22:35:50 +0300
Subject: [PATCH 23/83] Update README.md

---
 README.md | 60 +++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md
index 00f48286d4e..25a782221bb 100644
--- a/README.md
+++ b/README.md
@@ -2,30 +2,32 @@
 
 ## Presentation
 
-Public GitLab is a fork of the official GitLab software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects).
+Public GitLab is a fork of the official [GitLab](https://github.com/gitlabhq/gitlabhq) software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects). With this fork, I'm trying to reproduce Github behavior.
 
-By public I mean:
+So by public I mean:
 
-  * Allow anonymous users to browse your repository.
+  * Allow anonymous users to browse your public repositories.
   * Allow anonymous users to download your code (not only by `git clone`).
-  * Allow anonymous users to register and submit issues.
+  * Allow anonymous users to register and report issues on public projects.
 
 With these features, GitLab can be a self-hosted Github competitor.
 
-_Disclaimer_: I do not provide any support on GitLab itself. I'm only contribute on the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
+You can browse a live example at http://git.hoa.ro (you won't be able to create projects).
 
-You should also be aware that **Public GitLab** only applies to the lastest [stable](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/) release branch. `master` branch on this repo have high chance to be broken.
+_Disclaimer_: I do not provide any support on GitLab itself. I only contribute to the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
+
+You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
 
 ## Installation
 
 During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
 
-**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](http://git.hoa.ro/arthur/public-gitlab/repository/archive?ref=5-0-stable).
+**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-0-stable.zip).
 
 ### Clone the Source
 
     # Clone GitLab repository
-    sudo -u git -H git clone http://git.hoa.ro/arthur/public-gitlab.git gitlab
+    sudo -u git -H git clone https://github.com/ArthurHoaro/Public-GitLab.git gitlab
 
     # Go to gitlab dir
     cd /home/git/gitlab
@@ -33,14 +35,26 @@ During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-
     # Checkout to stable release
     sudo -u git -H git checkout 5-0-stable
 
-### Add guest user
+### Post installation
+At this point, every GitLab components are installed. You still can not access to GitLab yet though.
+
+The SQL script below will create a default `guest` user for anonymous access. It will also create a default team (`pgl_reporters`) which allows `reporter` permission to every new _future_ users, for all public projects.
+
+#### PostgreSQL
+You have to patch GitLab your database with `pgl_script_postgres.sql`:
 
-Connect to your database, and execute the following SQL command:
+    cd /home/git/gitlab/pgl
+    psql -h host -U user database < pgl_script_postgres.sql
 
-    insert into users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
-    values ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+#### MySQL
+You have to patch GitLab your database with `pgl_script_mysql.sql`:
 
-### Allow signup (optional)
+    cd /home/git/gitlab/pgl
+    mysql -hhost -uuser -p
+    use database
+    source pgl_script_mysql.sql
+
+### Allow signup
 
 In the file ~/gitlab/config/gitlab.yml, uncomment:
 
@@ -50,8 +64,24 @@ Note: Keep in mind that if you do not allow signup, guest wouldn't be able to re
 
 If you do not want guest users to create projects on your GitLab installation, set `default_projects_limit: 0` in `config/gitlab.yaml`.
 
+### Restart GitLab
+
+Remember to restart GitLab after all these changes :
+
+    sudo /etc/init.d/gitlab restart
+
+Then enjoy !
+
+## Reporting issues
+
+If you have issues with Public GitLab, you can report them with the [Github issues module](https://github.com/ArthurHoaro/Public-GitLab/issues). 
+
+Please remberer to tell us which database you are using.
+
 ## License
 
-Public GitLab is distributed under the [same license](http://git.hoa.ro/arthur/public-gitlab/tree/5-0-stable/LICENSE) as the original sofware.
+Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
+
+Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-0-stable/LICENSE) as the original sofware.
 
-This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
\ No newline at end of file
+This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
-- 
GitLab


From 5f3862d7c959ab00bcf85d1eba03f246f6c1d180 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Thu, 11 Apr 2013 22:42:30 +0300
Subject: [PATCH 24/83] Update README.md

---
 README.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 25a782221bb..79185d9bacc 100644
--- a/README.md
+++ b/README.md
@@ -78,10 +78,12 @@ If you have issues with Public GitLab, you can report them with the [Github issu
 
 Please remberer to tell us which database you are using.
 
+If there is a new stable branch, please do not open an issue to ask update. [Contact me](http://hoa.ro/static6/contact) instead.
+
 ## License
 
 Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
 
 Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-0-stable/LICENSE) as the original sofware.
 
-This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
+This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
-- 
GitLab


From fbfddb1c1582e79fe2a44737a73cd612c48f0daa Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Fri, 12 Apr 2013 10:57:04 +0300
Subject: [PATCH 25/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 79185d9bacc..4cad72fc02d 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ Then enjoy !
 
 If you have issues with Public GitLab, you can report them with the [Github issues module](https://github.com/ArthurHoaro/Public-GitLab/issues). 
 
-Please remberer to tell us which database you are using.
+Please rememberer to tell us which database you are using.
 
 If there is a new stable branch, please do not open an issue to ask update. [Contact me](http://hoa.ro/static6/contact) instead.
 
-- 
GitLab


From fa26559b42bebed89718533e759693cbd1e15ba6 Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Thu, 25 Apr 2013 21:27:28 +0200
Subject: [PATCH 26/83] 5.1 stable branch upgrade

---
 .gitignore                                    |   1 +
 .rspec                                        |   2 +-
 .travis.yml                                   |   3 +-
 CHANGELOG                                     |  29 ++-
 CONTRIBUTING.md                               |  62 ++---
 Gemfile                                       |  37 +--
 Gemfile.lock                                  | 205 +++++++--------
 Procfile                                      |   2 +-
 README.md                                     | 178 ++++++-------
 ROADMAP.md                                    |   6 +-
 VERSION                                       |   2 +-
 .../behaviors/toggler_behavior.coffee         |   8 +
 app/assets/javascripts/branch-graph.js.coffee | 190 ++++++++------
 app/assets/javascripts/chart.js.coffee        |  21 ++
 .../javascripts/extensions/jquery.js.coffee   |   9 +
 app/assets/javascripts/issues.js              |  80 ------
 app/assets/javascripts/issues.js.coffee       |  70 +++++
 app/assets/javascripts/main.js.coffee         |   2 +
 .../javascripts/merge_requests.js.coffee      |   1 -
 app/assets/javascripts/profile.js.coffee      |   6 +-
 app/assets/javascripts/tree.js.coffee         |   2 +-
 app/assets/javascripts/wall.js.coffee         |  28 +-
 app/assets/stylesheets/application.scss       |   1 +
 app/assets/stylesheets/common.scss            | 161 +-----------
 .../stylesheets/gitlab_bootstrap/avatar.scss  |  28 +-
 .../stylesheets/gitlab_bootstrap/blocks.scss  |   7 +-
 .../stylesheets/gitlab_bootstrap/buttons.scss |   4 +-
 .../stylesheets/gitlab_bootstrap/common.scss  |  19 +-
 .../stylesheets/gitlab_bootstrap/lists.scss   |   9 +
 .../stylesheets/gitlab_bootstrap/nav.scss     |   2 +-
 app/assets/stylesheets/sections/admin.scss    |  18 ++
 app/assets/stylesheets/sections/commits.scss  |  22 +-
 .../stylesheets/sections/dashboard.scss       |  48 ++++
 app/assets/stylesheets/sections/events.scss   |  11 +-
 app/assets/stylesheets/sections/graph.scss    |   2 +-
 app/assets/stylesheets/sections/issues.scss   |  35 ++-
 .../stylesheets/sections/merge_requests.scss  |  40 ++-
 app/assets/stylesheets/sections/nav.scss      | 112 ++++----
 app/assets/stylesheets/sections/notes.scss    |  13 +-
 app/assets/stylesheets/sections/profile.scss  |  13 +
 app/assets/stylesheets/sections/projects.scss |  35 ---
 app/assets/stylesheets/sections/tree.scss     |   2 +-
 app/assets/stylesheets/sections/votes.scss    |   5 -
 app/assets/stylesheets/sections/wall.scss     |  25 +-
 app/assets/stylesheets/selects.scss           |  10 +
 app/contexts/commit_load_context.rb           |   1 -
 app/contexts/notes/create_context.rb          |   2 -
 app/contexts/projects/transfer_context.rb     |  27 ++
 app/contexts/projects/update_context.rb       |  18 +-
 app/contexts/search_context.rb                |   2 +-
 app/controllers/admin/groups_controller.rb    |   2 +-
 app/controllers/admin/projects_controller.rb  |  28 --
 .../admin/teams/members_controller.rb         |   3 +-
 app/controllers/admin/users_controller.rb     |   4 +-
 app/controllers/blame_controller.rb           |   6 +-
 app/controllers/blob_controller.rb            |  13 +-
 app/controllers/commits_controller.rb         |   1 -
 app/controllers/compare_controller.rb         |  12 +-
 app/controllers/dashboard_controller.rb       |   1 +
 app/controllers/edit_tree_controller.rb       |  49 ++++
 app/controllers/groups_controller.rb          |   2 +-
 app/controllers/issues_controller.rb          |  25 +-
 app/controllers/merge_requests_controller.rb  |  13 +-
 app/controllers/milestones_controller.rb      |   4 +-
 app/controllers/notes_controller.rb           |   3 +-
 app/controllers/notifications_controller.rb   |  21 ++
 app/controllers/profiles_controller.rb        |   2 +-
 app/controllers/projects_controller.rb        |  14 +-
 app/controllers/raw_controller.rb             |  25 ++
 app/controllers/refs_controller.rb            |   7 +-
 app/controllers/repositories_controller.rb    |   2 +-
 app/controllers/team_members_controller.rb    |   2 +-
 app/controllers/teams/members_controller.rb   |   3 +-
 app/controllers/tree_controller.rb            |  39 ---
 app/controllers/wikis_controller.rb           |   6 +-
 app/decorators/application_decorator.rb       |  29 ---
 app/decorators/commit_decorator.rb            |  93 -------
 app/decorators/event_decorator.rb             |  44 ----
 app/decorators/tree_decorator.rb              |  33 ---
 app/decorators/user_decorator.rb              |  11 -
 app/helpers/application_helper.rb             |  29 ++-
 app/helpers/commits_helper.rb                 |  74 +++++-
 app/helpers/events_helper.rb                  |  41 +++
 app/helpers/graph_helper.rb                   |  11 +-
 app/helpers/issues_helper.rb                  |  16 +-
 app/helpers/merge_requests_helper.rb          |   2 +-
 app/helpers/notifications_helper.rb           |   2 +
 app/helpers/projects_helper.rb                |   6 +-
 app/helpers/tree_helper.rb                    |  37 ++-
 app/mailers/emails/issues.rb                  |  12 +-
 app/mailers/emails/merge_requests.rb          |  17 +-
 app/mailers/emails/notes.rb                   |   1 -
 app/models/ability.rb                         |   2 +-
 app/models/commit.rb                          | 194 ++++----------
 app/models/event.rb                           |  24 +-
 app/models/gollum_wiki.rb                     |  17 +-
 app/models/group.rb                           |   1 +
 app/models/issue.rb                           |  19 +-
 app/models/key.rb                             |   4 +-
 app/models/merge_request.rb                   |  43 ++--
 app/models/milestone.rb                       |   5 +-
 app/models/namespace.rb                       |  52 ++--
 app/models/network/commit.rb                  |   2 +-
 app/models/network/graph.rb                   |  62 ++---
 app/models/note.rb                            |  21 +-
 app/models/notification.rb                    |  39 +++
 app/models/project.rb                         |  63 ++---
 app/models/protected_branch.rb                |   2 +-
 app/models/repository.rb                      | 174 ++-----------
 app/models/tree.rb                            |  28 +-
 app/models/user.rb                            | 149 +++++------
 app/models/users_project.rb                   |  22 +-
 app/models/wiki.rb                            |  55 ----
 app/models/wiki_page.rb                       |   4 +-
 app/observers/activity_observer.rb            |   2 +-
 app/observers/base_observer.rb                |   9 +
 app/observers/issue_observer.rb               |  26 +-
 app/observers/key_observer.rb                 |   7 +-
 app/observers/merge_request_observer.rb       |  29 +--
 app/observers/note_observer.rb                |  37 +--
 .../project_activity_cache_observer.rb        |   8 +
 app/observers/project_observer.rb             |   8 +-
 app/observers/system_hook_observer.rb         |   2 +-
 app/observers/user_observer.rb                |  11 +-
 app/observers/users_project_observer.rb       |   9 +-
 app/services/git_push_service.rb              |   2 +-
 app/services/notification_service.rb          | 223 ++++++++++++++++
 app/services/project_transfer_service.rb      |  10 +-
 app/views/admin/groups/edit.html.haml         |   2 +-
 app/views/admin/groups/index.html.haml        |   2 +-
 app/views/admin/groups/new.html.haml          |   4 +-
 app/views/admin/groups/show.html.haml         |   4 +-
 app/views/admin/hooks/_data_ex.html.erb       |   8 +-
 app/views/admin/hooks/index.html.haml         |   2 +-
 app/views/admin/projects/_form.html.haml      |  86 -------
 app/views/admin/projects/edit.html.haml       |   3 -
 app/views/admin/projects/index.html.haml      |   8 +-
 app/views/admin/projects/show.html.haml       | 201 ++++++---------
 app/views/admin/projects/team.html.haml       |   0
 app/views/admin/teams/index.html.haml         |   2 +-
 app/views/admin/teams/new.html.haml           |   2 +-
 app/views/admin/users/_form.html.haml         |   3 +-
 app/views/admin/users/index.html.haml         |   3 +-
 app/views/blame/show.html.haml                |  12 +-
 .../_actions.html.haml}                       |  12 +-
 app/views/blob/_blob.html.haml                |  27 ++
 app/views/{tree => }/blob/_download.html.haml |   0
 app/views/{tree => }/blob/_image.html.haml    |   0
 app/views/{tree => }/blob/_text.html.haml     |   0
 app/views/blob/show.html.haml                 |   4 +
 app/views/blob/show.js.haml                   |  10 +
 .../{commits => commit}/_commit_box.html.haml |   4 +-
 app/views/commit/show.html.haml               |  13 +-
 app/views/commits/_commit.html.haml           |   4 +-
 app/views/commits/_commits.html.haml          |   3 +
 app/views/commits/_diffs.html.haml            |  14 +-
 app/views/commits/show.html.haml              |   2 +-
 app/views/compare/show.html.haml              |   2 +-
 app/views/dashboard/_groups.html.haml         |   4 +-
 app/views/dashboard/_projects.html.haml       |   4 +-
 app/views/dashboard/_sidebar.html.haml        |   5 +-
 app/views/dashboard/_teams.html.haml          |   4 +-
 app/views/dashboard/issues.html.haml          |   2 +-
 app/views/dashboard/projects.html.haml        |  15 +-
 app/views/dashboard/show.atom.builder         |   7 +-
 app/views/dashboard/show.html.haml            |   2 +-
 app/views/deploy_keys/index.html.haml         |   2 +-
 app/views/devise/sessions/new.html.haml       |  16 +-
 .../show.html.haml}                           |  12 +-
 app/views/events/_commit.html.haml            |   9 +-
 app/views/events/_event_push.atom.haml        |  10 +-
 app/views/events/event/_common.html.haml      |   8 +-
 app/views/events/event/_push.html.haml        |   4 +-
 app/views/graph/show.json.erb                 |   8 +-
 app/views/groups/issues.html.haml             |   2 +-
 app/views/groups/new.html.haml                |   2 +-
 app/views/groups/show.atom.builder            |   1 -
 app/views/groups/show.html.haml               |   9 +-
 app/views/issues/_issue.html.haml             |  53 ++--
 app/views/issues/_issues.html.haml            |  40 ++-
 app/views/issues/index.html.haml              |  40 +--
 app/views/issues/index.js.haml                |   4 +-
 app/views/issues/show.html.haml               |   3 +
 .../kaminari/admin/_first_page.html.haml      |   9 -
 app/views/kaminari/admin/_gap.html.haml       |   9 -
 app/views/kaminari/admin/_last_page.html.haml |   9 -
 app/views/kaminari/admin/_next_page.html.haml |   9 -
 app/views/kaminari/admin/_page.html.haml      |  10 -
 app/views/kaminari/admin/_paginator.html.haml |  17 --
 app/views/kaminari/admin/_prev_page.html.haml |   9 -
 app/views/kaminari/gitlab/_gap.html.haml      |   5 +-
 .../kaminari/gitlab/_next_page.html.haml      |   2 +-
 app/views/kaminari/gitlab/_page.html.haml     |   4 +-
 .../kaminari/gitlab/_paginator.html.haml      |  17 +-
 .../kaminari/gitlab/_prev_page.html.haml      |   2 +-
 app/views/layouts/admin.html.haml             |  22 +-
 app/views/layouts/application.html.haml       |  23 +-
 app/views/layouts/group.html.haml             |  23 +-
 app/views/layouts/nav/_admin.html.haml        |  19 ++
 app/views/layouts/nav/_dashboard.html.haml    |  20 ++
 app/views/layouts/nav/_group.html.haml        |  20 ++
 app/views/layouts/nav/_profile.html.haml      |  17 ++
 app/views/layouts/nav/_project.html.haml      |  43 ++++
 app/views/layouts/nav/_team.html.haml         |  25 ++
 app/views/layouts/profile.html.haml           |  18 +-
 app/views/layouts/project_resource.html.haml  |  47 +---
 app/views/layouts/user_team.html.haml         |  28 +-
 app/views/merge_requests/_form.html.haml      |   4 +-
 .../merge_requests/_merge_request.html.haml   |  53 ++--
 app/views/merge_requests/index.html.haml      |  12 +-
 .../merge_requests/show/_commits.html.haml    |   6 +-
 .../merge_requests/show/_mr_box.html.haml     |  12 +-
 .../merge_requests/show/_mr_ci.html.haml      |   2 +-
 app/views/milestones/_milestone.html.haml     |  11 +-
 app/views/milestones/index.html.haml          |  28 +-
 app/views/milestones/show.html.haml           |   5 +-
 app/views/milestones/update.js.haml           |   2 +
 app/views/notes/_form.html.haml               |  11 +-
 app/views/notifications/show.html.haml        |  77 ++++++
 app/views/notifications/update.js.haml        |   6 +
 app/views/notify/closed_issue_email.html.haml |   5 +
 app/views/notify/closed_issue_email.text.haml |   3 +
 .../closed_merge_request_email.html.haml      |   9 +
 .../closed_merge_request_email.text.haml      |   8 +
 .../merged_merge_request_email.html.haml      |   9 +
 .../merged_merge_request_email.text.haml      |   8 +
 app/views/notify/new_issue_email.html.haml    |   6 +-
 app/views/notify/new_issue_email.text.erb     |   5 +-
 app/views/notify/new_ssh_key_email.html.haml  |   2 +-
 app/views/notify/new_ssh_key_email.text.erb   |   2 +-
 app/views/profiles/show.html.haml             |  23 +-
 app/views/projects/_clone_panel.html.haml     |   2 +-
 app/views/projects/_form.html.haml            |  18 +-
 app/views/projects/edit.html.haml             |   2 +-
 app/views/projects/new.html.haml              |   2 +-
 app/views/projects/show.html.haml             |   2 +-
 app/views/projects/transfer.js.haml           |   7 +
 app/views/projects/update_failed.js.haml      |   2 -
 app/views/public/projects/index.html.haml     |   2 +-
 app/views/repositories/_branch.html.haml      |   3 +-
 app/views/repositories/_feed.html.haml        |   1 -
 app/views/repositories/stats.html.haml        |  20 +-
 app/views/repositories/tags.html.haml         |  49 ++--
 app/views/shared/_merge_requests.html.haml    |   2 +-
 app/views/shared/_promo.html.haml             |   4 +
 .../team_members/_assigned_team.html.haml     |   2 +-
 app/views/team_members/_team.html.haml        |   7 +-
 app/views/team_members/_team_member.html.haml |   6 +-
 app/views/team_members/index.html.haml        |  10 +-
 app/views/teams/issues.html.haml              |   2 +-
 app/views/teams/members/_show.html.haml       |  37 +--
 app/views/teams/members/new.html.haml         |  48 ++--
 app/views/teams/show.atom.builder             |   1 -
 app/views/teams/show.html.haml                |   9 +-
 app/views/tree/_blob.html.haml                |  13 -
 app/views/tree/_blob_item.html.haml           |   9 +
 app/views/tree/_tree.html.haml                |  60 +++--
 app/views/tree/_tree_commit_column.html.haml  |   2 +-
 app/views/tree/show.js.haml                   |   2 +-
 app/views/votes/_votes_inline.html.haml       |  13 +-
 app/views/walls/show.html.haml                |   7 +-
 app/views/wikis/_nav.html.haml                |   4 +-
 app/views/wikis/_new.html.haml                |  12 +-
 app/views/wikis/git_access.html.haml          |   4 +-
 app/views/wikis/history.html.haml             |   5 +-
 app/views/wikis/pages.html.haml               |   4 +-
 app/views/wikis/show.html.haml                |   3 +-
 app/workers/gitlab_shell_worker.rb            |   2 +-
 app/workers/post_receive.rb                   |   2 +-
 config/application.rb                         |   1 +
 config/database.yml.postgresql                |   2 +-
 config/gitlab.yml.example                     |   8 +
 config/initializers/5_backend.rb              |   3 +
 config/initializers/devise.rb                 |   2 +-
 config/puma.rb.example                        | 114 ++++++++
 config/routes.rb                              |  20 +-
 config/unicorn.rb.example                     |  68 -----
 db/fixtures/development/02_source_code.rb     |   4 +-
 db/fixtures/development/06_teams.rb           |  30 +--
 db/fixtures/development/09_issues.rb          |   2 +
 db/fixtures/development/10_merge_requests.rb  |  21 +-
 db/fixtures/development/11_keys.rb            |   1 +
 ...25173941_add_notification_level_to_user.rb |   5 +
 ...0_add_last_activity_column_into_project.rb |  21 ++
 ..._add_notification_level_to_user_project.rb |   5 +
 .../20130410175022_remove_wiki_table.rb       |   9 +
 db/schema.rb                                  |  91 +++----
 doc/api/users.md                              |   1 +
 doc/install/databases.md                      |   6 +-
 doc/install/installation.md                   |  67 +++--
 doc/install/requirements.md                   |  31 ++-
 doc/raketasks/maintenance.md                  |  82 +++---
 doc/raketasks/user_management.md              |   2 +-
 doc/update/5.0-to-5.1.md                      |  51 ++++
 features/admin/users.feature                  |   8 +
 features/dashboard/search.feature             |   5 -
 .../commits/commit_diff_comments.feature      |   7 -
 features/project/team_management.feature      |   1 -
 features/steps/admin/admin_projects.rb        |   2 -
 features/steps/admin/admin_users.rb           |  23 ++
 .../dashboard/dashboard_event_filters.rb      |  10 +-
 features/steps/dashboard/dashboard_search.rb  |  11 -
 .../steps/project/project_browse_commits.rb   |   4 +-
 .../steps/project/project_merge_requests.rb   |  22 +-
 .../steps/project/project_team_management.rb  |  28 +-
 features/steps/shared/active_tab.rb           |   6 +-
 features/steps/shared/diff_note.rb            |  20 +-
 features/steps/shared/note.rb                 |   4 +-
 features/steps/shared/paths.rb                |   2 +-
 features/steps/shared/project.rb              |   4 +-
 features/steps/userteams/userteams.rb         |   4 +-
 features/support/env.rb                       |  19 +-
 lib/api/internal.rb                           |   3 +-
 lib/api/merge_requests.rb                     |   2 +
 lib/api/projects.rb                           |  14 +-
 lib/api/users.rb                              |   1 +
 lib/backup/database.rb                        |  58 +++++
 lib/backup/repository.rb                      | 105 ++++++++
 lib/backup/uploads.rb                         |  25 ++
 lib/extracts_path.rb                          |  37 +--
 lib/gitlab/backend/shell.rb                   |  59 +++++
 lib/gitlab/backend/shell_adapter.rb           |  12 +
 lib/gitlab/git/blame.rb                       |  23 ++
 lib/gitlab/git/blob.rb                        |  42 +++
 lib/gitlab/git/commit.rb                      | 127 +++++++++
 lib/gitlab/git/compare.rb                     |  35 +++
 lib/gitlab/git/diff.rb                        |  63 +++++
 lib/gitlab/git/repository.rb                  | 212 +++++++++++++++
 lib/gitlab/git/stats.rb                       |  75 ++++++
 lib/gitlab/git/tree.rb                        |  52 ++++
 lib/gitlab/git_stats.rb                       |  73 ------
 lib/gitlab/markdown.rb                        |   2 +-
 lib/gitlab/user_team_manager.rb               |   2 +-
 lib/gitolited.rb                              |  11 -
 lib/tasks/cache.rake                          |   6 +
 lib/tasks/gitlab/backup.rake                  | 117 +++------
 lib/tasks/gitlab/check.rake                   |  24 +-
 lib/tasks/gitlab/migrate_wiki.rake            |  42 ---
 lib/tasks/gitlab/task_helpers.rake            |   5 +-
 lib/tasks/migrate/migrate_milestones.rake     |   4 +
 lib/tasks/migrate/migrate_mr.rake             |  18 ++
 lib/wiki_to_gollum_migrator.rb                | 124 ---------
 spec/controllers/blob_controller_spec.rb      |  37 +++
 spec/controllers/commit_controller_spec.rb    |   2 +-
 spec/controllers/commits_controller_spec.rb   |   2 +-
 .../merge_requests_controller_spec.rb         |   8 +-
 spec/controllers/tree_controller_spec.rb      |   8 +-
 spec/factories.rb                             |  22 +-
 spec/features/admin/admin_hooks_spec.rb       |   2 +-
 spec/features/admin/admin_projects_spec.rb    |  42 ---
 spec/features/admin/admin_users_spec.rb       |  12 +-
 .../features/gitlab_flavored_markdown_spec.rb |  77 +-----
 spec/features/notes_on_merge_requests_spec.rb | 199 +++++++-------
 spec/features/profile_spec.rb                 |   6 +-
 spec/features/projects_spec.rb                |   1 +
 spec/features/security/project_access_spec.rb |  36 +--
 spec/helpers/gitlab_markdown_helper_spec.rb   |   4 +-
 spec/helpers/issues_helper_spec.rb            |  27 ++
 spec/helpers/notifications_helper_spec.rb     |  15 ++
 spec/lib/extracts_path_spec.rb                |  42 ---
 spec/lib/{ => gitlab/backend}/shell_spec.rb   |   0
 spec/lib/gitlab/git/commit_spec.rb            |  40 +++
 spec/lib/gitlab/git/diff_spec.rb              |  34 +++
 .../gitlab/git}/repository_spec.rb            |  36 ++-
 spec/lib/gitlab/git/stats_spec.rb             |  28 ++
 spec/lib/{ => gitlab}/popen_spec.rb           |   0
 spec/lib/votes_spec.rb                        | 116 +++++----
 spec/lib/wiki_to_gollum_migrator_spec.rb      | 219 ----------------
 spec/mailers/notify_spec.rb                   |  17 +-
 spec/models/commit_spec.rb                    |  90 ++-----
 spec/models/event_spec.rb                     |   1 +
 spec/models/gollum_wiki_spec.rb               |   2 +-
 spec/models/namespace_spec.rb                 |   2 +-
 spec/models/project_spec.rb                   |  27 +-
 spec/models/user_spec.rb                      |   9 +-
 spec/models/user_team_spec.rb                 |  21 +-
 spec/models/users_project_spec.rb             |  13 +-
 spec/models/wiki_spec.rb                      |  35 ---
 spec/observers/issue_observer_spec.rb         | 129 ++--------
 spec/observers/merge_request_observer_spec.rb |  71 +----
 spec/observers/note_observer_spec.rb          | 110 +-------
 spec/observers/user_observer_spec.rb          |   9 +-
 spec/observers/users_project_observer_spec.rb |   7 +-
 spec/requests/api/merge_requests_spec.rb      |   2 +-
 spec/requests/api/milestones_spec.rb          |   1 +
 spec/requests/api/projects_spec.rb            |   3 +-
 spec/routing/admin_routing_spec.rb            |  20 --
 spec/routing/notifications_routing_spec.rb    |  13 +
 spec/routing/project_routing_spec.rb          |   9 +-
 spec/services/git_push_service_spec.rb        |   2 +-
 spec/services/notification_service_spec.rb    | 243 ++++++++++++++++++
 .../services/project_transfer_service_spec.rb |   2 +
 spec/spec_helper.rb                           |  98 ++++---
 spec/support/login_helpers.rb                 |   2 +-
 spec/support/matchers.rb                      |   2 +-
 spec/support/stubbed_repository.rb            |  75 ------
 spec/support/test_env.rb                      |  91 +++++++
 spec/workers/post_receive_spec.rb             |   2 +-
 398 files changed, 5130 insertions(+), 4718 deletions(-)
 create mode 100644 app/assets/javascripts/chart.js.coffee
 create mode 100644 app/assets/javascripts/extensions/jquery.js.coffee
 delete mode 100644 app/assets/javascripts/issues.js
 create mode 100644 app/assets/javascripts/issues.js.coffee
 create mode 100644 app/assets/stylesheets/sections/dashboard.scss
 create mode 100644 app/contexts/projects/transfer_context.rb
 create mode 100644 app/controllers/edit_tree_controller.rb
 create mode 100644 app/controllers/notifications_controller.rb
 create mode 100644 app/controllers/raw_controller.rb
 delete mode 100644 app/decorators/application_decorator.rb
 delete mode 100644 app/decorators/commit_decorator.rb
 delete mode 100644 app/decorators/event_decorator.rb
 delete mode 100644 app/decorators/tree_decorator.rb
 delete mode 100644 app/decorators/user_decorator.rb
 create mode 100644 app/helpers/notifications_helper.rb
 create mode 100644 app/models/notification.rb
 delete mode 100644 app/models/wiki.rb
 create mode 100644 app/observers/base_observer.rb
 create mode 100644 app/observers/project_activity_cache_observer.rb
 create mode 100644 app/services/notification_service.rb
 delete mode 100644 app/views/admin/projects/_form.html.haml
 delete mode 100644 app/views/admin/projects/edit.html.haml
 delete mode 100644 app/views/admin/projects/team.html.haml
 rename app/views/{tree/_blob_actions.html.haml => blob/_actions.html.haml} (57%)
 create mode 100644 app/views/blob/_blob.html.haml
 rename app/views/{tree => }/blob/_download.html.haml (100%)
 rename app/views/{tree => }/blob/_image.html.haml (100%)
 rename app/views/{tree => }/blob/_text.html.haml (100%)
 create mode 100644 app/views/blob/show.html.haml
 create mode 100644 app/views/blob/show.js.haml
 rename app/views/{commits => commit}/_commit_box.html.haml (93%)
 rename app/views/{tree/edit.html.haml => edit_tree/show.html.haml} (80%)
 delete mode 100644 app/views/kaminari/admin/_first_page.html.haml
 delete mode 100644 app/views/kaminari/admin/_gap.html.haml
 delete mode 100644 app/views/kaminari/admin/_last_page.html.haml
 delete mode 100644 app/views/kaminari/admin/_next_page.html.haml
 delete mode 100644 app/views/kaminari/admin/_page.html.haml
 delete mode 100644 app/views/kaminari/admin/_paginator.html.haml
 delete mode 100644 app/views/kaminari/admin/_prev_page.html.haml
 create mode 100644 app/views/layouts/nav/_admin.html.haml
 create mode 100644 app/views/layouts/nav/_dashboard.html.haml
 create mode 100644 app/views/layouts/nav/_group.html.haml
 create mode 100644 app/views/layouts/nav/_profile.html.haml
 create mode 100644 app/views/layouts/nav/_project.html.haml
 create mode 100644 app/views/layouts/nav/_team.html.haml
 create mode 100644 app/views/milestones/update.js.haml
 create mode 100644 app/views/notifications/show.html.haml
 create mode 100644 app/views/notifications/update.js.haml
 create mode 100644 app/views/notify/closed_issue_email.html.haml
 create mode 100644 app/views/notify/closed_issue_email.text.haml
 create mode 100644 app/views/notify/closed_merge_request_email.html.haml
 create mode 100644 app/views/notify/closed_merge_request_email.text.haml
 create mode 100644 app/views/notify/merged_merge_request_email.html.haml
 create mode 100644 app/views/notify/merged_merge_request_email.text.haml
 create mode 100644 app/views/projects/transfer.js.haml
 delete mode 100644 app/views/projects/update_failed.js.haml
 create mode 100644 app/views/shared/_promo.html.haml
 delete mode 100644 app/views/tree/_blob.html.haml
 create mode 100644 app/views/tree/_blob_item.html.haml
 create mode 100644 config/puma.rb.example
 delete mode 100644 config/unicorn.rb.example
 create mode 100644 db/migrate/20130325173941_add_notification_level_to_user.rb
 create mode 100644 db/migrate/20130403003950_add_last_activity_column_into_project.rb
 create mode 100644 db/migrate/20130404164628_add_notification_level_to_user_project.rb
 create mode 100644 db/migrate/20130410175022_remove_wiki_table.rb
 create mode 100644 doc/update/5.0-to-5.1.md
 create mode 100644 lib/backup/database.rb
 create mode 100644 lib/backup/repository.rb
 create mode 100644 lib/backup/uploads.rb
 create mode 100644 lib/gitlab/backend/shell_adapter.rb
 create mode 100644 lib/gitlab/git/blame.rb
 create mode 100644 lib/gitlab/git/blob.rb
 create mode 100644 lib/gitlab/git/commit.rb
 create mode 100644 lib/gitlab/git/compare.rb
 create mode 100644 lib/gitlab/git/diff.rb
 create mode 100644 lib/gitlab/git/repository.rb
 create mode 100644 lib/gitlab/git/stats.rb
 create mode 100644 lib/gitlab/git/tree.rb
 delete mode 100644 lib/gitlab/git_stats.rb
 delete mode 100644 lib/gitolited.rb
 create mode 100644 lib/tasks/cache.rake
 delete mode 100644 lib/tasks/gitlab/migrate_wiki.rake
 create mode 100644 lib/tasks/migrate/migrate_milestones.rake
 create mode 100644 lib/tasks/migrate/migrate_mr.rake
 delete mode 100644 lib/wiki_to_gollum_migrator.rb
 create mode 100644 spec/controllers/blob_controller_spec.rb
 create mode 100644 spec/helpers/notifications_helper_spec.rb
 rename spec/lib/{ => gitlab/backend}/shell_spec.rb (100%)
 create mode 100644 spec/lib/gitlab/git/commit_spec.rb
 create mode 100644 spec/lib/gitlab/git/diff_spec.rb
 rename spec/{models => lib/gitlab/git}/repository_spec.rb (78%)
 create mode 100644 spec/lib/gitlab/git/stats_spec.rb
 rename spec/lib/{ => gitlab}/popen_spec.rb (100%)
 delete mode 100644 spec/lib/wiki_to_gollum_migrator_spec.rb
 delete mode 100644 spec/models/wiki_spec.rb
 create mode 100644 spec/routing/notifications_routing_spec.rb
 create mode 100644 spec/services/notification_service_spec.rb
 delete mode 100644 spec/support/stubbed_repository.rb
 create mode 100644 spec/support/test_env.rb

diff --git a/.gitignore b/.gitignore
index 7e621d260fc..2a7e605a350 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ config/gitlab.yml
 config/database.yml
 config/initializers/omniauth.rb
 config/unicorn.rb
+config/puma.rb
 config/resque.yml
 config/aws.yml
 db/data.yml
diff --git a/.rspec b/.rspec
index 53607ea52b7..5902dd3af1f 100644
--- a/.rspec
+++ b/.rspec
@@ -1 +1 @@
---colour
+--colour --drb
diff --git a/.travis.yml b/.travis.yml
index befa0c32806..d7fbbc7bbcb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,8 @@ branches:
   only:
     - 'master'
 rvm:
-  - 1.9.3-p327
+  - 1.9.3-p392
+  - 2.0.0
 services:
   - mysql
   - postgresql
diff --git a/CHANGELOG b/CHANGELOG
index dbe60f4650b..e6cc2749cdf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,24 @@
+v 5.1.0
+  - You can login with email or username now
+  - Corrected project transfer rollback when repository cannot be moved
+  - Move both repo and wiki when project transfer requrested
+  - Admin area: project editing was removed from admin namespace
+  - Access: admin user has now access to any project.
+  - Notification settings
+  - Gitlab::Git set of objects to abstract from grit library
+  - Replace Unicorn web server with Puma
+  - Backup/Restore refactored. Backup dump project wiki too now
+  - Restyled Issues list. Show milestone version in issue row
+  - Restyled Merge Request list
+  - Backup now dump/restore uploads
+  - Improved perfomance of dashboard (Andrew Kumanyaev)
+  - File history now tracks renames (Akzhan Abdulin)
+  - Drop wiki migration tools
+  - Drop sqlite migration tools
+  - project tagging
+  - Paginate users in API
+  - Restyled network graph (Hiroyuki Sato)
+
 v 5.0.1
   - Fixed issue with gitlab-grit being overrided by grit
 
@@ -17,7 +38,7 @@ v 5.0.0
   - Add validations for Group and Team names
   - Restyle team page for project
   - Update capybara, rspec-rails, poltergeist to recent versions
-  - Wiki on git using Gollum 
+  - Wiki on git using Gollum
   - Added Solarized Dark theme for code review
   - Dont show user emails in autocomplete lists, profile pages
   - Added settings tab for group, team, project
@@ -27,7 +48,7 @@ v 5.0.0
   - Fixed search field on projects page
   - Added teams to search autocomplete
   - Move groups and teams on dashboard sidebar to sub-tabs
-  - API: improved return codes and docs.
+  - API: improved return codes and docs. (Felix Gilcher, Sebastian Ziebell)
   - Redesign wall to be more like chat
   - Snippets, Wall features are disabled by default for new projects
 
@@ -59,7 +80,7 @@ v 4.1.0
   - cleanup rake tasks
   - fix backup/restore
   - scss cleanup
-  - show preview for note images 
+  - show preview for note images
   - improved network-graph
   - get rid of app/roles/
   - added new classes Team, Repository
@@ -73,7 +94,7 @@ v 4.1.0
 v 4.0.0
   - Remove project code and path from API. Use id instead
   - Return valid clonable url to repo for web hook
-  - Fixed backup issue 
+  - Fixed backup issue
   - Reorganized settings
   - Fixed commits compare
   - Refactored scss
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d3ccbee97cf..79e57558084 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,35 +1,39 @@
 # Contribute to GitLab
 
-If you have a question or want to contribute to GitLab this guide show you the appropriate channel to use.
+This guide details how to use issues and pull requests to improve GitLab.
 
-## Ruling out common errors
+## Closing policy for issues and pull requests
 
-Some errors are common and it may so happen, that you are not the only one who stumbled over a particular issue. We have [collected several of those and documented quick solutions](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) for them.
+Issues and pull requests not in line with the guidelines listed in this document will be closed with just a link to this paragraph. GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. To get support for your problems please use other channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
 
-## Support forum
+## Issue tracker
 
-Please visit our [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) for any kind of question regarding the usage or adiministration/configuration of GitLab.
+The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the master branch of GitLab. When submitting an issue please conform to the issue submission guidelines listed below.
 
-### Use the support forum if ...
+Do not use the issue tracker for feature requests. We have a specific
+[Feedback and suggestions forum](http://feedback.gitlab.com) for this purpose.
 
-* You get permission denied errors
-* You can't see your repos
-* You have issues cloning, pulling or pushing
-* You have issues with web_hooks not firing
+Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there.
 
-**Search** for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and had it resolved.
+### Issue tracker guidelines
 
-## Paid support
+**Search** for similar entries before submitting your own, there's a good chance somebody else had the same issue or idea. Show your support with `:+1:` and/or join the discussion.
 
-Community support in the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) is done by volunteers. A support subscription is available from [GitLab.com](http://blog.gitlab.com/subscription/)
+* Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
+* Describe your issue in detail
+* How can we reproduce the issue on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: vagrant destroy && vagrant up && vagrant ssh)
+* Add the last commit sha1 of the GitLab version you used to replicate the issue
+* Add logs or screen shots when possible
+* Link to the line of code that might be responsible for the problem
+* Describe your setup (use relevant parts from `sudo -u gitlab -H bundle exec rake gitlab:env:info`)
 
-## Feature suggestions
+## Pull requests
 
-Feature suggestions don't belong in issues but can go to [Feedback forum](http://gitlab.uservoice.com/forums/176466-general) where they can be voted on.
+We welcome pull request with improvements to GitLab code and/or documentation. The issues we would really like a pull request for are listed with the [status 'accepting merge/pull requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome.
 
-## Pull requests
+### Pull request guidelines
 
-Code speaks louder than words. If you can please submit a pull request with the fix including tests. The workflow to make a pull request is as follows:
+ If you can please submit a pull request with the fix including tests. The workflow to make a pull request is as follows:
 
 1. Fork the project on GitHub
 1. Create a feature branch
@@ -50,27 +54,3 @@ We will accept pull requests if:
 * If it makes changes to the UI the pull request should include screenshots
 
 For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
-
-## Submitting via GitHub's issue tracker
-
-* For obvious bugs or misbehavior in GitLab in the master branch. Please include the revision id and a reproducible test case.
-* For problematic or insufficient documentation. Please give a suggestion on how to improve it.
-
-If you're unsure where to post, post it to the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) first.
-There are a lot of helpful GitLab users there who may be able to help you quickly.
-If your particular issue turns out to be a bug, it will find its way from there to the [issue tracker on GitHub](https://github.com/gitlabhq/gitlabhq/issues).
-
-### When submitting an issue
-
-**Search** for similar entries before submitting your own, there's a good chance somebody else had the same issue or idea. Show your support with `:+1:` and/or join the discussion.
-
-Please consider the following points when submitting an **issue**:
-
-* Summarize your issue in one sentence (what happened wrong, when you did/expected something else)
-* Describe your issue in detail (including steps to reproduce)
-* Add logs or screen shots when possible
-* Describe your setup (use relevant parts from `sudo -u gitlab -H bundle exec rake gitlab:env:info`)
-
-## Thank you!
-
-By taking the time to use the right channel, you help the development team to organize and prioritize issues and suggestions in order to make GitLab a better product for us all.
diff --git a/Gemfile b/Gemfile
index e1e5bba238f..71ac795772a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -23,8 +23,8 @@ gem 'omniauth-github'
 
 # Extracting information from a git repository
 # Since gollum requires grit we cannot use gitlab-grit gem name any more. Use grit instead
-gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: 'c40a32432616a07fa7fc3c32c24ab73ad6a9718f'
-gem 'grit_ext', '~> 0.6.2'
+gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: '42297cdcee16284d2e4eff23d41377f52fc28b9d'
+gem 'grit_ext', '~> 0.8.1'
 
 # Ruby/Rack Git Smart-HTTP Server Handler
 gem 'gitlab-grack', '~> 1.0.0', require: 'grack'
@@ -32,9 +32,6 @@ gem 'gitlab-grack', '~> 1.0.0', require: 'grack'
 # LDAP Auth
 gem 'gitlab_omniauth-ldap', '1.0.2', require: "omniauth-ldap"
 
-# Dump db to yml file. Mostly used to migrate from sqlite to mysql
-gem 'gitlab_yaml_db', '1.0.0', require: "yaml_db"
-
 # Syntax highlighter
 gem "gitlab-pygments.rb", '~> 0.3.2', require: 'pygments.rb'
 
@@ -64,9 +61,6 @@ gem "carrierwave"
 # Authorization
 gem "six"
 
-# Generate Fake data
-gem "ffaker"
-
 # Seed data
 gem "seed-fu"
 
@@ -75,7 +69,7 @@ gem "redcarpet",     "~> 2.2.2"
 gem "github-markup", "~> 0.7.4", require: 'github/markup'
 
 # Servers
-gem "unicorn"
+gem "puma", '~> 2.0.0.b7'
 
 # State machine
 gem "state_machine"
@@ -83,9 +77,6 @@ gem "state_machine"
 # Issue tags
 gem "acts-as-taggable-on", "2.3.3"
 
-# Decorators
-gem "draper"
-
 # Background jobs
 gem 'slim'
 gem 'sinatra', require: nil
@@ -100,16 +91,11 @@ gem "colored"
 # GitLab settings
 gem 'settingslogic'
 
-# Wiki
-# - Use latest master to resolve Gem dependency with Pygemnts
-# github-linquist needs pygments 0.4.2 but Gollum 2.4.11
-# requires pygments 0.3.2. The latest master Gollum has been updated
-# to use pygments 0.4.2. Change this after next Gollum release.
-gem "gollum", "~> 2.4.0", git: "git://github.com/gollum/gollum.git", ref: "5dcd3c8c8f"
+# Git Wiki
+gem "gollum-lib", "~> 1.0.0"
 
 # Misc
 gem "foreman"
-gem "git"
 
 # Cache
 gem "redis-rails"
@@ -154,15 +140,18 @@ end
 group :development, :test do
   gem 'coveralls', require: false
   gem 'rails-dev-tweaks'
-  gem 'spinach-rails', '0.2.0'
-  gem "rspec-rails", '2.12.2'
-  gem "capybara", '2.0.2'
+  gem 'spinach-rails'
+  gem "rspec-rails"
+  gem "capybara"
   gem "pry"
   gem "awesome_print"
   gem "database_cleaner"
   gem "launchy"
   gem 'factory_girl_rails'
 
+  # Generate Fake data
+  gem "ffaker"
+
   # Guard
   gem 'guard-rspec'
   gem 'guard-spinach'
@@ -173,7 +162,9 @@ group :development, :test do
   gem 'rb-inotify', require: linux_only('rb-inotify')
 
   # PhantomJS driver for Capybara
-  gem 'poltergeist', '1.1.0'
+  gem 'poltergeist', git: 'https://github.com/jonleighton/poltergeist.git', ref: '9645b52009e258921b860d3b7601d00008b22c45'
+
+  gem 'spork', '~> 1.0rc'
 end
 
 group :test do
diff --git a/Gemfile.lock b/Gemfile.lock
index 9614a07c5fa..c8d75f9dc89 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,20 +1,3 @@
-GIT
-  remote: git://github.com/gollum/gollum.git
-  revision: 5dcd3c8c8f68158e43ff79861279088ee56d0ebe
-  ref: 5dcd3c8c8f
-  specs:
-    gollum (2.4.11)
-      github-markdown (~> 0.5.3)
-      github-markup (>= 0.7.5, < 1.0.0)
-      grit (~> 2.5.0)
-      mustache (>= 0.99.4, < 1.0.0)
-      nokogiri (~> 1.5.6)
-      pygments.rb (~> 0.4.2)
-      sanitize (~> 2.0.3)
-      sinatra (~> 1.3.5)
-      stringex (~> 1.5.1)
-      useragent (~> 0.4.16)
-
 GIT
   remote: https://github.com/ctran/annotate_models.git
   revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
@@ -25,8 +8,8 @@ GIT
 
 GIT
   remote: https://github.com/gitlabhq/grit.git
-  revision: c40a32432616a07fa7fc3c32c24ab73ad6a9718f
-  ref: c40a32432616a07fa7fc3c32c24ab73ad6a9718f
+  revision: 42297cdcee16284d2e4eff23d41377f52fc28b9d
+  ref: 42297cdcee16284d2e4eff23d41377f52fc28b9d
   specs:
     grit (2.5.0)
       diff-lcs (~> 1.1)
@@ -39,6 +22,16 @@ GIT
   specs:
     raphael-rails (2.1.0)
 
+GIT
+  remote: https://github.com/jonleighton/poltergeist.git
+  revision: 9645b52009e258921b860d3b7601d00008b22c45
+  ref: 9645b52009e258921b860d3b7601d00008b22c45
+  specs:
+    poltergeist (1.1.0)
+      capybara (~> 2.0, >= 2.0.1)
+      faye-websocket (~> 0.4, >= 0.4.4)
+      http_parser.rb (~> 0.5.3)
+
 GEM
   remote: https://rubygems.org/
   specs:
@@ -84,13 +77,12 @@ GEM
     bootstrap-sass (2.2.1.1)
       sass (~> 3.2)
     builder (3.0.4)
-    capybara (2.0.2)
+    capybara (2.1.0)
       mime-types (>= 1.16)
       nokogiri (>= 1.3.3)
       rack (>= 1.0.0)
       rack-test (>= 0.5.4)
-      selenium-webdriver (~> 2.0)
-      xpath (~> 1.0.0)
+      xpath (~> 2.0)
     carrierwave (0.8.0)
       activemodel (>= 3.2.0)
       activesupport (>= 3.2.0)
@@ -98,14 +90,12 @@ GEM
       facter (>= 1.6.12)
       timers (>= 1.0.0)
     charlock_holmes (0.6.9)
-    childprocess (0.3.8)
-      ffi (~> 1.0, >= 1.0.11)
     chosen-rails (0.9.8)
       railties (~> 3.0)
       thor (~> 0.14)
     code_analyzer (0.3.1)
       sexp_processor
-    coderay (1.0.8)
+    coderay (1.0.9)
     coffee-rails (3.2.2)
       coffee-script (>= 2.2.0)
       railties (~> 3.2.0)
@@ -122,7 +112,7 @@ GEM
       rest-client
       simplecov (>= 0.7)
       thor
-    crack (0.3.1)
+    crack (0.3.2)
     daemons (1.1.9)
     database_cleaner (0.9.1)
     debug_inspector (0.0.2)
@@ -132,11 +122,7 @@ GEM
       orm_adapter (~> 0.1)
       railties (~> 3.1)
       warden (~> 1.2.1)
-    diff-lcs (1.1.3)
-    draper (1.1.0)
-      actionpack (>= 3.0)
-      activesupport (>= 3.0)
-      request_store (~> 1.0.3)
+    diff-lcs (1.2.1)
     email_spec (1.4.0)
       launchy (~> 2.1)
       mail (~> 2.2)
@@ -147,7 +133,7 @@ GEM
     eventmachine (1.0.0)
     execjs (1.4.0)
       multi_json (~> 1.0)
-    facter (1.6.17)
+    facter (1.6.18)
     factory_girl (4.1.0)
       activesupport (>= 3.0.0)
     factory_girl_rails (4.1.0)
@@ -158,15 +144,14 @@ GEM
     faye-websocket (0.4.7)
       eventmachine (>= 0.12.0)
     ffaker (1.15.0)
-    ffi (1.4.0)
-    font-awesome-sass-rails (3.0.0.1)
+    ffi (1.6.0)
+    font-awesome-sass-rails (3.0.2.2)
       railties (>= 3.1.1)
       sass-rails (>= 3.1.1)
-    foreman (0.61.0)
+    foreman (0.62.0)
       thor (>= 0.13.6)
     gemoji (1.2.1)
     gherkin-ruby (0.2.1)
-    git (1.2.5)
     github-linguist (2.3.4)
       charlock_holmes (~> 0.6.6)
       escape_utils (~> 0.2.3)
@@ -185,7 +170,14 @@ GEM
       omniauth (~> 1.0)
       pyu-ruby-sasl (~> 0.0.3.1)
       rubyntlm (~> 0.1.1)
-    gitlab_yaml_db (1.0.0)
+    gollum-lib (1.0.0)
+      github-markdown (~> 0.5.3)
+      github-markup (>= 0.7.5, < 1.0.0)
+      grit (~> 2.5.0)
+      nokogiri (~> 1.5.9)
+      pygments.rb (~> 0.4.2)
+      sanitize (~> 2.0.3)
+      stringex (~> 1.5.1)
     gon (4.0.2)
     grape (0.3.2)
       activesupport
@@ -200,15 +192,16 @@ GEM
     grape-entity (0.2.0)
       activesupport
       multi_json (>= 1.3.2)
-    grit_ext (0.6.2)
+    grit_ext (0.8.1)
       charlock_holmes (~> 0.6.9)
     growl (1.0.3)
-    guard (1.5.4)
-      listen (>= 0.4.2)
+    guard (1.6.2)
+      listen (>= 0.6.0)
       lumberjack (>= 1.0.2)
       pry (>= 0.9.10)
+      terminal-table (>= 1.4.3)
       thor (>= 0.14.6)
-    guard-rspec (2.1.2)
+    guard-rspec (2.5.1)
       guard (>= 1.1)
       rspec (~> 2.11)
     guard-spinach (0.0.2)
@@ -222,7 +215,7 @@ GEM
       haml (>= 3.1, < 4.1)
       railties (>= 3.1, < 4.1)
     hashie (1.2.0)
-    hike (1.2.1)
+    hike (1.2.2)
     http_parser.rb (0.5.3)
     httparty (0.10.2)
       multi_json (~> 1.0)
@@ -243,29 +236,27 @@ GEM
     kaminari (0.14.1)
       actionpack (>= 3.0.0)
       activesupport (>= 3.0.0)
-    kgio (2.8.0)
     launchy (2.1.2)
       addressable (~> 2.3)
     letter_opener (1.0.0)
       launchy (>= 2.0.4)
-    libv8 (3.3.10.4)
-    listen (0.5.3)
-    lumberjack (1.0.2)
+    libv8 (3.11.8.17)
+    listen (0.7.3)
+    lumberjack (1.0.3)
     mail (2.5.3)
       i18n (>= 0.4.0)
       mime-types (~> 1.16)
       treetop (~> 1.4.8)
     method_source (0.8.1)
-    mime-types (1.21)
+    mime-types (1.22)
     modernizr (2.6.2)
       sprockets (~> 2.0)
-    multi_json (1.7.1)
+    multi_json (1.7.2)
     multi_xml (0.5.3)
     multipart-post (1.1.5)
-    mustache (0.99.4)
     mysql2 (0.3.11)
     net-ldap (0.2.2)
-    nokogiri (1.5.6)
+    nokogiri (1.5.9)
     oauth (0.4.7)
     oauth2 (0.8.1)
       faraday (~> 0.8)
@@ -293,17 +284,14 @@ GEM
       omniauth-oauth (~> 1.0)
     orm_adapter (0.4.0)
     pg (0.14.1)
-    poltergeist (1.1.0)
-      capybara (~> 2.0, >= 2.0.1)
-      faye-websocket (~> 0.4, >= 0.4.4)
-      http_parser.rb (~> 0.5.3)
     polyglot (0.3.3)
     posix-spawn (0.3.6)
-    progressbar (0.12.0)
-    pry (0.9.10)
+    pry (0.9.12)
       coderay (~> 1.0.5)
       method_source (~> 0.8)
-      slop (~> 3.3.1)
+      slop (~> 3.4)
+    puma (2.0.0.b7)
+      rack (>= 1.1, < 2.0)
     pygments.rb (0.4.2)
       posix-spawn (~> 0.3.6)
       yajl-ruby (~> 1.1.0)
@@ -319,7 +307,7 @@ GEM
       rack (>= 1.1.3)
     rack-mount (0.8.3)
       rack (>= 1.0.0)
-    rack-protection (1.4.0)
+    rack-protection (1.5.0)
       rack
     rack-ssl (1.3.3)
       rack
@@ -336,14 +324,14 @@ GEM
     rails-dev-tweaks (0.6.1)
       actionpack (~> 3.1)
       railties (~> 3.1)
-    rails_best_practices (1.13.2)
+    rails_best_practices (1.13.4)
       activesupport
       awesome_print
       code_analyzer
       colored
       erubis
       i18n
-      progressbar
+      ruby-progressbar
     railties (3.2.13)
       actionpack (= 3.2.13)
       activesupport (= 3.2.13)
@@ -351,15 +339,14 @@ GEM
       rake (>= 0.8.7)
       rdoc (~> 3.4)
       thor (>= 0.14.6, < 2.0)
-    raindrops (0.10.0)
-    rake (10.0.3)
+    rake (10.0.4)
     rb-fsevent (0.9.2)
     rb-inotify (0.8.8)
       ffi (>= 0.5.0)
     rdoc (3.12.2)
       json (~> 1.4)
     redcarpet (2.2.2)
-    redis (3.0.2)
+    redis (3.0.3)
     redis-actionpack (3.2.3)
       actionpack (~> 3.2.3)
       redis-rack (~> 1.4.0)
@@ -378,30 +365,30 @@ GEM
       redis-store (~> 1.1.0)
     redis-store (1.1.3)
       redis (>= 2.2.0)
-    request_store (1.0.5)
+    ref (1.0.4)
     rest-client (1.6.7)
       mime-types (>= 1.16)
-    rspec (2.12.0)
-      rspec-core (~> 2.12.0)
-      rspec-expectations (~> 2.12.0)
-      rspec-mocks (~> 2.12.0)
-    rspec-core (2.12.0)
-    rspec-expectations (2.12.0)
-      diff-lcs (~> 1.1.3)
-    rspec-mocks (2.12.0)
-    rspec-rails (2.12.2)
+    rspec (2.13.0)
+      rspec-core (~> 2.13.0)
+      rspec-expectations (~> 2.13.0)
+      rspec-mocks (~> 2.13.0)
+    rspec-core (2.13.1)
+    rspec-expectations (2.13.0)
+      diff-lcs (>= 1.1.3, < 2.0)
+    rspec-mocks (2.13.0)
+    rspec-rails (2.13.0)
       actionpack (>= 3.0)
       activesupport (>= 3.0)
       railties (>= 3.0)
-      rspec-core (~> 2.12.0)
-      rspec-expectations (~> 2.12.0)
-      rspec-mocks (~> 2.12.0)
+      rspec-core (~> 2.13.0)
+      rspec-expectations (~> 2.13.0)
+      rspec-mocks (~> 2.13.0)
+    ruby-progressbar (1.0.2)
     rubyntlm (0.1.1)
-    rubyzip (0.9.9)
     sanitize (2.0.3)
       nokogiri (>= 1.4.4, < 1.6)
-    sass (3.2.5)
-    sass-rails (3.2.5)
+    sass (3.2.7)
+    sass-rails (3.2.6)
       railties (~> 3.2.0)
       sass (>= 3.1.10)
       tilt (~> 1.3)
@@ -414,16 +401,11 @@ GEM
     select2-rails (3.3.1)
       sass-rails (>= 3.2)
       thor (~> 0.14)
-    selenium-webdriver (2.30.0)
-      childprocess (>= 0.2.5)
-      multi_json (~> 1.0)
-      rubyzip
-      websocket (~> 1.0.4)
     settingslogic (2.0.9)
-    sexp_processor (4.1.3)
+    sexp_processor (4.2.0)
     shoulda-matchers (1.3.0)
       activesupport (>= 3.0.0)
-    sidekiq (2.7.5)
+    sidekiq (2.9.0)
       celluloid (~> 0.12.0)
       connection_pool (~> 1.0)
       multi_json (~> 1)
@@ -433,7 +415,7 @@ GEM
       multi_json (~> 1.0)
       simplecov-html (~> 0.7.1)
     simplecov-html (0.7.1)
-    sinatra (1.3.5)
+    sinatra (1.3.6)
       rack (~> 1.4)
       rack-protection (~> 1.3)
       tilt (~> 1.3, >= 1.3.3)
@@ -441,14 +423,15 @@ GEM
     slim (1.3.6)
       temple (~> 0.5.5)
       tilt (~> 1.3.3)
-    slop (3.3.3)
-    spinach (0.7.0)
-      colorize
-      gherkin-ruby (~> 0.2.0)
-    spinach-rails (0.2.0)
-      capybara (~> 2.0.0)
+    slop (3.4.4)
+    spinach (0.8.1)
+      colorize (= 0.5.8)
+      gherkin-ruby (~> 0.2.1)
+    spinach-rails (0.1.7)
+      capybara (>= 1.0)
       railties (>= 3)
       spinach (>= 0.4)
+    spork (1.0.0rc3)
     sprockets (2.2.2)
       hike (~> 1.2)
       multi_json (~> 1.0)
@@ -458,15 +441,17 @@ GEM
     state_machine (1.1.2)
     stringex (1.5.1)
     temple (0.5.5)
+    terminal-table (1.4.5)
     test_after_commit (0.0.1)
-    therubyracer (0.10.2)
-      libv8 (~> 3.3.10)
+    therubyracer (0.11.4)
+      libv8 (~> 3.11.8.12)
+      ref
     thin (1.5.0)
       daemons (>= 1.0.9)
       eventmachine (>= 0.12.6)
       rack (>= 1.0.0)
-    thor (0.17.0)
-    tilt (1.3.6)
+    thor (0.18.1)
+    tilt (1.3.7)
     timers (1.1.0)
     treetop (1.4.12)
       polyglot
@@ -475,11 +460,6 @@ GEM
     uglifier (1.3.0)
       execjs (>= 0.3.0)
       multi_json (~> 1.0, >= 1.0.2)
-    unicorn (4.6.2)
-      kgio (~> 2.6)
-      rack
-      raindrops (~> 0.7)
-    useragent (0.4.16)
     virtus (0.5.4)
       backports (~> 2.6.1)
       descendants_tracker (~> 0.0.1)
@@ -488,8 +468,7 @@ GEM
     webmock (1.9.0)
       addressable (>= 2.2.7)
       crack (>= 0.1.7)
-    websocket (1.0.7)
-    xpath (1.0.0)
+    xpath (2.0.0)
       nokogiri (~> 1.3)
     yajl-ruby (1.1.0)
 
@@ -503,7 +482,7 @@ DEPENDENCIES
   better_errors
   binding_of_caller
   bootstrap-sass (= 2.2.1.1)
-  capybara (= 2.0.2)
+  capybara
   carrierwave
   chosen-rails (= 0.9.8)
   coffee-rails (~> 3.2.2)
@@ -511,7 +490,6 @@ DEPENDENCIES
   coveralls
   database_cleaner
   devise
-  draper
   email_spec
   enumerize
   factory_girl_rails
@@ -519,20 +497,18 @@ DEPENDENCIES
   font-awesome-sass-rails (~> 3.0.0)
   foreman
   gemoji (~> 1.2.1)
-  git
   github-linguist (~> 2.3.4)
   github-markup (~> 0.7.4)
   gitlab-grack (~> 1.0.0)
   gitlab-pygments.rb (~> 0.3.2)
   gitlab_meta (= 5.0)
   gitlab_omniauth-ldap (= 1.0.2)
-  gitlab_yaml_db (= 1.0.0)
-  gollum (~> 2.4.0)!
+  gollum-lib (~> 1.0.0)
   gon
   grape (~> 0.3.1)
   grape-entity (~> 0.2.0)
   grit (~> 2.5.0)!
-  grit_ext (~> 0.6.2)
+  grit_ext (~> 0.8.1)
   growl
   guard-rspec
   guard-spinach
@@ -551,8 +527,9 @@ DEPENDENCIES
   omniauth-google-oauth2
   omniauth-twitter
   pg
-  poltergeist (= 1.1.0)
+  poltergeist!
   pry
+  puma (~> 2.0.0.b7)
   quiet_assets (~> 1.0.1)
   rack-mini-profiler
   rails (= 3.2.13)
@@ -563,7 +540,7 @@ DEPENDENCIES
   rb-inotify
   redcarpet (~> 2.2.2)
   redis-rails
-  rspec-rails (= 2.12.2)
+  rspec-rails
   sass-rails (~> 3.2.5)
   sdoc
   seed-fu
@@ -575,12 +552,12 @@ DEPENDENCIES
   sinatra
   six
   slim
-  spinach-rails (= 0.2.0)
+  spinach-rails
+  spork (~> 1.0rc)
   stamp
   state_machine
   test_after_commit
   therubyracer
   thin
   uglifier (~> 1.3.0)
-  unicorn
   webmock
diff --git a/Procfile b/Procfile
index 66ca562f131..fade88bd3a3 100644
--- a/Procfile
+++ b/Procfile
@@ -1,2 +1,2 @@
-web: bundle exec unicorn_rails -p $PORT
+web: bundle exec puma -p $PORT
 worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell
diff --git a/README.md b/README.md
index 4cad72fc02d..4771ed9803e 100644
--- a/README.md
+++ b/README.md
@@ -1,89 +1,89 @@
-# Public GitLab
-
-## Presentation
-
-Public GitLab is a fork of the official [GitLab](https://github.com/gitlabhq/gitlabhq) software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects). With this fork, I'm trying to reproduce Github behavior.
-
-So by public I mean:
-
-  * Allow anonymous users to browse your public repositories.
-  * Allow anonymous users to download your code (not only by `git clone`).
-  * Allow anonymous users to register and report issues on public projects.
-
-With these features, GitLab can be a self-hosted Github competitor.
-
-You can browse a live example at http://git.hoa.ro (you won't be able to create projects).
-
-_Disclaimer_: I do not provide any support on GitLab itself. I only contribute to the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
-
-You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
-
-## Installation
-
-During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
-
-**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-0-stable.zip).
-
-### Clone the Source
-
-    # Clone GitLab repository
-    sudo -u git -H git clone https://github.com/ArthurHoaro/Public-GitLab.git gitlab
-
-    # Go to gitlab dir
-    cd /home/git/gitlab
-
-    # Checkout to stable release
-    sudo -u git -H git checkout 5-0-stable
-
-### Post installation
-At this point, every GitLab components are installed. You still can not access to GitLab yet though.
-
-The SQL script below will create a default `guest` user for anonymous access. It will also create a default team (`pgl_reporters`) which allows `reporter` permission to every new _future_ users, for all public projects.
-
-#### PostgreSQL
-You have to patch GitLab your database with `pgl_script_postgres.sql`:
-
-    cd /home/git/gitlab/pgl
-    psql -h host -U user database < pgl_script_postgres.sql
-
-#### MySQL
-You have to patch GitLab your database with `pgl_script_mysql.sql`:
-
-    cd /home/git/gitlab/pgl
-    mysql -hhost -uuser -p
-    use database
-    source pgl_script_mysql.sql
-
-### Allow signup
-
-In the file ~/gitlab/config/gitlab.yml, uncomment:
-
-    signup_enabled: true
-
-Note: Keep in mind that if you do not allow signup, guest wouldn't be able to report issues. 
-
-If you do not want guest users to create projects on your GitLab installation, set `default_projects_limit: 0` in `config/gitlab.yaml`.
-
-### Restart GitLab
-
-Remember to restart GitLab after all these changes :
-
-    sudo /etc/init.d/gitlab restart
-
-Then enjoy !
-
-## Reporting issues
-
-If you have issues with Public GitLab, you can report them with the [Github issues module](https://github.com/ArthurHoaro/Public-GitLab/issues). 
-
-Please rememberer to tell us which database you are using.
-
-If there is a new stable branch, please do not open an issue to ask update. [Contact me](http://hoa.ro/static6/contact) instead.
-
-## License
-
-Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
-
-Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-0-stable/LICENSE) as the original sofware.
-
-This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
+# Public GitLab
+
+## Presentation
+
+Public GitLab is a fork of the official [GitLab](https://github.com/gitlabhq/gitlabhq) software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects). With this fork, I'm trying to reproduce Github behavior.
+
+So by public I mean:
+
+  * Allow anonymous users to browse your public repositories.
+  * Allow anonymous users to download your code (not only by `git clone`).
+  * Allow anonymous users to register and report issues on public projects.
+
+With these features, GitLab can be a self-hosted Github competitor.
+
+You can browse a live example at http://git.hoa.ro (you won't be able to create projects).
+
+_Disclaimer_: I do not provide any support on GitLab itself. I only contribute to the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
+
+You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
+
+## Installation
+
+During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
+
+**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-0-stable.zip).
+
+### Clone the Source
+
+    # Clone GitLab repository
+    sudo -u git -H git clone https://github.com/ArthurHoaro/Public-GitLab.git gitlab
+
+    # Go to gitlab dir
+    cd /home/git/gitlab
+
+    # Checkout to stable release
+    sudo -u git -H git checkout 5-0-stable
+
+### Post installation
+At this point, every GitLab components are installed. You still can not access to GitLab yet though.
+
+The SQL script below will create a default `guest` user for anonymous access. It will also create a default team (`pgl_reporters`) which allows `reporter` permission to every new _future_ users, for all public projects.
+
+#### PostgreSQL
+You have to patch GitLab your database with `pgl_script_postgres.sql`:
+
+    cd /home/git/gitlab/pgl
+    psql -h host -U user database < pgl_script_postgres.sql
+
+#### MySQL
+You have to patch GitLab your database with `pgl_script_mysql.sql`:
+
+    cd /home/git/gitlab/pgl
+    mysql -hhost -uuser -p
+    use database
+    source pgl_script_mysql.sql
+
+### Allow signup
+
+In the file ~/gitlab/config/gitlab.yml, uncomment:
+
+    signup_enabled: true
+
+Note: Keep in mind that if you do not allow signup, guest wouldn't be able to report issues. 
+
+If you do not want guest users to create projects on your GitLab installation, set `default_projects_limit: 0` in `config/gitlab.yaml`.
+
+### Restart GitLab
+
+Remember to restart GitLab after all these changes :
+
+    sudo /etc/init.d/gitlab restart
+
+Then enjoy !
+
+## Reporting issues
+
+If you have issues with Public GitLab, you can report them with the [Github issues module](https://github.com/ArthurHoaro/Public-GitLab/issues). 
+
+Please rememberer to tell us which database you are using.
+
+If there is a new stable branch, please do not open an issue to ask update. [Contact me](http://hoa.ro/static6/contact) instead.
+
+## License
+
+Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
+
+Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-0-stable/LICENSE) as the original sofware.
+
+This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
\ No newline at end of file
diff --git a/ROADMAP.md b/ROADMAP.md
index bf4fe695438..879064dc719 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -1,7 +1,5 @@
 ## GitLab Roadmap
 
-### v5.0 March 22
+Features that will be in the next release are listed on [the feedback and suggestions forum with the status "started"](http://feedback.gitlab.com/forums/176466-general/status/796456) as specified in the README.
 
-* Replace gitolite with gitlab-shell 
-* Usability improvements
-* Notification improvements
\ No newline at end of file
+This ROADMAP file will be deprecated.
diff --git a/VERSION b/VERSION
index 6b244dcd696..831446cbd27 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.0.1
+5.1.0
diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee
index 3fefbf8e121..d2181e7b759 100644
--- a/app/assets/javascripts/behaviors/toggler_behavior.coffee
+++ b/app/assets/javascripts/behaviors/toggler_behavior.coffee
@@ -3,3 +3,11 @@ $ ->
     container = $(@).closest(".js-toggler-container")
 
     container.toggleClass("on")
+  
+  $("body").on "click", ".js-toggle-visibility-link", (e) ->
+    $(@).find('i').
+      toggleClass('icon-chevron-down').
+      toggleClass('icon-chevron-up')
+    container = $(".js-toggle-visibility-container")
+    container.toggleClass("hide")
+    e.preventDefault()
diff --git a/app/assets/javascripts/branch-graph.js.coffee b/app/assets/javascripts/branch-graph.js.coffee
index 6e4d693109e..2a668de278a 100644
--- a/app/assets/javascripts/branch-graph.js.coffee
+++ b/app/assets/javascripts/branch-graph.js.coffee
@@ -5,6 +5,10 @@ class BranchGraph
     @mspace = 0
     @parents = {}
     @colors = ["#000"]
+    @offsetX = 120
+    @offsetY = 20
+    @unitTime = 30
+    @unitSpace = 10
     @load()
 
   load: ->
@@ -20,8 +24,6 @@ class BranchGraph
 
   prepareData: (@days, @commits) ->
     @collectParents()
-    @mtime += 4
-    @mspace += 10
 
     for c in @commits
       c.isParent = true  if c.id of @parents
@@ -35,6 +37,7 @@ class BranchGraph
       @mspace = Math.max(@mspace, c.space)
       for p in c.parents
         @parents[p[0]] = true
+        @mspace = Math.max(@mspace, p[1])
 
   collectColors: ->
     k = 0
@@ -46,25 +49,23 @@ class BranchGraph
       k++
 
   buildGraph: ->
+    graphHeight = $(@element).height()
     graphWidth = $(@element).width()
-    ch = @mspace * 20 + 100
-    cw = Math.max(graphWidth, @mtime * 20 + 260)
-    r = Raphael(@element.get(0), cw, ch)
+    ch = Math.max(graphHeight, @offsetY + @unitTime * @mtime + 150)
+    cw = Math.max(graphWidth, @offsetX + @unitSpace * @mspace + 300)
+    @r = r = Raphael(@element.get(0), cw, ch)
     top = r.set()
     cuday = 0
     cumonth = ""
-    offsetX = 20
-    offsetY = 60
-    barWidth = Math.max(graphWidth, @days.length * 20 + 320)
-    scrollLeft = cw
-    @raphael = r
-    r.rect(0, 0, barWidth, 20).attr fill: "#222"
-    r.rect(0, 20, barWidth, 20).attr fill: "#444"
+    barHeight = Math.max(graphHeight, @unitTime * @days.length + 320)
+
+    r.rect(0, 0, 26, barHeight).attr fill: "#222"
+    r.rect(26, 0, 20, barHeight).attr fill: "#444"
 
     for day, mm in @days
       if cuday isnt day[0]
         # Dates
-        r.text(offsetX + mm * 20, 31, day[0])
+        r.text(36, @offsetY + @unitTime * mm, day[0])
           .attr(
             font: "12px Monaco, monospace"
             fill: "#DDD"
@@ -73,7 +74,7 @@ class BranchGraph
 
       if cumonth isnt day[1]
         # Months
-        r.text(offsetX + mm * 20, 11, day[1])
+        r.text(13, @offsetY + @unitTime * mm, day[1])
           .attr(
             font: "12px Monaco, monospace"
             fill: "#EEE"
@@ -81,61 +82,20 @@ class BranchGraph
         cumonth = day[1]
 
     for commit in @commits
-      x = offsetX + 20 * commit.time
-      y = offsetY + 10 * commit.space
-      # Draw dot
-      r.circle(x, y, 3).attr(
-        fill: @colors[commit.space]
-        stroke: "none"
-      )
-
-      # Draw lines
-      for parent in commit.parents
-        parentCommit = @preparedCommits[parent[0]]
-        parentX = offsetX + 20 * parentCommit.time
-        parentY1 = offsetY + 10 * parentCommit.space
-        parentY2 = offsetY + 10 * parent[1]
-        if parentCommit.space is commit.space and parentCommit.space is parent[1]
-          r.path(["M", x, y, "L", parentX, parentY1]).attr(
-            stroke: @colors[parentCommit.space]
-            "stroke-width": 2
-          )
+      x = @offsetX + @unitSpace * (@mspace - commit.space)
+      y = @offsetY + @unitTime * commit.time
 
-        else if parentCommit.space < commit.space
-          if y is parentY2
-            r.path(["M", x - 5, y, "l-5,-2,0,4,5,-2", "L", x - 10, y, "L", x - 15, parentY2, "L", parentX + 5, parentY2, "L", parentX, parentY1]).attr(
-              stroke: @colors[commit.space]
-              "stroke-width": 2
-            )
-
-          else
-            r.path(["M", x - 3, y - 6, "l-4,-3,4,-2,0,5", "L", x - 5, y - 10, "L", x - 10, parentY2, "L", parentX + 5, parentY2, "L", parentX, parentY1]).attr(
-              stroke: @colors[commit.space]
-              "stroke-width": 2
-            )
-
-        else
-          r.path(["M", x - 3, y + 6, "l-4,3,4,2,0,-5", "L", x - 5, y + 10, "L", x - 10, parentY2, "L", parentX + 5, parentY2, "L", parentX, parentY1]).attr(
-            stroke: @colors[parentCommit.space]
-            "stroke-width": 2
-          )
+      @drawDot(x, y, commit)
 
-      @appendLabel x, y, commit.refs  if commit.refs
+      @drawLines(x, y, commit)
 
-      # Mark commit and displayed in the center
-      if commit.id is @options.commit_id
-        r.path(["M", x, y - 5, "L", x + 4, y - 15, "L", x - 4, y - 15, "Z"]).attr(
-          fill: "#000"
-          "fill-opacity": .7
-          stroke: "none"
-        )
+      @appendLabel(x, y, commit.refs)  if commit.refs
 
-        scrollLeft = x - graphWidth / 2
+      @appendAnchor(top, commit, x, y)
 
-      @appendAnchor top, commit, x, y
+      @markCommit(x, y, commit, graphHeight)
 
     top.toFront()
-    @element.scrollLeft scrollLeft
     @bindEvents()
 
   bindEvents: ->
@@ -167,35 +127,37 @@ class BranchGraph
         element.scrollTop element.scrollTop() + 50  if event.keyCode is 40
 
   appendLabel: (x, y, refs) ->
-    r = @raphael
+    r = @r
     shortrefs = refs
     # Truncate if longer than 15 chars
     shortrefs = shortrefs.substr(0, 15) + "…"  if shortrefs.length > 17
-    text = r.text(x + 5, y + 8 + 10, shortrefs).attr(
+    text = r.text(x + 4, y, shortrefs).attr(
+      "text-anchor": "start"
       font: "10px Monaco, monospace"
       fill: "#FFF"
       title: refs
     )
     textbox = text.getBBox()
-    text.transform ["t", textbox.height / -4, textbox.width / 2 + 5, "r90"]
     # Create rectangle based on the size of the textbox
-    rect = r.rect(x, y, textbox.width + 15, textbox.height + 5, 4).attr(
+    rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr(
       fill: "#000"
-      "fill-opacity": .7
+      "fill-opacity": .5
       stroke: "none"
     )
-    triangle = r.path(["M", x, y + 5, "L", x + 4, y + 15, "L", x - 4, y + 15, "Z"]).attr(
+    triangle = r.path(["M", x - 5, y, "L", x - 15, y - 4, "L", x - 15, y + 4, "Z"]).attr(
       fill: "#000"
-      "fill-opacity": .7
+      "fill-opacity": .5
       stroke: "none"
     )
-    # Rotate and reposition rectangle over text
-    rect.transform ["r", 90, x, y, "t", 15, -9]
+
+    label = r.set(rect, text)
+    label.transform(["t", -rect.getBBox().width - 15, 0])
+
     # Set text to front
     text.toFront()
 
   appendAnchor: (top, commit, x, y) ->
-    r = @raphael
+    r = @r
     options = @options
     anchor = r.circle(x, y, 10).attr(
       fill: "#000"
@@ -204,18 +166,92 @@ class BranchGraph
     ).click(->
       window.open options.commit_url.replace("%s", commit.id), "_blank"
     ).hover(->
-      @tooltip = r.commitTooltip(x, y + 5, commit)
+      @tooltip = r.commitTooltip(x + 5, y, commit)
       top.push @tooltip.insertBefore(this)
     , ->
       @tooltip and @tooltip.remove() and delete @tooltip
     )
     top.push anchor
 
+  drawDot: (x, y, commit) ->
+    r = @r
+    r.circle(x, y, 3).attr(
+      fill: @colors[commit.space]
+      stroke: "none"
+    )
+    r.rect(@offsetX + @unitSpace * @mspace + 10, y - 10, 20, 20).attr(
+      fill: "url(#{commit.author.icon})"
+      stroke: @colors[commit.space]
+      "stroke-width": 2
+    )
+    r.text(@offsetX + @unitSpace * @mspace + 35, y, commit.message.split("\n")[0]).attr(
+      "text-anchor": "start"
+      font: "14px Monaco, monospace"
+    )
+
+  drawLines: (x, y, commit) ->
+    r = @r
+    for parent, i in commit.parents
+      parentCommit = @preparedCommits[parent[0]]
+      parentY = @offsetY + @unitTime * parentCommit.time
+      parentX1 = @offsetX + @unitSpace * (@mspace - parentCommit.space)
+      parentX2 = @offsetX + @unitSpace * (@mspace - parent[1])
+
+      # Set line color
+      if parentCommit.space <= commit.space
+        color = @colors[commit.space]
+
+      else
+        color = @colors[parentCommit.space]
+
+      # Build line shape
+      if parent[1] is commit.space
+        offset = [0, 5]
+        arrow = "l-2,5,4,0,-2,-5,0,5"
+
+      else if parent[1] < commit.space
+        offset = [3, 3]
+        arrow = "l5,0,-2,4,-3,-4,4,2"
+
+      else
+        offset = [-3, 3]
+        arrow = "l-5,0,2,4,3,-4,-4,2"
+
+      # Start point
+      route = ["M", x + offset[0], y + offset[1]]
+
+      # Add arrow if not first parent
+      if i > 0
+        route.push(arrow)
+
+      # Circumvent if overlap
+      if commit.space isnt parentCommit.space or commit.space isnt parent[1]
+        route.push(
+          "L", parentX2, y + 10,
+          "L", parentX2, parentY - 5,
+        )
+
+      # End point
+      route.push("L", parentX1, parentY)
+
+      r
+        .path(route)
+        .attr(
+          stroke: color
+          "stroke-width": 2)
+
+  markCommit: (x, y, commit, graphHeight) ->
+    if commit.id is @options.commit_id
+      r = @r
+      r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr(
+        fill: "#000"
+        "fill-opacity": .5
+        stroke: "none"
+      )
+      # Displayed in the center
+      @element.scrollTop(y - graphHeight / 2)
+
 Raphael::commitTooltip = (x, y, commit) ->
-  icon = undefined
-  nameText = undefined
-  idText = undefined
-  messageText = undefined
   boxWidth = 300
   boxHeight = 200
   icon = @image(commit.author.icon, x, y, 20, 20)
diff --git a/app/assets/javascripts/chart.js.coffee b/app/assets/javascripts/chart.js.coffee
new file mode 100644
index 00000000000..989f48e5e75
--- /dev/null
+++ b/app/assets/javascripts/chart.js.coffee
@@ -0,0 +1,21 @@
+@Chart =
+  labels: []
+  values: []
+
+  init: (labels, values, title) ->
+    r = Raphael('activity-chart')
+
+    fin = ->
+      @flag = r.popup(@bar.x, @bar.y, @bar.value or "0").insertBefore(this)
+
+    fout = ->
+      @flag.animate
+        opacity: 0, 300, -> @remove()
+
+    r.text(160, 10, title).attr font: "13px sans-serif"
+    r.barchart(
+      10, 20, 560, 200,
+      [values],
+      {colors:["#456"]}
+    ).label(labels, true)
+      .hover(fin, fout)
diff --git a/app/assets/javascripts/extensions/jquery.js.coffee b/app/assets/javascripts/extensions/jquery.js.coffee
new file mode 100644
index 00000000000..8a997fe318e
--- /dev/null
+++ b/app/assets/javascripts/extensions/jquery.js.coffee
@@ -0,0 +1,9 @@
+$.fn.showAndHide = ->
+  $(@).show().
+    delay(3000).
+    fadeOut()
+
+$.fn.enableButton = ->
+  $(@).removeAttr('disabled').
+    removeClass('disabled')
+
diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js
deleted file mode 100644
index 9ba1a3f1bba..00000000000
--- a/app/assets/javascripts/issues.js
+++ /dev/null
@@ -1,80 +0,0 @@
-function initIssuesSearch() { 
-  var href       = $('#issue_search_form').attr('action');
-  var last_terms = '';
-
-  $('#issue_search').keyup(function() {
-    var terms       = $(this).val();
-    var milestone_id  = $('#milestone_id').val();
-    var status      = $('#status').val();
-
-    if (terms != last_terms) {
-      last_terms = terms;
-
-      if (terms.length >= 2 || terms.length == 0) {
-        $.get(href, { 'status': status, 'terms': terms, 'milestone_id': milestone_id }, function(response) {
-          $('#issues-table').html(response);
-        });
-      }
-    }
-  });
-}
-
-/**
- * Init issues page
- *
- */
-function issuesPage(){ 
-  initIssuesSearch();
-  $("#update_status").chosen();
-  $("#update_assignee_id").chosen();
-  $("#update_milestone_id").chosen();
-
-  $("#label_name").chosen();
-  $("#assignee_id").chosen();
-  $("#milestone_id").chosen();
-  $("#milestone_id, #assignee_id, #label_name").on("change", function(){
-    $(this).closest("form").submit();
-  });
-
-  $('body').on('ajax:success', '.close_issue, .reopen_issue', function(){
-    var t = $(this),
-        totalIssues,
-        reopen = t.hasClass('reopen_issue');
-    $('.issue_counter').each(function(){
-      var issue = $(this);
-      totalIssues = parseInt( $(this).html(), 10 );
-
-      if( reopen && issue.closest('.main_menu').length ){
-        $(this).html( totalIssues+1 );
-      }else {
-        $(this).html( totalIssues-1 );
-      }
-    });
-
-  });
-
-  $(".check_all_issues").click(function () {
-    $('.selected_issue').attr('checked', this.checked);
-    issuesCheckChanged();
-  });
-
-  $('.selected_issue').bind('change', issuesCheckChanged);
-}
-
-function issuesCheckChanged() { 
-  var checked_issues = $('.selected_issue:checked');
-
-  if(checked_issues.length > 0) { 
-    var ids = []
-    $.each(checked_issues, function(index, value) {
-      ids.push($(value).attr("data-id"));
-    })
-    $('#update_issues_ids').val(ids);
-    $('.issues_filters').hide();
-    $('.issues_bulk_update').show();
-  } else { 
-    $('#update_issues_ids').val([]);
-    $('.issues_bulk_update').hide();
-    $('.issues_filters').show();
-  }
-}
diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee
new file mode 100644
index 00000000000..ab952be29eb
--- /dev/null
+++ b/app/assets/javascripts/issues.js.coffee
@@ -0,0 +1,70 @@
+@Issues =
+  init: ->
+    Issues.initSearch()
+    Issues.initSelects()
+    Issues.initChecks()
+
+    $("body").on "ajax:success", ".close_issue, .reopen_issue", ->
+      t = $(this)
+      totalIssues = undefined
+      reopen = t.hasClass("reopen_issue")
+      $(".issue_counter").each ->
+        issue = $(this)
+        totalIssues = parseInt($(this).html(), 10)
+        if reopen and issue.closest(".main_menu").length
+          $(this).html totalIssues + 1
+        else
+          $(this).html totalIssues - 1
+
+
+  reload: ->
+    Issues.initSelects()
+    Issues.initChecks()
+    $('#filter_issue_search').val($('#issue_search').val())
+
+  initSelects: ->
+    $("#update_status").chosen()
+    $("#update_assignee_id").chosen()
+    $("#update_milestone_id").chosen()
+    $("#label_name").chosen()
+    $("#assignee_id").chosen()
+    $("#milestone_id").chosen()
+    $("#milestone_id, #assignee_id, #label_name").on "change", ->
+      $(this).closest("form").submit()
+
+  initChecks: ->
+    $(".check_all_issues").click ->
+      $(".selected_issue").attr "checked", @checked
+      Issues.checkChanged()
+
+    $(".selected_issue").bind "change", Issues.checkChanged
+
+
+  initSearch: ->
+    form = $("#issue_search_form")
+    last_terms = ""
+    $("#issue_search").keyup ->
+      terms = $(this).val()
+      unless terms is last_terms
+        last_terms = terms
+        if terms.length >= 2 or terms.length is 0
+          $('#search_status').val($('#status').val())
+          $('#search_assignee_id').val($('#assignee_id').val())
+          $('#search_milestone_id').val($('#milestone_id').val())
+          $('#search_label_name').val($('#label_name').val())
+          form.submit()
+
+  checkChanged: ->
+    checked_issues = $(".selected_issue:checked")
+    if checked_issues.length > 0
+      ids = []
+      $.each checked_issues, (index, value) ->
+        ids.push $(value).attr("data-id")
+
+      $("#update_issues_ids").val ids
+      $(".issues_filters").hide()
+      $(".issues_bulk_update").show()
+    else
+      $("#update_issues_ids").val []
+      $(".issues_bulk_update").hide()
+      $(".issues_filters").show()
diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee
index b61df846c7a..39ec86e623f 100644
--- a/app/assets/javascripts/main.js.coffee
+++ b/app/assets/javascripts/main.js.coffee
@@ -7,6 +7,8 @@ window.slugify = (text) ->
 window.ajaxGet = (url) ->
   $.ajax({type: "GET", url: url, dataType: "script"})
 
+window.showAndHide = (selector) ->
+
 window.errorMessage = (message) ->
   ehtml = $("<p>")
   ehtml.addClass("error_message")
diff --git a/app/assets/javascripts/merge_requests.js.coffee b/app/assets/javascripts/merge_requests.js.coffee
index 890ca400f81..9ab41f9ac1b 100644
--- a/app/assets/javascripts/merge_requests.js.coffee
+++ b/app/assets/javascripts/merge_requests.js.coffee
@@ -76,7 +76,6 @@ class MergeRequest
     $('.ci_widget.ci-' + state).show()
 
   loadDiff: (event) ->
-    $('.dashboard-loader').show()
     $.ajax
       type: 'GET'
       url: this.$('.nav-tabs .diffs-tab a').attr('href')
diff --git a/app/assets/javascripts/profile.js.coffee b/app/assets/javascripts/profile.js.coffee
index 42207a390b3..213133bc965 100644
--- a/app/assets/javascripts/profile.js.coffee
+++ b/app/assets/javascripts/profile.js.coffee
@@ -15,6 +15,8 @@ $ ->
     $(this).find('.update-failed').hide()
 
   $('.update-username form').on 'ajax:complete', ->
-    $(this).find('.save-btn').removeAttr('disabled')
-    $(this).find('.save-btn').removeClass('disabled')
+    $(this).find('.btn-save').enableButton()
     $(this).find('.loading-gif').hide()
+  
+  $('.update-notifications').on 'ajax:complete', ->
+    $(this).find('.btn-save').enableButton()
diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee
index 2603b9a96c6..10d0df700e1 100644
--- a/app/assets/javascripts/tree.js.coffee
+++ b/app/assets/javascripts/tree.js.coffee
@@ -6,7 +6,7 @@ $ ->
     $('span.log_loading:first').removeClass('hide')
 
     $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live "click", ->
-      $("#tree-content-holder").hide("slide", { direction: "left" }, 150)
+      $("#tree-content-holder").hide("slide", { direction: "left" }, 400)
 
     # Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
     $("#tree-slider .tree-item").live 'click', (e) ->
diff --git a/app/assets/javascripts/wall.js.coffee b/app/assets/javascripts/wall.js.coffee
index a35c8c6004e..e2fca3ddee4 100644
--- a/app/assets/javascripts/wall.js.coffee
+++ b/app/assets/javascripts/wall.js.coffee
@@ -58,14 +58,26 @@
     form.show()
   
   renderNote: (note) ->
-    author = '<strong class="wall-author">' + note.author.name + '</strong>'
-    body = '<span class="wall-text">' + linkify(sanitize(note.body)) + '</span>'
-    file = ''
-    time = '<abbr class="timeago" title="' + note.created_at + '">' + note.created_at + '</time>'
+    template = Wall.noteTemplate()
+    template = template.replace('{{author_name}}', note.author.name)
+    template = template.replace('{{created_at}}', note.created_at)
+    template = template.replace('{{text}}', linkify(sanitize(note.body)))
 
     if note.attachment
-      file = '<span class="wall-file"><a href="/files/note/' + note.id + '/' + note.attachment + '">' + note.attachment + '</a></span>'
-    
-    html = '<li>' + author + body + file + time + '</li>'
+      file = '<i class="icon-paper-clip"/><a href="/files/note/' + note.id + '/' + note.attachment + '">' + note.attachment + '</a>'
+    else
+      file = ''
+    template = template.replace('{{file}}', file)
+
+
+    $('ul.notes').append(template)
 
-    $('ul.notes').append(html)
+  noteTemplate: ->
+    return '<li>
+      <strong class="wall-author">{{author_name}}</strong>
+      <span class="wall-text">
+        {{text}}
+        <span class="wall-file">{{file}}</span>
+      </span>
+      <abbr class="timeago" title="{{created_at}}">{{created_at}}</abbr>
+    </li>'
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index fd15d5c6097..893cb2196d7 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -36,6 +36,7 @@
 @import "sections/admin.scss";
 @import "sections/wiki.scss";
 @import "sections/wall.scss";
+@import "sections/dashboard.scss";
 
 @import "highlight/white.scss";
 @import "highlight/dark.scss";
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index 4e7aa968ea7..ccc6f7a9d2d 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -17,7 +17,6 @@ body {
   margin: 0 0;
 }
 
-.visible_link,
 .author_link {
   color: $link_color;
 }
@@ -32,30 +31,12 @@ body {
   padding-bottom: 0;
 }
 
-.info_link {
-  margin-right: 5px;
-  float: left;
-
-  img {
-    width: 20px;
-  }
-}
-
-.download_repo_link {
-  background: url("images.png") no-repeat 0 -48px;
-  padding-left: 20px;
-}
-
 table a code {
   position: relative;
   top: -2px;
   margin-right: 3px;
 }
 
-.span12 hr{
- margin-top: 5px;
-}
-
 .loading {
   margin: 20px auto;
   background: url(ajax_loader.gif) no-repeat center center;
@@ -81,10 +62,6 @@ table a code {
   }
 }
 
-.git_url_wrapper {
-  margin-right:50px
-}
-
 span.update-author {
   display: block;
   color: #999;
@@ -96,37 +73,16 @@ span.update-author {
   }
 }
 
-.dashboard-loader {
-  float: left;
-  margin: 10px;
-  display: none;
-}
 .user-mention {
   color: #2FA0BB;
   font-weight: bold;
 }
 
-.neib {
-  margin-right: 10px;
-}
-
 .label {
-  padding: 0px 4px;
-  font-size: 10px;
+  padding: 1px 4px;
+  font-size: 12px;
   font-style: normal;
-  background-color: $link_color;
-
-  &.label-success {
-    background-color: #8D8;
-    color: #333;
-    text-shadow: 0 1px 1px white;
-  }
-
-  &.label-error {
-    background-color: #D88;
-    color: #333;
-    text-shadow: 0 1px 1px white;
-  }
+  font-weight: normal;
 }
 
 form {
@@ -182,27 +138,6 @@ input[type=text] {
   }
 }
 
-.merge-request-form-holder {
-  select {
-    width: 300px;
-  }
-}
-
-/** Issues **/
-#issue_assignee_id {
-  width: 300px;
-}
-
-#new_issue_dialog textarea{
-    height: 100px;
-}
-
-.project_list_url {
-  width: 250px;
-  background:#fff !important;
-}
-
-
 .line_holder {
   &:hover {
     td {
@@ -234,24 +169,6 @@ p.time {
   margin: 30px 3px 3px 2px;
 }
 
-
-.styled_image {
-  border: 2px solid #ddd;
-}
-
-
-
-/* Fix for readme code (stopped it from being yellow) */
-.readme {
-  pre {
-    background: white !important;
-
-    code {
-      background: none !important;
-    }
-  }
-}
-
 .search-holder {
   label, input {
      height: 30px;
@@ -278,6 +195,11 @@ p.time {
   top: -5px;
   @include border-radius(4px);
 
+  &.success {
+    background: #4A4;
+    color: #FFF;
+  }
+
   &.error {
     background: #DA4E49;
     color: #FFF;
@@ -345,25 +267,6 @@ li.note {
 }
 
 
-
-/**
- * Admin area
- *
- */
-.admin_dash {
-  .data {
-    a {
-      h1 {
-        line-height: 48px;
-        font-size: 48px;
-        padding: 20px;
-        text-align: center;
-        font-weight: normal;
-      }
-    }
-  }
-}
-
 .rss-icon {
   img {
     width: 24px;
@@ -376,24 +279,12 @@ li.note {
 }
 
 
-
-/* CHZN reset few styles */
-.chzn-container-single .chzn-single {
-  background: #FFF;
-  border: 1px solid #bbb;
-  box-shadow: none;
-}
-.chzn-container-active .chzn-single {
-  background: #fff;
-}
-
-
 .supp_diff_link,
 .show-all-commits {
   cursor: pointer;
 }
 
-.merge_request,
+.merge-request,
 .issue {
   &.today{
     background: #EFE;
@@ -493,27 +384,6 @@ pre {
   }
 }
 
-.float-link {
-  float: left;
-  margin-right: 15px;
-  .s16 {
-    margin-right: 5px;
-  }
-}
-
-.dashboard-search-filter {
-  padding:5px;
-
-  .search-text-input {
-    float:left;
-    @extend .span2;
-  }
-  .btn {
-    margin-left: 5px;
-    float:left;
-  }
-}
-
 h1.http_status_code {
   font-size: 56px;
   line-height: 100px;
@@ -544,14 +414,7 @@ img.emoji {
   display: none;
 }
 
-.label-branch {
-  @include border-radius(4px);
-  padding: 2px 4px;
-  border: none;
-  font-size: 14px;
-  background: #474D57;
-  color: #fff;
-  font-family: $monospace_font;
-  text-shadow: 0 1px 1px #111;
-  font-weight: normal;
+.chart {
+  overflow: hidden;
+  height: 220px;
 }
diff --git a/app/assets/stylesheets/gitlab_bootstrap/avatar.scss b/app/assets/stylesheets/gitlab_bootstrap/avatar.scss
index de1fb1551bf..ed6ec77b89b 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/avatar.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/avatar.scss
@@ -1,8 +1,24 @@
-/** AVATARS **/
-img.avatar { float: left; margin-right: 12px; width: 40px; border: 1px solid #ddd; padding: 1px; }
-img.avatar.s16 { width: 16px; height: 16px; margin-right: 6px; }
-img.avatar.s24 { width: 24px; height: 24px; margin-right: 8px; }
-img.avatar.s32 { width: 32px; height: 32px; margin-right: 10px; }
-img.avatar.s90 { width: 90px; height: 90px; margin-right: 15px; }
+.avatar {
+  float: left;
+  margin-right: 12px;
+  width: 40px;
+  border: 1px solid #ddd;
+  padding: 1px;
+
+  &.avatar-inline {
+    float: none;
+    margin-left: 3px;
+
+    &.s16 { margin-right: 2px; }
+    &.s24 { margin-right: 2px; }
+  }
+
+  &.s16 { width: 16px; height: 16px; margin-right: 6px; }
+  &.s24 { width: 24px; height: 24px; margin-right: 8px; }
+  &.s32 { width: 32px; height: 32px; margin-right: 10px; }
+  &.s90 { width: 90px; height: 90px; margin-right: 15px; }
+}
+
+
 img.lil_av { padding-left: 4px; padding-right: 3px; }
 img.small { width: 80px; }
diff --git a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
index cb055a1c08b..6604d11d0f8 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
@@ -13,6 +13,7 @@
   background: #F9F9F9;
   margin-bottom: 25px;
   border: 1px solid #CCC;
+  word-wrap: break-word;
   @include solid-shade;
 
   &.ui-box-show {
@@ -41,7 +42,6 @@
   .ui-box-body,
   .ui-box-bottom {
     padding: 15px;
-    word-wrap: break-word;
 
     .clearfix {
       margin: 0;
@@ -100,8 +100,9 @@
       margin-top: 0;
     }
 
-    .btn-tiny {
-      @include box-shadow(0 0px 0px 1px #f1f1f1);
+    .btn {
+      position: relative;
+      top: -2px;
     }
 
     .nav-pills {
diff --git a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
index 03497e32d26..e9b85686fad 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
@@ -23,7 +23,7 @@
 
     &.disabled {
       color: #fff;
-      background: #29B;
+      background: $primary_color;
     }
   }
 
@@ -39,7 +39,7 @@
 
     &.disabled {
       color: #fff;
-      background: #29B;
+      background: $primary_color;
     }
   }
 
diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss
index 6bdd1652fd6..3ec03b96434 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/common.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss
@@ -10,10 +10,16 @@
 
 /** COMMON CLASSES **/
 .left { float:left }
-.append-bottom-10 { margin-bottom:10px }
-.append-bottom-20 { margin-bottom:20px }
+
 .prepend-top-10 { margin-top:10px }
 .prepend-top-20 { margin-top:20px }
+.prepend-left-10 { margin-left:10px }
+.prepend-left-20 { margin-left:20px }
+.append-right-10 { margin-right:10px }
+.append-right-20 { margin-right:20px }
+.append-bottom-10 { margin-bottom:10px }
+.append-bottom-20 { margin-bottom:20px }
+
 .padded { padding:20px }
 .ipadded { padding:20px!important }
 .lborder { border-left:1px solid #eee }
@@ -31,8 +37,6 @@
   border-color: #DDD;
 }
 
-.well { padding: 15px; }
-
 /** HELPERS **/
 .nothing_here_message {
   text-align: center;
@@ -65,13 +69,6 @@ fieldset legend { font-size: 17px; }
 
 /** PAGINATION **/
 .gitlab_pagination {
-  span a { color: $link_color; }
-  .prev, .next, .current, .page a {
-    padding: 10px;
-  }
-  .current {
-    border-bottom: 2px solid $style_color;
-  }
 }
 
 .tab-content {
diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
index 0f893a553ee..e661e02623e 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
@@ -69,5 +69,14 @@ ul.bordered-list {
     display: block;
     margin: 0px;
     &:last-child { border:none }
+
+    &.active {
+      background: #f9f9f9;
+      a { font-weight: bold; }
+    }
+
+    &.light {
+      a { color: #777; }
+    }
   }
 }
diff --git a/app/assets/stylesheets/gitlab_bootstrap/nav.scss b/app/assets/stylesheets/gitlab_bootstrap/nav.scss
index 2eaef61ca33..0fc8b21de7b 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/nav.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/nav.scss
@@ -16,7 +16,7 @@
       padding: 12px;
     }
     > .active > a {
-      border-color: #29B;
+      border-color: $primary_color;
       border-radius: 0;
       background: #F1F1F1;
       color: $style_color;
diff --git a/app/assets/stylesheets/sections/admin.scss b/app/assets/stylesheets/sections/admin.scss
index 18b102d7022..e189fd27ac6 100644
--- a/app/assets/stylesheets/sections/admin.scss
+++ b/app/assets/stylesheets/sections/admin.scss
@@ -1,3 +1,21 @@
+/**
+ * Admin area
+ *
+ */
+.admin_dash {
+  .data {
+    a {
+      h1 {
+        line-height: 48px;
+        font-size: 48px;
+        padding: 20px;
+        text-align: center;
+        font-weight: normal;
+      }
+    }
+  }
+}
+
 .admin-filter form {
   label { width: 110px; }
   .controls { margin-left: 130px; }
diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss
index 1e564188892..51a307e4d4e 100644
--- a/app/assets/stylesheets/sections/commits.scss
+++ b/app/assets/stylesheets/sections/commits.scss
@@ -348,7 +348,7 @@
 
   .notes_count {
     float: right;
-    margin: -6px 8px 6px;
+    margin-right: 10px;
   }
 
   code {
@@ -369,19 +369,25 @@
 }
 
 .file-stats {
-  .new-file{
-    i{
+  .new-file {
+    a {
+      color: #090;
+    }
+    i {
       color: #1BCF00;
     }
   }
-  .renamed-file{
-    i{
+  .renamed-file {
+    i {
       color: #FE9300;
     }
   }
-  .deleted-file{
-    i{
-      color: #FF0000;
+  .deleted-file {
+    a {
+      color: #B00;
+    }
+    i {
+      color: #EE0000;
     }
   }
   .edit-file{
diff --git a/app/assets/stylesheets/sections/dashboard.scss b/app/assets/stylesheets/sections/dashboard.scss
new file mode 100644
index 00000000000..9bc4a09a097
--- /dev/null
+++ b/app/assets/stylesheets/sections/dashboard.scss
@@ -0,0 +1,48 @@
+.dashboard {
+  @extend .row;
+  .activities {
+  }
+
+  .side {
+    @extend .pull-right;
+
+    .ui-box {
+      margin: 3px;
+      > .title {
+        padding: 2px 15px;
+      }
+      .nav-projects-tabs li { padding: 0; }
+      .well-list {
+        li { padding: 15px; }
+        .arrow {
+          float: right;
+          padding: 10px;
+          margin: 0;
+        }
+        .last_activity {
+          padding-top: 5px;
+          display: block;
+          span, strong {
+            font-size: 12px;
+            color: #666;
+          }
+        }
+      }
+      @extend .ui-box;
+    }
+  }
+}
+
+.dashboard-search-filter {
+  padding:5px;
+
+  .search-text-input {
+    float:left;
+    @extend .span2;
+  }
+  .btn {
+    margin-left: 5px;
+    float:left;
+  }
+}
+
diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss
index 94e1d0b609c..40f35b65da6 100644
--- a/app/assets/stylesheets/sections/events.scss
+++ b/app/assets/stylesheets/sections/events.scss
@@ -35,13 +35,14 @@
   .event-title {
     color: #333;
     font-weight: bold;
+    font-size: 14px;
     .author_name {
       color: #333;
     }
   }
   .event-body {
     .commit p {
-      color: #555;
+      color: #666;
       padding-top: 5px;
     }
     .event-info {
@@ -123,7 +124,7 @@
   color: #777;
   padding: 10px;
   min-height: 22px;
-  border-left: 5px solid #5AB9C3;
+  border-left: 5px solid $primary_color;
   margin-bottom: 20px;
   background: #f9f9f9;
 
@@ -132,10 +133,10 @@
   }
 
   .btn-new-mr {
-    @extend .btn-info;
+    @extend .btn-primary;
     @extend .small;
     @extend .pull-right;
-    margin: -3px;
+    margin: -2px;
   }
 }
 
@@ -151,7 +152,7 @@
   .filter_icon {
     a {
       text-align:center;
-      border-left: 3px solid #29B;
+      border-left: 3px solid $primary_color;
       background: #f9f9f9;
       margin-bottom: 10px;
       float: left;
diff --git a/app/assets/stylesheets/sections/graph.scss b/app/assets/stylesheets/sections/graph.scss
index 5800098ade4..7da00719b33 100644
--- a/app/assets/stylesheets/sections/graph.scss
+++ b/app/assets/stylesheets/sections/graph.scss
@@ -12,7 +12,7 @@
   .graph { 
     background: #f1f1f1;
     cursor: move;
-    height: 70%;
+    height: 500px;
     overflow: hidden;
   }
 }
diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss
index 351f2404492..5a1b476fe25 100644
--- a/app/assets/stylesheets/sections/issues.scss
+++ b/app/assets/stylesheets/sections/issues.scss
@@ -1,22 +1,39 @@
-.issues_table {
+.issues-list {
   .issue {
     padding: 10px;
+    position: relative;
 
-    .issue_check {
+    .issue-title {
+      margin-bottom: 5px;
+      font-size: 14px;
+    }
+
+    .issue-info {
+      color: #999;
+    }
+
+    .issue-check {
       float: left;
       padding: 8px 0;
       padding-right: 8px;
       min-width: 15px;
     }
 
-    p {
-      padding-top: 0;
-      padding-bottom: 2px;
+    .issue-labels {
+      display: inline-block;
+    }
+
+    .issue-actions {
+      display: none;
+      position: absolute;
+      top: 10px;
+      right: 2px;
     }
 
-    img.avatar {
-      width: 32px;
-      margin-top: 1px;
+    &:hover {
+      .issue-actions {
+        display: block;
+      }
     }
   }
 }
@@ -60,7 +77,7 @@ input.check_all_issues {
 @media (min-width: 800px)  { .issues_bulk_update select { width: 120px; }  }
 @media (min-width: 1200px) { .issues_bulk_update select { width: 160px; }  }
 
-#issues-table-holder {
+.issues-holder {
   .issues_filters {
   }
 
diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index 4cca0083e44..a84ef71e743 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -53,18 +53,6 @@
   }
 }
 
-li.merge_request {
-  padding: 10px;
-  img.avatar {
-    width: 32px;
-    margin-top: 1px;
-  }
-  p {
-    padding: 0px;
-    padding-bottom: 2px;
-  }
-}
-
 .merge-in-progress {
   @extend .padded;
   @extend .append-bottom-10;
@@ -97,3 +85,31 @@ li.merge_request {
 .mr_direction_tip {
   margin-top:40px
 }
+
+.label-branch {
+  @include border-radius(4px);
+  padding: 2px 4px;
+  border: none;
+  font-size: 14px;
+  background: #474D57;
+  color: #fff;
+  font-family: $monospace_font;
+  text-shadow: 0 1px 1px #111;
+  font-weight: normal;
+}
+
+.mr-list {
+  .merge-request {
+    padding: 10px;
+    position: relative;
+
+    .merge-request-title {
+      margin-bottom: 5px;
+      font-size: 14px;
+    }
+
+    .merge-request-info {
+      color: #999;
+    }
+  }
+}
diff --git a/app/assets/stylesheets/sections/nav.scss b/app/assets/stylesheets/sections/nav.scss
index 50091cd7365..514b0b7c69f 100644
--- a/app/assets/stylesheets/sections/nav.scss
+++ b/app/assets/stylesheets/sections/nav.scss
@@ -1,68 +1,64 @@
-/*
- *  Main Menu of Application
- *
- */
-ul.main_menu {
-  margin: auto;
+.main-nav {
   margin: 30px 0;
   margin-top: 10px;
-  height: 38px;
-  position: relative;
-  overflow: hidden;
-  .count {
+  border-bottom: 1px solid #E1E1E1;
+
+  ul {
+    margin: auto;
+    height: 39px;
     position: relative;
-    top: -1px;
-    display: inline-block;
-    height: 15px;
-    margin: 0 0 0 5px;
-    padding: 0 8px 1px 8px;
-    height: auto;
-    font-size: 0.82em;
-    line-height: 14px;
-    text-align: center;
-    color: #777;
-  }
-  .label {
-    background: $hover;
-    text-shadow: none;
-    color: $style_color;
-  }
-  li {
-    list-style-type: none;
-    margin: 0;
-    display: table-cell;
-    width: 1%;
-    border-bottom: 2px solid #EEE;
-    &.active {
-      border-bottom: 2px solid #474D57;
-      a {
-        color: $style_color;
-      }
+    top: 3px;
+    overflow: hidden;
+    .count {
+      position: relative;
+      top: -1px;
+      display: inline-block;
+      height: 15px;
+      margin: 0 0 0 5px;
+      padding: 0 8px 1px 8px;
+      height: auto;
+      font-size: 0.82em;
+      line-height: 14px;
+      text-align: center;
+      color: #777;
+    }
+    .label {
+      background: $hover;
+      text-shadow: none;
+      color: $style_color;
     }
+    li {
+      list-style-type: none;
+      margin: 0;
+      display: table-cell;
+      width: 1%;
+      &.active {
+        border-bottom: 3px solid #777;
+        a {
+          color: $style_color;
+          font-weight: bolder;
+        }
+      }
 
-    &.home {
-      a {
-        i {
-          font-size: 20px;
-          position: relative;
-          top: 4px;
+      &.home {
+        a {
+          i {
+            font-size: 20px;
+            position: relative;
+            top: 4px;
+          }
         }
       }
     }
-  }
-  a {
-    display: block;
-    text-align: center;
-    font-weight: normal;
-    height: 36px;
-    line-height: 36px;
-    color: #777;
-    text-shadow: 0 1px 1px white;
-    padding: 0 10px;
+    a {
+      display: block;
+      text-align: center;
+      font-weight: normal;
+      height: 36px;
+      line-height: 34px;
+      color: #777;
+      text-shadow: 0 1px 1px white;
+      padding: 0 10px;
+    }
   }
 }
-/*
- *  End of Main Menu
- *
- */
-
diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss
index ae2e1b258d3..a8628fc58f2 100644
--- a/app/assets/stylesheets/sections/notes.scss
+++ b/app/assets/stylesheets/sections/notes.scss
@@ -274,6 +274,15 @@ ul.notes {
 }
 
 
+.common-note-form {
+  margin: 0;
+  height: 140px;
+  background: #F9F9F9;
+  padding: 3px;
+  padding-bottom: 25px;
+  border: 1px solid #DDD;
+}
+
 
 .note-form-actions {
   background: #F9F9F9;
@@ -281,8 +290,8 @@ ul.notes {
   padding: 0 5px;
 
   .note-form-option {
-    margin-top: 8px;
-    margin-left: 15px;
+    margin-top: 10px;
+    margin-left: 30px;
     @extend .pull-left;
   }
 
diff --git a/app/assets/stylesheets/sections/profile.scss b/app/assets/stylesheets/sections/profile.scss
index 607daf7a97e..c34cd23a9c9 100644
--- a/app/assets/stylesheets/sections/profile.scss
+++ b/app/assets/stylesheets/sections/profile.scss
@@ -20,3 +20,16 @@
     border: 1px solid #ddd;
   }
 }
+
+.save-status-fixed {
+  position: fixed;
+  left: 20px;
+  bottom: 50px;
+}
+
+.update-notifications {
+  margin-bottom: 0;
+  label {
+    margin-bottom: 0;
+  }
+}
diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss
index b6b1423e7d0..6c890d3420d 100644
--- a/app/assets/stylesheets/sections/projects.scss
+++ b/app/assets/stylesheets/sections/projects.scss
@@ -1,38 +1,3 @@
-.projects {
-  @extend .row;
-  .activities {
-  }
-
-  .side {
-    @extend .pull-right;
-
-    .ui-box {
-      margin: 3px;
-      > .title {
-        padding: 2px 15px;
-      }
-      .nav-projects-tabs li { padding: 0; }
-      .well-list {
-        li { padding: 15px; }
-        .arrow {
-          float: right;
-          padding: 10px;
-          margin: 0;
-        }
-        .last_activity {
-          padding-top: 5px;
-          display: block;
-          span, strong {
-            font-size: 12px;
-            color: #666;
-          }
-        }
-      }
-      @extend .ui-box;
-    }
-  }
-}
-
 .new_project,
 .edit_project {
   .project_name_holder {
diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss
index def440c7134..ffde6aa3fa6 100644
--- a/app/assets/stylesheets/sections/tree.scss
+++ b/app/assets/stylesheets/sections/tree.scss
@@ -97,7 +97,7 @@
 
 .tree-btn-group {
   .btn {
-    margin-right:-3px;
+    margin-right: 0px;
     padding: 2px 10px;
   }
 }
diff --git a/app/assets/stylesheets/sections/votes.scss b/app/assets/stylesheets/sections/votes.scss
index 4686f5422dc..6c81d9a81b8 100644
--- a/app/assets/stylesheets/sections/votes.scss
+++ b/app/assets/stylesheets/sections/votes.scss
@@ -35,9 +35,4 @@
 .votes-inline {
   display: inline-block;
   margin: 0 8px;
-  .progress {
-    display: inline-block;
-    padding: 0 0 2px;
-    width: 45px;
-  }
 }
diff --git a/app/assets/stylesheets/sections/wall.scss b/app/assets/stylesheets/sections/wall.scss
index 598d9df8a6a..d6ac08fcf6f 100644
--- a/app/assets/stylesheets/sections/wall.scss
+++ b/app/assets/stylesheets/sections/wall.scss
@@ -14,12 +14,31 @@
 
   .notes {
     margin-bottom: 160px;
+    background: #FFE;
+    border: 1px solid #EED;
+
+    > li {
+      @extend .clearfix;
+      border-bottom: 1px solid #EED;
+      padding: 10px;
+    }
 
     .wall-author {
       color: #666;
-      margin-right: 10px;
-      border-right: 1px solid #CCC;
-      padding-right: 5px
+      float: left;
+      font-size: 12px;
+      width: 120px;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      overflow: hidden;
+    }
+
+    .wall-text {
+      border-left: 1px solid #CCC;
+      margin-left: 10px;
+      padding-left: 10px;
+      float: left;
+      width: 75%;
     }
 
     .wall-file {
diff --git a/app/assets/stylesheets/selects.scss b/app/assets/stylesheets/selects.scss
index 07f7db75ffc..7abbe80bd39 100644
--- a/app/assets/stylesheets/selects.scss
+++ b/app/assets/stylesheets/selects.scss
@@ -1,3 +1,13 @@
+/* CHZN reset few styles */
+.chzn-container-single .chzn-single {
+  background: #FFF;
+  border: 1px solid #bbb;
+  box-shadow: none;
+}
+.chzn-container-active .chzn-single {
+  background: #fff;
+}
+
 .ajax-users-select {
   width: 400px;
 }
diff --git a/app/contexts/commit_load_context.rb b/app/contexts/commit_load_context.rb
index 1f23f633af3..2cf5420d62d 100644
--- a/app/contexts/commit_load_context.rb
+++ b/app/contexts/commit_load_context.rb
@@ -12,7 +12,6 @@ class CommitLoadContext < BaseContext
     commit = project.repository.commit(params[:id])
 
     if commit
-      commit = CommitDecorator.decorate(commit)
       line_notes = project.notes.for_commit_id(commit.id).inline
 
       result[:commit] = commit
diff --git a/app/contexts/notes/create_context.rb b/app/contexts/notes/create_context.rb
index 1367dff4699..36ea76ff949 100644
--- a/app/contexts/notes/create_context.rb
+++ b/app/contexts/notes/create_context.rb
@@ -3,8 +3,6 @@ module Notes
     def execute
       note = project.notes.new(params[:note])
       note.author = current_user
-      note.notify = params[:notify].present?
-      note.notify_author = params[:notify_author].present?
       note.save
       note
     end
diff --git a/app/contexts/projects/transfer_context.rb b/app/contexts/projects/transfer_context.rb
new file mode 100644
index 00000000000..aed396a5da5
--- /dev/null
+++ b/app/contexts/projects/transfer_context.rb
@@ -0,0 +1,27 @@
+module Projects
+  class TransferContext < BaseContext
+    def execute(role = :default)
+      namespace_id = params[:project].delete(:namespace_id)
+      allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin
+
+      if allowed_transfer && namespace_id.present?
+        if namespace_id == Namespace.global_id
+          if project.namespace.present?
+            # Transfer to global namespace from anyone
+            project.transfer(nil)
+          end
+        elsif namespace_id.to_i != project.namespace_id
+          # Transfer to someone namespace
+          namespace = Namespace.find(namespace_id)
+          project.transfer(namespace)
+        end
+      end
+
+    rescue ProjectTransferService::TransferError => ex
+      project.reload
+      project.errors.add(:namespace_id, ex.message)
+      false
+    end
+  end
+end
+
diff --git a/app/contexts/projects/update_context.rb b/app/contexts/projects/update_context.rb
index e5d09b7df7f..40385fa65b0 100644
--- a/app/contexts/projects/update_context.rb
+++ b/app/contexts/projects/update_context.rb
@@ -1,24 +1,8 @@
 module Projects
   class UpdateContext < BaseContext
     def execute(role = :default)
-      namespace_id = params[:project].delete(:namespace_id)
+      params[:project].delete(:namespace_id)
       params[:project].delete(:public) unless can?(current_user, :change_public_mode, project)
-
-      allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin
-
-      if allowed_transfer && namespace_id.present?
-        if namespace_id == Namespace.global_id
-          if project.namespace.present?
-            # Transfer to global namespace from anyone
-            project.transfer(nil)
-          end
-        elsif namespace_id.to_i != project.namespace_id
-          # Transfer to someone namespace
-          namespace = Namespace.find(namespace_id)
-          project.transfer(namespace)
-        end
-      end
-
       project.update_attributes(params[:project], as: role)
     end
   end
diff --git a/app/contexts/search_context.rb b/app/contexts/search_context.rb
index 9becb8d674f..de6542e82f4 100644
--- a/app/contexts/search_context.rb
+++ b/app/contexts/search_context.rb
@@ -13,7 +13,7 @@ class SearchContext
     result[:projects] = Project.where(id: project_ids).search(query).limit(10)
     result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
     result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
-    result[:wiki_pages] = Wiki.where(project_id: project_ids).search(query).limit(10)
+    result[:wiki_pages] = []
     result
   end
 
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index f552fb595b8..df520bea773 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -69,7 +69,7 @@ class Admin::GroupsController < Admin::ApplicationController
 
   def project_teams_update
     @group.add_users_to_project_teams(params[:user_ids], params[:project_access])
-    redirect_to [:admin, @group], notice: 'Users was successfully added.'
+    redirect_to [:admin, @group], notice: 'Users were successfully added.'
   end
 
   def destroy
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 8ae0bba9a2d..bbb80cbb839 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -19,34 +19,6 @@ class Admin::ProjectsController < Admin::ApplicationController
     @users = @users.all
   end
 
-  def edit
-  end
-
-  def team_update
-    @project.team.add_users_ids(params[:user_ids], params[:project_access])
-
-    redirect_to [:admin, @project], notice: 'Project was successfully updated.'
-  end
-
-  def update
-    project.creator = current_user unless project.creator
-
-    status = ::Projects::UpdateContext.new(project, current_user, params).execute(:admin)
-
-    if status
-      redirect_to [:admin, @project], notice: 'Project was successfully updated.'
-    else
-      render action: "edit"
-    end
-  end
-
-  def destroy
-    @project.team.truncate
-    @project.destroy
-
-    redirect_to admin_projects_path, notice: 'Project was successfully deleted.'
-  end
-
   protected
 
   def project
diff --git a/app/controllers/admin/teams/members_controller.rb b/app/controllers/admin/teams/members_controller.rb
index e6469874419..590617f67c9 100644
--- a/app/controllers/admin/teams/members_controller.rb
+++ b/app/controllers/admin/teams/members_controller.rb
@@ -1,7 +1,6 @@
 class Admin::Teams::MembersController < Admin::Teams::ApplicationController
   def new
     @users = User.potential_team_members(user_team)
-    @users = UserDecorator.decorate_collection @users
   end
 
   def create
@@ -12,7 +11,7 @@ class Admin::Teams::MembersController < Admin::Teams::ApplicationController
       user_team.add_members(user_ids, access, is_admin)
     end
 
-    redirect_to admin_team_path(user_team), notice: 'Members was successfully added into Team of users.'
+    redirect_to admin_team_path(user_team), notice: 'Members were successfully added into Team of users.'
   end
 
   def edit
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 43e6f09904f..3075e7502f3 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -14,7 +14,7 @@ class Admin::UsersController < Admin::ApplicationController
     @not_in_projects = @not_in_projects.without_user(admin_user) if admin_user.authorized_projects.present?
 
     # Projects he already own or joined
-    @projects = admin_user.authorized_projects.where('projects.id in (?)', admin_user.authorized_projects.map(&:id))
+    @projects = admin_user.authorized_projects
   end
 
   def team_update
@@ -84,6 +84,8 @@ class Admin::UsersController < Admin::ApplicationController
         format.html { redirect_to [:admin, admin_user], notice: 'User was successfully updated.' }
         format.json { head :ok }
       else
+        # restore username to keep form action url.
+        admin_user.username = params[:id]
         format.html { render action: "edit" }
         format.json { render json: admin_user.errors, status: :unprocessable_entity }
       end
diff --git a/app/controllers/blame_controller.rb b/app/controllers/blame_controller.rb
index 37d7245ccb4..c950af56e26 100644
--- a/app/controllers/blame_controller.rb
+++ b/app/controllers/blame_controller.rb
@@ -7,10 +7,8 @@ class BlameController < ProjectResourceController
   before_filter :authorize_code_access!
   before_filter :require_non_empty_project
 
-  before_filter :assign_ref_vars
-
   def show
-    @repo = @project.repo
-    @blame = Grit::Blob.blame(@repo, @commit.id, @path)
+    @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
+    @blame = Gitlab::Git::Blame.new(project.repository, @commit.id, @path)
   end
 end
diff --git a/app/controllers/blob_controller.rb b/app/controllers/blob_controller.rb
index d4a45d9508e..3547dfe2323 100644
--- a/app/controllers/blob_controller.rb
+++ b/app/controllers/blob_controller.rb
@@ -7,18 +7,7 @@ class BlobController < ProjectResourceController
   before_filter :authorize_code_access!
   before_filter :require_non_empty_project
 
-  before_filter :assign_ref_vars
-
   def show
-    if @tree.is_blob?
-      send_data(
-        @tree.data,
-        type: @tree.mime_type,
-        disposition: 'inline',
-        filename: @tree.name
-      )
-    else
-      not_found!
-    end
+    @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
   end
 end
diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb
index 9dc0d96883e..cde1f459d76 100644
--- a/app/controllers/commits_controller.rb
+++ b/app/controllers/commits_controller.rb
@@ -13,7 +13,6 @@ class CommitsController < ProjectResourceController
     @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
 
     @commits = @repo.commits(@ref, @path, @limit, @offset)
-    @commits = CommitDecorator.decorate_collection(@commits)
 
     respond_to do |format|
       format.html # index.html.erb
diff --git a/app/controllers/compare_controller.rb b/app/controllers/compare_controller.rb
index bd3f1115173..750e9c2380e 100644
--- a/app/controllers/compare_controller.rb
+++ b/app/controllers/compare_controller.rb
@@ -8,15 +8,13 @@ class CompareController < ProjectResourceController
   end
 
   def show
-    result = Commit.compare(project, params[:from], params[:to])
+    compare = Gitlab::Git::Compare.new(project.repository, params[:from], params[:to])
 
-    @commits       = result[:commits]
-    @commit        = result[:commit]
-    @diffs         = result[:diffs]
-    @refs_are_same = result[:same]
+    @commits       = compare.commits
+    @commit        = compare.commit
+    @diffs         = compare.diffs
+    @refs_are_same = compare.same
     @line_notes    = []
-
-    @commits = CommitDecorator.decorate_collection(@commits)
   end
 
   def create
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 91a67985710..f651b02c1e5 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -34,6 +34,7 @@ class DashboardController < ApplicationController
                   @projects
                 end
 
+    @projects = @projects.tagged_with(params[:label]) if params[:label].present?
     @projects = @projects.search(params[:search]) if params[:search].present?
     @projects = @projects.page(params[:page]).per(30)
   end
diff --git a/app/controllers/edit_tree_controller.rb b/app/controllers/edit_tree_controller.rb
new file mode 100644
index 00000000000..9ed7a2143e4
--- /dev/null
+++ b/app/controllers/edit_tree_controller.rb
@@ -0,0 +1,49 @@
+# Controller for edit a repository's file
+class EditTreeController < ProjectResourceController
+  include ExtractsPath
+
+  # Authorize
+  before_filter :authorize_read_project!
+  before_filter :authorize_code_access!
+  before_filter :require_non_empty_project
+
+  before_filter :edit_requirements, only: [:show, :update]
+
+  def show
+    @last_commit = @project.repository.last_commit_for(@ref, @path).sha
+  end
+
+  def update
+    edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
+    updated_successfully = edit_file_action.commit!(
+      params[:content],
+      params[:commit_message],
+      params[:last_commit]
+    )
+
+    if updated_successfully
+      redirect_to project_blob_path(@project, @id), notice: "Your changes have been successfully commited"
+    else
+      flash[:notice] = "Your changes could not be commited, because the file has been changed"
+      render :show
+    end
+  end
+
+  private
+
+  def edit_requirements
+    @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
+
+    unless @blob.exists? && @blob.text?
+      redirect_to project_blob_path(@project, @id), notice: "You can only edit text files"
+    end
+
+    allowed = if project.protected_branch? @ref
+                can?(current_user, :push_code_to_protected_branches, project)
+              else
+                can?(current_user, :push_code, project)
+              end
+
+    return access_denied! unless allowed
+  end
+end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index bdf3567fef2..8976262f4f7 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -73,7 +73,7 @@ class GroupsController < ApplicationController
 
   def team_members
     @group.add_users_to_project_teams(params[:user_ids], params[:project_access])
-    redirect_to people_group_path(@group), notice: 'Users was successfully added.'
+    redirect_to people_group_path(@group), notice: 'Users were successfully added.'
   end
 
   def edit
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 9917d198cbf..0739e7c78da 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -14,7 +14,10 @@ class IssuesController < ProjectResourceController
   respond_to :js, :html
 
   def index
+    terms = params['issue_search']
+
     @issues = issues_filtered
+    @issues = @issues.where("title LIKE ?", "%#{terms}%") if terms.present?
     @issues = @issues.page(params[:page]).per(20)
 
     respond_to do |format|
@@ -76,28 +79,6 @@ class IssuesController < ProjectResourceController
     end
   end
 
-  def sort
-    return render_404 unless can?(current_user, :admin_issue, @project)
-
-    @issues = @project.issues.where(id: params['issue'])
-    @issues.each do |issue|
-      issue.position = params['issue'].index(issue.id.to_s) + 1
-      issue.save
-    end
-
-    render nothing: true
-  end
-
-  def search
-    terms = params['terms']
-
-    @issues = issues_filtered
-    @issues = @issues.where("title LIKE ?", "%#{terms}%") unless terms.blank?
-    @issues = @issues.page(params[:page]).per(100)
-
-    render partial: 'issues'
-  end
-
   def bulk_update
     result = IssuesBulkUpdateContext.new(project, current_user, params).execute
     redirect_to :back, notice: "#{result[:count]} issues updated"
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index 88e0df16409..17c0392c384 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -20,9 +20,6 @@ class MergeRequestsController < ProjectResourceController
   end
 
   def show
-    @target_type = :merge_request
-    @target_id = @merge_request.id
-
     respond_to do |format|
       format.html
       format.js
@@ -94,12 +91,10 @@ class MergeRequestsController < ProjectResourceController
 
   def branch_from
     @commit = @repository.commit(params[:ref])
-    @commit = CommitDecorator.decorate(@commit)
   end
 
   def branch_to
     @commit = @repository.commit(params[:ref])
-    @commit = CommitDecorator.decorate(@commit)
   end
 
   def ci_status
@@ -129,11 +124,11 @@ class MergeRequestsController < ProjectResourceController
 
   def validates_merge_request
     # Show git not found page if target branch doesn't exist
-    return invalid_mr unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch)
+    return invalid_mr unless @project.repository.branch_names.include?(@merge_request.target_branch)
 
     # Show git not found page if source branch doesn't exist
     # and there is no saved commits between source & target branch
-    return invalid_mr if !@project.repo.heads.map(&:name).include?(@merge_request.source_branch) && @merge_request.commits.blank?
+    return invalid_mr if !@project.repository.branch_names.include?(@merge_request.source_branch) && @merge_request.commits.blank?
   end
 
   def define_show_vars
@@ -143,10 +138,12 @@ class MergeRequestsController < ProjectResourceController
     # Get commits from repository
     # or from cache if already merged
     @commits = @merge_request.commits
-    @commits = CommitDecorator.decorate_collection(@commits)
 
     @allowed_to_merge = allowed_to_merge?
     @show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge
+
+    @target_type = :merge_request
+    @target_id = @merge_request.id
   end
 
   def allowed_to_merge?
diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb
index cdac28c1bde..25647f97576 100644
--- a/app/controllers/milestones_controller.rb
+++ b/app/controllers/milestones_controller.rb
@@ -14,7 +14,7 @@ class MilestonesController < ProjectResourceController
     @milestones = case params[:f]
                   when 'all'; @project.milestones.order("state, due_date DESC")
                   when 'closed'; @project.milestones.closed.order("due_date DESC")
-                  else @project.milestones.active.order("due_date ASC")
+                  else @project.milestones.active.order("due_date DESC")
                   end
 
     @milestones = @milestones.includes(:project)
@@ -32,7 +32,7 @@ class MilestonesController < ProjectResourceController
 
   def show
     @issues = @milestone.issues
-    @users = UserDecorator.decorate_collection(@milestone.participants)
+    @users = @milestone.participants.uniq
     @merge_requests = @milestone.merge_requests
 
     respond_to do |format|
diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb
index 000c7bbb641..15ca963f281 100644
--- a/app/controllers/notes_controller.rb
+++ b/app/controllers/notes_controller.rb
@@ -71,7 +71,6 @@ class NotesController < ProjectResourceController
 
   # Helps to distinguish e.g. commit notes in mr notes list
   def note_for_main_target?(note)
-    note.for_wall? ||
-      (@target_type.camelize == note.noteable_type && !note.for_diff_line?)
+    (@target_type.camelize == note.noteable_type && !note.for_diff_line?)
   end
 end
diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb
new file mode 100644
index 00000000000..4aa3172912f
--- /dev/null
+++ b/app/controllers/notifications_controller.rb
@@ -0,0 +1,21 @@
+class NotificationsController < ApplicationController
+  layout 'profile'
+
+  def show
+    @notification = current_user.notification
+    @users_projects = current_user.users_projects
+  end
+
+  def update
+    type = params[:notification_type]
+
+    @saved = if type == 'global'
+               current_user.notification_level = params[:notification_level]
+               current_user.save
+             else
+               users_project = current_user.users_projects.find(params[:notification_id])
+               users_project.notification_level = params[:notification_level]
+               users_project.save
+             end
+  end
+end
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 684f0e85485..46f6219c08d 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -76,7 +76,7 @@ class ProfilesController < ApplicationController
     # validation for this fields
     %w(name skype linkedin twitter bio).each do |attr|
       value = user_attributes[attr]
-      user_attributes[attr] = sanitize(value) if value.present?
+      user_attributes[attr] = sanitize(strip_tags(value)) if value.present?
     end
 
     user_attributes
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index f2718344a3d..8e55aa01cc9 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -4,7 +4,7 @@ class ProjectsController < ProjectResourceController
 
   # Authorize
   before_filter :authorize_read_project!, except: [:index, :new, :create]
-  before_filter :authorize_admin_project!, only: [:edit, :update, :destroy]
+  before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer]
   before_filter :require_non_empty_project, only: [:blob, :tree, :graph]
 
   layout 'application', only: [:new, :create]
@@ -45,10 +45,10 @@ class ProjectsController < ProjectResourceController
         format.js
       end
     end
+  end
 
-  rescue Project::TransferError => ex
-    @error = ex
-    render :update_failed
+  def transfer
+    ::Projects::TransferContext.new(project, current_user, params).execute
   end
 
   def show
@@ -57,11 +57,11 @@ class ProjectsController < ProjectResourceController
 
     respond_to do |format|
       format.html do
-        if @project.repository && !@project.repository.empty?
+        if @project.empty_repo?
+          render "projects/empty"
+        else
           @last_push = current_user.recent_push(@project.id)
           render :show
-        else
-          render "projects/empty"
         end
       end
       format.js
diff --git a/app/controllers/raw_controller.rb b/app/controllers/raw_controller.rb
new file mode 100644
index 00000000000..18b401fe611
--- /dev/null
+++ b/app/controllers/raw_controller.rb
@@ -0,0 +1,25 @@
+# Controller for viewing a file's raw
+class RawController < ProjectResourceController
+  include ExtractsPath
+
+  # Authorize
+  before_filter :authorize_read_project!
+  before_filter :authorize_code_access!
+  before_filter :require_non_empty_project
+
+  def show
+    @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
+
+    if @blob.exists?
+      send_data(
+        @blob.data,
+        type: @blob.mime_type,
+        disposition: 'inline',
+        filename: @blob.name
+      )
+    else
+      not_found!
+    end
+  end
+end
+
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index 0e4dba3dc4b..e116bc358c9 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -30,11 +30,10 @@ class RefsController < ProjectResourceController
   end
 
   def logs_tree
-    contents = @tree.contents
+    contents = @tree.entries
     @logs = contents.map do |content|
       file = params[:path] ? File.join(params[:path], content.name) : content.name
       last_commit = @repo.commits(@commit.id, file, 1).last
-      last_commit = CommitDecorator.decorate(last_commit)
       {
         file_name: content.name,
         commit: last_commit
@@ -49,9 +48,7 @@ class RefsController < ProjectResourceController
 
     @repo = project.repository
     @commit = @repo.commit(@ref)
-    @commit = CommitDecorator.decorate(@commit)
-    @tree = Tree.new(@commit.tree, @ref, params[:path])
-    @tree = TreeDecorator.new(@tree)
+    @tree = Tree.new(@repo, @commit.id, @ref, params[:path])
     @hex_path = Digest::SHA1.hexdigest(params[:path] || "")
 
     if params[:path]
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 229cb36949b..6fba2518306 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -17,7 +17,7 @@ class RepositoriesController < ProjectResourceController
   end
 
   def stats
-    @stats = Gitlab::GitStats.new(@repository.raw, @repository.root_ref)
+    @stats = Gitlab::Git::Stats.new(@repository.raw, @repository.root_ref)
     @graph = @stats.graph
   end
 
diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb
index ba55648adad..35aa315dac1 100644
--- a/app/controllers/team_members_controller.rb
+++ b/app/controllers/team_members_controller.rb
@@ -52,7 +52,7 @@ class TeamMembersController < ProjectResourceController
     status = @project.team.import(giver)
     notice = status ? "Succesfully imported" : "Import failed"
 
-    redirect_to project_team_members_path(project), notice: notice
+    redirect_to project_team_index_path(project), notice: notice
   end
 
   protected
diff --git a/app/controllers/teams/members_controller.rb b/app/controllers/teams/members_controller.rb
index f87d422f84e..8ef786d1a66 100644
--- a/app/controllers/teams/members_controller.rb
+++ b/app/controllers/teams/members_controller.rb
@@ -8,7 +8,6 @@ class Teams::MembersController < Teams::ApplicationController
 
   def new
     @users = User.potential_team_members(user_team)
-    @users = UserDecorator.decorate_collection @users
   end
 
   def create
@@ -19,7 +18,7 @@ class Teams::MembersController < Teams::ApplicationController
       user_team.add_members(user_ids, access, is_admin)
     end
 
-    redirect_to team_members_path(user_team), notice: 'Members was successfully added into Team of users.'
+    redirect_to team_members_path(user_team), notice: 'Members were successfully added into Team of users.'
   end
 
   def edit
diff --git a/app/controllers/tree_controller.rb b/app/controllers/tree_controller.rb
index 2151bd7cbbd..a03ea3ff30d 100644
--- a/app/controllers/tree_controller.rb
+++ b/app/controllers/tree_controller.rb
@@ -7,9 +7,6 @@ class TreeController < ProjectResourceController
   before_filter :authorize_code_access!
   before_filter :require_non_empty_project
 
-  before_filter :assign_ref_vars
-  before_filter :edit_requirements, only: [:edit, :update]
-
   def show
     @hex_path  = Digest::SHA1.hexdigest(@path)
     @logs_path = logs_file_project_ref_path(@project, @ref, @path)
@@ -20,40 +17,4 @@ class TreeController < ProjectResourceController
       format.js { no_cache_headers }
     end
   end
-
-  def edit
-    @last_commit = @project.repository.last_commit_for(@ref, @path).sha
-  end
-
-  def update
-    edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
-    updated_successfully = edit_file_action.commit!(
-      params[:content],
-      params[:commit_message],
-      params[:last_commit]
-    )
-
-    if updated_successfully
-      redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
-    else
-      flash[:notice] = "Your changes could not be commited, because the file has been changed"
-      render :edit
-    end
-  end
-
-  private
-
-  def edit_requirements
-    unless @tree.is_blob? && @tree.text?
-      redirect_to project_tree_path(@project, @id), notice: "You can only edit text files"
-    end
-
-    allowed = if project.protected_branch? @ref
-                can?(current_user, :push_code_to_protected_branches, project)
-              else
-                can?(current_user, :push_code, project)
-              end
-
-    return access_denied! unless allowed
-  end
 end
diff --git a/app/controllers/wikis_controller.rb b/app/controllers/wikis_controller.rb
index 940b1e97340..be9ae4f37a4 100644
--- a/app/controllers/wikis_controller.rb
+++ b/app/controllers/wikis_controller.rb
@@ -49,9 +49,9 @@ class WikisController < ProjectResourceController
   end
 
   def history
-    unless @wiki = @gollum_wiki.find_page(params[:id])
-      redirect_to project_wiki_path(@project, :home), notice: "Page not found"
-    end
+    @wiki = @gollum_wiki.find_page(params[:id])
+
+    redirect_to(project_wiki_path(@project, :home), notice: "Page not found") unless @wiki
   end
 
   def destroy
diff --git a/app/decorators/application_decorator.rb b/app/decorators/application_decorator.rb
deleted file mode 100644
index b805b3479b8..00000000000
--- a/app/decorators/application_decorator.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-class ApplicationDecorator < Draper::Decorator
-  delegate_all
-  # Lazy Helpers
-  #   PRO: Call Rails helpers without the h. proxy
-  #        ex: number_to_currency(model.price)
-  #   CON: Add a bazillion methods into your decorator's namespace
-  #        and probably sacrifice performance/memory
-  #
-  #   Enable them by uncommenting this line:
-  #   lazy_helpers
-
-  # Shared Decorations
-  #   Consider defining shared methods common to all your models.
-  #
-  #   Example: standardize the formatting of timestamps
-  #
-  #   def formatted_timestamp(time)
-  #     h.content_tag :span, time.strftime("%a %m/%d/%y"),
-  #                   class: 'timestamp'
-  #   end
-  #
-  #   def created_at
-  #     formatted_timestamp(model.created_at)
-  #   end
-  #
-  #   def updated_at
-  #     formatted_timestamp(model.updated_at)
-  #   end
-end
diff --git a/app/decorators/commit_decorator.rb b/app/decorators/commit_decorator.rb
deleted file mode 100644
index 0337d8d43ce..00000000000
--- a/app/decorators/commit_decorator.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-class CommitDecorator < ApplicationDecorator
-  decorates :commit
-
-  # Returns a string describing the commit for use in a link title
-  #
-  # Example
-  #
-  #   "Commit: Alex Denisov - Project git clone panel"
-  def link_title
-    "Commit: #{author_name} - #{title}"
-  end
-
-  # Returns the commits title.
-  #
-  # Usually, the commit title is the first line of the commit message.
-  # In case this first line is longer than 80 characters, it is cut off
-  # after 70 characters and ellipses (`&hellp;`) are appended.
-  def title
-    title = safe_message
-
-    return no_commit_message if title.blank?
-
-    title_end = title.index(/\n/)
-    if (!title_end && title.length > 80) || (title_end && title_end > 80)
-      title[0..69] << "&hellip;".html_safe
-    else
-      title.split(/\n/, 2).first
-    end
-  end
-
-  # Returns the commits description
-  #
-  # cut off, ellipses (`&hellp;`) are prepended to the commit message.
-  def description
-    description = safe_message
-
-    title_end = description.index(/\n/)
-    if (!title_end && description.length > 80) || (title_end && title_end > 80)
-      "&hellip;".html_safe << description[70..-1]
-    else
-      description.split(/\n/, 2)[1].try(:chomp)
-    end
-  end
-
-  # Returns a link to the commit author. If the author has a matching user and
-  # is a member of the current @project it will link to the team member page.
-  # Otherwise it will link to the author email as specified in the commit.
-  #
-  # options:
-  #  avatar: true will prepend the avatar image
-  #  size:   size of the avatar image in px
-  def author_link(options = {})
-    person_link(options.merge source: :author)
-  end
-
-  # Just like #author_link but for the committer.
-  def committer_link(options = {})
-    person_link(options.merge source: :committer)
-  end
-
-  protected
-
-  def no_commit_message
-    "--no commit message"
-  end
-
-  # Private: Returns a link to a person. If the person has a matching user and
-  # is a member of the current @project it will link to the team member page.
-  # Otherwise it will link to the person email as specified in the commit.
-  #
-  # options:
-  #  source: one of :author or :committer
-  #  avatar: true will prepend the avatar image
-  #  size:   size of the avatar image in px
-  def person_link(options = {})
-    source_name = send "#{options[:source]}_name".to_sym
-    source_email = send "#{options[:source]}_email".to_sym
-    text = if options[:avatar]
-            avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: ""
-            %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
-          else
-            source_name
-          end
-
-    user = User.where('name like ? or email like ?', source_name, source_email).first
-
-    if user.nil?
-      h.mail_to(source_email, text.html_safe, class: "commit-#{options[:source]}-link")
-    else
-      h.link_to(text.html_safe, h.user_path(user), class: "commit-#{options[:source]}-link")
-    end
-  end
-end
diff --git a/app/decorators/event_decorator.rb b/app/decorators/event_decorator.rb
deleted file mode 100644
index 1b0ad0da28f..00000000000
--- a/app/decorators/event_decorator.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-class EventDecorator < ApplicationDecorator
-  decorates :event
-
-  def feed_title
-    if self.issue?
-      "#{self.author_name} #{self.action_name} issue ##{self.target_id}: #{self.issue_title} at #{self.project.name}"
-    elsif self.merge_request?
-      "#{self.author_name} #{self.action_name} MR ##{self.target_id}: #{self.merge_request_title} at #{self.project.name}"
-    elsif self.push?
-      "#{self.author_name} #{self.push_action_name} #{self.ref_type} #{self.ref_name} at #{self.project.name}"
-    elsif self.membership_changed?
-      "#{self.author_name} #{self.action_name} #{self.project.name}"
-    else
-      ""
-    end
-  end
-
-  def feed_url
-    if self.issue?
-      h.project_issue_url(self.project, self.issue)
-    elsif self.merge_request?
-      h.project_merge_request_url(self.project, self.merge_request)
-
-    elsif self.push?
-      if self.push_with_commits?
-        if self.commits_count > 1
-          h.project_compare_url(self.project, :from => self.parent_commit.id, :to => self.last_commit.id)
-        else
-          h.project_commit_url(self.project, :id => self.last_commit.id)
-        end
-      else
-        h.project_commits_url(self.project, self.ref_name)
-      end
-    end
-  end
-
-  def feed_summary
-    if self.issue?
-      h.render "events/event_issue", issue: self.issue
-    elsif self.push?
-      h.render "events/event_push", event: self
-    end
-  end
-end
diff --git a/app/decorators/tree_decorator.rb b/app/decorators/tree_decorator.rb
deleted file mode 100644
index 0e760f97dee..00000000000
--- a/app/decorators/tree_decorator.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-class TreeDecorator < ApplicationDecorator
-  decorates :tree
-
-  def breadcrumbs(max_links = 2)
-    if path
-      part_path = ""
-      parts = path.split("\/")
-
-      yield('..', nil) if parts.count > max_links
-
-      parts.each do |part|
-        part_path = File.join(part_path, part) unless part_path.empty?
-        part_path = part if part_path.empty?
-
-        next unless parts.last(2).include?(part) if parts.count > max_links
-        yield(part, h.tree_join(ref, part_path))
-      end
-    end
-  end
-
-  def up_dir?
-    path.present?
-  end
-
-  def up_dir_path
-    file = File.join(path, "..")
-    h.tree_join(ref, file)
-  end
-
-  def readme
-    @readme ||= contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
-  end
-end
diff --git a/app/decorators/user_decorator.rb b/app/decorators/user_decorator.rb
deleted file mode 100644
index af9c6a63e75..00000000000
--- a/app/decorators/user_decorator.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class UserDecorator < ApplicationDecorator
-  decorates :user
-
-  def avatar_image size = 16
-    h.image_tag h.gravatar_icon(self.email, size), class: "avatar #{"s#{size}"}", width: size
-  end
-
-  def tm_of(project)
-    project.team_member_by_id(self.id)
-  end
-end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index f03039e4b75..6b3f0053f12 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -37,7 +37,7 @@ module ApplicationHelper
     if !Gitlab.config.gravatar.enabled || user_email.blank?
       'no_avatar.png'
     else
-      gravatar_url = request.ssl? ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
+      gravatar_url = request.ssl? || Gitlab.config.gitlab.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
       user_email.strip!
       sprintf gravatar_url, hash: Digest::MD5.hexdigest(user_email.downcase), size: size
     end
@@ -96,7 +96,7 @@ module ApplicationHelper
     ]
 
     project_nav = []
-    if @project && @project.repository && @project.repository.root_ref
+    if @project && @project.repository.exists? && @project.repository.root_ref
       project_nav = [
         { label: "#{simple_sanitize(@project.name_with_namespace)} - Issues",   url: project_issues_path(@project) },
         { label: "#{simple_sanitize(@project.name_with_namespace)} - Commits",  url: project_commits_path(@project, @ref || @project.repository.root_ref) },
@@ -137,13 +137,21 @@ module ApplicationHelper
     end
   end
 
+  # Define whenever show last push event
+  # with suggestion to create MR
   def show_last_push_widget?(event)
-    event &&
-      event.last_push_to_non_root? &&
-      !event.rm_ref? &&
-      event.project &&
-      event.project.repository &&
-      event.project.merge_requests_enabled
+    # Skip if event is not about added or modified non-master branch
+    return false unless event && event.last_push_to_non_root? && !event.rm_ref?
+
+    project = event.project
+
+    # Skip if project repo is empty or MR disabled
+    return false unless project && !project.empty_repo? && project.merge_requests_enabled
+
+    # Skip if user already created appropriate MR
+    return false if project.merge_requests.where(source_branch: event.branch_name).opened.any?
+
+    true
   end
 
   def hexdigest(string)
@@ -151,9 +159,8 @@ module ApplicationHelper
   end
 
   def project_last_activity project
-    activity = project.last_activity
-    if activity && activity.created_at
-      time_ago_in_words(activity.created_at) + " ago"
+    if project.last_activity_at
+      time_ago_in_words(project.last_activity_at) + " ago"
     else
       "Never"
     end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index acdd48e04eb..95ca294cd2d 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -1,4 +1,20 @@
 module CommitsHelper
+  # Returns a link to the commit author. If the author has a matching user and
+  # is a member of the current @project it will link to the team member page.
+  # Otherwise it will link to the author email as specified in the commit.
+  #
+  # options:
+  #  avatar: true will prepend the avatar image
+  #  size:   size of the avatar image in px
+  def commit_author_link(commit, options = {})
+    commit_person_link(commit, options.merge(source: :author))
+  end
+
+  # Just like #author_link but for the committer.
+  def commit_committer_link(commit, options = {})
+    commit_person_link(commit, options.merge(source: :committer))
+  end
+
   def identification_type(line)
     if line[0] == "+"
       "new"
@@ -93,9 +109,7 @@ module CommitsHelper
   end
 
   def commit_to_html commit
-    if commit.model
-      escape_javascript(render 'commits/commit', commit: commit)
-    end
+    escape_javascript(render 'commits/commit', commit: commit)
   end
 
   def diff_line_content(line)
@@ -105,4 +119,58 @@ module CommitsHelper
       line
     end
   end
+
+  # Breadcrumb links for a Project and, if applicable, a tree path
+  def commits_breadcrumbs
+    return unless @project && @ref
+
+    # Add the root project link and the arrow icon
+    crumbs = content_tag(:li) do
+      content_tag(:span, nil, class: 'arrow') +
+      link_to(@project.name, project_commits_path(@project, @ref))
+    end
+
+    if @path
+      parts = @path.split('/')
+
+      parts.each_with_index do |part, i|
+        crumbs += content_tag(:span, '/', class: 'divider')
+        crumbs += content_tag(:li) do
+          # The text is just the individual part, but the link needs all the parts before it
+          link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
+        end
+      end
+    end
+
+    crumbs.html_safe
+  end
+
+  protected
+
+  # Private: Returns a link to a person. If the person has a matching user and
+  # is a member of the current @project it will link to the team member page.
+  # Otherwise it will link to the person email as specified in the commit.
+  #
+  # options:
+  #  source: one of :author or :committer
+  #  avatar: true will prepend the avatar image
+  #  size:   size of the avatar image in px
+  def commit_person_link(commit, options = {})
+    source_name = commit.send "#{options[:source]}_name".to_sym
+    source_email = commit.send "#{options[:source]}_email".to_sym
+    text = if options[:avatar]
+            avatar = image_tag(gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "")
+            %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
+          else
+            source_name
+          end
+
+    user = User.where('name like ? or email like ?', source_name, source_email).first
+
+    if user.nil?
+      mail_to(source_email, text.html_safe, class: "commit-#{options[:source]}-link")
+    else
+      link_to(text.html_safe, user_path(user), class: "commit-#{options[:source]}-link")
+    end
+  end
 end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index 38374e3394d..7155036eeed 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -42,4 +42,45 @@ module EventsHelper
       EventFilter.team     => "icon-user",
     }
   end
+
+  def event_feed_title(event)
+    if event.issue?
+      "#{event.author_name} #{event.action_name} issue ##{event.target_id}: #{event.issue_title} at #{event.project.name}"
+    elsif event.merge_request?
+      "#{event.author_name} #{event.action_name} MR ##{event.target_id}: #{event.merge_request_title} at #{event.project.name}"
+    elsif event.push?
+      "#{event.author_name} #{event.push_action_name} #{event.ref_type} #{event.ref_name} at #{event.project.name}"
+    elsif event.membership_changed?
+      "#{event.author_name} #{event.action_name} #{event.project.name}"
+    else
+      ""
+    end
+  end
+
+  def event_feed_url(event)
+    if event.issue?
+      project_issue_url(event.project, event.issue)
+    elsif event.merge_request?
+      project_merge_request_url(event.project, event.merge_request)
+
+    elsif event.push?
+      if event.push_with_commits?
+        if event.commits_count > 1
+          project_compare_url(event.project, from: event.commit_from, to: event.commit_to)
+        else
+          project_commit_url(event.project, id: event.commit_to)
+        end
+      else
+        project_commits_url(event.project, event.ref_name)
+      end
+    end
+  end
+
+  def event_feed_summary(event)
+    if event.issue?
+      render "events/event_issue", issue: event.issue
+    elsif event.push?
+      render "events/event_push", event: event
+    end
+  end
 end
diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb
index 369330151f4..ca7d823a45a 100644
--- a/app/helpers/graph_helper.rb
+++ b/app/helpers/graph_helper.rb
@@ -1,6 +1,13 @@
 module GraphHelper
-  def join_with_space(ary)
-    ary.collect{|r|r.name}.join(" ") unless ary.nil?
+  def get_refs(commit)
+    refs = ""
+    refs += commit.refs.collect{|r|r.name}.join(" ") if commit.refs
+
+    # append note count
+    notes = @project.notes.for_commit_id(commit.id)
+    refs += "[#{notes.count}]" if notes.any?
+
+    refs
   end
 
   def parents_zip_spaces(parents, parent_spaces)
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 54385117c26..70ebbdd374a 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -48,19 +48,31 @@ module IssuesHelper
     if @project.used_default_issues_tracker?
       project_issues_filter_path(@project)
     else
-      url = Settings[:issues_tracker][@project.issues_tracker]["project_url"]
+      url = Gitlab.config.issues_tracker[@project.issues_tracker]["project_url"]
       url.gsub(':project_id', @project.id.to_s)
          .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s)
     end
   end
 
+  def url_for_new_issue
+    return "" if @project.nil?
+
+    if @project.used_default_issues_tracker?
+      url = new_project_issue_path project_id: @project
+    else
+      url = Gitlab.config.issues_tracker[@project.issues_tracker]["new_issue_url"]
+      url.gsub(':project_id', @project.id.to_s)
+        .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s)
+    end
+  end
+
   def url_for_issue(issue_id)
     return "" if @project.nil?
 
     if @project.used_default_issues_tracker?
       url = project_issue_url project_id: @project, id: issue_id
     else
-      url = Settings[:issues_tracker][@project.issues_tracker]["issues_url"]
+      url = Gitlab.config.issues_tracker[@project.issues_tracker]["issues_url"]
       url.gsub(':id', issue_id.to_s)
         .gsub(':project_id', @project.id.to_s)
         .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s)
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 155d03d1147..05ffec066f8 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -11,7 +11,7 @@ module MergeRequestsHelper
   end
 
   def mr_css_classes mr
-    classes = "merge_request"
+    classes = "merge-request"
     classes << " closed" if mr.closed?
     classes << " merged" if mr.merged?
     classes
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
new file mode 100644
index 00000000000..7342393a707
--- /dev/null
+++ b/app/helpers/notifications_helper.rb
@@ -0,0 +1,2 @@
+module NotificationsHelper
+end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index e6427ea84c0..9e7c4ee245a 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -3,6 +3,10 @@ module ProjectsHelper
     "You are going to remove #{user.name} from #{project.name} project team. Are you sure?"
   end
 
+  def projects_labels
+    Project.tag_counts_on(:labels).map(&:name)
+  end
+
   def link_to_project project
     link_to project do
       title = content_tag(:strong, project.name)
@@ -25,7 +29,7 @@ module ProjectsHelper
     author_html =  ""
 
     # Build avatar image tag
-    author_html << image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av") if opts[:avatar]
+    author_html << image_tag(gravatar_icon(author.try(:email)), width: 16, class: "avatar avatar-inline s16") if opts[:avatar]
 
     # Build name span tag
     author_html << content_tag(:span, sanitize(author.name), class: 'author')
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index fab0085ba73..e7002f60b8a 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -3,9 +3,9 @@ module TreeHelper
   # their corresponding partials
   #
   # contents - A Grit::Tree object for the current tree
-  def render_tree(contents)
+  def render_tree(tree)
     # Render Folders before Files/Submodules
-    folders, files = contents.partition { |v| v.kind_of?(Grit::Tree) }
+    folders, files = tree.trees, tree.blobs
 
     tree = ""
 
@@ -18,7 +18,7 @@ module TreeHelper
                render partial: 'tree/submodule_item', object: f
              else
                # Object is a Blob
-               render partial: 'tree/tree_item', object: f, locals: {type: 'file'}
+               render partial: 'tree/blob_item', object: f, locals: {type: 'file'}
              end
 
       tree += html if html.present?
@@ -70,28 +70,25 @@ module TreeHelper
     end
   end
 
-  # Breadcrumb links for a Project and, if applicable, a tree path
-  def breadcrumbs
-    return unless @project && @ref
+  def tree_breadcrumbs(tree, max_links = 2)
+    if tree.path
+      part_path = ""
+      parts = tree.path.split("\/")
 
-    # Add the root project link and the arrow icon
-    crumbs = content_tag(:li) do
-      content_tag(:span, nil, class: 'arrow') +
-      link_to(@project.name, project_commits_path(@project, @ref))
-    end
+      yield('..', nil) if parts.count > max_links
 
-    if @path
-      parts = @path.split('/')
+      parts.each do |part|
+        part_path = File.join(part_path, part) unless part_path.empty?
+        part_path = part if part_path.empty?
 
-      parts.each_with_index do |part, i|
-        crumbs += content_tag(:span, '/', class: 'divider')
-        crumbs += content_tag(:li) do
-          # The text is just the individual part, but the link needs all the parts before it
-          link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
-        end
+        next unless parts.last(2).include?(part) if parts.count > max_links
+        yield(part, tree_join(tree.ref, part_path))
       end
     end
+  end
 
-    crumbs.html_safe
+  def up_dir_path tree
+    file = File.join(tree.path, "..")
+    tree_join(tree.ref, file)
   end
 end
diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb
index 5b69886f9ce..79731b60f45 100644
--- a/app/mailers/emails/issues.rb
+++ b/app/mailers/emails/issues.rb
@@ -1,9 +1,9 @@
 module Emails
   module Issues
-    def new_issue_email(issue_id)
+    def new_issue_email(recipient_id, issue_id)
       @issue = Issue.find(issue_id)
       @project = @issue.project
-      mail(to: @issue.assignee_email, subject: subject("new issue ##{@issue.id}", @issue.title))
+      mail(to: recipient(recipient_id), subject: subject("new issue ##{@issue.id}", @issue.title))
     end
 
     def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id)
@@ -13,6 +13,14 @@ module Emails
       mail(to: recipient(recipient_id), subject: subject("changed issue ##{@issue.id}", @issue.title))
     end
 
+    def closed_issue_email(recipient_id, issue_id, updated_by_user_id)
+      @issue = Issue.find issue_id
+      @project = @issue.project
+      @updated_by = User.find updated_by_user_id
+      mail(to: recipient(recipient_id),
+           subject: subject("Closed issue ##{@issue.id}", @issue.title))
+    end
+
     def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id)
       @issue = Issue.find issue_id
       @issue_status = status
diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index 35890460e05..806f1b01b72 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -1,9 +1,9 @@
 module Emails
   module MergeRequests
-    def new_merge_request_email(merge_request_id)
+    def new_merge_request_email(recipient_id, merge_request_id)
       @merge_request = MergeRequest.find(merge_request_id)
       @project = @merge_request.project
-      mail(to: @merge_request.assignee_email, subject: subject("new merge request !#{@merge_request.id}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("new merge request !#{@merge_request.id}", @merge_request.title))
     end
 
     def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
@@ -12,5 +12,18 @@ module Emails
       @project = @merge_request.project
       mail(to: recipient(recipient_id), subject: subject("changed merge request !#{@merge_request.id}", @merge_request.title))
     end
+
+    def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
+      @merge_request = MergeRequest.find(merge_request_id)
+      @project = @merge_request.project
+      @updated_by = User.find updated_by_user_id
+      mail(to: recipient(recipient_id), subject: subject("Closed merge request !#{@merge_request.id}", @merge_request.title))
+    end
+
+    def merged_merge_request_email(recipient_id, merge_request_id)
+      @merge_request = MergeRequest.find(merge_request_id)
+      @project = @merge_request.project
+      mail(to: recipient(recipient_id), subject: subject("Accepted merge request !#{@merge_request.id}", @merge_request.title))
+    end
   end
 end
diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb
index de51debfeb5..769b6e0b861 100644
--- a/app/mailers/emails/notes.rb
+++ b/app/mailers/emails/notes.rb
@@ -3,7 +3,6 @@ module Emails
     def note_commit_email(recipient_id, note_id)
       @note = Note.find(note_id)
       @commit = @note.noteable
-      @commit = CommitDecorator.decorate(@commit)
       @project = @note.project
       mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title))
     end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 405b90b2330..9a73b093263 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -44,7 +44,7 @@ class Ability
         rules << project_anon_and_download_rules
       end
 
-      if project.owner == user
+      if project.owner == user || user.admin?
         rules << project_admin_rules
       end
 
diff --git a/app/models/commit.rb b/app/models/commit.rb
index daba5414afa..e3363350997 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -8,168 +8,70 @@ class Commit
   #
   DIFF_SAFE_SIZE = 100
 
-  attr_accessor :commit, :head, :refs
-
-  delegate  :message, :authored_date, :committed_date, :parents, :sha,
-            :date, :committer, :author, :diffs, :tree, :id, :stats,
-            :to_patch, to: :commit
-
-  class << self
-    def find_or_first(repo, commit_id = nil, root_ref)
-      commit = if commit_id
-                 repo.commit(commit_id)
-               else
-                 repo.commits(root_ref).first
-               end
-
-      Commit.new(commit) if commit
-    end
-
-    def fresh_commits(repo, n = 10)
-      commits = repo.heads.map do |h|
-        repo.commits(h.name, n).map { |c| Commit.new(c, h) }
-      end.flatten.uniq { |c| c.id }
-
-      commits.sort! do |x, y|
-        y.committed_date <=> x.committed_date
-      end
-
-      commits[0...n]
-    end
-
-    def commits_with_refs(repo, n = 20)
-      commits = repo.branches.map { |ref| Commit.new(ref.commit, ref) }
-
-      commits.sort! do |x, y|
-        y.committed_date <=> x.committed_date
-      end
-
-      commits[0..n]
-    end
-
-    def commits_since(repo, date)
-      commits = repo.heads.map do |h|
-        repo.log(h.name, nil, since: date).each { |c| Commit.new(c, h) }
-      end.flatten.uniq { |c| c.id }
-
-      commits.sort! do |x, y|
-        y.committed_date <=> x.committed_date
-      end
-
-      commits
-    end
-
-    def commits(repo, ref, path = nil, limit = nil, offset = nil)
-      if path
-        repo.log(ref, path, max_count: limit, skip: offset)
-      elsif limit && offset
-        repo.commits(ref, limit, offset)
-      else
-        repo.commits(ref)
-      end.map{ |c| Commit.new(c) }
-    end
-
-    def commits_between(repo, from, to)
-      repo.commits_between(from, to).map { |c| Commit.new(c) }
-    end
-
-    def compare(project, from, to)
-      result = {
-        commits: [],
-        diffs: [],
-        commit: nil,
-        same: false
-      }
-
-      return result unless from && to
-
-      first = project.repository.commit(to.try(:strip))
-      last = project.repository.commit(from.try(:strip))
-
-      if first && last
-        result[:same] = (first.id == last.id)
-        result[:commits] = project.repo.commits_between(last.id, first.id).map {|c| Commit.new(c)}
-
-        # Dont load diff for 100+ commits
-        result[:diffs] = if result[:commits].size > 100
-                           []
-                         else
-                           project.repo.diff(last.id, first.id) rescue []
-                         end
-
-        result[:commit] = Commit.new(first)
-      end
-
-      result
-    end
-  end
-
-  def initialize(raw_commit, head = nil)
-    raise "Nil as raw commit passed" unless raw_commit
-
-    @commit = raw_commit
-    @head = head
-  end
-
-  def short_id(length = 10)
-    id.to_s[0..length]
+  def self.decorate(commits)
+    commits.map { |c| self.new(c) }
   end
 
-  def safe_message
-    @safe_message ||= message
-  end
+  attr_accessor :raw
 
-  def created_at
-    committed_date
-  end
-
-  def author_email
-    author.email
-  end
+  def initialize(raw_commit)
+    raise "Nil as raw commit passed" unless raw_commit
 
-  def author_name
-    author.name
+    @raw = raw_commit
   end
 
-  # Was this commit committed by a different person than the original author?
-  def different_committer?
-    author_name != committer_name || author_email != committer_email
+  def id
+    @raw.id
   end
 
-  def committer_name
-    committer.name
+  # Returns a string describing the commit for use in a link title
+  #
+  # Example
+  #
+  #   "Commit: Alex Denisov - Project git clone panel"
+  def link_title
+    "Commit: #{author_name} - #{title}"
   end
 
-  def committer_email
-    committer.email
+  # Returns the commits title.
+  #
+  # Usually, the commit title is the first line of the commit message.
+  # In case this first line is longer than 80 characters, it is cut off
+  # after 70 characters and ellipses (`&hellp;`) are appended.
+  def title
+    title = safe_message
+
+    return no_commit_message if title.blank?
+
+    title_end = title.index(/\n/)
+    if (!title_end && title.length > 80) || (title_end && title_end > 80)
+      title[0..69] << "&hellip;".html_safe
+    else
+      title.split(/\n/, 2).first
+    end
   end
 
-  def prev_commit
-    @prev_commit ||= if parents.present?
-                       Commit.new(parents.first)
-                     else
-                       nil
-                     end
+  # Returns the commits description
+  #
+  # cut off, ellipses (`&hellp;`) are prepended to the commit message.
+  def description
+    description = safe_message
+
+    title_end = description.index(/\n/)
+    if (!title_end && description.length > 80) || (title_end && title_end > 80)
+      "&hellip;".html_safe << description[70..-1]
+    else
+      description.split(/\n/, 2)[1].try(:chomp)
+    end
   end
 
-  def prev_commit_id
-    prev_commit.try :id
+  def method_missing(m, *args, &block)
+    @raw.send(m, *args, &block)
   end
 
-  # Shows the diff between the commit's parent and the commit.
-  #
-  # Cuts out the header and stats from #to_patch and returns only the diff.
-  def to_diff
-    # see Grit::Commit#show
-    patch = to_patch
+  def respond_to?(method)
+    return true if @raw.respond_to?(method)
 
-    # discard lines before the diff
-    lines = patch.split("\n")
-    while !lines.first.start_with?("diff --git") do
-      lines.shift
-    end
-    lines.pop if lines.last =~ /^[\d.]+$/ # Git version
-    lines.pop if lines.last == "-- "      # end of diff
-    lines.join("\n")
+    super
   end
 end
diff --git a/app/models/event.rb b/app/models/event.rb
index ae14454c59a..97f96ac8f9e 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -134,7 +134,7 @@ class Event < ActiveRecord::Base
     if closed?
       "closed"
     elsif merged?
-      "merged"
+      "accepted"
     elsif joined?
       'joined'
     elsif left?
@@ -200,7 +200,7 @@ class Event < ActiveRecord::Base
 
   # Max 20 commits from push DESC
   def commits
-    @commits ||= data[:commits].map { |commit| repository.commit(commit[:id]) }.reverse
+    @commits ||= data[:commits].reverse
   end
 
   def commits_count
@@ -221,26 +221,8 @@ class Event < ActiveRecord::Base
     end
   end
 
-  def repository
-    project.repository
-  end
-
-  def parent_commit
-    repository.commit(commit_from)
-  rescue => ex
-    nil
-  end
-
-  def last_commit
-    repository.commit(commit_to)
-  rescue => ex
-    nil
-  end
-
   def push_with_commits?
-    md_ref? && commits.any? && parent_commit && last_commit
-  rescue Grit::NoSuchPathError
-    false
+    md_ref? && commits.any? && commit_from && commit_to
   end
 
   def last_push_to_non_root?
diff --git a/app/models/gollum_wiki.rb b/app/models/gollum_wiki.rb
index a1ee3a0899a..d1edbab4533 100644
--- a/app/models/gollum_wiki.rb
+++ b/app/models/gollum_wiki.rb
@@ -16,6 +16,10 @@ class GollumWiki
     @user = user
   end
 
+  def path
+    @project.path + '.wiki'
+  end
+
   def path_with_namespace
     @project.path_with_namespace + ".wiki"
   end
@@ -47,12 +51,6 @@ class GollumWiki
     wiki.pages.map { |page| WikiPage.new(self, page, true) }
   end
 
-  # Returns the last 30 Commit objects across the entire
-  # repository.
-  def recent_history
-    Commit.fresh_commits(wiki.repo, 30)
-  end
-
   # Finds a page within the repository based on a tile
   # or slug.
   #
@@ -90,13 +88,17 @@ class GollumWiki
   private
 
   def create_repo!
-    if gitlab_shell.add_repository(path_with_namespace)
+    if init_repo(path_with_namespace)
       Gollum::Wiki.new(path_to_repo)
     else
       raise CouldNotCreateWikiError
     end
   end
 
+  def init_repo(path_with_namespace)
+    gitlab_shell.add_repository(path_with_namespace)
+  end
+
   def commit_details(action, message = nil, title = nil)
     commit_message = message || default_message(action, title)
 
@@ -114,5 +116,4 @@ class GollumWiki
   def path_to_repo
     @path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git")
   end
-
 end
diff --git a/app/models/group.rb b/app/models/group.rb
index 5d838d2b9b0..17671c3defe 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -13,6 +13,7 @@
 #
 
 class Group < Namespace
+
   def add_users_to_project_teams(user_ids, project_access)
     UsersProject.add_users_into_projects(
       projects.map(&:id),
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 54d9af7e67e..91dd6477b04 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -25,19 +25,9 @@ class Issue < ActiveRecord::Base
 
   acts_as_taggable_on :labels
 
-  class << self
-    def cared(user)
-      where('assignee_id = :user', user: user.id)
-    end
-
-    def authored(user)
-      where('author_id = :user', user: user.id)
-    end
-
-    def open_for(user)
-      opened.assigned(user)
-    end
-  end
+  scope :cared, ->(user) { where(assignee_id: user) }
+  scope :authored, ->(user) { where(author_id: user) }
+  scope :open_for, ->(user) { opened.assigned(user) }
 
   state_machine :state, initial: :opened do
     event :close do
@@ -54,4 +44,7 @@ class Issue < ActiveRecord::Base
 
     state :closed
   end
+
+  # Both open and reopened issues should be listed as opened
+  scope :opened, -> { with_state(:opened, :reopened) }
 end
diff --git a/app/models/key.rb b/app/models/key.rb
index 53eee511e13..ce62b802c0d 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -23,7 +23,7 @@ class Key < ActiveRecord::Base
   before_validation :strip_white_space
 
   validates :title, presence: true, length: { within: 0..255 }
-  validates :key, presence: true, length: { within: 0..5000 }, format: { :with => /ssh-.{3} / }, uniqueness: true
+  validates :key, presence: true, length: { within: 0..5000 }, format: { with: /ssh-.{3} / }, uniqueness: true
   validate :fingerprintable_key
 
   delegate :name, :email, to: :user, prefix: true
@@ -48,7 +48,7 @@ class Key < ActiveRecord::Base
   end
 
   def is_deploy_key
-    !!project_id
+    project.present?
   end
 
   # projects that has this key
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 9d42b1e1f32..c1b4d4e0760 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -24,8 +24,6 @@ require Rails.root.join("lib/static_model")
 class MergeRequest < ActiveRecord::Base
   include Issuable
 
-  BROKEN_DIFF = "--broken-diff"
-
   attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id,
                   :author_id_of_changes, :state_event
 
@@ -109,22 +107,18 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def diffs
-    st_diffs || []
+    load_diffs(st_diffs) || []
   end
 
   def reloaded_diffs
     if opened? && unmerged_diffs.any?
-      self.st_diffs = unmerged_diffs
+      self.st_diffs = dump_diffs(unmerged_diffs)
       self.save
     end
-
-  rescue Grit::Git::GitTimeout
-    self.st_diffs = [BROKEN_DIFF]
-    self.save
   end
 
   def broken_diffs?
-    diffs == [BROKEN_DIFF]
+    diffs == [Gitlab::Git::Diff::BROKEN_DIFF]
   end
 
   def valid_diffs?
@@ -132,11 +126,7 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def unmerged_diffs
-    # Only show what is new in the source branch compared to the target branch, not the other way around.
-    # The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
-    # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
-    common_commit = project.repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
-    diffs = project.repo.diff(common_commit, source_branch)
+    project.repository.diffs_between(source_branch, target_branch)
   end
 
   def last_commit
@@ -152,7 +142,7 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def commits
-    st_commits || []
+    load_commits(st_commits || [])
   end
 
   def probably_merged?
@@ -162,16 +152,15 @@ class MergeRequest < ActiveRecord::Base
 
   def reloaded_commits
     if opened? && unmerged_commits.any?
-      self.st_commits = unmerged_commits
+      self.st_commits = dump_commits(unmerged_commits)
       save
     end
     commits
   end
 
   def unmerged_commits
-    self.project.repo.
+    self.project.repository.
       commits_between(self.target_branch, self.source_branch).
-      map {|c| Commit.new(c)}.
       sort_by(&:created_at).
       reverse
   end
@@ -213,4 +202,22 @@ class MergeRequest < ActiveRecord::Base
   def last_commit_short_sha
     @last_commit_short_sha ||= last_commit.sha[0..10]
   end
+
+  private
+
+  def dump_commits(commits)
+    commits.map(&:to_hash)
+  end
+
+  def load_commits(array)
+    array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash)) }
+  end
+
+  def dump_diffs(diffs)
+    diffs.map(&:to_hash)
+  end
+
+  def load_diffs(array)
+    array.map { |hash| Gitlab::Git::Diff.new(hash) }
+  end
 end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 2a9b9e4482c..759f35313c6 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -19,6 +19,7 @@ class Milestone < ActiveRecord::Base
   belongs_to :project
   has_many :issues
   has_many :merge_requests
+  has_many :participants, through: :issues, source: :assignee
 
   scope :active, -> { with_state(:active) }
   scope :closed, -> { with_state(:closed) }
@@ -48,10 +49,6 @@ class Milestone < ActiveRecord::Base
     end
   end
 
-  def participants
-    User.where(id: issues.pluck(:assignee_id))
-  end
-
   def open_items_count
     self.issues.opened.count + self.merge_requests.opened.count
   end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index e8b7d0c3706..cb7164eab13 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -13,6 +13,8 @@
 #
 
 class Namespace < ActiveRecord::Base
+  include Gitlab::ShellAdapter
+
   attr_accessible :name, :description, :path
 
   has_many :projects, dependent: :destroy
@@ -31,7 +33,7 @@ class Namespace < ActiveRecord::Base
   delegate :name, to: :owner, allow_nil: true, prefix: true
 
   after_create :ensure_dir_exist
-  after_update :move_dir
+  after_update :move_dir, if: :path_changed?
   after_destroy :rm_dir
 
   scope :root, -> { where('type IS NULL') }
@@ -53,48 +55,34 @@ class Namespace < ActiveRecord::Base
   end
 
   def ensure_dir_exist
-    unless dir_exists?
-      FileUtils.mkdir( namespace_full_path, mode: 0770 )
-    end
-  end
-
-  def dir_exists?
-    File.exists?(namespace_full_path)
+    gitlab_shell.add_namespace(path)
   end
 
-  def namespace_full_path
-    @namespace_full_path ||= File.join(Gitlab.config.gitlab_shell.repos_path, path)
+  def rm_dir
+    gitlab_shell.rm_namespace(path)
   end
 
   def move_dir
-    if path_changed?
-      old_path = File.join(Gitlab.config.gitlab_shell.repos_path, path_was)
-      new_path = File.join(Gitlab.config.gitlab_shell.repos_path, path)
-      if File.exists?(new_path)
-        raise "Already exists"
-      end
-
-
+    if gitlab_shell.mv_namespace(path_was, path)
+      # If repositories moved successfully we need to remove old satellites
+      # and send update instructions to users.
+      # However we cannot allow rollback since we moved namespace dir
+      # So we basically we mute exceptions in next actions
       begin
-        # Remove satellite when moving repo
-        if path_was.present?
-          satellites_path = File.join(Gitlab.config.satellites.path, path_was)
-          FileUtils.rm_r( satellites_path, force: true )
-        end
-
-        FileUtils.mv( old_path, new_path )
+        gitlab_shell.rm_satellites(path_was)
         send_update_instructions
-      rescue Exception => e
-        raise "Namespace move error #{old_path} #{new_path}"
+      rescue
+        # Returning false does not rolback after_* transaction but gives
+        # us information about failing some of tasks
+        false
       end
+    else
+      # if we cannot move namespace directory we should rollback
+      # db changes in order to prevent out of sync between db and fs
+      raise Exception.new('namespace directory cannot be moved')
     end
   end
 
-  def rm_dir
-    dir_path = File.join(Gitlab.config.gitlab_shell.repos_path, path)
-    FileUtils.rm_r( dir_path, force: true )
-  end
-
   def send_update_instructions
     projects.each(&:send_move_instructions)
   end
diff --git a/app/models/network/commit.rb b/app/models/network/commit.rb
index d0bc61c3bf7..3cd0c015fa0 100644
--- a/app/models/network/commit.rb
+++ b/app/models/network/commit.rb
@@ -8,7 +8,7 @@ module Network
     attr_accessor :time, :spaces, :parent_spaces
 
     def initialize(raw_commit, refs)
-      @commit = ::Commit.new(raw_commit)
+      @commit = Gitlab::Git::Commit.new(raw_commit)
       @time = -1
       @spaces = []
       @parent_spaces = []
diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb
index 4b1abf5215e..0fe7765b9ea 100644
--- a/app/models/network/graph.rb
+++ b/app/models/network/graph.rb
@@ -25,10 +25,9 @@ module Network
     def collect_commits
       refs_cache = build_refs_cache
 
-      find_commits(count_to_display_commit_in_center)
-      .map do |commit|
-          # Decorate with app/model/network/commit.rb
-          Network::Commit.new(commit, refs_cache[commit.id])
+      find_commits(count_to_display_commit_in_center).map do |commit|
+        # Decorate with app/model/network/commit.rb
+        Network::Commit.new(commit, refs_cache[commit.id])
       end
     end
 
@@ -40,15 +39,12 @@ module Network
     def index_commits
       days = []
       @map = {}
+      @reserved = {}
 
-      @commits.reverse.each_with_index do |c,i|
+      @commits.each_with_index do |c,i|
         c.time = i
         days[i] = c.committed_date
         @map[c.id] = c
-      end
-
-      @reserved = {}
-      days.each_index do |i|
         @reserved[i] = []
       end
 
@@ -96,15 +92,13 @@ module Network
     end
 
     def find_commits(skip = 0)
-      Grit::Commit.find_all(
-        @repo,
-        nil,
-        {
-          date_order: true,
-          max_count: self.class.max_count,
-          skip: skip
-        }
-      )
+      opts = {
+        date_order: true,
+        max_count: self.class.max_count,
+        skip: skip
+      }
+
+      Grit::Commit.find_all(@repo, nil, opts)
     end
 
     def commits_sort_by_ref
@@ -135,11 +129,7 @@ module Network
       spaces = []
 
       commit.parents(@map).each do |parent|
-        range = if commit.time < parent.time then
-                  commit.time..parent.time
-                else
-                  parent.time..commit.time
-                end
+        range = commit.time..parent.time
 
         space = if commit.space >= parent.space then
                   find_free_parent_space(range, parent.space, -1, commit.space)
@@ -166,7 +156,7 @@ module Network
       range.each do |i|
         if i != range.first &&
           i != range.last &&
-          @commits[reversed_index(i)].spaces.include?(overlap_space) then
+          @commits[i].spaces.include?(overlap_space) then
 
           return true;
         end
@@ -184,7 +174,7 @@ module Network
         return
       end
 
-      time_range = leaves.last.time..leaves.first.time
+      time_range = leaves.first.time..leaves.last.time
       space_base = get_space_base(leaves)
       space = find_free_space(time_range, 2, space_base)
       leaves.each do |l|
@@ -198,17 +188,17 @@ module Network
       end
 
       # and mark it as reserved
-      min_time = leaves.last.time
-      leaves.last.parents(@map).each do |parent|
-        if parent.time < min_time
-          min_time = parent.time
-        end
-      end
-
       if parent_time.nil?
-        max_time = leaves.first.time
+        min_time = leaves.first.time
       else
-        max_time = parent_time - 1
+        min_time = parent_time + 1
+      end
+
+      max_time = leaves.last.time
+      leaves.last.parents(@map).each do |parent|
+        if max_time < parent.time
+          max_time = parent.time
+        end
       end
       mark_reserved(min_time..max_time, space)
 
@@ -289,9 +279,5 @@ module Network
       end
       refs_cache
     end
-
-    def reversed_index(index)
-      -index - 1
-    end
   end
 end
diff --git a/app/models/note.rb b/app/models/note.rb
index f56f999fda1..7b7e6e99df4 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -22,9 +22,6 @@ class Note < ActiveRecord::Base
   attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id,
                   :attachment, :line_code, :commit_id
 
-  attr_accessor :notify
-  attr_accessor :notify_author
-
   belongs_to :project
   belongs_to :noteable, polymorphic: true
   belongs_to :author, class_name: "User"
@@ -44,7 +41,7 @@ class Note < ActiveRecord::Base
   # Scopes
   scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
   scope :inline, -> { where("line_code IS NOT NULL") }
-  scope :not_inline, -> { where("line_code IS NULL") }
+  scope :not_inline, -> { where(line_code: [nil, '']) }
 
   scope :common, ->{ where(noteable_type: ["", nil]) }
   scope :fresh, ->{ order("created_at ASC, id ASC") }
@@ -71,8 +68,8 @@ class Note < ActiveRecord::Base
   def diff
     if noteable.diffs.present?
       noteable.diffs.select do |d|
-        if d.b_path
-          Digest::SHA1.hexdigest(d.b_path) == diff_file_index
+        if d.new_path
+          Digest::SHA1.hexdigest(d.new_path) == diff_file_index
         end
       end.first
     end
@@ -83,7 +80,7 @@ class Note < ActiveRecord::Base
   end
 
   def diff_file_name
-    diff.b_path
+    diff.new_path
   end
 
   def diff_new_line
@@ -91,7 +88,7 @@ class Note < ActiveRecord::Base
   end
 
   def discussion_id
-    @discussion_id ||= [:discussion, noteable_type.try(:underscore), noteable_id, line_code].join("-").to_sym
+    @discussion_id ||= [:discussion, noteable_type.try(:underscore), noteable_id || commit_id, line_code].join("-").to_sym
   end
 
   # Returns true if this is a downvote note,
@@ -143,14 +140,6 @@ class Note < ActiveRecord::Base
     nil
   end
 
-  def notify
-    @notify ||= false
-  end
-
-  def notify_author
-    @notify_author ||= false
-  end
-
   # Returns true if this is an upvote note,
   # otherwise false is returned
   def upvote?
diff --git a/app/models/notification.rb b/app/models/notification.rb
new file mode 100644
index 00000000000..ff6a18d6a51
--- /dev/null
+++ b/app/models/notification.rb
@@ -0,0 +1,39 @@
+class Notification
+  #
+  # Notification levels
+  #
+  N_DISABLED = 0
+  N_PARTICIPATING = 1
+  N_WATCH = 2
+  N_GLOBAL = 3
+
+  attr_accessor :target
+
+  def self.notification_levels
+    [N_DISABLED, N_PARTICIPATING, N_WATCH]
+  end
+
+  def self.project_notification_levels
+    [N_DISABLED, N_PARTICIPATING, N_WATCH, N_GLOBAL]
+  end
+
+  def initialize(target)
+    @target = target
+  end
+
+  def disabled?
+    target.notification_level == N_DISABLED
+  end
+
+  def participating?
+    target.notification_level == N_PARTICIPATING
+  end
+
+  def watch?
+    target.notification_level == N_WATCH
+  end
+
+  def global?
+    target.notification_level == N_GLOBAL
+  end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index 1aee6306baa..25a7e26640d 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -18,22 +18,24 @@
 #  public                 :boolean          default(FALSE), not null
 #  issues_tracker         :string(255)      default("gitlab"), not null
 #  issues_tracker_id      :string(255)
+#  snippets_enabled       :boolean          default(TRUE), not null
+#  last_activity_at       :datetime
 #
 
 require "grit"
 
 class Project < ActiveRecord::Base
-  include Gitolited
+  include Gitlab::ShellAdapter
   extend Enumerize
 
-  class TransferError < StandardError; end
-
-  attr_accessible :name, :path, :description, :default_branch, :issues_tracker,
+  attr_accessible :name, :path, :description, :default_branch, :issues_tracker, :label_list,
     :issues_enabled, :wall_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id,
-    :wiki_enabled, :public, :import_url, as: [:default, :admin]
+    :wiki_enabled, :public, :import_url, :last_activity_at, as: [:default, :admin]
 
   attr_accessible :namespace_id, :creator_id, as: :admin
 
+  acts_as_taggable_on :labels
+
   attr_accessor :import_url
 
   # Relations
@@ -53,7 +55,6 @@ class Project < ActiveRecord::Base
   has_many :snippets,           dependent: :destroy
   has_many :deploy_keys,        dependent: :destroy, class_name: "Key", foreign_key: "project_id"
   has_many :hooks,              dependent: :destroy, class_name: "ProjectHook"
-  has_many :wikis,              dependent: :destroy
   has_many :protected_branches, dependent: :destroy
   has_many :user_team_project_relationships, dependent: :destroy
 
@@ -87,17 +88,18 @@ class Project < ActiveRecord::Base
   validate :check_limit, :repo_name
 
   # Scopes
-  scope :without_user, ->(user)  { where("id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) }
-  scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) }
-  scope :without_team, ->(team) { team.projects.present? ? where("id NOT IN (:ids)", ids: team.projects.map(&:id)) : scoped  }
-  scope :in_team, ->(team) { where("id IN (:ids)", ids: team.projects.map(&:id)) }
+  scope :without_user, ->(user)  { where("projects.id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) }
+  scope :without_team, ->(team) { team.projects.present? ? where("projects.id NOT IN (:ids)", ids: team.projects.map(&:id)) : scoped  }
+  scope :not_in_group, ->(group) { where("projects.id NOT IN (:ids)", ids: group.project_ids ) }
+  scope :in_team, ->(team) { where("projects.id IN (:ids)", ids: team.projects.map(&:id)) }
   scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) }
-  scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") }
+  scope :in_group_namespace, -> { joins(:group) }
+  scope :sorted_by_activity, -> { order("projects.last_activity_at DESC") }
   scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
   scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
   scope :public_only, -> { where(public: true) }
 
-  enumerize :issues_tracker, :in => (Gitlab.config.issues_tracker.keys).append(:gitlab), :default => :gitlab
+  enumerize :issues_tracker, in: (Gitlab.config.issues_tracker.keys).append(:gitlab), default: :gitlab
 
   class << self
     def abandoned
@@ -142,13 +144,7 @@ class Project < ActiveRecord::Base
   end
 
   def repository
-    if path
-      @repository ||= Repository.new(path_with_namespace, default_branch)
-    else
-      nil
-    end
-  rescue Grit::NoSuchPathError
-    nil
+    @repository ||= Repository.new(path_with_namespace, default_branch)
   end
 
   def saved?
@@ -196,7 +192,7 @@ class Project < ActiveRecord::Base
   end
 
   def last_activity_date
-    last_event.try(:created_at) || updated_at
+    last_activity_at || updated_at
   end
 
   def project_id
@@ -337,14 +333,14 @@ class Project < ActiveRecord::Base
   end
 
   def valid_repo?
-    repo
+    repository.exists?
   rescue
     errors.add(:path, "Invalid repository path")
     false
   end
 
   def empty_repo?
-    !repository || repository.empty?
+    !repository.exists? || repository.empty?
   end
 
   def ensure_satellite_exists
@@ -368,18 +364,25 @@ class Project < ActiveRecord::Base
   end
 
   def repo_exists?
-    @repo_exists ||= (repository && repository.branches.present?)
+    @repo_exists ||= repository.exists?
   rescue
     @repo_exists = false
   end
 
   def open_branches
-    if protected_branches.empty?
-      self.repo.heads
-    else
-      pnames = protected_branches.map(&:name)
-      self.repo.heads.reject { |h| pnames.include?(h.name) }
-    end.sort_by(&:name)
+    all_branches = repository.branches
+
+    if protected_branches.present?
+      all_branches.reject! do |branch|
+        protected_branches_names.include?(branch.name)
+      end
+    end
+
+    all_branches
+  end
+
+  def protected_branches_names
+    @protected_branches_names ||= protected_branches.map(&:name)
   end
 
   def root_ref?(branch)
@@ -401,6 +404,6 @@ class Project < ActiveRecord::Base
 
   # Check if current branch name is marked as protected in the system
   def protected_branch? branch_name
-    protected_branches.map(&:name).include?(branch_name)
+    protected_branches_names.include?(branch_name)
   end
 end
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
index 57229d50759..16379720e59 100644
--- a/app/models/protected_branch.rb
+++ b/app/models/protected_branch.rb
@@ -10,7 +10,7 @@
 #
 
 class ProtectedBranch < ActiveRecord::Base
-  include Gitolited
+  include Gitlab::ShellAdapter
 
   attr_accessible :name
 
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 934c1a6e086..ed600e29232 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1,169 +1,45 @@
 class Repository
-  include Gitlab::Popen
+  attr_accessor :raw_repository
 
-  # Repository directory name with namespace direcotry
-  # Examples:
-  #   gitlab/gitolite
-  #   diaspora
-  #
-  attr_accessor :path_with_namespace
-
-  # Grit repo object
-  attr_accessor :repo
-
-  # Default branch in the repository
-  attr_accessor :root_ref
-
-  def initialize(path_with_namespace, root_ref = 'master')
-    @root_ref = root_ref || "master"
-    @path_with_namespace = path_with_namespace
-
-    # Init grit repo object
-    repo
-  end
-
-  def raw
-    repo
-  end
-
-  def path_to_repo
-    @path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git")
-  end
-
-  def repo
-    @repo ||= Grit::Repo.new(path_to_repo)
-  end
-
-  def commit(commit_id = nil)
-    Commit.find_or_first(repo, commit_id, root_ref)
+  def initialize(path_with_namespace, default_branch)
+    @raw_repository = Gitlab::Git::Repository.new(path_with_namespace, default_branch)
+  rescue Gitlab::Git::Repository::NoRepository
+    nil
   end
 
-  def fresh_commits(n = 10)
-    Commit.fresh_commits(repo, n)
+  def exists?
+    raw_repository
   end
 
-  def commits_with_refs(n = 20)
-    Commit.commits_with_refs(repo, n)
+  def empty?
+    raw_repository.empty?
   end
 
-  def commits_since(date)
-    Commit.commits_since(repo, date)
+  def commit(id = nil)
+    commit = raw_repository.commit(id)
+    commit = Commit.new(commit) if commit
+    commit
   end
 
   def commits(ref, path = nil, limit = nil, offset = nil)
-    Commit.commits(repo, ref, path, limit, offset)
-  end
-
-  def last_commit_for(ref, path = nil)
-    commits(ref, path, 1).first
-  end
-
-  def commits_between(from, to)
-    Commit.commits_between(repo, from, to)
+    commits = raw_repository.commits(ref, path, limit, offset)
+    commits = Commit.decorate(commits) if commits.present?
+    commits
   end
 
-  # Returns an Array of branch names
-  def branch_names
-    repo.branches.collect(&:name).sort
+  def commits_between(target, source)
+    commits = raw_repository.commits_between(target, source)
+    commits = Commit.decorate(commits) if commits.present?
+    commits
   end
 
-  # Returns an Array of Branches
-  def branches
-    repo.branches.sort_by(&:name)
+  def method_missing(m, *args, &block)
+    raw_repository.send(m, *args, &block)
   end
 
-  # Returns an Array of tag names
-  def tag_names
-    repo.tags.collect(&:name).sort.reverse
-  end
-
-  # Returns an Array of Tags
-  def tags
-    repo.tags.sort_by(&:name).reverse
-  end
-
-  # Returns an Array of branch and tag names
-  def ref_names
-    [branch_names + tag_names].flatten
-  end
-
-  def heads
-    @heads ||= repo.heads
-  end
-
-  def tree(fcommit, path = nil)
-    fcommit = commit if fcommit == :head
-    tree = fcommit.tree
-    path ? (tree / path) : tree
-  end
-
-  def has_commits?
-    !!commit
-  rescue Grit::NoSuchPathError
-    false
-  end
-
-  def empty?
-    !has_commits?
-  end
-
-  # Discovers the default branch based on the repository's available branches
-  #
-  # - If no branches are present, returns nil
-  # - If one branch is present, returns its name
-  # - If two or more branches are present, returns the one that has a name
-  #   matching root_ref (default_branch or 'master' if default_branch is nil)
-  def discover_default_branch
-    if branch_names.length == 0
-      nil
-    elsif branch_names.length == 1
-      branch_names.first
-    else
-      branch_names.select { |v| v == root_ref }.first
-    end
-  end
-
-  # Archive Project to .tar.gz
-  #
-  # Already packed repo archives stored at
-  # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
-  #
-  def archive_repo(ref)
-    ref = ref || self.root_ref
-    commit = self.commit(ref)
-    return nil unless commit
-
-    # Build file path
-    file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"
-    storage_path = Rails.root.join("tmp", "repositories")
-    file_path = File.join(storage_path, self.path_with_namespace, file_name)
-
-    # Put files into a directory before archiving
-    prefix = File.basename(self.path_with_namespace) + "/"
-
-    # Create file if not exists
-    unless File.exists?(file_path)
-      FileUtils.mkdir_p File.dirname(file_path)
-      file = self.repo.archive_to_file(ref, prefix,  file_path)
-    end
-
-    file_path
-  end
-
-  # Return repo size in megabytes
-  # Cached in redis
-  def size
-    Rails.cache.fetch(cache_key(:size)) do
-      size = popen('du -s', path_to_repo).first.strip.to_i
-      (size.to_f / 1024).round(2)
-    end
-  end
-
-  def expire_cache
-    Rails.cache.delete(cache_key(:size))
-  end
+  def respond_to?(method)
+    return true if raw_repository.respond_to?(method)
 
-  def cache_key(type)
-    "#{type}:#{path_with_namespace}"
+    super
   end
 end
diff --git a/app/models/tree.rb b/app/models/tree.rb
index 96395a42394..042050527c1 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -1,29 +1,17 @@
 class Tree
-  include Linguist::BlobHelper
+  attr_accessor :raw
 
-  attr_accessor :path, :tree, :ref
-
-  delegate  :contents, :basename, :name, :data, :mime_type,
-            :mode, :size, :text?, :colorize, to: :tree
-
-  def initialize(raw_tree, ref = nil, path = nil)
-    @ref, @path = ref, path
-    @tree = if path.present?
-              raw_tree / path
-            else
-              raw_tree
-            end
+  def initialize(repository, sha, ref = nil, path = nil)
+    @raw = Gitlab::Git::Tree.new(repository, sha, ref, path)
   end
 
-  def is_blob?
-    tree.is_a?(Grit::Blob)
+  def method_missing(m, *args, &block)
+    @raw.send(m, *args, &block)
   end
 
-  def invalid?
-    tree.nil?
-  end
+  def respond_to?(method)
+    return true if @raw.respond_to?(method)
 
-  def empty?
-    data.blank?
+    super
   end
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index 3ff57984e67..74c2a93f59a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -33,6 +33,7 @@
 #  can_create_team        :boolean          default(TRUE), not null
 #  state                  :string(255)
 #  color_scheme_id        :integer          default(1), not null
+#  notification_level     :integer          default(1), not null
 #
 
 class User < ActiveRecord::Base
@@ -46,16 +47,22 @@ class User < ActiveRecord::Base
 
   attr_accessor :force_random_password
 
+  # Virtual attribute for authenticating by either username or email
+  attr_accessor :login
+
+  # Add login to attr_accessible
+  attr_accessible :login
+
+
   #
   # Relations
   #
 
   # Namespace for personal projects
-  has_one :namespace,
-    dependent: :destroy,
-    foreign_key: :owner_id,
-    class_name: "Namespace",
-    conditions: 'type IS NULL'
+  has_one :namespace, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace", conditions: 'type IS NULL'
+
+  # Namespaces (owned groups and own namespace)
+  has_many :namespaces, foreign_key: :owner_id
 
   # Profile
   has_many :keys, dependent: :destroy
@@ -64,15 +71,11 @@ class User < ActiveRecord::Base
   has_many :groups, class_name: "Group", foreign_key: :owner_id
 
   # Teams
-  has_many :own_teams,
-    class_name: "UserTeam",
-    foreign_key: :owner_id,
-    dependent: :destroy
-
-  has_many :user_team_user_relationships, dependent: :destroy
-  has_many :user_teams, through: :user_team_user_relationships
+  has_many :own_teams,                       dependent: :destroy, class_name: "UserTeam", foreign_key: :owner_id
+  has_many :user_team_user_relationships,    dependent: :destroy
+  has_many :user_teams,                      through: :user_team_user_relationships
   has_many :user_team_project_relationships, through: :user_teams
-  has_many :team_projects, through: :user_team_project_relationships
+  has_many :team_projects,                   through: :user_team_project_relationships
 
   # Projects
   has_many :users_projects,           dependent: :destroy
@@ -80,14 +83,14 @@ class User < ActiveRecord::Base
   has_many :notes,                    dependent: :destroy, foreign_key: :author_id
   has_many :merge_requests,           dependent: :destroy, foreign_key: :author_id
   has_many :events,                   dependent: :destroy, foreign_key: :author_id,   class_name: "Event"
+  has_many :recent_events,                                 foreign_key: :author_id,   class_name: "Event", order: "id DESC"
   has_many :assigned_issues,          dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue"
   has_many :assigned_merge_requests,  dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest"
-  has_many :projects, through: :users_projects
 
-  has_many :recent_events,
-    class_name: "Event",
-    foreign_key: :author_id,
-    order: "id DESC"
+  has_many :personal_projects,        through: :namespace, source: :projects
+  has_many :projects,                 through: :users_projects
+  has_many :own_projects,             foreign_key: :creator_id
+  has_many :owned_projects,           through: :namespaces, source: :projects
 
   #
   # Validations
@@ -101,6 +104,7 @@ class User < ActiveRecord::Base
             format: { with: Gitlab::Regex.username_regex,
                       message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
 
+  validates :notification_level, inclusion: { in: Notification.notification_levels }, presence: true
 
   validate :namespace_uniq, if: ->(user) { user.username_changed? }
 
@@ -134,12 +138,25 @@ class User < ActiveRecord::Base
   scope :alphabetically, -> { order('name ASC') }
   scope :in_team, ->(team){ where(id: team.member_ids) }
   scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
+  scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : scoped }
+  scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') }
+
   scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active  }
 
   #
   # Class methods
   #
   class << self
+    # Devise method overriden to allow sing in with email or username
+    def find_for_database_authentication(warden_conditions)
+      conditions = warden_conditions.dup
+      if login = conditions.delete(:login)
+        where(conditions).where(["lower(username) = :value OR lower(email) = :value", { value: login.downcase }]).first
+      else
+        where(conditions).first
+      end
+    end
+
     def filter filter_name
       case filter_name
       when "admins"; self.admins
@@ -150,18 +167,6 @@ class User < ActiveRecord::Base
       end
     end
 
-    def not_in_project(project)
-      if project.users.present?
-        where("id not in (:ids)", ids: project.users.map(&:id) )
-      else
-        scoped
-      end
-    end
-
-    def without_projects
-      where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)')
-    end
-
     def create_from_omniauth(auth, ldap = false)
       gitlab_auth.create_from_omniauth(auth, ldap)
     end
@@ -191,6 +196,10 @@ class User < ActiveRecord::Base
     username
   end
 
+  def notification
+    @notification ||= Notification.new(self)
+  end
+
   def generate_password
     if self.force_random_password
       self.password = self.password_confirmation = Devise.friendly_token.first(8)
@@ -204,52 +213,41 @@ class User < ActiveRecord::Base
     end
   end
 
-  # Namespaces user has access to
-  def namespaces
-    namespaces = []
-
-    # Add user account namespace
-    namespaces << self.namespace if self.namespace
-
-    # Add groups you can manage
-    namespaces += groups.all
-
-    namespaces
-  end
-
   # Groups where user is an owner
   def owned_groups
     groups
   end
 
+  def owned_teams
+    own_teams
+  end
+
   # Groups user has access to
   def authorized_groups
-    @authorized_groups ||= begin
-                           groups = Group.where(id: self.authorized_projects.pluck(:namespace_id)).all
-                           groups = groups + self.groups
-                           groups.uniq
-                         end
+    @group_ids ||= (groups.pluck(:id) + authorized_projects.pluck(:namespace_id))
+    Group.where(id: @group_ids)
   end
 
 
   # Projects user has access to
   def authorized_projects
-    project_ids = users_projects.pluck(:project_id)
-    project_ids = project_ids | owned_projects.pluck(:id)
-    project_ids = project_ids | public_projects.pluck(:id) 
-    Project.where(id: project_ids)
-  end
+  #   project_ids = users_projects.pluck(:project_id)
+  #   project_ids = project_ids | owned_projects.pluck(:id)
+  #   project_ids = project_ids | public_projects.pluck(:id) 
+  #   Project.where(id: project_ids)
+  # end
+
+  # # Projects in user namespace
+  # def personal_projects
+  #   Project.personal(self)
 
-  # Projects in user namespace
-  def personal_projects
-    Project.personal(self)
+    @project_ids ||= (owned_projects.pluck(:id) + projects.pluck(:id) + public_projects.pluck(:id)).uniq
+    Project.where(id: @project_ids)
   end
 
-  # Projects where user is an owner
-  def owned_projects
-    Project.where("(projects.namespace_id IN (:namespaces)) OR
-                  (projects.namespace_id IS NULL AND projects.creator_id = :user_id)",
-                  namespaces: namespaces.map(&:id), user_id: self.id)
+  def authorized_teams
+    @team_ids ||= (user_teams.pluck(:id) + own_teams.pluck(:id)).uniq
+    UserTeam.where(id: @team_ids)
   end
   
   def public_projects
@@ -258,7 +256,7 @@ class User < ActiveRecord::Base
 
   # Team membership in authorized projects
   def tm_in_authorized_projects
-    UsersProject.where(project_id:  authorized_projects.map(&:id), user_id: self.id)
+    UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
   end
 
   def is_admin?
@@ -309,9 +307,13 @@ class User < ActiveRecord::Base
     MergeRequest.cared(self)
   end
 
+  def projects_limit_left
+    projects_limit - owned_projects.count
+  end
+
   def projects_limit_percent
     return 100 if projects_limit.zero?
-    (personal_projects.count.to_f / projects_limit) * 100
+    (owned_projects.count.to_f / projects_limit) * 100
   end
 
   def recent_push project_id = nil
@@ -328,29 +330,18 @@ class User < ActiveRecord::Base
   end
 
   def several_namespaces?
-    namespaces.size > 1
+    namespaces.many?
   end
 
   def namespace_id
     namespace.try :id
   end
 
-  def authorized_teams
-    @authorized_teams ||= begin
-                            ids = []
-                            ids << UserTeam.with_member(self).pluck('user_teams.id')
-                            ids << UserTeam.created_by(self).pluck('user_teams.id')
-                            ids.flatten
-
-                            UserTeam.where(id: ids)
-                          end
-  end
-
-  def owned_teams
-    UserTeam.where(owner_id: self.id)
-  end
-
   def name_with_username
     "#{name} (#{username})"
   end
+
+  def tm_of(project)
+    project.team_member_by_id(self.id)
+  end
 end
diff --git a/app/models/users_project.rb b/app/models/users_project.rb
index 486aaa6966a..935ecede42c 100644
--- a/app/models/users_project.rb
+++ b/app/models/users_project.rb
@@ -2,16 +2,17 @@
 #
 # Table name: users_projects
 #
-#  id             :integer          not null, primary key
-#  user_id        :integer          not null
-#  project_id     :integer          not null
-#  created_at     :datetime         not null
-#  updated_at     :datetime         not null
-#  project_access :integer          default(0), not null
+#  id                 :integer          not null, primary key
+#  user_id            :integer          not null
+#  project_id         :integer          not null
+#  created_at         :datetime         not null
+#  updated_at         :datetime         not null
+#  project_access     :integer          default(0), not null
+#  notification_level :integer          default(3), not null
 #
 
 class UsersProject < ActiveRecord::Base
-  include Gitolited
+  include Gitlab::ShellAdapter
 
   GUEST     = 10
   REPORTER  = 20
@@ -29,6 +30,7 @@ class UsersProject < ActiveRecord::Base
   validates :user_id, uniqueness: { scope: [:project_id], message: "already exists in project" }
   validates :project_access, inclusion: { in: [GUEST, REPORTER, DEVELOPER, MASTER] }, presence: true
   validates :project, presence: true
+  validates :notification_level, inclusion: { in: Notification.project_notification_levels }, presence: true
 
   delegate :name, :username, :email, to: :user, prefix: true
 
@@ -38,7 +40,7 @@ class UsersProject < ActiveRecord::Base
   scope :masters,  -> { where(project_access: MASTER) }
 
   scope :in_project, ->(project) { where(project_id: project.id) }
-  scope :in_projects, ->(projects) { where(project_id: project_ids) }
+  scope :in_projects, ->(projects) { where(project_id: projects.map { |p| p.id }) }
   scope :with_user, ->(user) { where(user_id: user.id) }
 
   class << self
@@ -134,4 +136,8 @@ class UsersProject < ActiveRecord::Base
   def skip_git?
     !!@skip_git
   end
+
+  def notification
+    @notification ||= Notification.new(self)
+  end
 end
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
deleted file mode 100644
index 7f488ca7625..00000000000
--- a/app/models/wiki.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# == Schema Information
-#
-# Table name: wikis
-#
-#  id         :integer          not null, primary key
-#  title      :string(255)
-#  content    :text
-#  project_id :integer
-#  created_at :datetime         not null
-#  updated_at :datetime         not null
-#  slug       :string(255)
-#  user_id    :integer
-#
-
-class Wiki < ActiveRecord::Base
-  attr_accessible :title, :content, :slug
-
-  belongs_to :project
-  belongs_to :user
-  has_many :notes, as: :noteable, dependent: :destroy
-
-  validates :content, presence: true
-  validates :user, presence: true
-  validates :title, presence: true, length: 1..250
-
-  before_update :set_slug
-
-  scope :ordered, order("created_at DESC")
-
-  def to_param
-    slug
-  end
-
-  class << self
-    def search(query)
-      where("title like :query OR content like :query", query: "%#{query}%")
-    end
-  end
-
-  protected
-
-  def self.regenerate_from wiki
-    regenerated_field = [:slug, :content, :title]
-
-    new_wiki = Wiki.new
-    regenerated_field.each do |field|
-      new_wiki.send("#{field}=", wiki.send(field))
-    end
-    new_wiki
-  end
-
-  def set_slug
-    self.slug = self.title.parameterize
-  end
-end
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index adc77b22231..497d69e8e90 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -79,14 +79,14 @@ class WikiPage
   def version
     return nil unless persisted?
 
-    @version ||= Commit.new(@page.version)
+    @version ||= Commit.new(Gitlab::Git::Commit.new(@page.version))
   end
 
   # Returns an array of Gitlab Commit instances.
   def versions
     return [] unless persisted?
 
-    @page.versions.map { |v| Commit.new(v) }
+    @page.versions.map { |v| Commit.new(Gitlab::Git::Commit.new(v)) }
   end
 
   # Returns the Date that this latest version was
diff --git a/app/observers/activity_observer.rb b/app/observers/activity_observer.rb
index c040c4c5ca2..ee3e4629b4c 100644
--- a/app/observers/activity_observer.rb
+++ b/app/observers/activity_observer.rb
@@ -1,4 +1,4 @@
-class ActivityObserver < ActiveRecord::Observer
+class ActivityObserver < BaseObserver
   observe :issue, :merge_request, :note, :milestone
 
   def after_create(record)
diff --git a/app/observers/base_observer.rb b/app/observers/base_observer.rb
new file mode 100644
index 00000000000..182d3b7b73c
--- /dev/null
+++ b/app/observers/base_observer.rb
@@ -0,0 +1,9 @@
+class BaseObserver < ActiveRecord::Observer
+  def notification
+    NotificationService.new
+  end
+
+  def log_info message
+    Gitlab::AppLogger.info message
+  end
+end
diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb
index 29e24040378..03ce4b95ac8 100644
--- a/app/observers/issue_observer.rb
+++ b/app/observers/issue_observer.rb
@@ -1,42 +1,30 @@
-class IssueObserver < ActiveRecord::Observer
+class IssueObserver < BaseObserver
   cattr_accessor :current_user
 
   def after_create(issue)
-    if issue.assignee && issue.assignee != current_user
-      Notify.delay.new_issue_email(issue.id)
-    end
+    notification.new_issue(issue, current_user)
   end
 
   def after_close(issue, transition)
-    send_reassigned_email(issue) if issue.is_being_reassigned?
+    notification.close_issue(issue, current_user)
 
     create_note(issue)
   end
 
   def after_reopen(issue, transition)
-    send_reassigned_email(issue) if issue.is_being_reassigned?
-
     create_note(issue)
   end
 
   def after_update(issue)
-    send_reassigned_email(issue) if issue.is_being_reassigned?
+    if issue.is_being_reassigned?
+      notification.reassigned_issue(issue, current_user)
+    end
   end
 
   protected
 
+  # Create issue note with service comment like 'Status changed to closed'
   def create_note(issue)
     Note.create_status_change_note(issue, current_user, issue.state)
-    [issue.author, issue.assignee].compact.uniq.each do |recipient|
-      Notify.delay.issue_status_changed_email(recipient.id, issue.id, issue.state, current_user.id)
-    end
-  end
-
-  def send_reassigned_email(issue)
-    recipient_ids = [issue.assignee_id, issue.assignee_id_was].keep_if {|id| id && id != current_user.id }
-
-    recipient_ids.each do |recipient_id|
-      Notify.delay.reassigned_issue_email(recipient_id, issue.id, issue.assignee_id_was)
-    end
   end
 end
diff --git a/app/observers/key_observer.rb b/app/observers/key_observer.rb
index 9d02cbc16f7..28fef55abf9 100644
--- a/app/observers/key_observer.rb
+++ b/app/observers/key_observer.rb
@@ -1,6 +1,4 @@
-class KeyObserver < ActiveRecord::Observer
-  include Gitolited
-
+class KeyObserver < BaseObserver
   def after_save(key)
     GitlabShellWorker.perform_async(
       :add_key,
@@ -8,8 +6,7 @@ class KeyObserver < ActiveRecord::Observer
       key.key
     )
 
-    # Notify about ssh key being added
-    Notify.delay.new_ssh_key_email(key.id) if key.user
+    notification.new_key(key)
   end
 
   def after_destroy(key)
diff --git a/app/observers/merge_request_observer.rb b/app/observers/merge_request_observer.rb
index d89e7734c1a..d0dfad8869d 100644
--- a/app/observers/merge_request_observer.rb
+++ b/app/observers/merge_request_observer.rb
@@ -1,36 +1,25 @@
-class MergeRequestObserver < ActiveRecord::Observer
+class MergeRequestObserver < BaseObserver
   cattr_accessor :current_user
 
   def after_create(merge_request)
-    if merge_request.assignee && merge_request.assignee != current_user
-      Notify.delay.new_merge_request_email(merge_request.id)
-    end
+    notification.new_merge_request(merge_request, current_user)
   end
 
   def after_close(merge_request, transition)
-    send_reassigned_email(merge_request) if merge_request.is_being_reassigned?
-
     Note.create_status_change_note(merge_request, current_user, merge_request.state)
+
+    notification.close_mr(merge_request, current_user)
   end
 
-  def after_reopen(merge_request, transition)
-    send_reassigned_email(merge_request) if merge_request.is_being_reassigned?
+  def after_merge(merge_request, transition)
+    notification.merge_mr(merge_request)
+  end
 
+  def after_reopen(merge_request, transition)
     Note.create_status_change_note(merge_request, current_user, merge_request.state)
   end
 
   def after_update(merge_request)
-    send_reassigned_email(merge_request) if merge_request.is_being_reassigned?
-  end
-
-  protected
-
-  def send_reassigned_email(merge_request)
-    recipients_ids = merge_request.assignee_id_was, merge_request.assignee_id
-    recipients_ids.delete current_user.id
-
-    recipients_ids.each do |recipient_id|
-      Notify.delay.reassigned_merge_request_email(recipient_id, merge_request.id, merge_request.assignee_id_was)
-    end
+    notification.reassigned_merge_request(merge_request, current_user) if merge_request.is_being_reassigned?
   end
 end
diff --git a/app/observers/note_observer.rb b/app/observers/note_observer.rb
index 0f820a263b3..7b79161cce4 100644
--- a/app/observers/note_observer.rb
+++ b/app/observers/note_observer.rb
@@ -1,38 +1,5 @@
-class NoteObserver < ActiveRecord::Observer
+class NoteObserver < BaseObserver
   def after_create(note)
-    send_notify_mails(note)
-  end
-
-  protected
-
-  def send_notify_mails(note)
-    if note.notify
-      notify_team(note)
-    elsif note.notify_author
-      # Notify only author of resource
-      if note.commit_author
-        Notify.delay.note_commit_email(note.commit_author.id, note.id)
-      end
-    else
-      # Otherwise ignore it
-      nil
-    end
-  end
-
-  # Notifies the whole team except the author of note
-  def notify_team(note)
-    # Note: wall posts are not "attached" to anything, so fall back to "Wall"
-    noteable_type = note.noteable_type.presence || "Wall"
-    notify_method = "note_#{noteable_type.underscore}_email".to_sym
-
-    if Notify.respond_to? notify_method
-      team_without_note_author(note).map do |u|
-        Notify.delay.send(notify_method, u.id, note.id)
-      end
-    end
-  end
-
-  def team_without_note_author(note)
-    note.project.users.reject { |u| u.id == note.author.id }
+    notification.new_note(note)
   end
 end
diff --git a/app/observers/project_activity_cache_observer.rb b/app/observers/project_activity_cache_observer.rb
new file mode 100644
index 00000000000..96ced90db80
--- /dev/null
+++ b/app/observers/project_activity_cache_observer.rb
@@ -0,0 +1,8 @@
+class ProjectActivityCacheObserver < BaseObserver
+  observe :event
+
+  def after_create(event)
+    event.project.update_column(:last_activity_at, event.created_at) if event.project
+  end
+end
+
diff --git a/app/observers/project_observer.rb b/app/observers/project_observer.rb
index 89dc97ac140..7d7ecdd319f 100644
--- a/app/observers/project_observer.rb
+++ b/app/observers/project_observer.rb
@@ -1,4 +1,4 @@
-class ProjectObserver < ActiveRecord::Observer
+class ProjectObserver < BaseObserver
   def after_create(project)
     GitlabShellWorker.perform_async(
       :add_repository,
@@ -27,10 +27,4 @@ class ProjectObserver < ActiveRecord::Observer
 
     log_info("Project \"#{project.name}\" was removed")
   end
-
-  protected
-
-  def log_info message
-    Gitlab::AppLogger.info message
-  end
 end
diff --git a/app/observers/system_hook_observer.rb b/app/observers/system_hook_observer.rb
index be2594b4916..3a649fd590d 100644
--- a/app/observers/system_hook_observer.rb
+++ b/app/observers/system_hook_observer.rb
@@ -1,4 +1,4 @@
-class SystemHookObserver < ActiveRecord::Observer
+class SystemHookObserver < BaseObserver
   observe :user, :project, :users_project
 
   def after_create(model)
diff --git a/app/observers/user_observer.rb b/app/observers/user_observer.rb
index 6c461e07865..6bb3c471d0c 100644
--- a/app/observers/user_observer.rb
+++ b/app/observers/user_observer.rb
@@ -1,9 +1,8 @@
-class UserObserver < ActiveRecord::Observer
+class UserObserver < BaseObserver
   def after_create(user)
     log_info("User \"#{user.name}\" (#{user.email}) was created")
 
-    # Dont email omniauth created users
-    Notify.delay.new_user_email(user.id, user.password) unless user.extern_uid?
+    notification.new_user(user)
   end
 
   def after_destroy user
@@ -19,10 +18,4 @@ class UserObserver < ActiveRecord::Observer
       end
     end
   end
-
-  protected
-
-  def log_info message
-    Gitlab::AppLogger.info message
-  end
 end
diff --git a/app/observers/users_project_observer.rb b/app/observers/users_project_observer.rb
index 66b421753f0..ca9649c76ab 100644
--- a/app/observers/users_project_observer.rb
+++ b/app/observers/users_project_observer.rb
@@ -1,7 +1,6 @@
-class UsersProjectObserver < ActiveRecord::Observer
+class UsersProjectObserver < BaseObserver
   def after_commit(users_project)
     return if users_project.destroyed?
-    Notify.delay.project_access_granted_email(users_project.id)
   end
 
   def after_create(users_project)
@@ -10,6 +9,12 @@ class UsersProjectObserver < ActiveRecord::Observer
       action: Event::JOINED,
       author_id: users_project.user.id
     )
+
+    notification.new_team_member(users_project)
+  end
+
+  def after_update(users_project)
+    notification.update_team_member(users_project)
   end
 
   def after_destroy(users_project)
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 383e6398b74..e8b32f52ce1 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -104,7 +104,7 @@ class GitPushService
       data[:commits] << {
         id: commit.id,
         message: commit.safe_message,
-        timestamp: commit.date.xmlschema,
+        timestamp: commit.committed_date.xmlschema,
         url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/#{commit.id}",
         author: {
           name: commit.author_name,
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
new file mode 100644
index 00000000000..379d2c54629
--- /dev/null
+++ b/app/services/notification_service.rb
@@ -0,0 +1,223 @@
+# NotificationService class
+#
+# Used for notifing users with emails about different events
+#
+# Ex.
+#   NotificationService.new.new_issue(issue, current_user)
+#
+class NotificationService
+  # Always notify user about ssh key added
+  # only if ssh key is not deploy key
+  #
+  # This is security email so it will be sent
+  # even if user disabled notifications
+  def new_key(key)
+    if key.user
+      mailer.new_ssh_key_email(key.id)
+    end
+  end
+
+  # When create an issue we should send next emails:
+  #
+  #  * issue assignee if his notification level is not Disabled
+  #  * project team members with notification level higher then Participating
+  #
+  def new_issue(issue, current_user)
+    new_resource_email(issue, 'new_issue_email')
+  end
+
+  # When we close an issue we should send next emails:
+  #
+  #  * issue author if his notification level is not Disabled
+  #  * issue assignee if his notification level is not Disabled
+  #  * project team members with notification level higher then Participating
+  #
+  def close_issue(issue, current_user)
+    close_resource_email(issue, current_user, 'closed_issue_email')
+  end
+
+  # When we reassign an issue we should send next emails:
+  #
+  #  * issue old assignee if his notification level is not Disabled
+  #  * issue new assignee if his notification level is not Disabled
+  #
+  def reassigned_issue(issue, current_user)
+    reassign_resource_email(issue, current_user, 'reassigned_issue_email')
+  end
+
+
+  # When create a merge request we should send next emails:
+  #
+  #  * mr assignee if his notification level is not Disabled
+  #
+  def new_merge_request(merge_request, current_user)
+    new_resource_email(merge_request, 'new_merge_request_email')
+  end
+
+  # When we reassign a merge_request we should send next emails:
+  #
+  #  * merge_request old assignee if his notification level is not Disabled
+  #  * merge_request assignee if his notification level is not Disabled
+  #
+  def reassigned_merge_request(merge_request, current_user)
+    reassign_resource_email(merge_request, current_user, 'reassigned_merge_request_email')
+  end
+
+  # When we close a merge request we should send next emails:
+  #
+  #  * merge_request author if his notification level is not Disabled
+  #  * merge_request assignee if his notification level is not Disabled
+  #  * project team members with notification level higher then Participating
+  #
+  def close_mr(merge_request, current_user)
+    close_resource_email(merge_request, current_user, 'closed_merge_request_email')
+  end
+
+  # When we merge a merge request we should send next emails:
+  #
+  #  * merge_request author if his notification level is not Disabled
+  #  * merge_request assignee if his notification level is not Disabled
+  #  * project team members with notification level higher then Participating
+  #
+  def merge_mr(merge_request)
+    recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.project)
+    recipients = recipients.concat(project_watchers(merge_request.project)).uniq
+
+    recipients.each do |recipient|
+      mailer.merged_merge_request_email(recipient.id, merge_request.id)
+    end
+  end
+
+  # Notify new user with email after creation
+  def new_user(user)
+    # Dont email omniauth created users
+    mailer.new_user_email(user.id, user.password) unless user.extern_uid?
+  end
+
+  # Notify users on new note in system
+  #
+  # TODO: split on methods and refactor
+  #
+  def new_note(note)
+    # ignore wall messages
+    return true unless note.noteable_type.present?
+
+    opts = { noteable_type: note.noteable_type, project_id: note.project_id }
+
+    if note.commit_id.present?
+      opts.merge!(commit_id: note.commit_id)
+      recipients = [note.commit_author]
+    else
+      opts.merge!(noteable_id: note.noteable_id)
+      target = note.noteable
+      recipients = []
+      recipients << target.assignee if target.respond_to?(:assignee)
+      recipients << target.author if target.respond_to?(:author)
+    end
+
+    # Get users who left comment in thread
+    recipients = recipients.concat(User.where(id: Note.where(opts).pluck(:author_id)))
+
+    # Merge project watchers
+    recipients = recipients.concat(project_watchers(note.project)).compact.uniq
+
+    # Reject mutes users
+    recipients = reject_muted_users(recipients, note.project)
+
+    # Reject author
+    recipients.delete(note.author)
+
+    # build notify method like 'note_commit_email'
+    notify_method = "note_#{note.noteable_type.underscore}_email".to_sym
+
+    recipients.each do |recipient|
+      mailer.send(notify_method, recipient.id, note.id)
+    end
+  end
+
+  def new_team_member(users_project)
+    mailer.project_access_granted_email(users_project.id)
+  end
+
+  def update_team_member(users_project)
+    mailer.project_access_granted_email(users_project.id)
+  end
+
+  protected
+
+  # Get project users with WATCH notification level
+  def project_watchers(project)
+
+    # Get project notification settings since it has higher priority
+    user_ids = project.users_projects.where(notification_level: Notification::N_WATCH).pluck(:user_id)
+    project_watchers = User.where(id: user_ids)
+
+    # next collect users who use global settings with watch state
+    user_ids = project.users_projects.where(notification_level: Notification::N_GLOBAL).pluck(:user_id)
+    project_watchers += User.where(id: user_ids, notification_level: Notification::N_WATCH)
+
+    project_watchers.uniq
+  end
+
+  # Remove users with disabled notifications from array
+  # Also remove duplications and nil recipients
+  def reject_muted_users(users, project = nil)
+    users = users.compact.uniq
+
+    users.reject do |user|
+      next user.notification.disabled? unless project
+
+      tm = project.users_projects.find_by_user_id(user.id)
+
+      # reject users who globally disabled notification and has no membership
+      next user.notification.disabled? unless tm
+
+      # reject users who disabled notification in project
+      next true if tm.notification.disabled?
+
+      # reject users who have N_GLOBAL in project and disabled in global settings
+      tm.notification.global? && user.notification.disabled?
+    end
+  end
+
+  def new_resource_email(target, method)
+    recipients = reject_muted_users([target.assignee], target.project)
+    recipients = recipients.concat(project_watchers(target.project)).uniq
+    recipients.delete(target.author)
+
+    recipients.each do |recipient|
+      mailer.send(method, recipient.id, target.id)
+    end
+  end
+
+  def close_resource_email(target, current_user, method)
+    recipients = reject_muted_users([target.author, target.assignee], target.project)
+    recipients = recipients.concat(project_watchers(target.project)).uniq
+    recipients.delete(current_user)
+
+    recipients.each do |recipient|
+      mailer.send(method, recipient.id, target.id, current_user.id)
+    end
+  end
+
+  def reassign_resource_email(target, current_user, method)
+    recipients = User.where(id: [target.assignee_id, target.assignee_id_was])
+
+    # Add watchers to email list
+    recipients = recipients.concat(project_watchers(target.project))
+
+    # reject users with disabled notifications
+    recipients = reject_muted_users(recipients, target.project)
+
+    # Reject me from recipients if I reassign an item
+    recipients.delete(current_user)
+
+    recipients.each do |recipient|
+      mailer.send(method, recipient.id, target.id, target.assignee_id_was)
+    end
+  end
+
+  def mailer
+    Notify.delay
+  end
+end
diff --git a/app/services/project_transfer_service.rb b/app/services/project_transfer_service.rb
index 2ff1aa919df..3b8c4847f20 100644
--- a/app/services/project_transfer_service.rb
+++ b/app/services/project_transfer_service.rb
@@ -3,7 +3,9 @@
 # Used for transfer project to another namespace
 #
 class ProjectTransferService
-  include Gitolited
+  include Gitlab::ShellAdapter
+
+  class TransferError < StandardError; end
 
   attr_accessor :project
 
@@ -19,14 +21,16 @@ class ProjectTransferService
       project.namespace = new_namespace
       project.save!
 
+      # Move main repository
       unless gitlab_shell.mv_repository(old_path, new_path)
         raise TransferError.new('Cannot move project')
       end
 
+      # Move wiki repo also if present
+      gitlab_shell.mv_repository("#{old_path}.wiki", "#{new_path}.wiki")
+
       true
     end
-  rescue => ex
-    raise Project::TransferError.new(ex.message)
   end
 end
 
diff --git a/app/views/admin/groups/edit.html.haml b/app/views/admin/groups/edit.html.haml
index bb1398f66cd..af87503128e 100644
--- a/app/views/admin/groups/edit.html.haml
+++ b/app/views/admin/groups/edit.html.haml
@@ -27,5 +27,5 @@
         %li It will change the git path to repositories under this group.
 
   .form-actions
-    = f.submit 'Edit group', class: "btn btn-remove"
+    = f.submit 'Save changes', class: "btn btn-primary"
     = link_to  'Cancel', admin_groups_path, class: "btn btn-cancel"
diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml
index 0029cc78e3e..08d99411bfc 100644
--- a/app/views/admin/groups/index.html.haml
+++ b/app/views/admin/groups/index.html.haml
@@ -34,4 +34,4 @@
       %td.bgred
         = link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-small"
         = link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove"
-= paginate @groups, theme: "admin"
+= paginate @groups, theme: "gitlab"
diff --git a/app/views/admin/groups/new.html.haml b/app/views/admin/groups/new.html.haml
index 3fa63e1ba25..2da654ec764 100644
--- a/app/views/admin/groups/new.html.haml
+++ b/app/views/admin/groups/new.html.haml
@@ -15,7 +15,7 @@
       = f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
 
   .form-actions
-    = f.submit 'Create group', class: "btn btn-primary"
+    = f.submit 'Create group', class: "btn btn-create"
 
   %hr
   .padded
@@ -23,5 +23,5 @@
       %li Group is kind of directory for several projects
       %li All created groups are private
       %li People within a group see only projects they have access to
-      %li All projects of group will be stored in group directory
+      %li All projects of group will be stored in a group directory
       %li You will be able to move existing projects into group
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 63ea78fdd99..e73321a5bab 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -94,7 +94,7 @@
         %td= select_tag :project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3"}
 
       %tr
-        %td= submit_tag 'Add user to projects in group', class: "btn btn-primary"
+        %td= submit_tag 'Add user to projects in group', class: "btn btn-create"
         %td
           Read more about project permissions
           %strong= link_to "here", help_permissions_path, class: "vlink"
@@ -116,7 +116,7 @@
       .input
         = select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
     .form-actions
-      = submit_tag 'Add', class: "btn btn-primary"
+      = submit_tag 'Move projects', class: "btn btn-create"
 
 :javascript
   $(function(){
diff --git a/app/views/admin/hooks/_data_ex.html.erb b/app/views/admin/hooks/_data_ex.html.erb
index 652ee5aa56f..eeb78b5f0c5 100644
--- a/app/views/admin/hooks/_data_ex.html.erb
+++ b/app/views/admin/hooks/_data_ex.html.erb
@@ -28,8 +28,8 @@
      "project_id": 74, 
    "project_name": "StoreCloud",
    "project_path": "storecloud", 
-    "owner_email": "johnsmith@gmail.com",
-     "owner_name": "John Smith",
+    "user_email": "johnsmith@gmail.com",
+     "user_name": "John Smith",
 }
 
 4. Team Member Removed:
@@ -40,8 +40,8 @@
      "project_id": 74, 
    "project_name": "StoreCloud",
    "project_path": "storecloud", 
-    "owner_email": "johnsmith@gmail.com",
-     "owner_name": "John Smith",
+    "user_email": "johnsmith@gmail.com",
+     "user_name": "John Smith",
 }
 
 5. User created:
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index acbf7a108b8..316e8235cbe 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -15,7 +15,7 @@
     .input
       = f.text_field :url, class: "text_field xxlarge"
       &nbsp;
-      = f.submit "Add System Hook", class: "btn btn-primary"
+      = f.submit "Add System Hook", class: "btn btn-create"
 %hr
 
 -if @hooks.any?
diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml
deleted file mode 100644
index 29b90bdd4cb..00000000000
--- a/app/views/admin/projects/_form.html.haml
+++ /dev/null
@@ -1,86 +0,0 @@
-= form_for [:admin, project] do |f|
-  -if project.errors.any?
-    .alert.alert-error
-      %ul
-        - project.errors.full_messages.each do |msg|
-          %li= msg
-
-  .clearfix.project_name_holder
-    = f.label :name do
-      Project name is
-    .input
-      = f.text_field :name, placeholder: "Example Project", class: "xxlarge"
-
-  - if project.repo_exists?
-    %fieldset.adv_settings
-      %legend Advanced settings:
-      .clearfix
-        = f.label :path do
-          Path
-        .input
-          = text_field_tag :ppath, @project.repository.path_to_repo, class: "xlarge", disabled: true
-
-      .clearfix
-        = f.label :default_branch, "Default Branch"
-        .input= f.select(:default_branch, @project.repository.heads.map(&:name), {}, style: "width:210px;")
-
-  %fieldset.adv_settings
-    %legend Features:
-
-    .clearfix
-      = f.label :issues_enabled, "Issues"
-      .input= f.check_box :issues_enabled
-
-    - if Project.issues_tracker.values.count > 1
-      .clearfix
-        = f.label :issues_tracker, "Issues tracker", class: 'control-label'
-        .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled })
-
-      .clearfix
-        = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label'
-        .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id?
-
-    .clearfix
-      = f.label :merge_requests_enabled, "Merge Requests"
-      .input= f.check_box :merge_requests_enabled
-
-    .clearfix
-      = f.label :wall_enabled, "Wall"
-      .input= f.check_box :wall_enabled
-
-    .clearfix
-      = f.label :wiki_enabled, "Wiki"
-      .input= f.check_box :wiki_enabled
-
-  %fieldset.features
-    %legend Public mode:
-    .clearfix
-      = f.label :public do
-        %span Allow public http clone
-      .input= f.check_box :public
-
-  %fieldset.features
-    %legend Transfer:
-    .control-group
-      = f.label :namespace_id do
-        %span Namespace
-      .controls
-        = f.select :namespace_id, namespaces_options(@project.namespace_id, :all), {}, {class: 'chosen'}
-        %br
-        %ul.prepend-top-10.cred
-          %li Be careful. Changing project namespace can have unintended side effects
-          %li You can transfer project only to namespaces you can manage
-          %li You will need to update your local repositories to point to the new location.
-
-
-  .actions
-    = f.submit 'Save Project', class: "btn btn-save"
-    = link_to 'Cancel', admin_projects_path, class: "btn btn-cancel"
-
-
-
-:javascript
-  $(function(){
-    new Projects();
-  })
-
diff --git a/app/views/admin/projects/edit.html.haml b/app/views/admin/projects/edit.html.haml
deleted file mode 100644
index 7b59a0cc753..00000000000
--- a/app/views/admin/projects/edit.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-%h3.page_title #{@project.name} &rarr; Edit project
-%hr
-= render 'form', project: @project
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 15b2778252a..aa006dfc997 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -52,10 +52,8 @@
               %i.icon-lock.cgreen
             = link_to project.name_with_namespace, [:admin, project]
             .pull-right
-              = link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
-              = link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove"
+              = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
+              = link_to 'Destroy', [project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove"
         - if @projects.blank?
           %p.nothing_here_message 0 projects matches
-        - else
-          %li.bottom
-            = paginate @projects, theme: "gitlab"
+    = paginate @projects, theme: "gitlab"
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 65b921170fd..92b8960151e 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -1,129 +1,90 @@
 %h3.page_title
   Project: #{@project.name_with_namespace}
-  = link_to edit_admin_project_path(@project), class: "btn pull-right" do
+  = link_to edit_project_path(@project), class: "btn pull-right" do
     %i.icon-edit
     Edit
+%hr
+.row
+  .span6
+    .ui-box
+      %h5.title
+        Project info:
+      %ul.well-list
+        %li
+          %span.light Name:
+          %strong= @project.name
+        %li
+          %span.light Namespace:
+          %strong
+            - if @project.namespace
+              = link_to @project.namespace.human_name, [:admin, @project.group || @project.owner]
+            - else
+              Global
+        %li
+          %span.light Owned by:
+          %strong
+            - if @project.owner
+              = link_to @project.owner_name, admin_user_path(@project.owner)
+            - else
+              (deleted)
 
+        %li
+          %span.light Created by:
+          %strong
+            = @project.creator.try(:name) || '(deleted)'
 
-%br
-%table.zebra-striped
-  %thead
-    %tr
-      %th Project
-      %th
-  %tr
-    %td
-      %b
-        Name:
-    %td
-      = @project.name
-  %tr
-    %td
-      %b
-        Namespace:
-    %td
-      - if @project.namespace
-        = @project.namespace.human_name
-      - else
-        Global
-  %tr
-    %td
-      %b
-        Owned by:
-    %td
-      - if @project.owner
-        = link_to @project.owner_name, admin_user_path(@project.owner)
-      - else
-        (deleted)
-  %tr
-    %td
-      %b
-        Created by:
-    %td
-      = @project.creator.try(:name) || '(deleted)'
-  %tr
-    %td
-      %b
-        Created at:
-    %td
-      = @project.created_at.stamp("March 1, 1999")
-    %tr
-      %td
-        %b
-          Smart HTTP:
-      %td
-        = link_to @project.http_url_to_repo
-    %tr
-      %td
-        %b
-          SSH:
-      %td
-        = link_to @project.ssh_url_to_repo
-  - if @project.public
-    %tr.bgred
-      %td
-        %b
-          Public Read-Only Code access:
-      %td
-        = check_box_tag 'public', nil, @project.public
+        %li
+          %span.light Created at:
+          %strong
+            = @project.created_at.stamp("March 1, 1999")
 
-- if @repository
-  %table.zebra-striped
-    %thead
-      %tr
-        %th Repository
-        %th
-    %tr
-      %td
-        %b
-          FS Path:
-      %td
-        %code= @repository.path_to_repo
-    %tr
-      %td
-        %b
-          Last commit at:
-      %td
-        = last_commit(@project)
+        %li
+          %span.light http:
+          %strong
+            = link_to @project.http_url_to_repo
+        %li
+          %span.light ssh:
+          %strong
+            = link_to @project.ssh_url_to_repo
+        - if @project.repository.exists?
+          %li
+            %span.light fs:
+            %strong
+              = @repository.path_to_repo
 
-%br
-%h5
-  Team
-  %small
-    (#{@project.users.count})
-%br
-%table.zebra-striped.team_members
-  %thead
-    %tr
-      %th Name
-      %th Project Access
-      %th Repository Access
-      %th
+          %li
+            %span.light last commit:
+            %strong
+              = last_commit(@project)
+        - else
+          %li
+            %span.light repository:
+            %strong.cred
+              does not exist
 
-  - @project.users.each do |tm|
-    %tr
-      %td
-        = link_to tm.name, admin_user_path(tm)
-      %td= @project.project_access_human(tm)
-      %td= link_to 'Edit Access', edit_admin_project_member_path(@project, tm), class: "btn btn-small"
-      %td= link_to 'Remove from team', admin_project_member_path(@project, tm), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove small"
-
-%br
-%h5 Add new team member
-%br
-= form_tag team_update_admin_project_path(@project), class: "bulk_import", method: :put  do
-  %table.zebra-striped
-    %thead
-      %tr
-        %th Users
-        %th Project Access:
-
-    %tr
-      %td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5'
-      %td= select_tag :project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3"}
-
-    %tr
-      %td= submit_tag 'Add', class: "btn btn-primary"
-      %td
-        Read more about project permissions
-        %strong= link_to "here", help_permissions_path, class: "vlink"
+        %li
+          %span.light access:
+          %strong
+            - if @project.public
+              %span.cblue
+                %i.icon-share
+                Public
+            - else
+              %span.cgreen
+                %i.icon-lock
+                Private
+  .span6
+    .ui-box
+      %h5.title
+        Team
+        %small
+          (#{@project.users.count})
+        = link_to project_team_index_path(@project), class: "btn btn-tiny" do
+          %i.icon-edit
+          Edit Team
+      %ul.well-list.team_members
+        - @project.users.each do |tm|
+          %li
+            %strong
+              = link_to tm.name, admin_user_path(tm)
+            %span.pull-right.light= @project.project_access_human(tm)
diff --git a/app/views/admin/projects/team.html.haml b/app/views/admin/projects/team.html.haml
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/app/views/admin/teams/index.html.haml b/app/views/admin/teams/index.html.haml
index 3690d6d9eb4..225ad166774 100644
--- a/app/views/admin/teams/index.html.haml
+++ b/app/views/admin/teams/index.html.haml
@@ -40,4 +40,4 @@
         = link_to 'Edit', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn btn-small"
         = link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove"
 
-= paginate @teams, theme: "admin"
+= paginate @teams, theme: "gitlab"
diff --git a/app/views/admin/teams/new.html.haml b/app/views/admin/teams/new.html.haml
index 1c90cb20c10..8bccdacc351 100644
--- a/app/views/admin/teams/new.html.haml
+++ b/app/views/admin/teams/new.html.haml
@@ -16,7 +16,7 @@
       = f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
 
   .form-actions
-    = f.submit 'Create team', class: "btn btn-primary"
+    = f.submit 'Create team', class: "btn btn-create"
 
   %hr
   .padded
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index 1d1fe341c5b..9bde50f8947 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -80,8 +80,9 @@
         .input= f.text_field :twitter
 
     .actions
-      = f.submit 'Save', class: "btn btn-save"
       - if @admin_user.new_record?
+        = f.submit 'Create user', class: "btn btn-create"
         = link_to 'Cancel', admin_users_path, class: "btn btn-cancel"
       - else
+        = f.submit 'Save changes', class: "btn btn-save"
         = link_to 'Cancel', admin_user_path(@admin_user), class: "btn btn-cancel"
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 9da2871e992..3657f660c9b 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -58,5 +58,4 @@
                 - else
                   = link_to 'Block', block_admin_user_path(user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn btn-small btn-remove"
                 = link_to 'Destroy', [:admin, user], confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn btn-small btn-remove"
-        %li.bottom
-          = paginate @admin_users, theme: "gitlab"
+      = paginate @admin_users, theme: "gitlab"
diff --git a/app/views/blame/show.html.haml b/app/views/blame/show.html.haml
index b2a45ef5303..d4cd3ac1a32 100644
--- a/app/views/blame/show.html.haml
+++ b/app/views/blame/show.html.haml
@@ -6,7 +6,7 @@
       %i.icon-angle-right
       = link_to project_tree_path(@project, @ref) do
         = @project.name
-    - @tree.breadcrumbs(6) do |link|
+    - tree_breadcrumbs(@tree, 6) do |link|
       \/
       %li= link
   .clear
@@ -15,20 +15,20 @@
     .file_title
       %i.icon-file
       %span.file_name
-        = @tree.name
-        %small= number_to_human_size @tree.size
-      %span.options= render "tree/blob_actions"
+        = @blob.name
+        %small= number_to_human_size @blob.size
+      %span.options= render "blob/actions"
     .file_content.blame
       %table
         - current_line = 1
         - @blame.each do |commit, lines|
-          - commit = CommitDecorator.decorate(Commit.new(commit))
+          - commit = Commit.new(commit)
           %tr
             %td.blame-commit
               %span.commit
                 = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
                 &nbsp;
-                = commit.author_link avatar: true, size: 16
+                = commit_author_link(commit, avatar: true, size: 16)
                 &nbsp;
                 = link_to_gfm truncate(commit.title, length: 20), project_commit_path(@project, commit.id), class: "row_title"
             %td.lines.blame-numbers
diff --git a/app/views/tree/_blob_actions.html.haml b/app/views/blob/_actions.html.haml
similarity index 57%
rename from app/views/tree/_blob_actions.html.haml
rename to app/views/blob/_actions.html.haml
index 0bde968d0e6..456c7432c94 100644
--- a/app/views/tree/_blob_actions.html.haml
+++ b/app/views/blob/_actions.html.haml
@@ -1,12 +1,12 @@
 .btn-group.tree-btn-group
   -# only show edit link for text files
-  - if @tree.text?
-    = link_to "edit", edit_project_tree_path(@project, @id), class: "btn btn-tiny", disabled: !allowed_tree_edit?
-  = link_to "raw", project_blob_path(@project, @id), class: "btn btn-tiny", target: "_blank"
+  - if @blob.text?
+    = link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-tiny", disabled: !allowed_tree_edit?
+  = link_to "raw", project_raw_path(@project, @id), class: "btn btn-tiny", target: "_blank"
   -# only show normal/blame view links for text files
-  - if @tree.text?
+  - if @blob.text?
     - if current_page? project_blame_path(@project, @id)
-      = link_to "normal view", project_tree_path(@project, @id), class: "btn btn-tiny"
+      = link_to "normal view", project_blob_path(@project, @id), class: "btn btn-tiny"
     - else
-      = link_to "blame", project_blame_path(@project, @id), class: "btn btn-tiny"
+      = link_to "blame", project_blame_path(@project, @id), class: "btn btn-tiny" unless @blob.empty?
   = link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny"
diff --git a/app/views/blob/_blob.html.haml b/app/views/blob/_blob.html.haml
new file mode 100644
index 00000000000..d055d485787
--- /dev/null
+++ b/app/views/blob/_blob.html.haml
@@ -0,0 +1,27 @@
+%ul.breadcrumb
+  %li
+    %i.icon-angle-right
+    = link_to project_tree_path(@project, @ref) do
+      = @project.path
+  - tree_breadcrumbs(@tree, 6) do |title, path|
+    \/
+    %li
+      - if path
+        = link_to truncate(title, length: 40), project_tree_path(@project, path)
+      - else
+        = link_to title, '#'
+
+%div#tree-content-holder.tree-content-holder
+  .file_holder
+    .file_title
+      %i.icon-file
+      %span.file_name
+        = blob.name
+        %small= number_to_human_size blob.size
+      %span.options= render "actions"
+    - if blob.text?
+      = render "text", blob: blob
+    - elsif blob.image?
+      = render "image", blob: blob
+    - else
+      = render "download", blob: blob
diff --git a/app/views/tree/blob/_download.html.haml b/app/views/blob/_download.html.haml
similarity index 100%
rename from app/views/tree/blob/_download.html.haml
rename to app/views/blob/_download.html.haml
diff --git a/app/views/tree/blob/_image.html.haml b/app/views/blob/_image.html.haml
similarity index 100%
rename from app/views/tree/blob/_image.html.haml
rename to app/views/blob/_image.html.haml
diff --git a/app/views/tree/blob/_text.html.haml b/app/views/blob/_text.html.haml
similarity index 100%
rename from app/views/tree/blob/_text.html.haml
rename to app/views/blob/_text.html.haml
diff --git a/app/views/blob/show.html.haml b/app/views/blob/show.html.haml
new file mode 100644
index 00000000000..d1ca0e05e83
--- /dev/null
+++ b/app/views/blob/show.html.haml
@@ -0,0 +1,4 @@
+%div.tree-ref-holder
+  = render 'shared/ref_switcher', destination: 'tree', path: @path
+%div#tree-holder.tree-holder
+  = render 'blob', blob: @blob
diff --git a/app/views/blob/show.js.haml b/app/views/blob/show.js.haml
new file mode 100644
index 00000000000..804107f42fa
--- /dev/null
+++ b/app/views/blob/show.js.haml
@@ -0,0 +1,10 @@
+:plain
+  // Load Files list
+  $("#tree-holder").html("#{escape_javascript(render(partial: "blob", locals: {blob: @blob}))}");
+  $("#tree-content-holder").show("slide", { direction: "right" }, 400);
+  $('.project-refs-form #path').val("#{@path}");
+
+  //  Load last commit log for each file in tree
+  $('#tree-slider').waitForImages(function() {
+    ajaxGet('#{@logs_path}');
+  });
diff --git a/app/views/commits/_commit_box.html.haml b/app/views/commit/_commit_box.html.haml
similarity index 93%
rename from app/views/commits/_commit_box.html.haml
rename to app/views/commit/_commit_box.html.haml
index 4c80c13ced1..646791773b2 100644
--- a/app/views/commits/_commit_box.html.haml
+++ b/app/views/commit/_commit_box.html.haml
@@ -24,14 +24,14 @@
     .row
       .span5
         .author
-          = @commit.author_link avatar: true, size: 32
+          = commit_author_link(@commit, avatar: true, size: 32)
           authored
           %time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")}
             #{time_ago_in_words(@commit.authored_date)} ago
         - if @commit.different_committer?
           .committer
             &rarr;
-            = @commit.committer_link
+            = commit_committer_link(@commit)
             committed
             %time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")}
               #{time_ago_in_words(@commit.committed_date)} ago
diff --git a/app/views/commit/show.html.haml b/app/views/commit/show.html.haml
index 485f2d1e67c..48fb44a99d5 100644
--- a/app/views/commit/show.html.haml
+++ b/app/views/commit/show.html.haml
@@ -1,10 +1,11 @@
-= render "commits/commit_box"
+= render "commit_box"
 
-%p.pull-right.cgray
-  This commit has
-  %span.cgreen #{@commit.stats.additions} additions
-  and
-  %span.cred #{@commit.stats.deletions} deletions
+- unless @commit.has_zero_stats?
+  %p.pull-right.cgray
+    This commit has
+    %span.cgreen #{@commit.stats.additions} additions
+    and
+    %span.cred #{@commit.stats.deletions} deletions
 
 = render "commits/diffs", diffs: @commit.diffs
 = render "notes/notes_with_form"
diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml
index 2f5ff130f03..eba6c206c46 100644
--- a/app/views/commits/_commit.html.haml
+++ b/app/views/commits/_commit.html.haml
@@ -4,7 +4,7 @@
       %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right"
   %p
     = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
-    = commit.author_link avatar: true, size: 24
+    = commit_author_link(commit, avatar: true, size: 24)
     &nbsp;
     = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "row_title"
 
@@ -16,6 +16,6 @@
     %span.notes_count
       - notes = @project.notes.for_commit_id(commit.id)
       - if notes.any?
-        %span.btn.disabled.grouped
+        %span.badge.badge-info
           %i.icon-comment
           = notes.count
diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml
index 869d1f9c769..933780e4534 100644
--- a/app/views/commits/_commits.html.haml
+++ b/app/views/commits/_commits.html.haml
@@ -3,4 +3,7 @@
     %h5.title
       %i.icon-calendar
       %span= day.stamp("28 Aug, 2010")
+
+      .pull-right
+        %small= pluralize(commits.count, 'commit')
     %ul.well-list= render commits
diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml
index b2da4796db6..3f4d51f753a 100644
--- a/app/views/commits/_diffs.html.haml
+++ b/app/views/commits/_diffs.html.haml
@@ -16,16 +16,16 @@
   - unless @suppress_diff
     - diffs.each_with_index do |diff, i|
       - next if diff.diff.empty?
-      - file = (@commit.tree / diff.new_path)
-      - file = (@commit.prev_commit.tree / diff.old_path) unless file
-      - next unless file
+      - file = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, diff.new_path)
+      - file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) unless file.exists?
+      - next unless file.exists?
       .file{id: "diff-#{i}"}
         .header
           - if diff.deleted_file
             %span= diff.old_path
 
-            - if @commit.prev_commit
-              = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
+            - if @commit.parent_ids.present?
+              = link_to project_blob_path(@project, tree_join(@commit.parent_id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
                 View file @
                 %span.commit-short-id= @commit.short_id(6)
           - else
@@ -33,7 +33,7 @@
             - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
               %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
 
-            = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
+            = link_to project_blob_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
               View file @
               %span.commit-short-id= @commit.short_id(6)
 
@@ -43,7 +43,7 @@
           - if file.text?
             = render "commits/text_file", diff: diff, index: i
           - elsif file.image?
-            - old_file = (@commit.prev_commit.tree / diff.old_path) if !@commit.prev_commit.nil?
+            - old_file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) if @commit.parent_id
             = render "commits/image", diff: diff, old_file: old_file, file: file, index: i
           - else
             %p.nothing_here_message No preview for this file type
diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml
index d180b8ec426..586b21dfa5d 100644
--- a/app/views/commits/show.html.haml
+++ b/app/views/commits/show.html.haml
@@ -2,7 +2,7 @@
 
 - if @path.present?
   %ul.breadcrumb
-    = breadcrumbs
+    = commits_breadcrumbs
 
 %div{id: dom_id(@project)}
   #commits-list= render "commits"
diff --git a/app/views/compare/show.html.haml b/app/views/compare/show.html.haml
index 476be2550af..56c4a113ea0 100644
--- a/app/views/compare/show.html.haml
+++ b/app/views/compare/show.html.haml
@@ -16,7 +16,7 @@
   %div.ui-box
     %h5.title
       Commits (#{@commits.count})
-    %ul.well-list= render @commits
+    %ul.well-list= render Commit.decorate(@commits)
 
   - unless @diffs.empty?
     %h4 Diff
diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml
index 3124d76aa7f..2fedf87a9ba 100644
--- a/app/views/dashboard/_groups.html.haml
+++ b/app/views/dashboard/_groups.html.haml
@@ -1,11 +1,11 @@
 .ui-box
   %h5.title
     Groups
-    %small
+    %span.light
       (#{groups.count})
     - if current_user.can_create_group?
       %span.pull-right
-        = link_to new_group_path, class: "btn btn-tiny info" do
+        = link_to new_group_path, class: "btn btn-small" do
           %i.icon-plus
           New Group
   %ul.well-list
diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml
index 105e23fe12a..a106e83e783 100644
--- a/app/views/dashboard/_projects.html.haml
+++ b/app/views/dashboard/_projects.html.haml
@@ -1,11 +1,11 @@
 .ui-box
   %h5.title
     Projects
-    %small
+    %span.light
       (#{@projects_count})
     - if current_user.can_create_project?
       %span.pull-right
-        = link_to new_project_path, class: "btn btn-tiny info" do
+        = link_to new_project_path, class: "btn btn-small" do
           %i.icon-plus
           New Project
 
diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml
index 876a5b61297..748ff9810b5 100644
--- a/app/views/dashboard/_sidebar.html.haml
+++ b/app/views/dashboard/_sidebar.html.haml
@@ -22,7 +22,4 @@
         News Feed
 
 %hr
-.gitlab-promo
-  = link_to "Homepage", "http://gitlab.org"
-  = link_to "Blog", "http://blog.gitlab.org"
-  = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
+= render 'shared/promo'
diff --git a/app/views/dashboard/_teams.html.haml b/app/views/dashboard/_teams.html.haml
index 5c28f964cb6..95d87f508e0 100644
--- a/app/views/dashboard/_teams.html.haml
+++ b/app/views/dashboard/_teams.html.haml
@@ -1,10 +1,10 @@
 .ui-box.teams-box
   %h5.title
     Teams
-    %small
+    %span.light
       (#{teams.count})
     %span.pull-right
-      = link_to new_team_path, class: "btn btn-tiny info" do
+      = link_to new_team_path, class: "btn btn-small" do
         %i.icon-plus
         New Team
   %ul.well-list
diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml
index 539c57651f7..df85d5ba204 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -15,7 +15,7 @@
           - project = group[0]
           %h5.title
             = link_to_project project
-          %ul.well-list.issues_table
+          %ul.well-list.issues-list
             - group[1].each do |issue|
               = render issue
       %hr
diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml
index 29a16d61e63..511366cf1ab 100644
--- a/app/views/dashboard/projects.html.haml
+++ b/app/views/dashboard/projects.html.haml
@@ -20,6 +20,15 @@
       = nav_tab :scope, 'joined' do
         = link_to "Joined", projects_dashboard_path(scope: 'joined')
 
+    %p.light Filter by label:
+    %ul.bordered-list
+      - projects_labels.each do |label|
+        %li{ class: (label == params[:label]) ? 'active' : 'light' }
+          = link_to projects_dashboard_path(scope: params[:scope], label: label) do
+            %i.icon-tag
+            = label
+
+
   .span9
     = form_tag projects_dashboard_path, method: 'get' do
       %fieldset.dashboard-search-filter
@@ -28,7 +37,7 @@
         = button_tag type: 'submit', class: 'btn' do
           %i.icon-search
 
-    %ul.well-list
+    %ul.bordered-list
       - @projects.each do |project|
         %li.clearfix
           .clearfix
@@ -49,6 +58,10 @@
             .left
               - if project.description.present?
                 %span.light= project.description
+              - project.labels.each do |label|
+                %span.label.label-info
+                  %i.icon-tag
+                  = label.name
 
             .pull-right.light
               %small.light
diff --git a/app/views/dashboard/show.atom.builder b/app/views/dashboard/show.atom.builder
index 29b2e4a26d8..a913df92299 100644
--- a/app/views/dashboard/show.atom.builder
+++ b/app/views/dashboard/show.atom.builder
@@ -8,11 +8,10 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
 
   @events.each do |event|
     if event.proper?
-      event = EventDecorator.decorate(event)
       xml.entry do
-        event_link = event.feed_url
-        event_title = event.feed_title
-        event_summary = event.feed_summary
+        event_link = event_feed_url(event)
+        event_title = event_feed_title(event)
+        event_summary = event_feed_summary(event)
 
         xml.id      "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}"
         xml.link    :href => event_link
diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml
index 1a66ba4fb37..ff2db0e3180 100644
--- a/app/views/dashboard/show.html.haml
+++ b/app/views/dashboard/show.html.haml
@@ -1,5 +1,5 @@
 - if @has_authorized_projects
-  .projects
+  .dashboard
     .activities.span8
       = render 'activities'
     .side.span4
diff --git a/app/views/deploy_keys/index.html.haml b/app/views/deploy_keys/index.html.haml
index 80d30e1c2dc..66a8d3b7b7b 100644
--- a/app/views/deploy_keys/index.html.haml
+++ b/app/views/deploy_keys/index.html.haml
@@ -1,7 +1,7 @@
 = render "projects/settings_nav"
 
 %p.slead
-  Deploy keys allow read-only access to repository. It matches perfectly for CI, staging or production servers.
+  Deploy keys allow read-only access to repository. They can be used for for CI, staging or production servers. A deploy key can be added to only one project. If you need to add the same key to multiple projects you can create a deploy user and add that user to multiple projects.
 
   - if can? current_user, :admin_project, @project
     = link_to new_project_deploy_key_path(@project), class: "btn btn-small", title: "New Deploy Key" do
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index d904e701b8a..5e93ab18dc0 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,19 +1,19 @@
 - if ldap_enable?
-  = render :partial => 'devise/sessions/new_ldap'
+  = render partial: 'devise/sessions/new_ldap'
 - else
-  = form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "login-box" }) do |f|
-    = image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo"
-    = f.email_field :email, :class => "text top", :placeholder => "Email", :autofocus => "autofocus"
-    = f.password_field :password, :class => "text bottom", :placeholder => "Password"
+  = form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "login-box" }) do |f|
+    = image_tag "login-logo.png", width: "304", height: "66", class: "login-logo", alt: "Login Logo"
+    = f.text_field :login, class: "text top", placeholder: "Username or Email", autofocus: "autofocus"
+    = f.password_field :password, class: "text bottom", placeholder: "Password"
     - if devise_mapping.rememberable?
       .clearfix.inputs-list
-        %label.checkbox.remember_me{:for => "user_remember_me"}
+        %label.checkbox.remember_me{for: "user_remember_me"}
           = f.check_box :remember_me
           %span Remember me
     %br/
-    = f.submit "Sign in", :class => "btn-create btn"
+    = f.submit "Sign in", class: "btn-create btn"
     .pull-right
-      = link_to "Forgot your password?", new_password_path(resource_name), :class => "btn"
+      = link_to "Forgot your password?", new_password_path(resource_name), class: "btn"
     %br/
     - if Gitlab.config.gitlab.signup_enabled
       %hr/
diff --git a/app/views/tree/edit.html.haml b/app/views/edit_tree/show.html.haml
similarity index 80%
rename from app/views/tree/edit.html.haml
rename to app/views/edit_tree/show.html.haml
index 81918e509b8..e7bdeb39e72 100644
--- a/app/views/tree/edit.html.haml
+++ b/app/views/edit_tree/show.html.haml
@@ -1,24 +1,24 @@
 .file-editor
-  = form_tag(project_tree_path(@project, @id), method: :put, class: "form-horizontal") do
+  = form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do
     .file_holder
       .file_title
         %i.icon-file
         %span.file_name
-          = @tree.path
+          = @path
           %small
             on
             %strong= @ref
         %span.options
           .btn-group.tree-btn-group
-            = link_to "Cancel", project_tree_path(@project, @id), class: "btn btn-tiny btn-cancel", confirm: "Are you sure?"
+            = link_to "Cancel", project_blob_path(@project, @id), class: "btn btn-tiny btn-cancel", confirm: "Are you sure?"
       .file_content.code
-        %pre#editor= @tree.data
+        %pre#editor= @blob.data
 
     .control-group.commit_message-group
       = label_tag 'commit_message', class: "control-label" do
         Commit message
       .controls
-        = text_area_tag 'commit_message', '', placeholder: "Update #{@tree.name}", required: true, rows: 3
+        = text_area_tag 'commit_message', '', placeholder: "Update #{@blob.name}", required: true, rows: 3
     .form-actions
       = hidden_field_tag 'last_commit', @last_commit
       = hidden_field_tag 'content', '', id: :file_content
@@ -30,7 +30,7 @@
       = link_to "Cancel", project_tree_path(@project, @id), class: "btn btn-cancel", confirm: "Are you sure?"
 
 :javascript
-  var ace_mode = "#{@tree.language.try(:ace_mode)}";
+  var ace_mode = "#{@blob.language.try(:ace_mode)}";
   var editor = ace.edit("editor");
   if (ace_mode) {
     editor.getSession().setMode('ace/mode/' + ace_mode);
diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml
index ea417aa9f30..2d80fc103f6 100644
--- a/app/views/events/_commit.html.haml
+++ b/app/views/events/_commit.html.haml
@@ -1,8 +1,7 @@
-- commit = CommitDecorator.decorate(commit)
 %li.commit
   %p
-    = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id"
-    %span= commit.author_name
+    = link_to commit[:id][0..8], project_commit_path(project, commit[:id]), class: "commit_short_id"
+    %span= commit[:author][:name]
     &ndash;
-    = image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16
-    = gfm escape_once(truncate(commit.title, length: 50)) rescue "--broken encoding"
+    = image_tag gravatar_icon(commit[:author][:email]), class: "avatar", width: 16
+    = gfm escape_once(truncate(commit[:message], length: 50)) rescue "--broken encoding"
diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml
index d09e6e03f01..e44b366040f 100644
--- a/app/views/events/_event_push.atom.haml
+++ b/app/views/events/_event_push.atom.haml
@@ -1,12 +1,12 @@
-%div{:xmlns => "http://www.w3.org/1999/xhtml"}
+%div{xmlns: "http://www.w3.org/1999/xhtml"}
   - event.commits.first(15).each do |commit|
     %p
-      %strong= commit.author_name
-      = link_to "(##{commit.short_id})", project_commit_path(event.project, :id => commit.id)
+      %strong= commit[:author][:name]
+      = link_to "(##{commit[:id][0...8]})", project_commit_path(event.project, id: commit[:id])
       %i
         at
-        = commit.committed_date.strftime("%Y-%m-%d %H:%M:%S")
-    %blockquote= simple_format(escape_once(commit.safe_message))
+        = commit[:timestamp].to_time.to_s(:short)
+    %blockquote= simple_format(escape_once(commit[:message]))
   - if event.commits_count > 15
     %p
       %i
diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml
index 53cbe1c94ce..05d3832c7f9 100644
--- a/app/views/events/event/_common.html.haml
+++ b/app/views/events/event/_common.html.haml
@@ -2,11 +2,15 @@
   %span.author_name= link_to_author event
   %span.event_label{class: event.action_name}= event_action_name(event)
   - if event.target
-    %strong= link_to_gfm truncate(event.target_title), [event.project, event.target]
+    %strong= link_to "##{event.target_id}", [event.project, event.target]
   - else
-    %strong= gfm truncate(event.target_title)
+    %strong= gfm event.target_title
   at
   - if event.project
     = link_to_project event.project
   - else
     = event.project_name
+.event-body
+  .event-note
+    - if event.target.respond_to?(:title)
+      = event.target.title
diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml
index 119b8e828d0..f2b8dc4238c 100644
--- a/app/views/events/event/_push.html.haml
+++ b/app/views/events/event/_push.html.haml
@@ -21,5 +21,5 @@
         %li.commits-stat
           - if event.commits_count > 2
             %span ... and #{event.commits_count - 2} more commits.
-          = link_to project_compare_path(event.project, from: event.parent_commit.id, to: event.last_commit.id) do
-            %strong Compare &rarr; #{event.parent_commit.id[0..7]}...#{event.last_commit.id[0..7]}
+          = link_to project_compare_path(event.project, from: event.commit_from, to: event.commit_to) do
+            %strong Compare &rarr; #{event.commit_from[0..7]}...#{event.commit_to[0..7]}
diff --git a/app/views/graph/show.json.erb b/app/views/graph/show.json.erb
index d0a0709ac47..9a62cdb3dc9 100644
--- a/app/views/graph/show.json.erb
+++ b/app/views/graph/show.json.erb
@@ -7,13 +7,13 @@
       {
         parents: parents_zip_spaces(c.parents(@graph.map), c.parent_spaces),
         author: {
-          name: c.author.name,
-          email: c.author.email,
-          icon: gravatar_icon(c.author.email, 20)
+          name: c.author_name,
+          email: c.author_email,
+          icon: gravatar_icon(c.author_email, 20)
         },
         time: c.time,
         space: c.spaces.first,
-        refs: join_with_space(c.refs),
+        refs: get_refs(c),
         id: c.sha,
         date: c.date,
         message: c.message,
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index 96aa2a1626d..6d642b65cbd 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -14,7 +14,7 @@
           - project = group[0]
           %h5.title
             = link_to_project project
-          %ul.well-list.issues_table
+          %ul.well-list.issues-list
             - group[1].each do |issue|
               = render issue
       %hr
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 36ee4922731..b395a8bc6a3 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -24,5 +24,5 @@
       %li Group is kind of directory for several projects
       %li All created groups are private
       %li People within a group see only projects they have access to
-      %li All projects of group will be stored in group directory
+      %li All projects of group will be stored in a group directory
       %li You will be able to move existing projects into group
diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder
index 5f2999c3d8e..807ff5f39b4 100644
--- a/app/views/groups/show.atom.builder
+++ b/app/views/groups/show.atom.builder
@@ -8,7 +8,6 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
 
   @events.each do |event|
     if event.proper?
-      event = EventDecorator.decorate(event)
       xml.entry do
         event_link = event.feed_url
         event_title = event.feed_title
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index adf249f656a..e90abc71c0c 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -1,4 +1,4 @@
-.projects
+.dashboard
   .activities.span8
     = render "events/event_last_push", event: @last_push
     = link_to dashboard_path, class: 'btn btn-tiny' do
@@ -13,7 +13,7 @@
     .loading.hide
   .side.span4
     - if @group.description.present?
-      .description.well.light
+      .description.well.well-small.light
         = @group.description
     = render "projects", projects: @projects
     .prepend-top-20
@@ -23,10 +23,7 @@
           News Feed
 
     %hr
-    .gitlab-promo
-      = link_to "Homepage", "http://gitlabhq.com"
-      = link_to "Blog", "http://blog.gitlabhq.com"
-      = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
+    = render 'shared/promo'
 
 :javascript
   $(function(){ Pager.init(20, true); });
diff --git a/app/views/issues/_issue.html.haml b/app/views/issues/_issue.html.haml
index 3d1ecd43881..6c6d45e987b 100644
--- a/app/views/issues/_issue.html.haml
+++ b/app/views/issues/_issue.html.haml
@@ -1,12 +1,37 @@
 %li{ id: dom_id(issue), class: issue_css_classes(issue), url: project_issue_path(issue.project, issue) }
   - if controller.controller_name == 'issues'
-    .issue_check
+    .issue-check
       = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue)
-  .pull-right
+
+  .issue-title
+    %span.light= "##{issue.id}"
+    = link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title"
+
+  .issue-info
+    - if issue.assignee
+      assigned to #{link_to_member(@project, issue.assignee)}
+    - else
+      unassigned
+    - if issue.votes_count > 0
+      = render 'votes/votes_inline', votable: issue
     - if issue.notes.any?
-      %span.btn.btn-small.disabled.grouped
-        %i.icon-comment
+      %span
+        %i.icon-comments
         = issue.notes.count
+    - if issue.milestone_id?
+      %span
+        %i.icon-time
+        = issue.milestone.title
+    .pull-right
+      %small updated #{time_ago_in_words(issue.updated_at)} ago
+
+    .issue-labels
+      - issue.labels.each do |label|
+        %span.label.label-info
+          %i.icon-tag
+          = label.name
+
+  .issue-actions
     - if can? current_user, :modify_issue, issue
       - if issue.closed?
         = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {state_event: :reopen }, status_only: true), method: :put,  class: "btn btn-small grouped reopen_issue", remote: true
@@ -16,24 +41,4 @@
         %i.icon-edit
         Edit
 
-  - if issue.assignee
-    = image_tag gravatar_icon(issue.assignee_email), class: "avatar"
-  - else
-    = image_tag "no_avatar.png", class: "avatar"
-
-  %p= link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title"
-
-  %span.update-author
-    %span.cdark= "##{issue.id}"
-    - if issue.assignee
-      assigned to #{issue.assignee_name}
-    - else
-      &nbsp;
 
-    - if issue.votes_count > 0
-      = render 'votes/votes_inline', votable: issue
-    %span
-      - issue.labels.each do |label|
-        %span.label
-          %i.icon-tag
-          = label.name
diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml
index dc7db9061ac..93fa9da2767 100644
--- a/app/views/issues/_issues.html.haml
+++ b/app/views/issues/_issues.html.haml
@@ -1,12 +1,34 @@
-= render @issues
+.ui-box
+  .title
+    = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
+    .clearfix
+      .issues_bulk_update.hide
+        = form_tag bulk_update_project_issues_path(@project), method: :post  do
+          %span.update_issues_text Update selected issues with &nbsp;
+          .left
+            = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status")
+            = select_tag('update[assignee_id]', options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
+            = select_tag('update[milestone_id]', options_from_collection_for_select(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
+            = hidden_field_tag 'update[issues_ids]', []
+            = hidden_field_tag :status, params[:status]
+          = button_tag "Save", class: "btn update_selected_issues btn-small btn-save"
+      .issues_filters
+        = form_tag project_issues_path(@project), method: :get, remote: true  do
+          = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels")
+          = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
+          = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
+          = hidden_field_tag :status, params[:status]
+          = hidden_field_tag :issue_search, params[:status], id: 'filter_issue_search'
+
+  %ul.well-list.issues-list
+    = render @issues
+    - if @issues.blank?
+      %li
+        %h4.nothing_here_message Nothing to show here
 
 - if @issues.present?
-  %li.bottom
-    .left= paginate @issues, remote: true, theme: "gitlab"
-    .pull-right
-      %span.issue_counter #{@issues.total_count}
-      issues for this filter
-- else
-  %li
-    %h4.nothing_here_message Nothing to show here
+  .pull-right
+    %span.issue_counter #{@issues.total_count}
+    issues for this filter
 
+  = paginate @issues, remote: true, theme: "gitlab"
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index 875f29e2600..81777869f4a 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -4,47 +4,27 @@
     Issues
     %span (<span class=issue_counter>#{@issues.total_count}</span>)
     .pull-right
-      .span5
+      .span6
         - if can? current_user, :write_issue, @project
           = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-primary pull-right", title: "New Issue", id: "new_issue_link" do
             %i.icon-plus
             New Issue
-        = form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: 'pull-right'  do
-          = hidden_field_tag :project_id, @project.id, { id: 'project_id' }
-          = hidden_field_tag :status, params[:status]
-          = search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search span3 pull-right neib search-text-input' }
+        = form_tag project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: 'pull-right'  do
+          = hidden_field_tag :status, params[:status], id: 'search_status'
+          = hidden_field_tag :assignee_id, params[:assignee_id], id: 'search_assignee_id'
+          = hidden_field_tag :milestone_id, params[:milestone_id], id: 'search_milestone_id'
+          = hidden_field_tag :label_name, params[:label_name], id: 'search_label_name'
+          = search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search input-xlarge append-right-10 search-text-input' }
 
   .clearfix
 
 .row
   .span3
     = render 'filter', entity: 'issue'
-  .span9
-    %div#issues-table-holder.ui-box
-      .title
-        = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
-        .clearfix
-          .issues_bulk_update.hide
-            = form_tag bulk_update_project_issues_path(@project), method: :post  do
-              %span.update_issues_text Update selected issues with &nbsp;
-              .left
-                = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status")
-                = select_tag('update[assignee_id]', options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
-                = select_tag('update[milestone_id]', options_from_collection_for_select(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
-                = hidden_field_tag 'update[issues_ids]', []
-                = hidden_field_tag :status, params[:status]
-              = button_tag "Save", class: "btn update_selected_issues btn-small btn-save"
-          .issues_filters
-            = form_tag project_issues_path(@project), method: :get  do
-              = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels")
-              = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
-              = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone")
-              = hidden_field_tag :status, params[:status]
-
-      %ul#issues-table.well-list.issues_table
-        = render "issues"
+  .span9.issues-holder
+    = render "issues"
 
 :javascript
   $(function(){
-    issuesPage();
+    Issues.init();
   })
diff --git a/app/views/issues/index.js.haml b/app/views/issues/index.js.haml
index 48d7f582be2..1be6a64f535 100644
--- a/app/views/issues/index.js.haml
+++ b/app/views/issues/index.js.haml
@@ -1,2 +1,4 @@
 :plain
-  $('#issues-table').html("#{escape_javascript(render('issues'))}");
+  $('.issues-holder').html("#{escape_javascript(render('issues'))}");
+  History.replaceState({path: "#{request.url}"}, document.title, "#{request.url}");
+  Issues.reload();
diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml
index 70f94e52942..67fe89a761b 100644
--- a/app/views/issues/show.html.haml
+++ b/app/views/issues/show.html.haml
@@ -6,6 +6,9 @@
     = @issue.created_at.stamp("Aug 21, 2011")
 
   %span.pull-right
+    = link_to new_project_issue_path(@project), class: "btn grouped", title: "New Issue", id: "new_issue_link" do
+      %i.icon-plus
+      New Issue
     - if can?(current_user, :modify_issue, @issue)
       - if @issue.closed?
         = link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put,  class: "btn grouped reopen_issue"
diff --git a/app/views/kaminari/admin/_first_page.html.haml b/app/views/kaminari/admin/_first_page.html.haml
deleted file mode 100644
index 41c9c0b3af6..00000000000
--- a/app/views/kaminari/admin/_first_page.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
--#  Link to the "First" page
--#  available local variables
--#    url:           url to the first page
--#    current_page:  a page object for the currently displayed page
--#    num_pages:     total number of pages
--#    per_page:      number of items to fetch per page
--#    remote:        data-remote
-%span.first
-  = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote
diff --git a/app/views/kaminari/admin/_gap.html.haml b/app/views/kaminari/admin/_gap.html.haml
deleted file mode 100644
index 3ffd12f8587..00000000000
--- a/app/views/kaminari/admin/_gap.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
--#  Non-link tag that stands for skipped pages...
--#  available local variables
--#    current_page:  a page object for the currently displayed page
--#    num_pages:     total number of pages
--#    per_page:      number of items to fetch per page
--#    remote:        data-remote
-%li{class: "page"}
-  %span.page.gap
-    = raw(t 'views.pagination.truncate')
diff --git a/app/views/kaminari/admin/_last_page.html.haml b/app/views/kaminari/admin/_last_page.html.haml
deleted file mode 100644
index b03a206224c..00000000000
--- a/app/views/kaminari/admin/_last_page.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
--#  Link to the "Last" page
--#  available local variables
--#    url:           url to the last page
--#    current_page:  a page object for the currently displayed page
--#    num_pages:     total number of pages
--#    per_page:      number of items to fetch per page
--#    remote:        data-remote
-%span.last
-  = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {remote: remote}
diff --git a/app/views/kaminari/admin/_next_page.html.haml b/app/views/kaminari/admin/_next_page.html.haml
deleted file mode 100644
index 00c5f0b6f4e..00000000000
--- a/app/views/kaminari/admin/_next_page.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
--#  Link to the "Next" page
--#  available local variables
--#    url:           url to the next page
--#    current_page:  a page object for the currently displayed page
--#    num_pages:     total number of pages
--#    per_page:      number of items to fetch per page
--#    remote:        data-remote
-%li.next
-  = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote
diff --git a/app/views/kaminari/admin/_page.html.haml b/app/views/kaminari/admin/_page.html.haml
deleted file mode 100644
index a52d883b9a8..00000000000
--- a/app/views/kaminari/admin/_page.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
--#  Link showing page number
--#  available local variables
--#    page:          a page object for "this" page
--#    url:           url to this page
--#    current_page:  a page object for the currently displayed page
--#    num_pages:     total number of pages
--#    per_page:      number of items to fetch per page
--#    remote:        data-remote
-%li{class: "page#{' active' if page.current?}"}
-  = link_to page, url, {remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil}
diff --git a/app/views/kaminari/admin/_paginator.html.haml b/app/views/kaminari/admin/_paginator.html.haml
deleted file mode 100644
index 6f9fb332261..00000000000
--- a/app/views/kaminari/admin/_paginator.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
--#  The container tag
--#  available local variables
--#    current_page:  a page object for the currently displayed page
--#    num_pages:     total number of pages
--#    per_page:      number of items to fetch per page
--#    remote:        data-remote
--#    paginator:     the paginator that renders the pagination tags inside
-= paginator.render do
-  %div.pagination
-    %ul
-      = prev_page_tag unless current_page.first?
-      - each_page do |page|
-        - if page.left_outer? || page.right_outer? || page.inside_window?
-          = page_tag page
-        - elsif !page.was_truncated?
-          = gap_tag
-      = next_page_tag unless current_page.last?
diff --git a/app/views/kaminari/admin/_prev_page.html.haml b/app/views/kaminari/admin/_prev_page.html.haml
deleted file mode 100644
index f673abdb3ae..00000000000
--- a/app/views/kaminari/admin/_prev_page.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
--#  Link to the "Previous" page
--#  available local variables
--#    url:           url to the previous page
--#    current_page:  a page object for the currently displayed page
--#    num_pages:     total number of pages
--#    per_page:      number of items to fetch per page
--#    remote:        data-remote
-%li{class: "prev" }
-  = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote
diff --git a/app/views/kaminari/gitlab/_gap.html.haml b/app/views/kaminari/gitlab/_gap.html.haml
index f82f185ac35..3ffd12f8587 100644
--- a/app/views/kaminari/gitlab/_gap.html.haml
+++ b/app/views/kaminari/gitlab/_gap.html.haml
@@ -4,5 +4,6 @@
 -#    num_pages:     total number of pages
 -#    per_page:      number of items to fetch per page
 -#    remote:        data-remote
-%span.page.gap
-  = raw(t 'views.pagination.truncate')
+%li{class: "page"}
+  %span.page.gap
+    = raw(t 'views.pagination.truncate')
diff --git a/app/views/kaminari/gitlab/_next_page.html.haml b/app/views/kaminari/gitlab/_next_page.html.haml
index 296cceb080b..00c5f0b6f4e 100644
--- a/app/views/kaminari/gitlab/_next_page.html.haml
+++ b/app/views/kaminari/gitlab/_next_page.html.haml
@@ -5,5 +5,5 @@
 -#    num_pages:     total number of pages
 -#    per_page:      number of items to fetch per page
 -#    remote:        data-remote
-%span.next
+%li.next
   = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote
diff --git a/app/views/kaminari/gitlab/_page.html.haml b/app/views/kaminari/gitlab/_page.html.haml
index 19456dcc058..a52d883b9a8 100644
--- a/app/views/kaminari/gitlab/_page.html.haml
+++ b/app/views/kaminari/gitlab/_page.html.haml
@@ -6,5 +6,5 @@
 -#    num_pages:     total number of pages
 -#    per_page:      number of items to fetch per page
 -#    remote:        data-remote
-%span{class: "page#{' current' if page.current?}"}
-  = link_to_unless page.current?, page, url, {remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil}
+%li{class: "page#{' active' if page.current?}"}
+  = link_to page, url, {remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil}
diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml
index 6dd5a5782a2..6f9fb332261 100644
--- a/app/views/kaminari/gitlab/_paginator.html.haml
+++ b/app/views/kaminari/gitlab/_paginator.html.haml
@@ -6,11 +6,12 @@
 -#    remote:        data-remote
 -#    paginator:     the paginator that renders the pagination tags inside
 = paginator.render do
-  %nav.gitlab_pagination
-    = prev_page_tag
-    - each_page do |page|
-      - if page.left_outer? || page.right_outer? || page.inside_window?
-        = page_tag page
-      - elsif !page.was_truncated?
-        = gap_tag
-    = next_page_tag
+  %div.pagination
+    %ul
+      = prev_page_tag unless current_page.first?
+      - each_page do |page|
+        - if page.left_outer? || page.right_outer? || page.inside_window?
+          = page_tag page
+        - elsif !page.was_truncated?
+          = gap_tag
+      = next_page_tag unless current_page.last?
diff --git a/app/views/kaminari/gitlab/_prev_page.html.haml b/app/views/kaminari/gitlab/_prev_page.html.haml
index 5c2061690ac..f673abdb3ae 100644
--- a/app/views/kaminari/gitlab/_prev_page.html.haml
+++ b/app/views/kaminari/gitlab/_prev_page.html.haml
@@ -5,5 +5,5 @@
 -#    num_pages:     total number of pages
 -#    per_page:      number of items to fetch per page
 -#    remote:        data-remote
-%span.prev
+%li{class: "prev" }
   = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index 00a08e6131d..abe3f2ea854 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -4,24 +4,8 @@
   %body{class: "#{app_theme} admin"}
     = render "layouts/head_panel", title: "Admin area"
     = render "layouts/flash"
-    .container
-      %ul.main_menu
-        = nav_link(controller: :dashboard, html_options: {class: 'home'}) do
-          = link_to admin_root_path, title: "Stats" do
-            %i.icon-home
-        = nav_link(controller: :projects) do
-          = link_to "Projects", admin_projects_path
-        = nav_link(controller: :teams) do
-          = link_to "Teams", admin_teams_path
-        = nav_link(controller: :groups) do
-          = link_to "Groups", admin_groups_path
-        = nav_link(controller: :users) do
-          = link_to "Users", admin_users_path
-        = nav_link(controller: :logs) do
-          = link_to "Logs", admin_logs_path
-        = nav_link(controller: :hooks) do
-          = link_to "Hooks", admin_hooks_path
-        = nav_link(controller: :resque) do
-          = link_to "Background Jobs", admin_resque_path
+    %nav.main-nav
+      .container= render 'layouts/nav/admin'
 
+    .container
       .content= yield
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 90c2653438d..4e6831406e3 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -4,25 +4,8 @@
   %body{class: "#{app_theme} application"}
     = render "layouts/head_panel", title: "Dashboard"
     = render "layouts/flash"
-    .container
-      %ul.main_menu
-        = nav_link(path: 'dashboard#show', html_options: {class: 'home'}) do
-          = link_to root_path, title: "Home" do
-            %i.icon-home
-        = nav_link(path: 'dashboard#projects') do
-          = link_to projects_dashboard_path do
-            Projects
-        = nav_link(path: 'dashboard#issues') do
-          = link_to issues_dashboard_path do
-            Issues
-            %span.count= current_user.assigned_issues.opened.count
-        = nav_link(path: 'dashboard#merge_requests') do
-          = link_to merge_requests_dashboard_path do
-            Merge Requests
-            %span.count= current_user.cared_merge_requests.opened.count
-        = nav_link(path: 'search#show') do
-          = link_to "Search", search_path
-        = nav_link(controller: :help) do
-          = link_to "Help", help_path
+    %nav.main-nav
+      .container= render 'layouts/nav/dashboard'
 
+    .container
       .content= yield
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index 45528281ed0..8296b8ae9a8 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -4,25 +4,8 @@
   %body{class: "#{app_theme} application"}
     = render "layouts/head_panel", title: "group: #{@group.name}"
     = render "layouts/flash"
-    .container
-      %ul.main_menu
-        = nav_link(path: 'groups#show', html_options: {class: 'home'}) do
-          = link_to group_path(@group), title: "Home" do
-            %i.icon-home
-        = nav_link(path: 'groups#issues') do
-          = link_to issues_group_path(@group) do
-            Issues
-            %span.count= current_user.assigned_issues.opened.of_group(@group).count
-        = nav_link(path: 'groups#merge_requests') do
-          = link_to merge_requests_group_path(@group) do
-            Merge Requests
-            %span.count= current_user.cared_merge_requests.opened.of_group(@group).count
-        = nav_link(path: 'groups#people') do
-          = link_to "People", people_group_path(@group)
-
-        - if can?(current_user, :manage_group, @group)
-          = nav_link(path: 'groups#edit') do
-            = link_to edit_group_path(@group), class: "tab " do
-              Settings
+    %nav.main-nav
+      .container= render 'layouts/nav/group'
 
+    .container
       .content= yield
diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml
new file mode 100644
index 00000000000..ca77c26e23d
--- /dev/null
+++ b/app/views/layouts/nav/_admin.html.haml
@@ -0,0 +1,19 @@
+%ul
+  = nav_link(controller: :dashboard, html_options: {class: 'home'}) do
+    = link_to admin_root_path, title: "Stats" do
+      %i.icon-home
+  = nav_link(controller: :projects) do
+    = link_to "Projects", admin_projects_path
+  = nav_link(controller: :teams) do
+    = link_to "Teams", admin_teams_path
+  = nav_link(controller: :groups) do
+    = link_to "Groups", admin_groups_path
+  = nav_link(controller: :users) do
+    = link_to "Users", admin_users_path
+  = nav_link(controller: :logs) do
+    = link_to "Logs", admin_logs_path
+  = nav_link(controller: :hooks) do
+    = link_to "Hooks", admin_hooks_path
+  = nav_link(controller: :resque) do
+    = link_to "Background Jobs", admin_resque_path
+
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
new file mode 100644
index 00000000000..2ac35050b64
--- /dev/null
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -0,0 +1,20 @@
+%ul
+  = nav_link(path: 'dashboard#show', html_options: {class: 'home'}) do
+    = link_to root_path, title: "Home" do
+      %i.icon-home
+  = nav_link(path: 'dashboard#projects') do
+    = link_to projects_dashboard_path do
+      Projects
+  = nav_link(path: 'dashboard#issues') do
+    = link_to issues_dashboard_path do
+      Issues
+      %span.count= current_user.assigned_issues.opened.count
+  = nav_link(path: 'dashboard#merge_requests') do
+    = link_to merge_requests_dashboard_path do
+      Merge Requests
+      %span.count= current_user.cared_merge_requests.opened.count
+  = nav_link(path: 'search#show') do
+    = link_to "Search", search_path
+  = nav_link(controller: :help) do
+    = link_to "Help", help_path
+
diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml
new file mode 100644
index 00000000000..f3cdb5ac457
--- /dev/null
+++ b/app/views/layouts/nav/_group.html.haml
@@ -0,0 +1,20 @@
+%ul
+  = nav_link(path: 'groups#show', html_options: {class: 'home'}) do
+    = link_to group_path(@group), title: "Home" do
+      %i.icon-home
+  = nav_link(path: 'groups#issues') do
+    = link_to issues_group_path(@group) do
+      Issues
+      %span.count= current_user.assigned_issues.opened.of_group(@group).count
+  = nav_link(path: 'groups#merge_requests') do
+    = link_to merge_requests_group_path(@group) do
+      Merge Requests
+      %span.count= current_user.cared_merge_requests.opened.of_group(@group).count
+  = nav_link(path: 'groups#people') do
+    = link_to "People", people_group_path(@group)
+
+  - if can?(current_user, :manage_group, @group)
+    = nav_link(path: 'groups#edit') do
+      = link_to edit_group_path(@group), class: "tab " do
+        Settings
+
diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml
new file mode 100644
index 00000000000..e5e4b27c665
--- /dev/null
+++ b/app/views/layouts/nav/_profile.html.haml
@@ -0,0 +1,17 @@
+%ul
+  = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
+    = link_to profile_path, title: "Profile" do
+      %i.icon-home
+  = nav_link(path: 'profiles#account') do
+    = link_to "Account", account_profile_path
+  = nav_link(controller: :notifications) do
+    = link_to "Notifications", profile_notifications_path
+  = nav_link(controller: :keys) do
+    = link_to keys_path do
+      SSH Keys
+      %span.count= current_user.keys.count
+  = nav_link(path: 'profiles#design') do
+    = link_to "Design", design_profile_path
+  = nav_link(path: 'profiles#history') do
+    = link_to "History", history_profile_path
+
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
new file mode 100644
index 00000000000..ec3da964037
--- /dev/null
+++ b/app/views/layouts/nav/_project.html.haml
@@ -0,0 +1,43 @@
+%ul
+  = nav_link(path: 'projects#show', html_options: {class: "home"}) do
+    = link_to project_path(@project), title: "Project" do
+      %i.icon-home
+
+  - unless @project.empty_repo?
+    - if can? current_user, :download_code, @project
+      = nav_link(controller: %w(tree blob blame)) do
+        = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref)
+      = nav_link(controller: %w(commit commits compare repositories protected_branches)) do
+        = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref)
+      = nav_link(controller: %w(graph)) do
+        = link_to "Network", project_graph_path(@project, @ref || @repository.root_ref)
+
+  - if @project.issues_enabled
+    = nav_link(controller: %w(issues milestones labels)) do
+      = link_to url_for_project_issues do
+        Issues
+        - if @project.used_default_issues_tracker?
+          %span.count.issue_counter= @project.issues.opened.count
+
+  - if @project.repo_exists? && @project.merge_requests_enabled
+    = nav_link(controller: :merge_requests) do
+      = link_to project_merge_requests_path(@project) do
+        Merge Requests
+        %span.count.merge_counter= @project.merge_requests.opened.count
+
+  - if @project.wiki_enabled
+    = nav_link(controller: :wikis) do
+      = link_to 'Wiki', project_wiki_path(@project, :home)
+
+  - if @project.wall_enabled
+    = nav_link(controller: :walls) do
+      = link_to 'Wall', project_wall_path(@project)
+
+  - if @project.snippets_enabled
+    = nav_link(controller: :snippets) do
+      = link_to 'Snippets', project_snippets_path(@project)
+
+  - if can? current_user, :admin_project, @project
+    = nav_link(html_options: {class: "#{project_tab_class}"}) do
+      = link_to edit_project_path(@project), class: "stat-tab tab " do
+        Settings
diff --git a/app/views/layouts/nav/_team.html.haml b/app/views/layouts/nav/_team.html.haml
new file mode 100644
index 00000000000..415e45104df
--- /dev/null
+++ b/app/views/layouts/nav/_team.html.haml
@@ -0,0 +1,25 @@
+%ul
+  = nav_link(path: 'teams#show', html_options: {class: 'home'}) do
+    = link_to team_path(@team), title: "Home" do
+      %i.icon-home
+
+  = nav_link(path: 'teams#issues') do
+    = link_to issues_team_path(@team) do
+      Issues
+      %span.count= Issue.opened.of_user_team(@team).count
+
+  = nav_link(path: 'teams#merge_requests') do
+    = link_to merge_requests_team_path(@team) do
+      Merge Requests
+      %span.count= MergeRequest.opened.of_user_team(@team).count
+
+  = nav_link(controller: [:members]) do
+    = link_to team_members_path(@team), class: "team-tab tab" do
+      Members
+      %span.count= @team.members.count
+
+  - if can? current_user, :admin_user_team, @team
+    = nav_link(path: 'teams#edit') do
+      = link_to edit_team_path(@team), class: "stat-tab tab " do
+        Settings
+
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index 611063e8c99..535f94c4ef6 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -4,20 +4,8 @@
   %body{class: "#{app_theme} profile"}
     = render "layouts/head_panel", title: "Profile"
     = render "layouts/flash"
-    .container
-      %ul.main_menu
-        = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
-          = link_to profile_path, title: "Profile" do
-            %i.icon-home
-        = nav_link(path: 'profiles#account') do
-          = link_to "Account", account_profile_path
-        = nav_link(controller: :keys) do
-          = link_to keys_path do
-            SSH Keys
-            %span.count= current_user.keys.count
-        = nav_link(path: 'profiles#design') do
-          = link_to "Design", design_profile_path
-        = nav_link(path: 'profiles#history') do
-          = link_to "History", history_profile_path
+    %nav.main-nav
+      .container= render 'layouts/nav/profile'
 
+    .container
       .content= yield
diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml
index ca2f6e9a702..7b0d4789f8e 100644
--- a/app/views/layouts/project_resource.html.haml
+++ b/app/views/layouts/project_resource.html.haml
@@ -7,49 +7,8 @@
     - if can?(current_user, :download_code, @project)
       = render 'shared/no_ssh'
 
-    .container
-      %ul.main_menu
-        = nav_link(path: 'projects#show', html_options: {class: "home"}) do
-          = link_to project_path(@project), title: "Project" do
-            %i.icon-home
-
-        - if @project.repo_exists?
-          - if can? current_user, :download_code, @project
-            = nav_link(controller: %w(tree blob blame)) do
-              = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref)
-            = nav_link(controller: %w(commit commits compare repositories protected_branches)) do
-              = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref)
-            = nav_link(controller: %w(graph)) do
-              = link_to "Network", project_graph_path(@project, @ref || @repository.root_ref)
-
-        - if @project.issues_enabled
-          = nav_link(controller: %w(issues milestones labels)) do
-            = link_to url_for_project_issues do
-              Issues
-              - if @project.used_default_issues_tracker?
-                %span.count.issue_counter= @project.issues.opened.count
-
-        - if @project.repo_exists? && @project.merge_requests_enabled
-          = nav_link(controller: :merge_requests) do
-            = link_to project_merge_requests_path(@project) do
-              Merge Requests
-              %span.count.merge_counter= @project.merge_requests.opened.count
-
-        - if @project.wiki_enabled
-          = nav_link(controller: :wikis) do
-            = link_to 'Wiki', project_wiki_path(@project, :home)
-
-        - if @project.wall_enabled
-          = nav_link(controller: :walls) do
-            = link_to 'Wall', project_wall_path(@project)
-
-        - if @project.snippets_enabled
-          = nav_link(controller: :snippets) do
-            = link_to 'Snippets', project_snippets_path(@project)
-
-        - if can? current_user, :admin_project, @project
-          = nav_link(html_options: {class: "#{project_tab_class}"}) do
-            = link_to edit_project_path(@project), class: "stat-tab tab " do
-              Settings
+    %nav.main-nav
+      .container= render 'layouts/nav/project'
 
+    .container
       .content= yield
diff --git a/app/views/layouts/user_team.html.haml b/app/views/layouts/user_team.html.haml
index 483bfad66ae..f2ead9d242a 100644
--- a/app/views/layouts/user_team.html.haml
+++ b/app/views/layouts/user_team.html.haml
@@ -4,30 +4,8 @@
   %body{class: "#{app_theme} application"}
     = render "layouts/head_panel", title: "team: #{@team.name}"
     = render "layouts/flash"
-    .container
-      %ul.main_menu
-        = nav_link(path: 'teams#show', html_options: {class: 'home'}) do
-          = link_to team_path(@team), title: "Home" do
-            %i.icon-home
-
-        = nav_link(path: 'teams#issues') do
-          = link_to issues_team_path(@team) do
-            Issues
-            %span.count= Issue.opened.of_user_team(@team).count
-
-        = nav_link(path: 'teams#merge_requests') do
-          = link_to merge_requests_team_path(@team) do
-            Merge Requests
-            %span.count= MergeRequest.opened.of_user_team(@team).count
-
-        = nav_link(controller: [:members]) do
-          = link_to team_members_path(@team), class: "team-tab tab" do
-            Members
-            %span.count= @team.members.count
-
-        - if can? current_user, :admin_user_team, @team
-          = nav_link(path: 'teams#edit') do
-            = link_to edit_team_path(@team), class: "stat-tab tab " do
-              Settings
+    %nav.main-nav
+      .container= render 'layouts/nav/team'
 
+    .container
       .content= yield
diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml
index 816c852d24b..6d64988c15a 100644
--- a/app/views/merge_requests/_form.html.haml
+++ b/app/views/merge_requests/_form.html.haml
@@ -13,7 +13,7 @@
         .mr_branch_box
           %h5.cgray From (Head Branch)
           .body
-            .padded= f.select(:source_branch, @repository.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
+            .padded= f.select(:source_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
         .mr_source_commit
 
       .span2
@@ -22,7 +22,7 @@
         .mr_branch_box
           %h5.cgray To (Base Branch)
           .body
-            .padded= f.select(:target_branch, @repository.heads.map(&:name), { include_blank: "Select branch" }, {class: 'chosen span4'})
+            .padded= f.select(:target_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
         .mr_target_commit
 
   %fieldset
diff --git a/app/views/merge_requests/_merge_request.html.haml b/app/views/merge_requests/_merge_request.html.haml
index 09c55d98465..ffc6b8fda1e 100644
--- a/app/views/merge_requests/_merge_request.html.haml
+++ b/app/views/merge_requests/_merge_request.html.haml
@@ -1,32 +1,29 @@
 %li{ class: mr_css_classes(merge_request) }
-  .pull-right
-    .left
-      - if merge_request.merged?
-        %span.btn.btn-small.disabled.grouped
-          %strong
-            %i.icon-ok
-            = "MERGED"
-      - if merge_request.notes.any?
-        %span.btn.btn-small.disabled.grouped
-          %i.icon-comment
-          = merge_request.mr_and_commit_notes.count
-      - if merge_request.milestone_id?
-        %span.btn.btn-small.disabled.grouped
-          %i.icon-time
-          = merge_request.milestone.title
-      %span.btn.btn-small.disabled.grouped
-        = merge_request.source_branch
-        &rarr;
+  .merge-request-title
+    %span.light= "##{merge_request.id}"
+    = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.project, merge_request), class: "row_title"
+    - if merge_request.merged?
+      %small.pull-right
+        %i.icon-ok
+        = "MERGED"
+    - else
+      %span.pull-right
+        %i.icon-angle-right
         = merge_request.target_branch
-  = image_tag gravatar_icon(merge_request.author_email), class: "avatar"
-
-  %p= link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.project, merge_request), class: "row_title"
-
-  %span.update-author
-    %small.cdark= "##{merge_request.id}"
-    authored by #{merge_request.author_name}
-    = time_ago_in_words(merge_request.created_at)
-    ago
-
+  .merge-request-info
+    - if merge_request.author
+      authored by #{link_to_member(@project, merge_request.author)}
     - if merge_request.votes_count > 0
       = render 'votes/votes_inline', votable: merge_request
+    - if merge_request.notes.any?
+      %span
+        %i.icon-comments
+        = merge_request.mr_and_commit_notes.count
+    - if merge_request.milestone_id?
+      %span
+        %i.icon-time
+        = merge_request.milestone.title
+
+
+    .pull-right
+      %small updated #{time_ago_in_words(merge_request.updated_at)} ago
diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml
index 3073c8f6bab..b9e9096e3ae 100644
--- a/app/views/merge_requests/index.html.haml
+++ b/app/views/merge_requests/index.html.haml
@@ -20,16 +20,16 @@
           = hidden_field_tag :f, params[:f]
         .clearfix
 
-      %ul.well-list
+      %ul.well-list.mr-list
         = render @merge_requests
         - if @merge_requests.blank?
           %li
             %h4.nothing_here_message Nothing to show here
-        - if @merge_requests.present?
-          %li.bottom
-            .left= paginate @merge_requests, theme: "gitlab"
-            .pull-right
-              %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter
+    - if @merge_requests.present?
+      .pull-right
+        %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter
+
+      = paginate @merge_requests, theme: "gitlab"
 
 :javascript
   $(merge_requestsPage);
diff --git a/app/views/merge_requests/show/_commits.html.haml b/app/views/merge_requests/show/_commits.html.haml
index 5e27b6dc25a..eee786d71ef 100644
--- a/app/views/merge_requests/show/_commits.html.haml
+++ b/app/views/merge_requests/show/_commits.html.haml
@@ -22,9 +22,9 @@
             = render "commits/commit", commit: commit
 
 - else
-  %h5
+  %h4.nothing_here_message
     Nothing to merge from
-    %span.label #{@merge_request.source_branch}
+    %span.label-branch #{@merge_request.source_branch}
     to
-    %span.label #{@merge_request.target_branch}
+    %span.label-branch #{@merge_request.target_branch}
   %br
diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml
index 3b54f613f58..594f4061c23 100644
--- a/app/views/merge_requests/show/_mr_box.html.haml
+++ b/app/views/merge_requests/show/_mr_box.html.haml
@@ -1,13 +1,13 @@
 .ui-box.ui-box-show
   .ui-box-head
     %h4.box-title
+      = gfm escape_once(@merge_request.title)
       - if @merge_request.merged?
-        .error.status_info
+        .success.status_info
           %i.icon-ok
           Merged
       - elsif @merge_request.closed?
         .error.status_info Closed
-      = gfm escape_once(@merge_request.title)
 
   .ui-box-body
     %div
@@ -22,13 +22,15 @@
 
 
   - if @merge_request.closed?
-    .ui-box-bottom
+    .ui-box-bottom.alert-error
       %span
+        %i.icon-remove
         Closed by #{link_to_member(@project, @merge_request.closed_event.author)}
         %small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago.
   - if @merge_request.merged?
-    .ui-box-bottom
+    .ui-box-bottom.alert-success
       %span
+        %i.icon-ok
         Merged by #{link_to_member(@project, @merge_request.merge_event.author)}
-        %small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago.
+        #{time_ago_in_words(@merge_request.merge_event.created_at)} ago.
 
diff --git a/app/views/merge_requests/show/_mr_ci.html.haml b/app/views/merge_requests/show/_mr_ci.html.haml
index a8faa6ba617..9b15c4526e9 100644
--- a/app/views/merge_requests/show/_mr_ci.html.haml
+++ b/app/views/merge_requests/show/_mr_ci.html.haml
@@ -1,4 +1,4 @@
-- if @merge_request.opened? && @commits.any?
+- if @commits.any?
   .ci_widget.ci-success{style: "display:none"}
     .alert.alert-success
       %i.icon-ok
diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml
index 8a3727c6f6a..894fa6c1133 100644
--- a/app/views/milestones/_milestone.html.haml
+++ b/app/views/milestones/_milestone.html.haml
@@ -4,6 +4,8 @@
       = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do
         %i.icon-edit
         Edit
+      - if milestone.can_be_closed?
+        = link_to 'Close', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-small btn-remove"
   %h4
     = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone)
     - if milestone.expired? and not milestone.closed?
@@ -13,11 +15,8 @@
   - if milestone.is_empty?
     %span.muted Empty
   - else
-    .row
-      .span4
-        .progress.progress-info
-          .bar{style: "width: #{milestone.percent_complete}%;"}
-      .span6
+    %div
+      %div
         = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do
           = pluralize milestone.issues.count, 'Issue'
         &nbsp;
@@ -25,3 +24,5 @@
           = pluralize milestone.merge_requests.count, 'Merge Request'
         &nbsp;
         %span.light #{milestone.percent_complete}% complete
+      .progress.progress-info
+        .bar{style: "width: #{milestone.percent_complete}%;"}
diff --git a/app/views/milestones/index.html.haml b/app/views/milestones/index.html.haml
index b78f17053fd..89892cd23f1 100644
--- a/app/views/milestones/index.html.haml
+++ b/app/views/milestones/index.html.haml
@@ -3,11 +3,14 @@
   %h3.page_title
     Milestones
     - if can? current_user, :admin_milestone, @project
-      = link_to "New Milestone", new_project_milestone_path(@project), class: "pull-right btn btn-small", title: "New Milestone"
+      = link_to new_project_milestone_path(@project), class: "pull-right btn btn-primary", title: "New Milestone" do
+        %i.icon-plus
+        New Milestone
   %br
-  %div.ui-box
-    .title
-      %ul.nav.nav-pills
+
+  .row
+    .span3
+      %ul.nav.nav-pills.nav-stacked
         %li{class: ("active" if (params[:f] == "active" || !params[:f]))}
           = link_to project_milestones_path(@project, f: "active") do
             Active
@@ -17,12 +20,13 @@
         %li{class: ("active" if params[:f] == "all")}
           = link_to project_milestones_path(@project, f: "all") do
             All
+    .span9
+      %div.ui-box
+        %ul.well-list
+          = render @milestones
 
-    %ul.well-list
-      = render @milestones
-
-      - if @milestones.present?
-        %li.bottom= paginate @milestones, theme: "gitlab"
-      - else
-        %li
-          %h3.nothing_here_message Nothing to show here
+          - if @milestones.present?
+            %li.bottom= paginate @milestones, theme: "gitlab"
+          - else
+            %li
+              %h3.nothing_here_message Nothing to show here
diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml
index e1808a2003f..034c37852f1 100644
--- a/app/views/milestones/show.html.haml
+++ b/app/views/milestones/show.html.haml
@@ -1,3 +1,4 @@
+= render "issues/head"
 .row
   .span6
     %h3.page_title
@@ -87,8 +88,6 @@
 %h6 Participants:
 %div
   - @users.each do |user|
-    = link_to user, class: 'float-link' do
-      = user.avatar_image
-      = user.name
+    = link_to_member(@project, user)
 
 .clearfix
diff --git a/app/views/milestones/update.js.haml b/app/views/milestones/update.js.haml
new file mode 100644
index 00000000000..3ff84915e97
--- /dev/null
+++ b/app/views/milestones/update.js.haml
@@ -0,0 +1,2 @@
+:plain
+  $('##{dom_id(@milestone)}').fadeOut();
diff --git a/app/views/notes/_form.html.haml b/app/views/notes/_form.html.haml
index c2bdeafb830..7add2921830 100644
--- a/app/views/notes/_form.html.haml
+++ b/app/views/notes/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for [@project, @note], remote: true, html: { multipart: true, id: nil, class: "new_note js-new-note-form" } do |f|
+= form_for [@project, @note], remote: true, html: { multipart: true, id: nil, class: "new_note js-new-note-form common-note-form" } do |f|
 
   = note_target_fields
   = f.hidden_field :commit_id
@@ -26,15 +26,6 @@
 
       %a.btn.grouped.js-close-discussion-note-form Cancel
 
-    .note-form-option
-      = label_tag :notify do
-        = check_box_tag :notify, 1, false
-        %span.light Notify team via email
-
-      .js-notify-commit-author
-        = label_tag :notify_author do
-          = check_box_tag :notify_author, 1 , false
-          %span.light Notify commit author
     .note-form-option
       %a.choose-btn.btn.btn-small.js-choose-note-attachment-button
         %i.icon-paper-clip
diff --git a/app/views/notifications/show.html.haml b/app/views/notifications/show.html.haml
new file mode 100644
index 00000000000..b7f39306fd8
--- /dev/null
+++ b/app/views/notifications/show.html.haml
@@ -0,0 +1,77 @@
+%h3.page_title Setup your notification level
+
+%br
+
+%p.light
+  %strong Disabled
+  &ndash; You will not get any notifications via email
+%p.light
+  %strong Participating
+  &ndash; You will receive only notifications from related resources(ex. from assigned issue or your commit)
+%p.light
+  %strong Watch
+  &ndash; You will receive all notifications from projects in which you participate
+%hr
+
+.row
+  .span4
+    %h5 Global setting
+  .span7
+    = form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do
+      = hidden_field_tag :notification_type, 'global'
+
+      = label_tag do
+        = radio_button_tag :notification_level, Notification::N_DISABLED, @notification.disabled?, class: 'trigger-submit'
+        %span Disabled
+
+      = label_tag do
+        = radio_button_tag :notification_level, Notification::N_PARTICIPATING, @notification.participating?, class: 'trigger-submit'
+        %span Participating
+
+      = label_tag do
+        = radio_button_tag :notification_level, Notification::N_WATCH, @notification.watch?, class: 'trigger-submit'
+        %span Watch
+
+%hr
+= link_to '#', class: 'js-toggle-visibility-link' do
+  %h6.btn.btn-tiny
+    %i.icon-chevron-down
+    %span Per project notifications setting
+
+%ul.well-list.js-toggle-visibility-container.hide
+  - @users_projects.each do |users_project|
+    - notification = Notification.new(users_project)
+    %li
+      .row
+        .span4
+          %span
+            = link_to_project(users_project.project)
+        .span7
+          = form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do
+            = hidden_field_tag :notification_type, 'project', id: dom_id(users_project, 'notification_type')
+            = hidden_field_tag :notification_id, users_project.id, id: dom_id(users_project, 'notification_id')
+
+            = label_tag do
+              = radio_button_tag :notification_level, Notification::N_GLOBAL, notification.global?, id: dom_id(users_project, 'notification_level'), class: 'trigger-submit'
+              %span Use global setting
+
+            = label_tag do
+              = radio_button_tag :notification_level, Notification::N_DISABLED, notification.disabled?, id: dom_id(users_project, 'notification_level'), class: 'trigger-submit'
+              %span Disabled
+
+            = label_tag do
+              = radio_button_tag :notification_level, Notification::N_PARTICIPATING, notification.participating?, id: dom_id(users_project, 'notification_level'), class: 'trigger-submit'
+              %span Participating
+
+            = label_tag do
+              = radio_button_tag :notification_level, Notification::N_WATCH, notification.watch?, id: dom_id(users_project, 'notification_level'), class: 'trigger-submit'
+              %span Watch
+
+
+.save-status-fixed
+  %span.update-success.cgreen.hide
+    %i.icon-ok
+    Saved
+  %span.update-failed.cred.hide
+    %i.icon-remove
+    Failed
diff --git a/app/views/notifications/update.js.haml b/app/views/notifications/update.js.haml
new file mode 100644
index 00000000000..88e74d50671
--- /dev/null
+++ b/app/views/notifications/update.js.haml
@@ -0,0 +1,6 @@
+- if @saved
+  :plain
+    $('.save-status-fixed .update-success').showAndHide();
+- else
+  :plain
+    $('.save-status-fixed .update-failed').showAndHide();
diff --git a/app/views/notify/closed_issue_email.html.haml b/app/views/notify/closed_issue_email.html.haml
new file mode 100644
index 00000000000..23ccc4538de
--- /dev/null
+++ b/app/views/notify/closed_issue_email.html.haml
@@ -0,0 +1,5 @@
+%p
+  = "Issue was closed by #{@updated_by.name}"
+%p
+  = "Issue ##{@issue.id}"
+  = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title
diff --git a/app/views/notify/closed_issue_email.text.haml b/app/views/notify/closed_issue_email.text.haml
new file mode 100644
index 00000000000..0cca321552c
--- /dev/null
+++ b/app/views/notify/closed_issue_email.text.haml
@@ -0,0 +1,3 @@
+= "Issue was closed by #{@updated_by.name}"
+
+Issue ##{@issue.id}: #{project_issue_url(@issue.project, @issue)}
diff --git a/app/views/notify/closed_merge_request_email.html.haml b/app/views/notify/closed_merge_request_email.html.haml
new file mode 100644
index 00000000000..0c6c79e097a
--- /dev/null
+++ b/app/views/notify/closed_merge_request_email.html.haml
@@ -0,0 +1,9 @@
+%p
+  = "Merge Request #{@merge_request.id} was closed by #{@updated_by.name}"
+%p
+  = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
+%p
+  Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
+%p
+  Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
+
diff --git a/app/views/notify/closed_merge_request_email.text.haml b/app/views/notify/closed_merge_request_email.text.haml
new file mode 100644
index 00000000000..ee4648e3d09
--- /dev/null
+++ b/app/views/notify/closed_merge_request_email.text.haml
@@ -0,0 +1,8 @@
+= "Merge Request #{@merge_request.id} was closed by #{@updated_by.name}"
+
+Merge Request url: #{project_merge_request_url(@merge_request.project, @merge_request)}
+
+Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch}
+
+Author: #{@merge_request.author_name}
+Assignee: #{@merge_request.assignee_name}
diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml
new file mode 100644
index 00000000000..2b8cc030b23
--- /dev/null
+++ b/app/views/notify/merged_merge_request_email.html.haml
@@ -0,0 +1,9 @@
+%p
+  = "Merge Request #{@merge_request.id} was merged"
+%p
+  = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
+%p
+  Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
+%p
+  Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
+
diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml
new file mode 100644
index 00000000000..91c23360195
--- /dev/null
+++ b/app/views/notify/merged_merge_request_email.text.haml
@@ -0,0 +1,8 @@
+= "Merge Request #{@merge_request.id} was merged"
+
+Merge Request Url: #{project_merge_request_url(@merge_request.project, @merge_request)}
+
+Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch}
+
+Author: #{@merge_request.author_name}
+Assignee: #{@merge_request.assignee_name}
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index 0c891748918..f11c850641b 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -1,5 +1,9 @@
 %p
-  New Issue was created and assigned to you.
+  New Issue was created.
 %p
   = "Issue ##{@issue.id}"
   = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title
+%p
+  Author: #{@issue.author_name}
+%p
+  Assignee: #{@issue.assignee_name}
diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb
index 5ed55c35b23..9907ca83247 100644
--- a/app/views/notify/new_issue_email.text.erb
+++ b/app/views/notify/new_issue_email.text.erb
@@ -1,4 +1,5 @@
-New Issue was created and assigned to you.
+New Issue was created.
           
-
 Issue <%= @issue.id %>: <%= url_for(project_issue_url(@issue.project, @issue)) %>
+Author:   <%= @issue.author_name %>
+Asignee:  <%= @issue.assignee_name %>
diff --git a/app/views/notify/new_ssh_key_email.html.haml b/app/views/notify/new_ssh_key_email.html.haml
index 57f4297e6cb..eff197ce0f4 100644
--- a/app/views/notify/new_ssh_key_email.html.haml
+++ b/app/views/notify/new_ssh_key_email.html.haml
@@ -6,5 +6,5 @@
   title:
   %code= @key.title
 %p
-  If this key was added in error, you can remove here:
+  If this key was added in error, you can remove it here:
   = link_to "SSH Keys", keys_url
diff --git a/app/views/notify/new_ssh_key_email.text.erb b/app/views/notify/new_ssh_key_email.text.erb
index 71974eab975..2b1f8a06858 100644
--- a/app/views/notify/new_ssh_key_email.text.erb
+++ b/app/views/notify/new_ssh_key_email.text.erb
@@ -4,4 +4,4 @@ A new public key was added to your account:
 
 title.................. <%= @key.title %>
 
-If this key was added in error, you can remove here:  <%= keys_url %>
+If this key was added in error, you can remove it here: <%= keys_url %>
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 9cab3ba5252..d4793da8987 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -51,7 +51,7 @@
         %legend Tips:
         %ul
           %li
-            %p You can change your password on Account page
+            %p You can change your password on the Account page
           - if Gitlab.config.gravatar.enabled
             %li
               %p You can change your avatar at #{link_to "gravatar.com", "http://gravatar.com"}
@@ -73,16 +73,17 @@
                 Want to share a team between projects?
                 = link_to new_team_path, class: "btn btn-tiny" do
                   Create a team
-      %fieldset
-        %legend
-          Personal projects:
-          %small.pull-right
-            %span= current_user.owned_projects.count
-            of
-            %span= current_user.projects_limit
-        .padded
-          .progress
-            .bar{style: "width: #{current_user.projects_limit_percent}%;"}
+      - unless current_user.projects_limit_left > 100
+        %fieldset
+          %legend
+            Owned projects:
+            %small.pull-right
+              %span= current_user.owned_projects.count
+              of
+              %span= current_user.projects_limit
+          .padded
+            .progress
+              .bar{style: "width: #{current_user.projects_limit_percent}%;"}
 
       %fieldset
         %legend
diff --git a/app/views/projects/_clone_panel.html.haml b/app/views/projects/_clone_panel.html.haml
index e52df19be96..9a2be429206 100644
--- a/app/views/projects/_clone_panel.html.haml
+++ b/app/views/projects/_clone_panel.html.haml
@@ -13,5 +13,5 @@
             = link_to new_project_merge_request_path(@project), title: "New Merge Request", class: "btn-small btn grouped" do
               Merge Request
           - if @project.issues_enabled && can?(current_user, :write_issue, @project)
-            = link_to new_project_issue_path(@project), title: "New Issue", class: "btn-small btn grouped" do
+            = link_to url_for_new_issue, title: "New Issue", class: "btn-small btn grouped" do
               Issue
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index 6d547c94e98..eb5fa1755b4 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -36,10 +36,10 @@
                   .input
                     = f.text_area :description, placeholder: "awesome project", class: "span5", rows: 3, maxlength: 250
 
-                - unless @repository.heads.empty?
+                - unless @project.empty_repo?
                   .clearfix
                     = f.label :default_branch, "Default Branch"
-                    .input= f.select(:default_branch, @repository.heads.map(&:name), {}, style: "width:210px;")
+                    .input= f.select(:default_branch, @repository.branch_names, {})
 
 
               - if can?(current_user, :change_public_mode, @project)
@@ -54,9 +54,18 @@
                       %span.descr
                         If checked, this project can be cloned
                         %em without any
-                        authentification.
+                        authentication.
                         It will also be listed on the #{link_to "public access directory", public_root_path}.
 
+              %fieldset.features
+                %legend
+                  Labels:
+                .control-group
+                  = f.label :label_list, "Labels", class: 'control-label'
+                  .controls
+                    = f.text_field :label_list, maxlength: 2000, class: "xxlarge"
+                    %p.hint Separate with comma.
+
               %fieldset.features
                 %legend
                   Features:
@@ -107,8 +116,9 @@
         - if can?(current_user, :change_namespace, @project)
           .ui-box.ui-box-danger
             %h5.title Transfer project
+            .errors-holder
             .form-holder
-              = form_for(@project, remote: true, html: { class: 'transfer-project' }) do |f|
+              = form_for(@project, url: transfer_project_path(@project), remote: true, html: { class: 'transfer-project' }) do |f|
                 .control-group
                   = f.label :namespace_id do
                     %span Namespace
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 394522bfd88..c050f9454a5 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -7,7 +7,7 @@
 %div.save-project-loader.hide
   %center
     = image_tag "ajax_loader.gif"
-    %h3 Saving project. Please wait a few minutes
+    %h3 Saving project. Please wait a moment, this page will automatically refresh when ready.
 
 :javascript
   $(function(){ new Projects(); });
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 933cb671142..eb4ef5979cf 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -6,7 +6,7 @@
 %div.save-project-loader.hide
   %center
     = image_tag "ajax_loader.gif"
-    %h3 Creating project &amp; repository. Please wait a few minutes
+    %h3 Creating project &amp; repository. Please wait a moment, this page will automatically refresh when ready.
 
 :javascript
   $(function(){ new Projects(); });
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 824d4daf698..1e11ebbb335 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -1,8 +1,8 @@
 = render 'clone_panel'
-= render "events/event_last_push", event: @last_push
 
 .row
   .span9
+    = render "events/event_last_push", event: @last_push
     .content_list= render @events
     .loading.hide
   .span3
diff --git a/app/views/projects/transfer.js.haml b/app/views/projects/transfer.js.haml
new file mode 100644
index 00000000000..10b0de98c04
--- /dev/null
+++ b/app/views/projects/transfer.js.haml
@@ -0,0 +1,7 @@
+- if @project.errors[:namespace_id].present?
+  :plain
+    $("#tab-transfer .errors-holder").replaceWith(errorMessage('#{escape_javascript(@project.errors[:namespace_id].first)}'));
+    $("#tab-transfer .form-actions input").removeAttr('disabled').removeClass('disabled');
+- else
+  :plain
+    location.href = "#{edit_project_path(@project)}";
diff --git a/app/views/projects/update_failed.js.haml b/app/views/projects/update_failed.js.haml
deleted file mode 100644
index a3ac5f4088f..00000000000
--- a/app/views/projects/update_failed.js.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-:plain
-  $(".save-project-loader").replaceWith(errorMessage('#{escape_javascript(@error.message)}'));
diff --git a/app/views/public/projects/index.html.haml b/app/views/public/projects/index.html.haml
index b50484f6354..3d0d793b2d2 100644
--- a/app/views/public/projects/index.html.haml
+++ b/app/views/public/projects/index.html.haml
@@ -17,4 +17,4 @@
     - unless @projects.present?
       %h3.nothing_here_message No public projects
 
-  = paginate @projects, theme: "admin"
+  = paginate @projects, theme: "gitlab"
diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml
index a6faa5fd633..dd91e14b66b 100644
--- a/app/views/repositories/_branch.html.haml
+++ b/app/views/repositories/_branch.html.haml
@@ -1,5 +1,4 @@
-- commit = Commit.new(branch.commit)
-- commit = CommitDecorator.decorate(commit)
+- commit = Commit.new(Gitlab::Git::Commit.new(branch.commit))
 %tr
   %td
     = link_to project_commits_path(@project, branch.name) do
diff --git a/app/views/repositories/_feed.html.haml b/app/views/repositories/_feed.html.haml
index eaf15ca77d6..6bb75265ffb 100644
--- a/app/views/repositories/_feed.html.haml
+++ b/app/views/repositories/_feed.html.haml
@@ -1,5 +1,4 @@
 - commit = update
-- commit = CommitDecorator.new(commit)
 %tr
   %td
     = link_to project_commits_path(@project, commit.head.name) do
diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml
index dde35ea38aa..d448c669271 100644
--- a/app/views/repositories/stats.html.haml
+++ b/app/views/repositories/stats.html.haml
@@ -1,8 +1,8 @@
 = render "commits/head"
 .row
-  .span5
-    %h4
-      Stats:
+  .span6
+    %div#activity-chart.chart
+    %hr
     %p
       %b Total commits:
       %span= @stats.commits_count
@@ -13,9 +13,8 @@
       %b Authors:
       %span= @stats.authors_count
 
-    %br
-    %div#activity-chart
-  .span7
+
+  .span6
     %h4 Top 50 Committers:
     %ol.styled
       - @stats.authors[0...50].each do |author|
@@ -31,11 +30,6 @@
   $(function(){
     var labels = [#{@graph.labels.to_json}];
     var commits = [#{@graph.commits.join(', ')}];
-    var r = Raphael('activity-chart');
-    r.text(160, 10, "Commit activity for last #{@graph.weeks} weeks").attr({ font: "13px sans-serif" });
-    r.barchart(
-      10, 10, 400, 160,
-      [commits],
-      {colors:["#456"]}
-    ).label(labels, true);
+    var title = "Commit activity for last #{@graph.weeks} weeks";
+    Chart.init(labels, commits, title);
   })
diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml
index d4b8bbe10d4..bef5cd0841b 100644
--- a/app/views/repositories/tags.html.haml
+++ b/app/views/repositories/tags.html.haml
@@ -1,33 +1,30 @@
 = render "commits/head"
 - unless @tags.empty?
-  %table
-    %thead
-      %tr
-        %th Name
-        %th Last commit
-        %th
+  %ul.bordered-list
     - @tags.each do |tag|
-      - commit = Commit.new(tag.commit)
-      - commit = CommitDecorator.decorate(commit)
-      %tr
-        %td
-          %strong
-            = link_to project_commits_path(@project, tag.name), class: "" do
-              %i.icon-tag
-              = tag.name
-          %small.light= truncate(tag.message || '', length: 70)
-        %td
-          = image_tag gravatar_icon(commit.author_email), class: "avatar s16"
-          = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do
-            = commit.short_id
-          %span.light
-            = time_ago_in_words(commit.committed_date)
-            ago
-        %td
+      - commit = Commit.new(Gitlab::Git::Commit.new(tag.commit))
+      %li
+        %h5
+          = link_to project_commits_path(@project, tag.name), class: "" do
+            %i.icon-tag
+            = tag.name
+          %small
+            = truncate(tag.message || '', length: 70)
+          .pull-right
+            %span.light
+              = time_ago_in_words(commit.committed_date)
+              ago
+        %div.prepend-left-20
+          = link_to commit.short_id(8), project_commit_path(@project, commit), class: "monospace"
+          &ndash;
+          = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "cdark"
+
           - if can? current_user, :download_code, @project
-            = link_to archive_project_repository_path(@project, ref: tag.name) do
-              %i.icon-download-alt
-              Download
+            .pull-right
+              = link_to archive_project_repository_path(@project, ref: tag.name) do
+                %i.icon-download-alt
+                Download
+
 
 - else
   %h3.nothing_here_message
diff --git a/app/views/shared/_merge_requests.html.haml b/app/views/shared/_merge_requests.html.haml
index 85391a34316..a2800b11d8d 100644
--- a/app/views/shared/_merge_requests.html.haml
+++ b/app/views/shared/_merge_requests.html.haml
@@ -4,7 +4,7 @@
       - project = group[0]
       %h5.title
         = link_to_project project
-      %ul.well-list
+      %ul.well-list.mr-list
         - group[1].each do |merge_request|
           = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
   %hr
diff --git a/app/views/shared/_promo.html.haml b/app/views/shared/_promo.html.haml
new file mode 100644
index 00000000000..c97f8ba0f0e
--- /dev/null
+++ b/app/views/shared/_promo.html.haml
@@ -0,0 +1,4 @@
+.gitlab-promo
+  = link_to "Homepage", "http://gitlab.org"
+  = link_to "Blog", "http://blog.gitlab.org"
+  = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
diff --git a/app/views/team_members/_assigned_team.html.haml b/app/views/team_members/_assigned_team.html.haml
index 1d512c44b26..51a31a6456d 100644
--- a/app/views/team_members/_assigned_team.html.haml
+++ b/app/views/team_members/_assigned_team.html.haml
@@ -1,7 +1,7 @@
 %li{id: dom_id(team), class: "user_team_row team_#{team.id}"}
   .pull-right
     - if can?(current_user, :admin_team_member, @project)
-      = link_to resign_project_team_path(@project, team), method: :delete, confirm: "Are you shure?", class: "btn btn-remove btn-tiny" do
+      = link_to resign_project_team_path(@project, team), method: :delete, confirm: "Are you sure?", class: "btn btn-remove btn-tiny" do
         %i.icon-minus.icon-white
 
   %strong= link_to team.name, team_path(team), title: team.name, class: "dark"
diff --git a/app/views/team_members/_team.html.haml b/app/views/team_members/_team.html.haml
index 2ec8c1a8451..4b49b308edc 100644
--- a/app/views/team_members/_team.html.haml
+++ b/app/views/team_members/_team.html.haml
@@ -1,8 +1,9 @@
 - team.each do |access, members|
-  .ui-box
+  - role = Project.access_options.key(access).pluralize
+  .ui-box{class: role.downcase}
     %h5.title
-      = Project.access_options.key(access).pluralize
-      %small= members.size
+      = role
+      %span.light (#{members.size})
     %ul.well-list
       - members.sort_by(&:user_name).each do |team_member|
         = render 'team_members/team_member', member: team_member
diff --git a/app/views/team_members/_team_member.html.haml b/app/views/team_members/_team_member.html.haml
index 2b0709beb92..5fd8d2465d1 100644
--- a/app/views/team_members/_team_member.html.haml
+++ b/app/views/team_members/_team_member.html.haml
@@ -16,11 +16,11 @@
             = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2 trigger-submit"
       .pull-right
         - if current_user == user
-          %span.label This is you!
+          %span.label.label-success This is you!
         - if @project.namespace_owner == user
-          %span.label Owner
+          %span.label.label-info Owner
         - elsif user.blocked?
-          %span.label Blocked
+          %span.label.label-error Blocked
         - elsif allow_admin
           = link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do
             %i.icon-minus.icon-white
diff --git a/app/views/team_members/index.html.haml b/app/views/team_members/index.html.haml
index 50d44bcd8d8..3132fd5ca8a 100644
--- a/app/views/team_members/index.html.haml
+++ b/app/views/team_members/index.html.haml
@@ -22,22 +22,22 @@
   .span3
     %ul.nav.nav-pills.nav-stacked
       %li{class: ("active" if !params[:type])}
-        = link_to project_team_members_path(type: nil) do
+        = link_to project_team_index_path(type: nil) do
           All
       %li{class: ("active" if params[:type] == 'masters')}
-        = link_to project_team_members_path(type: 'masters') do
+        = link_to project_team_index_path(type: 'masters') do
           Masters
           %span.pull-right= @project.users_projects.masters.count
       %li{class: ("active" if params[:type] == 'developers')}
-        = link_to project_team_members_path(type: 'developers') do
+        = link_to project_team_index_path(type: 'developers') do
           Developers
           %span.pull-right= @project.users_projects.developers.count
       %li{class: ("active" if params[:type] == 'reporters')}
-        = link_to project_team_members_path(type: 'reporters') do
+        = link_to project_team_index_path(type: 'reporters') do
           Reporters
           %span.pull-right= @project.users_projects.reporters.count
       %li{class: ("active" if params[:type] == 'guests')}
-        = link_to project_team_members_path(type: 'guests') do
+        = link_to project_team_index_path(type: 'guests') do
           Guests
           %span.pull-right= @project.users_projects.guests.count
 
diff --git a/app/views/teams/issues.html.haml b/app/views/teams/issues.html.haml
index 5b17c5d4f0b..94818ccd7f4 100644
--- a/app/views/teams/issues.html.haml
+++ b/app/views/teams/issues.html.haml
@@ -14,7 +14,7 @@
           - @project = group[0]
           %h5.title
             = link_to_project @project
-          %ul.well-list.issues_table
+          %ul.well-list.issues-list
             - group[1].each do |issue|
               = render issue
       %hr
diff --git a/app/views/teams/members/_show.html.haml b/app/views/teams/members/_show.html.haml
index 1a323043d09..dc32acb4693 100644
--- a/app/views/teams/members/_show.html.haml
+++ b/app/views/teams/members/_show.html.haml
@@ -2,7 +2,7 @@
 - allow_admin = can? current_user, :manage_user_team, @team
 %li{id: dom_id(member), class: "team_member_row user_#{user.id}"}
   .row
-    .span5
+    .span4
       = link_to user_path(user.username), title: user.name, class: "dark" do
         = image_tag gravatar_icon(user.email, 40), class: "avatar s32"
       = link_to user_path(user.username), title: user.name, class: "dark" do
@@ -10,21 +10,22 @@
         %br
         %small.cgray= user.username
 
-    .span4
+    .span7.pull-right
       - if allow_admin
-        = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f|
-          = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium trigger-submit"
-          %br
-          = label_tag do
-            = f.check_box :group_admin, class: 'trigger-submit'
-            %span Admin access
-    .pull-right
-      - if current_user == user
-        %span.btn.disabled This is you!
-      - if @team.owner == user
-        %span.btn.disabled Owner
-      - elsif user.blocked?
-        %span.btn.disabled.blocked Blocked
-      - elsif allow_admin
-        = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
-          %i.icon-minus.icon-white
+        .pull-left
+          = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f|
+            = label_tag do
+              = f.check_box :group_admin, class: 'trigger-submit'
+              %span Admin access
+            &nbsp;
+            = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium trigger-submit"
+      .pull-right
+        - if current_user == user
+          %span.btn.disabled This is you!
+        - if @team.owner == user
+          %span.btn.disabled Owner
+        - elsif user.blocked?
+          %span.btn.disabled.blocked Blocked
+        - elsif allow_admin
+          = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
+            %i.icon-minus.icon-white
diff --git a/app/views/teams/members/new.html.haml b/app/views/teams/members/new.html.haml
index 9b9b3cef59b..99530ebb7f0 100644
--- a/app/views/teams/members/new.html.haml
+++ b/app/views/teams/members/new.html.haml
@@ -1,29 +1,25 @@
 %h3.page_title
   Team: #{@team.name}
 
-%fieldset
-  %legend Members (#{@team.members.count})
-  = form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post  do
-    %table#members_list
-      %thead
-        %tr
-          %th User name
-          %th Default project access
-          %th Team access
-          %th
-      - @team.members.each do |member|
-        %tr.member
-          %td
-            = member.name
-            %small= "(#{member.username})"
-          %td= @team.human_default_projects_access(member)
-          %td= @team.admin?(member) ? "Admin" : "Member"
-          %td
-      %tr
-        %td
-          = users_select_tag(:user_ids, multiple: true)
-        %td= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
-        %td
-          %span= check_box_tag :group_admin
-          %span Admin?
-        %td= submit_tag 'Add User', class: "btn btn-create", id: :add_members_to_team
+%hr
+
+= form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post  do
+  %h6 1. Choose people you want in the team
+  .clearfix
+    = label_tag :user_ids, "People"
+    .input
+      = users_select_tag(:user_ids, multiple: true)
+
+  %h6 2. Set access level for them
+  .clearfix
+    = label_tag :project_access, "Project Access"
+    .input= select_tag :default_project_access, options_for_select(Project.access_options), class: "project-access-select chosen"
+
+  .clearfix
+    = label_tag :group_admin do
+      %span Team Admin?
+    .input= check_box_tag :group_admin
+
+  .actions
+    = submit_tag 'Add users', class: "btn btn-create", id: :add_members_to_team
+    = link_to "Cancel", team_members_path(@team), class: "btn btn-cancel"
diff --git a/app/views/teams/show.atom.builder b/app/views/teams/show.atom.builder
index bb0f666e860..1468ac1d03c 100644
--- a/app/views/teams/show.atom.builder
+++ b/app/views/teams/show.atom.builder
@@ -8,7 +8,6 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
 
   @events.each do |event|
     if event.proper?
-      event = EventDecorator.decorate(event)
       xml.entry do
         event_link = event.feed_url
         event_title = event.feed_title
diff --git a/app/views/teams/show.html.haml b/app/views/teams/show.html.haml
index 2eb0283e0ab..4b9ff61203f 100644
--- a/app/views/teams/show.html.haml
+++ b/app/views/teams/show.html.haml
@@ -1,4 +1,4 @@
-.projects
+.dashboard
   .activities.span8
     = link_to dashboard_path, class: 'btn btn-tiny' do
       &larr; To dashboard
@@ -12,7 +12,7 @@
     .loading.hide
   .side.span4
     - if @team.description.present?
-      .description.well.light
+      .description.well.well-small.light
         = @team.description
     = render "projects", projects: @projects
     .prepend-top-20
@@ -22,10 +22,7 @@
           News Feed
 
     %hr
-    .gitlab-promo
-      = link_to "Homepage", "http://gitlabhq.com"
-      = link_to "Blog", "http://blog.gitlabhq.com"
-      = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
+    = render 'shared/promo'
 
 :javascript
   $(function(){ Pager.init(20, true); });
diff --git a/app/views/tree/_blob.html.haml b/app/views/tree/_blob.html.haml
deleted file mode 100644
index ebf1ee2c678..00000000000
--- a/app/views/tree/_blob.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-.file_holder
-  .file_title
-    %i.icon-file
-    %span.file_name
-      = blob.name
-      %small= number_to_human_size blob.size
-    %span.options= render "tree/blob_actions"
-  - if blob.text?
-    = render "tree/blob/text", blob: blob
-  - elsif blob.image?
-    = render "tree/blob/image", blob: blob
-  - else
-    = render "tree/blob/download", blob: blob
diff --git a/app/views/tree/_blob_item.html.haml b/app/views/tree/_blob_item.html.haml
new file mode 100644
index 00000000000..ec15b608f85
--- /dev/null
+++ b/app/views/tree/_blob_item.html.haml
@@ -0,0 +1,9 @@
+%tr{ class: "tree-item #{tree_hex_class(blob_item)}" }
+  %td.tree-item-file-name
+    = tree_icon(type)
+    %strong= link_to truncate(blob_item.name, length: 40), project_blob_path(@project, tree_join(@id || @commit.id, blob_item.name))
+  %td.tree_time_ago.cgray
+    %span.log_loading.hide
+      Loading commit data...
+      = image_tag "ajax_loader_tree.gif", width: 14
+  %td.tree_commit{ colspan: 2 }
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index 24a57ae7a29..a98a44e90dd 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -3,7 +3,7 @@
     %i.icon-angle-right
     = link_to project_tree_path(@project, @ref) do
       = @project.path
-  - tree.breadcrumbs(6) do |title, path|
+  - tree_breadcrumbs(tree, 6) do |title, path|
     \/
     %li
       - if path
@@ -12,36 +12,40 @@
         = link_to title, '#'
 
 %div#tree-content-holder.tree-content-holder
-  - if tree.is_blob?
-    = render "tree/blob", blob: tree
-  - else
-    %table#tree-slider{class: "table_#{@hex_path} tree-table" }
-      %thead
-        %tr
-          %th Name
-          %th Last Update
-          %th Last Commit
-          %th= link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny pull-right"
+  %table#tree-slider{class: "table_#{@hex_path} tree-table" }
+    %thead
+      %tr
+        %th Name
+        %th Last Update
+        %th
+          Last Commit
+          &nbsp;
+          %i.icon-angle-right
+          &nbsp;
+          %small.light
+            = link_to @commit.short_id, project_commit_path(@project, @commit)
+            &ndash;
+            = truncate(@commit.title, length: 50)
+        %th= link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny pull-right"
 
-      - if tree.up_dir?
-        %tr.tree-item
-          %td.tree-item-file-name
-            = image_tag "file_empty.png", size: '16x16'
-            = link_to "..", project_tree_path(@project, tree.up_dir_path)
-          %td
-          %td
-          %td
+    - if tree.up_dir?
+      %tr.tree-item
+        %td.tree-item-file-name
+          = image_tag "file_empty.png", size: '16x16'
+          = link_to "..", project_tree_path(@project, up_dir_path(tree))
+        %td
+        %td
+        %td
 
-      = render_tree(tree.contents)
+    = render_tree(tree)
 
-    - if tree.readme
-      = render "tree/readme", readme: tree.readme
+  - if tree.readme
+    = render "tree/readme", readme: tree.readme
 
 %div.tree_progress
 
-- unless tree.is_blob?
-  :javascript
-    // Load last commit log for each file in tree
-    $(window).load(function(){
-      ajaxGet('#{@logs_path}');
-    });
+:javascript
+  // Load last commit log for each file in tree
+  $(window).load(function(){
+    ajaxGet('#{@logs_path}');
+  });
diff --git a/app/views/tree/_tree_commit_column.html.haml b/app/views/tree/_tree_commit_column.html.haml
index 9d02132b0f4..7ae2582c130 100644
--- a/app/views/tree/_tree_commit_column.html.haml
+++ b/app/views/tree/_tree_commit_column.html.haml
@@ -1,2 +1,2 @@
-%span.tree_author= commit.author_link avatar: true
+%span.tree_author= commit_author_link(commit, avatar: true)
 = link_to_gfm truncate(commit.title, length: 80), project_commit_path(@project, commit.id), class: "tree-commit-link"
diff --git a/app/views/tree/show.js.haml b/app/views/tree/show.js.haml
index fadd5e2251f..a01d49179b9 100644
--- a/app/views/tree/show.js.haml
+++ b/app/views/tree/show.js.haml
@@ -1,7 +1,7 @@
 :plain
   // Load Files list
   $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {tree: @tree}))}");
-  $("#tree-content-holder").show("slide", { direction: "right" }, 150);
+  $("#tree-content-holder").show("slide", { direction: "right" }, 400);
   $('.project-refs-form #path').val("#{@path}");
 
   //  Load last commit log for each file in tree
diff --git a/app/views/votes/_votes_inline.html.haml b/app/views/votes/_votes_inline.html.haml
index 91bd200df44..ee805474830 100644
--- a/app/views/votes/_votes_inline.html.haml
+++ b/app/views/votes/_votes_inline.html.haml
@@ -1,6 +1,9 @@
 .votes.votes-inline
-  .upvotes= votable.upvotes
-  .progress
-    .bar.bar-success{style: "width: #{votable.upvotes_in_percent}%;"}
-    .bar.bar-danger{style: "width: #{votable.downvotes_in_percent}%;"}
-  .downvotes= votable.downvotes
+  - unless votable.upvotes.zero?
+    .upvotes
+      + #{votable.upvotes}
+    - unless votable.downvotes.zero?
+      \/
+  - unless votable.downvotes.zero?
+    .downvotes
+      \- #{votable.downvotes}
diff --git a/app/views/walls/show.html.haml b/app/views/walls/show.html.haml
index 0cd29486d93..139e66f5dd0 100644
--- a/app/views/walls/show.html.haml
+++ b/app/views/walls/show.html.haml
@@ -1,5 +1,5 @@
 %div.wall-page
-  %ul.well-list.notes
+  %ul.notes
 
   - if can? current_user, :write_note, @project
     .note-form-holder
@@ -11,11 +11,6 @@
           .buttons
             = f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button"
 
-          .note-form-option
-            = label_tag :notify do
-              = check_box_tag :notify, 1, false
-              %span.light Notify team via email
-
           .note-form-option
             %a.choose-btn.btn.btn-small.js-choose-note-attachment-button
               %i.icon-paper-clip
diff --git a/app/views/wikis/_nav.html.haml b/app/views/wikis/_nav.html.haml
index 0dffdd8fc14..09a1986e105 100644
--- a/app/views/wikis/_nav.html.haml
+++ b/app/views/wikis/_nav.html.haml
@@ -11,8 +11,8 @@
       Git Access
 
   - if can?(current_user, :write_wiki, @project)
-    %li.pull-right
-      = link_to '#', class: "add-new-wiki" do
+    .pull-right
+      = link_to '#', class: "add-new-wiki btn btn-small btn-primary" do
         %i.icon-plus
         New Page
 
diff --git a/app/views/wikis/_new.html.haml b/app/views/wikis/_new.html.haml
index 50b40bff41c..bc1635eb174 100644
--- a/app/views/wikis/_new.html.haml
+++ b/app/views/wikis/_new.html.haml
@@ -1,11 +1,13 @@
 %div#modal-new-wiki.modal.hide
   .modal-header
     %a.close{href: "#"} ×
-    %h3 New Wiki Page
+    %h3.page_title New Wiki Page
   .modal-body
     = label_tag :new_wiki_path do
       %span Page slug
-    = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'input-xlarge'
+    = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'input-xlarge', required: true
+    %p.hint
+      Please dont use spaces and slashes
   .modal-footer
     = link_to 'Build', '#', class: 'build-new-wiki btn btn-create'
 
@@ -16,7 +18,11 @@
       modal.show();
     });
     $('.build-new-wiki').bind("click", function(){
-      location.href = "#{project_wikis_path(@project)}/" + $('#new_wiki_path').val();
+      var slug = $('#new_wiki_path').val();
+
+      if(slug.length > 0) {
+        location.href = "#{project_wikis_path(@project)}/" + slug;
+      }
     });
     $('.modal-header .close').bind("click", function(){
       modal.hide();
diff --git a/app/views/wikis/git_access.html.haml b/app/views/wikis/git_access.html.haml
index 58c8aa06aca..462d483fd85 100644
--- a/app/views/wikis/git_access.html.haml
+++ b/app/views/wikis/git_access.html.haml
@@ -24,8 +24,8 @@
       %legend Clone Your Wiki:
       %pre.dark
         :preserve
-          git clone #{@gollum_wiki.path_with_namespace}.git
-          cd #{@gollum_wiki.path_with_namespace}
+          git clone #{@gollum_wiki.ssh_url_to_repo}
+          cd #{@gollum_wiki.path}
 
       %legend Start Gollum And Edit Locally:
       %pre.dark
diff --git a/app/views/wikis/history.html.haml b/app/views/wikis/history.html.haml
index 599e9cf6793..f4946ed000d 100644
--- a/app/views/wikis/history.html.haml
+++ b/app/views/wikis/history.html.haml
@@ -14,12 +14,13 @@
       %th Format
   %tbody
     - @wiki.versions.each do |version|
-      - commit = CommitDecorator.new(version)
+      - commit = version
       %tr
         %td
           = link_to project_wiki_path(@project, @wiki, version_id: commit.id) do
             = commit.short_id
-        %td= commit.author_link avatar: true, size: 24
+        %td
+          = commit_author_link(commit, avatar: true, size: 24)
         %td
           = commit.title
         %td
diff --git a/app/views/wikis/pages.html.haml b/app/views/wikis/pages.html.haml
index eb65599d087..95d5eef16f5 100644
--- a/app/views/wikis/pages.html.haml
+++ b/app/views/wikis/pages.html.haml
@@ -21,5 +21,5 @@
           = wiki_page.created_at.to_s(:short) do
             (#{time_ago_in_words(wiki_page.created_at)}
             ago)
-        - commit = CommitDecorator.decorate(wiki_page.version)
-        %td= commit.author_link avatar: true, size: 24
+        %td
+          = commit_author_link(wiki_page.version, avatar: true, size: 24)
diff --git a/app/views/wikis/show.html.haml b/app/views/wikis/show.html.haml
index b660a15ee32..b237bc524ed 100644
--- a/app/views/wikis/show.html.haml
+++ b/app/views/wikis/show.html.haml
@@ -13,5 +13,4 @@
     = preserve do
       = render_wiki_content(@wiki)
 
-- commit = CommitDecorator.new(@wiki.version)
-%p.time Last edited by #{commit.author_link(avatar: true, size: 16)} #{time_ago_in_words @wiki.created_at} ago
+%p.time Last edited by #{commit_author_link(@wiki.version, avatar: true, size: 16)} #{time_ago_in_words @wiki.created_at} ago
diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb
index 0a921b1bd44..cfeda88bbc5 100644
--- a/app/workers/gitlab_shell_worker.rb
+++ b/app/workers/gitlab_shell_worker.rb
@@ -1,6 +1,6 @@
 class GitlabShellWorker
   include Sidekiq::Worker
-  include Gitolited
+  include Gitlab::ShellAdapter
 
   sidekiq_options queue: :gitlab_shell
 
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 72cef0fd295..132f1a6d7e9 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -23,7 +23,7 @@ class PostReceive
 
     user = if identifier.blank?
              # Local push from gitlab
-             email = project.repository.commit(newrev).author.email rescue nil
+             email = project.repository.commit(newrev).author_email rescue nil
              User.find_by_email(email) if email
 
            elsif identifier =~ /\Auser-\d+\Z/
diff --git a/config/application.rb b/config/application.rb
index d71de88ebe3..8f7d9c07ac8 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -24,6 +24,7 @@ module Gitlab
 
     # Activate observers that should always be running.
     config.active_record.observers = :activity_observer,
+                                     :project_activity_cache_observer,
                                      :issue_observer,
                                      :key_observer,
                                      :merge_request_observer,
diff --git a/config/database.yml.postgresql b/config/database.yml.postgresql
index 2bc0884f099..4a4aa3465a6 100644
--- a/config/database.yml.postgresql
+++ b/config/database.yml.postgresql
@@ -6,7 +6,7 @@ production:
   encoding: unicode
   database: gitlabhq_production
   pool: 5
-  username: gitlab
+  username: git
   password:
   # host: localhost
   # port: 5432 
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index a8704719137..10fe1245115 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -46,12 +46,19 @@ production: &base
     #   ##  :project_id        - GitLab project identifier
     #   ##  :issues_tracker_id - Project Name or Id in external issue tracker
     #   project_url: "http://redmine.sample/projects/:issues_tracker_id"
+    #
     #   ## If not nil, links from /#\d/ entities from commit messages will replaced with this
     #   ## Use placeholders:
     #   ##  :project_id        - GitLab project identifier
     #   ##  :issues_tracker_id - Project Name or Id in external issue tracker
     #   ##  :id                - Issue id (from commit messages)
     #   issues_url: "http://redmine.sample/issues/:id"
+    #
+    #   ## If not nil, linkis to creating new issues will be replaced with this
+    #   ## Use placeholders:
+    #   ##  :project_id        - GitLab project identifier
+    #   ##  :issues_tracker_id - Project Name or Id in external issue tracker
+    #   new_issue_url: "http://redmine.sample/projects/:issues_tracker_id/issues/new"
 
   ## Gravatar
   gravatar:
@@ -152,6 +159,7 @@ test:
     redmine:
       project_url: "http://redmine/projects/:issues_tracker_id"
       issues_url: "http://redmine/:project_id/:issues_tracker_id/:id"
+      new_issue_url: "http://redmine/projects/:issues_tracker_id/issues/new"
 
 staging:
   <<: *base
diff --git a/config/initializers/5_backend.rb b/config/initializers/5_backend.rb
index 73436608c93..7c2e7f39000 100644
--- a/config/initializers/5_backend.rb
+++ b/config/initializers/5_backend.rb
@@ -3,3 +3,6 @@ require Rails.root.join("lib", "gitlab", "backend", "grack_auth")
 
 # GIT over SSH
 require Rails.root.join("lib", "gitlab", "backend", "shell")
+
+# GitLab shell adapter
+require Rails.root.join("lib", "gitlab", "backend", "shell_adapter")
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index 9c3976335ff..5714407f393 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -23,7 +23,7 @@ Devise.setup do |config|
   # session. If you need permissions, you should implement that in a before filter.
   # You can also supply a hash where the value is a boolean determining whether
   # or not authentication should be aborted when the value is not present.
-  # config.authentication_keys = [ :email ]
+  config.authentication_keys = [ :login ]
 
   # Configure parameters from the request object used for authentication. Each entry
   # given should be a request method and it will automatically be passed to the
diff --git a/config/puma.rb.example b/config/puma.rb.example
new file mode 100644
index 00000000000..e166992b8c2
--- /dev/null
+++ b/config/puma.rb.example
@@ -0,0 +1,114 @@
+#!/usr/bin/env puma
+
+# Start Puma with next command:
+# RAILS_ENV=production bundle exec puma -e production -C ./config/puma.rb
+
+application_path = '/home/git/gitlab'
+
+# The directory to operate out of.
+#
+# The default is the current directory.
+#
+directory application_path
+
+# Set the environment in which the rack's app will run.
+#
+# The default is “development”.
+#
+environment = :production
+
+# Daemonize the server into the background. Highly suggest that
+# this be combined with “pidfile” and “stdout_redirect”.
+#
+# The default is “false”.
+#
+daemonize true
+
+# Store the pid of the server in the file at “path”.
+#
+pidfile "#{application_path}/tmp/pids/puma.pid"
+
+# Use “path” as the file to store the server info state. This is
+# used by “pumactl” to query and control the server.
+#
+state_path "#{application_path}/tmp/pids/puma.state"
+
+# Redirect STDOUT and STDERR to files specified. The 3rd parameter
+# (“append”) specifies whether the output is appended, the default is
+# “false”.
+#
+stdout_redirect "#{application_path}/log/puma.stdout.log", "#{application_path}/log/puma.stderr.log"
+# stdout_redirect '/u/apps/lolcat/log/stdout', '/u/apps/lolcat/log/stderr', true
+
+# Disable request logging.
+#
+# The default is “false”.
+#
+# quiet
+
+# Configure “min” to be the minimum number of threads to use to answer
+# requests and “max” the maximum.
+#
+# The default is “0, 16”.
+#
+# threads 0, 16
+
+# Bind the server to “url”. “tcp://”, “unix://” and “ssl://” are the only
+# accepted protocols.
+#
+# The default is “tcp://0.0.0.0:9292”.
+#
+# bind 'tcp://0.0.0.0:9292'
+bind "unix://#{application_path}/tmp/sockets/gitlab.socket"
+
+# Instead of “bind 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'” you
+# can also use the “ssl_bind” option.
+#
+# ssl_bind '127.0.0.1', '9292', { key: path_to_key, cert: path_to_cert }
+
+# Code to run before doing a restart. This code should
+# close log files, database connections, etc.
+#
+# This can be called multiple times to add code each time.
+#
+# on_restart do
+#   puts 'On restart...'
+# end
+
+# Command to use to restart puma. This should be just how to
+# load puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments
+# to puma, as those are the same as the original process.
+#
+# restart_command '/u/app/lolcat/bin/restart_puma'
+
+# === Cluster mode ===
+
+# How many worker processes to run.
+#
+# The default is “0”.
+#
+# workers 2
+
+# Code to run when a worker boots to setup the process before booting
+# the app.
+#
+# This can be called multiple times to add hooks.
+#
+# on_worker_boot do
+#   puts 'On worker boot...'
+# end
+
+# === Puma control rack application ===
+
+# Start the puma control rack application on “url”. This application can
+# be communicated with to control the main server. Additionally, you can
+# provide an authentication token, so all requests to the control server
+# will need to include that token as a query parameter. This allows for
+# simple authentication.
+#
+# Check out https://github.com/puma/puma/blob/master/lib/puma/app/status.rb
+# to see what the app has available.
+#
+# activate_control_app 'unix:///var/run/pumactl.sock'
+# activate_control_app 'unix:///var/run/pumactl.sock', { auth_token: '12345' }
+# activate_control_app 'unix:///var/run/pumactl.sock', { no_token: true }
diff --git a/config/routes.rb b/config/routes.rb
index 0028baf8d53..18475e03277 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -85,11 +85,7 @@ Gitlab::Application.routes.draw do
     resource :logs, only: [:show]
     resource :resque, controller: 'resque', only: [:show]
 
-    resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, except: [:new, :create] do
-      member do
-        get :team
-        put :team_update
-      end
+    resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, only: [:index, :show] do
       scope module: :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ } do
         resources :members, only: [:edit, :update, :destroy]
       end
@@ -114,6 +110,8 @@ Gitlab::Application.routes.draw do
       put :reset_private_token
       put :update_username
     end
+
+    resource :notifications
   end
 
   resources :keys
@@ -167,8 +165,14 @@ Gitlab::Application.routes.draw do
   # Project Area
   #
   resources :projects, constraints: { id: /(?:[a-zA-Z.0-9_\-]+\/)?[a-zA-Z.0-9_\-]+/ }, except: [:new, :create, :index], path: "/" do
+    member do
+      put :transfer
+    end
+
     resources :blob,    only: [:show], constraints: {id: /.+/}
-    resources :tree,    only: [:show, :edit, :update], constraints: {id: /.+/}
+    resources :raw,    only: [:show], constraints: {id: /.+/}
+    resources :tree,    only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
+    resources :edit_tree,    only: [:show, :update], constraints: {id: /.+/}, path: 'edit'
     resources :commit,  only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
     resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
     resources :compare, only: [:index, :create]
@@ -262,13 +266,11 @@ Gitlab::Application.routes.draw do
     resources :labels, only: [:index]
     resources :issues, except: [:destroy] do
       collection do
-        post  :sort
         post  :bulk_update
-        get   :search
       end
     end
 
-    resources :team_members do
+    resources :team_members, except: [:index, :edit] do
       collection do
 
         # Used for import team
diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example
deleted file mode 100644
index 75945182806..00000000000
--- a/config/unicorn.rb.example
+++ /dev/null
@@ -1,68 +0,0 @@
-# uncomment and customize to run in non-root path
-# note that config/gitlab.yml web path should also be changed
-# ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
-
-app_dir = File.expand_path '../../', __FILE__
-worker_processes 2
-working_directory app_dir
-
-# Load app into the master before forking workers for super-fast
-# worker spawn times
-preload_app true
-
-# nuke workers after 30 seconds (60 is the default)
-timeout 30
-
-# listen on a Unix domain socket and/or a TCP port,
-
-#listen 8080 # listen to port 8080 on all TCP interfaces
-#listen "127.0.0.1:8080"  # listen to port 8080 on the loopback interface
-listen "#{app_dir}/tmp/sockets/gitlab.socket"
-
-pid "#{app_dir}/tmp/pids/unicorn.pid"
-stderr_path "#{app_dir}/log/unicorn.stderr.log"
-stdout_path "#{app_dir}/log/unicorn.stdout.log"
-
-# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
-if GC.respond_to?(:copy_on_write_friendly=)
-  GC.copy_on_write_friendly = true
-end
-
-
-before_fork do |server, worker|
-  # the following is highly recommended for Rails + "preload_app true"
-  # as there's no need for the master process to hold a connection
-  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
-
-  ##
-  # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
-  # immediately start loading up a new version of itself (loaded with a new
-  # version of our app). When this new Unicorn is completely loaded
-  # it will begin spawning workers. The first worker spawned will check to
-  # see if an .oldbin pidfile exists. If so, this means we've just booted up
-  # a new Unicorn and need to tell the old one that it can now die. To do so
-  # we send it a QUIT.
-  #
-  # Using this method we get 0 downtime deploys.
-
-  old_pid = "#{server.config[:pid]}.oldbin"
-
-  if File.exists?(old_pid) && server.pid != old_pid
-    begin
-      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
-      Process.kill(sig, File.read(old_pid).to_i)
-    rescue Errno::ENOENT, Errno::ESRCH
-      # someone else did our job for us
-    end
-  end
-end
-
-after_fork do |server, worker|
-  # Unicorn master loads the app then forks off workers - because of the way
-  # Unix forking works, we need to make sure we aren't using any of the parent's
-  # sockets, e.g. db connection
-
-  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
-  # Redis and Memcached would go here but their connections are established
-  # on demand, so the master never opens a socket
-end
diff --git a/db/fixtures/development/02_source_code.rb b/db/fixtures/development/02_source_code.rb
index a0a46c9e927..5ce5bcf4aba 100644
--- a/db/fixtures/development/02_source_code.rb
+++ b/db/fixtures/development/02_source_code.rb
@@ -1,3 +1,4 @@
+gitlab_shell_path =  File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
 root = Gitlab.config.gitlab_shell.repos_path
 
 projects = [
@@ -17,8 +18,7 @@ projects.each do |project|
     print '-'
     next
   end
-
-  if system("/home/git/gitlab-shell/bin/gitlab-projects import-project #{project[:path]} #{project[:git]}")
+  if system("#{gitlab_shell_path}/gitlab-shell/bin/gitlab-projects import-project #{project[:path]} #{project[:git]}")
     print '.'
   else
     print 'F'
diff --git a/db/fixtures/development/06_teams.rb b/db/fixtures/development/06_teams.rb
index 9fbf21a02d7..f82977d7fdc 100644
--- a/db/fixtures/development/06_teams.rb
+++ b/db/fixtures/development/06_teams.rb
@@ -1,22 +1,14 @@
-Gitlab::Seeder.quiet do
-
-  (1..300).each  do |i|
-    # Random Project
-    project = Project.scoped.sample
-
-    # Random user
-    user = User.not_in_project(project).sample
+ActiveRecord::Base.observers.disable :all
 
-    next unless user
-
-    UsersProject.seed(:id, [{
-      id: i,
-      project_id: project.id,
-      user_id: user.id,
-      project_access: UsersProject.access_roles.values.sample
-    }])
-
-    print('.')
+Gitlab::Seeder.quiet do
+  Project.all.each do |project|
+    project.team << [User.first, :master]
+    print '.'
+
+    User.all.sample(rand(10)).each do |user|
+      role = [:master, :developer, :reporter].sample
+      project.team << [user, role]
+      print '.'
+    end
   end
 end
-puts "OK".green
diff --git a/db/fixtures/development/09_issues.rb b/db/fixtures/development/09_issues.rb
index cd9b2b3e456..d13d520e3dd 100644
--- a/db/fixtures/development/09_issues.rb
+++ b/db/fixtures/development/09_issues.rb
@@ -1,3 +1,5 @@
+ActiveRecord::Base.observers.disable :all
+
 Gitlab::Seeder.quiet do
   (1..300).each  do |i|
     # Random Project
diff --git a/db/fixtures/development/10_merge_requests.rb b/db/fixtures/development/10_merge_requests.rb
index 6d111b26c53..d122d96235e 100644
--- a/db/fixtures/development/10_merge_requests.rb
+++ b/db/fixtures/development/10_merge_requests.rb
@@ -1,5 +1,7 @@
+ActiveRecord::Base.observers.disable :all
+
 Gitlab::Seeder.quiet do
-  (1..300).each  do |i|
+  (1..100).each  do |i|
     # Random Project
     project = Project.all.sample
 
@@ -8,19 +10,30 @@ Gitlab::Seeder.quiet do
 
     next unless user
 
+    next if project.empty_repo?
+
+    branches = project.repository.branch_names.sample(2)
+
+    next if branches.uniq.size < 2
+
     user_id = user.id
     MergeRequestObserver.current_user = user
     MergeRequest.seed(:id, [{
       id: i,
-      source_branch: 'master',
-      target_branch: 'feature',
+      source_branch: branches.first,
+      target_branch: branches.last,
       project_id: project.id,
       author_id: user_id,
       assignee_id: user_id,
-      state: ['opened', 'closed'].sample,
       milestone: project.milestones.sample,
       title: Faker::Lorem.sentence(6)
     }])
     print('.')
   end
 end
+
+puts 'Load diffs for Merge Requests (it will take some time)...'
+MergeRequest.all.each do |mr|
+  mr.reload_code
+  print '.'
+end
diff --git a/db/fixtures/development/11_keys.rb b/db/fixtures/development/11_keys.rb
index 8e4724c277c..4b53ff411f2 100644
--- a/db/fixtures/development/11_keys.rb
+++ b/db/fixtures/development/11_keys.rb
@@ -1,3 +1,4 @@
+ActiveRecord::Base.observers.enable :all
 
 Gitlab::Seeder.quiet do
   User.first(30).each_with_index do |user, i|
diff --git a/db/migrate/20130325173941_add_notification_level_to_user.rb b/db/migrate/20130325173941_add_notification_level_to_user.rb
new file mode 100644
index 00000000000..9f466e38c13
--- /dev/null
+++ b/db/migrate/20130325173941_add_notification_level_to_user.rb
@@ -0,0 +1,5 @@
+class AddNotificationLevelToUser < ActiveRecord::Migration
+  def change
+    add_column :users, :notification_level, :integer, null: false, default: 1
+  end
+end
diff --git a/db/migrate/20130403003950_add_last_activity_column_into_project.rb b/db/migrate/20130403003950_add_last_activity_column_into_project.rb
new file mode 100644
index 00000000000..2a036bd9993
--- /dev/null
+++ b/db/migrate/20130403003950_add_last_activity_column_into_project.rb
@@ -0,0 +1,21 @@
+class AddLastActivityColumnIntoProject < ActiveRecord::Migration
+  def up
+    add_column :projects, :last_activity_at, :datetime
+    add_index :projects, :last_activity_at
+
+    Project.find_each do |project|
+      last_activity_date = if project.last_activity
+                             project.last_activity.created_at
+                           else
+                             project.updated_at
+                           end
+
+      project.update_attribute(:last_activity_at, last_activity_date)
+    end
+  end
+
+  def down
+    remove_index :projects, :last_activity_at
+    remove_column :projects, :last_activity_at
+  end
+end
diff --git a/db/migrate/20130404164628_add_notification_level_to_user_project.rb b/db/migrate/20130404164628_add_notification_level_to_user_project.rb
new file mode 100644
index 00000000000..27de5d6bf55
--- /dev/null
+++ b/db/migrate/20130404164628_add_notification_level_to_user_project.rb
@@ -0,0 +1,5 @@
+class AddNotificationLevelToUserProject < ActiveRecord::Migration
+  def change
+    add_column :users_projects, :notification_level, :integer, null: false, default: 3
+  end
+end
diff --git a/db/migrate/20130410175022_remove_wiki_table.rb b/db/migrate/20130410175022_remove_wiki_table.rb
new file mode 100644
index 00000000000..9077aa2473c
--- /dev/null
+++ b/db/migrate/20130410175022_remove_wiki_table.rb
@@ -0,0 +1,9 @@
+class RemoveWikiTable < ActiveRecord::Migration
+  def up
+    drop_table :wikis
+  end
+
+  def down
+    raise ActiveRecord::IrreversibleMigration
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index e4349ac4bf7..33407e600a4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20130318212250) do
+ActiveRecord::Schema.define(:version => 20130410175022) do
 
   create_table "events", :force => true do |t|
     t.string   "target_type"
@@ -37,8 +37,8 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
     t.integer  "assignee_id"
     t.integer  "author_id"
     t.integer  "project_id"
-    t.datetime "created_at",                  :null => false
-    t.datetime "updated_at",                  :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.integer  "position",     :default => 0
     t.string   "branch_name"
     t.text     "description"
@@ -55,8 +55,8 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
 
   create_table "keys", :force => true do |t|
     t.integer  "user_id"
-    t.datetime "created_at", :null => false
-    t.datetime "updated_at", :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.text     "key"
     t.string   "title"
     t.string   "identifier"
@@ -74,8 +74,8 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
     t.integer  "author_id"
     t.integer  "assignee_id"
     t.string   "title"
-    t.datetime "created_at",                          :null => false
-    t.datetime "updated_at",                          :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.text     "st_commits",    :limit => 2147483647
     t.text     "st_diffs",      :limit => 2147483647
     t.integer  "milestone_id"
@@ -124,8 +124,8 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
     t.text     "note"
     t.string   "noteable_type"
     t.integer  "author_id"
-    t.datetime "created_at",    :null => false
-    t.datetime "updated_at",    :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.integer  "project_id"
     t.string   "attachment"
     t.string   "line_code"
@@ -143,8 +143,8 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
     t.string   "name"
     t.string   "path"
     t.text     "description"
-    t.datetime "created_at",                                   :null => false
-    t.datetime "updated_at",                                   :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.integer  "creator_id"
     t.string   "default_branch"
     t.boolean  "issues_enabled",         :default => true,     :null => false
@@ -156,9 +156,11 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
     t.string   "issues_tracker",         :default => "gitlab", :null => false
     t.string   "issues_tracker_id"
     t.boolean  "snippets_enabled",       :default => true,     :null => false
+    t.datetime "last_activity_at"
   end
 
   add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
+  add_index "projects", ["last_activity_at"], :name => "index_projects_on_last_activity_at"
   add_index "projects", ["namespace_id"], :name => "index_projects_on_namespace_id"
 
   create_table "protected_branches", :force => true do |t|
@@ -186,8 +188,8 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
     t.text     "content"
     t.integer  "author_id",  :null => false
     t.integer  "project_id", :null => false
-    t.datetime "created_at", :null => false
-    t.datetime "updated_at", :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.string   "file_name"
     t.datetime "expires_at"
   end
@@ -206,9 +208,6 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
     t.datetime "created_at"
   end
 
-  add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
-  add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context"
-
   create_table "tags", :force => true do |t|
     t.string "name"
   end
@@ -240,51 +239,52 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
   end
 
   create_table "users", :force => true do |t|
-    t.string   "email",                  :default => "",    :null => false
-    t.string   "encrypted_password",     :default => "",    :null => false
+    t.string   "email",                                 :default => "",    :null => false
+    t.string   "encrypted_password",     :limit => 128, :default => "",    :null => false
     t.string   "reset_password_token"
     t.datetime "reset_password_sent_at"
     t.datetime "remember_created_at"
-    t.integer  "sign_in_count",          :default => 0
+    t.integer  "sign_in_count",                         :default => 0
     t.datetime "current_sign_in_at"
     t.datetime "last_sign_in_at"
     t.string   "current_sign_in_ip"
     t.string   "last_sign_in_ip"
-    t.datetime "created_at",                                :null => false
-    t.datetime "updated_at",                                :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.string   "name"
-    t.boolean  "admin",                  :default => false, :null => false
-    t.integer  "projects_limit",         :default => 10
-    t.string   "skype",                  :default => "",    :null => false
-    t.string   "linkedin",               :default => "",    :null => false
-    t.string   "twitter",                :default => "",    :null => false
+    t.boolean  "admin",                                 :default => false, :null => false
+    t.integer  "projects_limit",                        :default => 10
+    t.string   "skype",                                 :default => "",    :null => false
+    t.string   "linkedin",                              :default => "",    :null => false
+    t.string   "twitter",                               :default => "",    :null => false
     t.string   "authentication_token"
-    t.integer  "theme_id",               :default => 1,     :null => false
+    t.integer  "theme_id",                              :default => 1,     :null => false
     t.string   "bio"
-    t.integer  "failed_attempts",        :default => 0
+    t.integer  "failed_attempts",                       :default => 0
     t.datetime "locked_at"
     t.string   "extern_uid"
     t.string   "provider"
     t.string   "username"
-    t.boolean  "can_create_group",       :default => true,  :null => false
-    t.boolean  "can_create_team",        :default => true,  :null => false
+    t.boolean  "can_create_group",                      :default => true,  :null => false
+    t.boolean  "can_create_team",                       :default => true,  :null => false
     t.string   "state"
-    t.integer  "color_scheme_id",        :default => 1,     :null => false
+    t.integer  "color_scheme_id",                       :default => 1,     :null => false
+    t.integer  "notification_level",                    :default => 1,     :null => false
   end
 
   add_index "users", ["admin"], :name => "index_users_on_admin"
   add_index "users", ["email"], :name => "index_users_on_email", :unique => true
-  add_index "users", ["extern_uid", "provider"], :name => "index_users_on_extern_uid_and_provider", :unique => true
   add_index "users", ["name"], :name => "index_users_on_name"
   add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
   add_index "users", ["username"], :name => "index_users_on_username"
 
   create_table "users_projects", :force => true do |t|
-    t.integer  "user_id",                       :null => false
-    t.integer  "project_id",                    :null => false
-    t.datetime "created_at",                    :null => false
-    t.datetime "updated_at",                    :null => false
-    t.integer  "project_access", :default => 0, :null => false
+    t.integer  "user_id",                           :null => false
+    t.integer  "project_id",                        :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.integer  "project_access",     :default => 0, :null => false
+    t.integer  "notification_level", :default => 3, :null => false
   end
 
   add_index "users_projects", ["project_access"], :name => "index_users_projects_on_project_access"
@@ -294,23 +294,10 @@ ActiveRecord::Schema.define(:version => 20130318212250) do
   create_table "web_hooks", :force => true do |t|
     t.string   "url"
     t.integer  "project_id"
-    t.datetime "created_at",                            :null => false
-    t.datetime "updated_at",                            :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
     t.string   "type",       :default => "ProjectHook"
     t.integer  "service_id"
   end
 
-  create_table "wikis", :force => true do |t|
-    t.string   "title"
-    t.text     "content"
-    t.integer  "project_id"
-    t.datetime "created_at", :null => false
-    t.datetime "updated_at", :null => false
-    t.string   "slug"
-    t.integer  "user_id"
-  end
-
-  add_index "wikis", ["project_id"], :name => "index_wikis_on_project_id"
-  add_index "wikis", ["slug"], :name => "index_wikis_on_slug"
-
 end
diff --git a/doc/api/users.md b/doc/api/users.md
index c05bcb3e539..ee5e98a016c 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -1,6 +1,7 @@
 ## List users
 
 Get a list of users.
+This function takes pagination parameters `page` and `per_page` to restrict the list of users.
 
 ```
 GET /users
diff --git a/doc/install/databases.md b/doc/install/databases.md
index 2c4fb9dbfff..a198e726aa0 100644
--- a/doc/install/databases.md
+++ b/doc/install/databases.md
@@ -21,7 +21,7 @@ GitLab supports the following databases:
     mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
 
     # Grant the GitLab user necessary permissopns on the table.
-    mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
+    mysql> GRANT SELECT, LOCK TABLES, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
 
     # Quit the database session
     mysql> \q
@@ -38,10 +38,10 @@ GitLab supports the following databases:
     sudo -u postgres psql -d template1
 
     # Create a user for GitLab. (change $password to a real password)
-    template1=# CREATE USER gitlab WITH PASSWORD '$password';
+    template1=# CREATE USER git WITH PASSWORD '$password';
 
     # Create the GitLab production database & grant all privileges on database
-    template1=# CREATE DATABASE gitlabhq_production OWNER gitlab;
+    template1=# CREATE DATABASE gitlabhq_production OWNER git;
 
     # Quit the database session
     template1=# \q
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 853a6e78364..90f93e84db6 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -1,19 +1,12 @@
-This installation guide was created for Debian/Ubuntu and tested on it. Please read [`doc/install/requirements.md`](./requirements.md) for hardware and platform requirements.
+# Important notes
 
-This installation guide is recommended to set up a production server. If you want a development environment please use the [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) since it makes it much easier to set up all the dependencies for integration testing.
+This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [`doc/install/requirements.md`](./requirements.md) for hardware and operating system requirements.
 
-**Important Note:**
-The following steps have been known to work.
-If you deviate from this guide, do it with caution and make sure you don't
-violate any assumptions GitLab makes about its environment.
-For things like AWS installation scripts, init scripts or config files for
-alternative web server have a look at the [`Advanced Setup
-Tips`](./installation.md#advanced-setup-tips) section.
+This is the official installation guide to set up a production server. To set up a **development installation** or for many other installation options please consult [the installation section in the readme](https://github.com/gitlabhq/gitlabhq#installation).
 
+The following steps have been known to work. Please **use caution when you deviate** from this guide. Make sure you don't violate any assumptions GitLab makes about its environment.
 
-**Important Note:**
-If you find a bug/error in this guide please submit an issue or pull request
-following the [`contribution guide`](../../CONTRIBUTING.md).
+If you find a bug/error in this guide please **submit a pull request** following the [`contributing guide`](../../CONTRIBUTING.md).
 
 - - -
 
@@ -74,8 +67,8 @@ Make sure you have the right version of Python installed.
 Download and compile it:
 
     mkdir /tmp/ruby && cd /tmp/ruby
-    curl --progress http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p327.tar.gz | tar xz
-    cd ruby-1.9.3-p327
+    curl --progress http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p392.tar.gz | tar xz
+    cd ruby-1.9.3-p392
     ./configure
     make
     sudo make install
@@ -106,11 +99,10 @@ GitLab Shell is a ssh access and repository management software developed specia
     git clone https://github.com/gitlabhq/gitlab-shell.git
 
     cd gitlab-shell
-    
-    # switch to right version for v5.0
-    git checkout v1.1.0
-    git checkout -b v1.1.0
-    
+
+    # switch to right version
+    git checkout v1.2.0
+
     cp config.yml.example config.yml
 
     # Edit config and replace gitlab_url
@@ -140,10 +132,10 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install
     cd /home/git/gitlab
 
     # Checkout to stable release
-    sudo -u git -H git checkout 5-0-stable
+    sudo -u git -H git checkout 5-1-stable
 
 **Note:**
-You can change `5-0-stable` to `master` if you want the *bleeding edge* version, but
+You can change `5-1-stable` to `master` if you want the *bleeding edge* version, but
 do so with caution!
 
 ## Configure it
@@ -170,8 +162,8 @@ do so with caution!
     sudo -u git -H mkdir tmp/pids/
     sudo chmod -R u+rwX  tmp/pids/
 
-    # Copy the example Unicorn config
-    sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb
+    # Copy the example Of Puma config
+    sudo -u git -H cp config/puma.rb.example config/puma.rb
 
 **Important Note:**
 Make sure to edit both files to match your setup.
@@ -208,7 +200,7 @@ Make sure to update username/password in config/database.yml.
 
 Download the init script (will be /etc/init.d/gitlab):
 
-    sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab
+    sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-1-stable/init.d/gitlab
     sudo chmod +x /etc/init.d/gitlab
 
 Make GitLab start on boot:
@@ -249,7 +241,7 @@ If you can't or don't want to use Nginx as your web server, have a look at the
 
 Download an example site config:
 
-    sudo curl --output /etc/nginx/sites-available/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab
+    sudo curl --output /etc/nginx/sites-available/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-1-stable/nginx/gitlab
     sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab
 
 Make sure to edit the config file to match your setup:
@@ -305,7 +297,26 @@ If you are running SSH on a non-standard port, you must change the gitlab user's
 
 You also need to change the corresponding options (e.g. ssh_user, ssh_host, admin_uri) in the `config\gitlab.yml` file.
 
-## User-contributed Configurations
+## LDAP authentication
+
+You can configure LDAP authentication in config/gitlab.yml. Please restart GitLab after editing this file.
+
+## Using Custom Omniauth Providers
+
+GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already ships with a few providers preinstalled (e.g. LDAP, GitHub, Twitter). But sometimes that is not enough and you need to integrate with other authentication solutions. For these cases you can use the Omniauth provider.
+
+### Steps
+
+These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation.
+
+* Add `gem "omniauth-your-auth-provider"` to the [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/master/Gemfile#L18)
+* Run `sudo -u git -H bundle install` to install the new gem(s)
+* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/master/config/gitlab.yml.example#L53) as a reference)
+* Add icons for the new provider into the [vendor/assets/images/authbuttons](https://github.com/gitlabhq/gitlabhq/tree/master/vendor/assets/images/authbuttons) directory (you can find some more popular ones over at https://github.com/intridea/authbuttons)
+* Restart GitLab
+
+### Examples
 
-You can find things like  AWS installation scripts, init scripts or config files
-for alternative web server in our [recipes collection](https://github.com/gitlabhq/gitlab-recipes/).
+If you have successfully set up a provider that is not shipped with GitLab itself, please let us know.
+You can help others by reporting successful configurations and probably share a few insights or provide warnings for common errors or pitfalls by sharing your experience [in the public Wiki](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Working-Custom-Omniauth-Provider-Configurations).
+While we can't officially support every possible auth mechanism out there, we'd like to at least help those with special needs.
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index ec5b013c5d8..9209fad571b 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -1,13 +1,3 @@
-# Hardware
-
-We recommend you to run GitLab on a server with at least 1GB RAM.
-
-The necessary hard disk space largely depends on the size of the repos you want
-to use GitLab with. But as a *rule of thumb* you should have at least as much
-free space as your all repos combined take up.
-
-
-
 # Operating Systems
 
 ## Linux
@@ -36,8 +26,7 @@ systems. This means you may get it to work on systems running FreeBSD or OS X.
 ## Windows
 
 GitLab does **not** run on Windows and we have no plans of supporting it in the
-near future.
-
+near future. Please consider using a virtual machine to run GitLab.
 
 
 # Rubies
@@ -48,6 +37,24 @@ While it is generally possible to use other Rubies (like
 some work on your part.
 
 
+# Hardware requirements
+
+## CPU
+
+We recommend a processor with **4 cores**. At a minimum you need a processor with 2 cores to responsively run an unmodified installation.
+
+## Memory
+
+We recommend you to run GitLab on a server with at least **1GB of RAM** memory. You can use it with 512MB of memory but you need to setup unicorn to use only 1 worker and you need at least 200MB of swap. The minimal requirement for an unmodified installation is 768MB. With 1.5GB of memory you should be able to support 1000+ users.
+
+## Storage
+
+The necessary hard drive space largely depends on the size of the repos you want
+to store in GitLab. But as a *rule of thumb* you should have at least twice as much
+free space as your all repos combined take up. You need twice the storage because [GitLab satellites](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/structure.md) contain an extra copy of each repo. Apart from a local hard drive you can also mount a volume that supports the network file system (NFS) protocol. This volume might be located on a file server, a network attached storage (NAS) device, a storage area network (SAN) or on an Amazon Web Services (AWS) Elastic Block Store (EBS) volume.
+
+If you have enough RAM memory and a recent CPU the speed of GitLab is mainly limited by hard drive seek times. Having a fast drive (7200 RPM and up) or a solid state drive (SSD) will improve the responsiveness of GitLab.
+
 
 # Installation troubles and reporting success or failure
 
diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md
index 726cc083f10..338e885851d 100644
--- a/doc/raketasks/maintenance.md
+++ b/doc/raketasks/maintenance.md
@@ -11,31 +11,30 @@ Example output:
 
 ```
 System information
-System:         Debian 6.0.6
-Current User:   gitlab
-Using RVM:      yes
-RVM Version:    1.17.2
-Ruby Version:   ruby-1.9.3-p327
-Gem Version:    1.8.24
-Bundler Version:1.2.3
-Rake Version:   10.0.1
+System:		Debian 6.0.7
+Current User:	git
+Using RVM:	no
+Ruby Version:	1.9.3p392
+Gem Version:	1.8.23
+Bundler Version:1.3.5
+Rake Version:	10.0.4
 
 GitLab information
-Version:        3.1.0
-Resivion:       fd5141d
-Directory:      /home/gitlab/gitlab
-DB Adapter:     mysql2
-URL:            http://localhost:3000
-HTTP Clone URL: http://localhost:3000/some-project.git
-SSH Clone URL:  git@localhost:some-project.git
-Using LDAP:     no
-Using Omniauth: no
+Version:	5.1.0.beta2
+Revision:	4da8b37
+Directory:	/home/git/gitlab
+DB Adapter:	mysql2
+URL:		http://localhost
+HTTP Clone URL:	http://localhost/some-project.git
+SSH Clone URL:	git@localhost:some-project.git
+Using LDAP:	no
+Using Omniauth:	no
 
 GitLab Shell
-Version:        1.0.4
-Repositories:   /home/git/repositories/
-Hooks:          /home/git/gitlab-shell/hooks/
-Git:            /usr/bin/git
+Version:	1.2.0
+Repositories:	/home/git/repositories/
+Hooks:		/home/git/gitlab-shell/hooks/
+Git:		/usr/bin/git
 ```
 
 
@@ -61,60 +60,43 @@ Example output:
 ```
 Checking Environment ...
 
-gitlab user is in git group? ... yes
-Has no "-e" in ~git/.profile ... yes
-Git configured for gitlab user? ... yes
+Git configured for git user? ... yes
 Has python2? ... yes
 python2 is supported version? ... yes
 
 Checking Environment ... Finished
 
-Checking Gitolite ...
+Checking Gitlab Shell ...
 
-Using recommended version ... yes
-Config directory exists? ... yes
-Config directory owned by git:git? ... yes
-Config directory access is drwxr-x---? ... yes
+GitLab Shell version? ... OK (1.2.0)
 Repo base directory exists? ... yes
+Repo base directory is a symlink? ... no
 Repo base owned by git:git? ... yes
 Repo base access is drwxrws---? ... yes
-post-receive hook exists? ... yes
 post-receive hook up-to-date? ... yes
-post-receive hooks in repos are links: ...
-GitLab ... ok
-Non-Ascii Files Test ... ok
-Touch Commit Test ... ok
-Without Master Test ... ok
-Git config in repos: ...
-GitLab ... ok
-Non-Ascii Files Test ... ok
-Touch Commit Test ... ok
-Without Master Test ... ok
+post-receive hooks in repos are links: ... yes
 
-Checking Gitolite ... Finished
+Checking Gitlab Shell ... Finished
 
-Checking Resque ...
+Checking Sidekiq ...
 
 Running? ... yes
 
-Checking Resque ... Finished
+Checking Sidekiq ... Finished
 
 Checking GitLab ...
 
 Database config exists? ... yes
-Database is not SQLite ... yes
+Database is SQLite ... no
 All migrations up? ... yes
 GitLab config exists? ... yes
-GitLab config not outdated? ... yes
+GitLab config outdated? ... no
 Log directory writable? ... yes
 Tmp directory writable? ... yes
 Init script exists? ... yes
 Init script up-to-date? ... yes
-Projects have satellites? ...
-GitLab ... yes
-Non-Ascii Files Test ... yes
-Touch Commit Test ... yes
-Without Master Test ... yes
+Projects have satellites? ... yes
+Redis version >= 2.0.0? ... yes
 
 Checking GitLab ... Finished
 ```
diff --git a/doc/raketasks/user_management.md b/doc/raketasks/user_management.md
index 021ce35931f..8fa2ed1311c 100644
--- a/doc/raketasks/user_management.md
+++ b/doc/raketasks/user_management.md
@@ -1,4 +1,4 @@
-### Add user to as a developer to all projects
+### Add user as a developer to all projects
 
 ```
 bundle exec rake gitlab:import:user_to_projects[username@domain.tld]
diff --git a/doc/update/5.0-to-5.1.md b/doc/update/5.0-to-5.1.md
new file mode 100644
index 00000000000..d3abe462971
--- /dev/null
+++ b/doc/update/5.0-to-5.1.md
@@ -0,0 +1,51 @@
+## Release notes:
+
+* `unicorn` replaced with `puma`
+* merge request cached diff will be truncated
+
+### 1. stop server
+
+    sudo service gitlab stop
+
+### 2. get latest code
+
+```
+
+sudo -u git -H git fetch
+sudo -u git -H git checkout 5-1-stable
+
+```
+
+### 3. Update gitlab-shell
+
+```
+cd /home/git/gitlab-shell
+sudo -u git -H git fetch
+sudo -u git -H git checkout v1.3.0
+```
+
+### 4. Install libs, migrations etc
+
+```
+sudo rm tmp/sockets/gitlab.socket
+sudo -u git -H cp config/puma.rb.example config/puma.rb
+
+
+sudo -u git -H bundle install --without development test postgres --deployment
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+sudo -u git -H bundle exec rake migrate_merge_requests RAILS_ENV=production
+
+```
+
+### 5. Update init.d script with a new one
+
+```bash
+# init.d
+sudo rm /etc/init.d/gitlab
+sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-1-stable/init.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
+```
+
+### 6. Start application
+
+    sudo service gitlab start
diff --git a/features/admin/users.feature b/features/admin/users.feature
index 03ac86a367b..4c951df9fe2 100644
--- a/features/admin/users.feature
+++ b/features/admin/users.feature
@@ -6,3 +6,11 @@ Feature: Admin Users
   Scenario: On Admin Users
     Given I visit admin users page
     Then I should see all users
+
+  Scenario: Edit user and change username to non ascii char
+    When I visit admin users page
+    And Click edit
+    And Input non ascii char in username
+    And Click save
+    Then See username error message
+    And Not chenged form action url
diff --git a/features/dashboard/search.feature b/features/dashboard/search.feature
index 9813d9d1e7c..91d870f46f3 100644
--- a/features/dashboard/search.feature
+++ b/features/dashboard/search.feature
@@ -2,13 +2,8 @@ Feature: Dashboard Search
   Background:
     Given I sign in as a user
     And I own project "Shop"
-    And Project "Shop" has wiki page "Contibuting guide"
     And I visit dashboard search page
 
   Scenario: I should see project I am looking for
     Given I search for "Sho"
     Then I should see "Shop" project link
-
-  Scenario: I should see wiki page I am looking for
-    Given I search for "Contibuting"
-    Then I should see "Contibuting guide" wiki link
\ No newline at end of file
diff --git a/features/project/commits/commit_diff_comments.feature b/features/project/commits/commit_diff_comments.feature
index 884fab527f5..b26019f832f 100644
--- a/features/project/commits/commit_diff_comments.feature
+++ b/features/project/commits/commit_diff_comments.feature
@@ -83,10 +83,3 @@ Feature: Comments on commit diffs
     And I submit the diff comment
     Then I should not see the diff comment form
     And I should see a discussion reply button
-
-
-  #@wip @javascript
-  #Scenario: I can delete a discussion comment
-  #  Given I leave a diff comment like "Typo, please fix"
-  #  And I delete a diff comment
-  #  Then I should not see a diff comment saying "Typo, please fix"
diff --git a/features/project/team_management.feature b/features/project/team_management.feature
index 04545a08e0a..fc353424e36 100644
--- a/features/project/team_management.feature
+++ b/features/project/team_management.feature
@@ -21,7 +21,6 @@ Feature: Project Team management
   Scenario: Update user access
     Given I should see "Sam" in team list as "Developer"
     And I change "Sam" role to "Reporter"
-    Then I visit project "Shop" team page
     And I should see "Sam" in team list as "Reporter"
 
   Scenario: Cancel team member
diff --git a/features/steps/admin/admin_projects.rb b/features/steps/admin/admin_projects.rb
index dd6b4e9810b..b410b23851b 100644
--- a/features/steps/admin/admin_projects.rb
+++ b/features/steps/admin/admin_projects.rb
@@ -16,9 +16,7 @@ class AdminProjects < Spinach::FeatureSteps
   Then 'I should see project details' do
     project = Project.first
     current_path.should == admin_project_path(project)
-
     page.should have_content(project.name_with_namespace)
     page.should have_content(project.creator.name)
-    page.should have_content('Add new team member')
   end
 end
diff --git a/features/steps/admin/admin_users.rb b/features/steps/admin/admin_users.rb
index 1828ae705ce..61b3ed91beb 100644
--- a/features/steps/admin/admin_users.rb
+++ b/features/steps/admin/admin_users.rb
@@ -8,4 +8,27 @@ class AdminUsers < Spinach::FeatureSteps
       page.should have_content user.name
     end
   end
+
+  And 'Click edit' do
+    @user = User.first
+    find("#edit_user_#{@user.id}").click
+  end
+
+  And 'Input non ascii char in username' do
+    fill_in 'user_username', with: "\u3042\u3044"
+  end
+
+  And 'Click save' do
+    click_button("Save")
+  end
+
+  Then 'See username error message' do
+    within "#error_explanation" do
+      page.should have_content "Username"
+    end
+  end
+
+  And 'Not chenged form action url' do
+    page.should have_selector %(form[action="/admin/users/#{@user.username}"])
+  end
 end
diff --git a/features/steps/dashboard/dashboard_event_filters.rb b/features/steps/dashboard/dashboard_event_filters.rb
index afa15c31332..09da4e6756f 100644
--- a/features/steps/dashboard/dashboard_event_filters.rb
+++ b/features/steps/dashboard/dashboard_event_filters.rb
@@ -1,12 +1,12 @@
 class EventFilters < Spinach::FeatureSteps
   include SharedAuthentication
-  include SharedPaths 
+  include SharedPaths
   include SharedProject
 
   Then 'I should see push event' do
     page.should have_selector('span.pushed')
   end
-  
+
   Then 'I should not see push event' do
     page.should_not have_selector('span.pushed')
   end
@@ -20,11 +20,11 @@ class EventFilters < Spinach::FeatureSteps
   end
 
   Then 'I should see merge request event' do
-    page.should have_selector('span.merged')
+    page.should have_selector('span.accepted')
   end
 
   And 'I should not see merge request event' do
-    page.should_not have_selector('span.merged')
+    page.should_not have_selector('span.accepted')
   end
 
   And 'this project has push event' do
@@ -68,7 +68,7 @@ class EventFilters < Spinach::FeatureSteps
       target_id: merge_request.id,
       target_type: "MergeRequest",
       author_id: @user.id
-    )    
+    )
   end
 
   When 'I click "push" event filter' do
diff --git a/features/steps/dashboard/dashboard_search.rb b/features/steps/dashboard/dashboard_search.rb
index 9c8c879479d..32966a8617a 100644
--- a/features/steps/dashboard/dashboard_search.rb
+++ b/features/steps/dashboard/dashboard_search.rb
@@ -16,15 +16,4 @@ class DashboardSearch < Spinach::FeatureSteps
     fill_in "dashboard_search", with: "Contibuting"
     click_button "Search"
   end
-
-  And 'Project "Shop" has wiki page "Contibuting guide"' do
-    @wiki_page = create :wiki,
-      project: @project,
-      title: "Contibuting guide",
-      slug: "contributing"
-  end
-
-  Then 'I should see "Contibuting guide" wiki link' do
-    page.should have_link "Contibuting guide"
-  end
 end
diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb
index 3433c2ba5f6..fb26d41f43e 100644
--- a/features/steps/project/project_browse_commits.rb
+++ b/features/steps/project/project_browse_commits.rb
@@ -15,7 +15,7 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
   end
 
   Then 'I see commits atom feed' do
-    commit = CommitDecorator.decorate(@project.repository.commit)
+    commit = @project.repository.commit
     page.response_headers['Content-Type'].should have_content("application/atom+xml")
     page.body.should have_selector("title", :text => "Recent commits to #{@project.name}")
     page.body.should have_selector("author email", :text => commit.author_email)
@@ -53,7 +53,7 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
   end
 
   Then 'I see commits stats' do
-    page.should have_content 'Stats'
+    page.should have_content 'Top 50 Committers'
     page.should have_content 'Committers'
     page.should have_content 'Total commits'
     page.should have_content 'Authors'
diff --git a/features/steps/project/project_merge_requests.rb b/features/steps/project/project_merge_requests.rb
index 4c22119b07e..fa7666bcbb6 100644
--- a/features/steps/project/project_merge_requests.rb
+++ b/features/steps/project/project_merge_requests.rb
@@ -97,7 +97,7 @@ class ProjectMergeRequests < Spinach::FeatureSteps
   end
 
   And 'I leave a comment on the diff page' do
-    find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185 .add-diff-note").click
+    init_diff_note
 
     within('.js-temp-notes-holder') do
       fill_in "note_note", with: "One comment to rule them all"
@@ -106,7 +106,7 @@ class ProjectMergeRequests < Spinach::FeatureSteps
   end
 
   And 'I leave a comment like "Line is wrong" on line 185 of the first file' do
-    find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185 .add-diff-note").click
+    init_diff_note
 
     within(".js-temp-notes-holder") do
       fill_in "note_note", with: "Line is wrong"
@@ -116,29 +116,21 @@ class ProjectMergeRequests < Spinach::FeatureSteps
   end
 
   Then 'I should see a discussion has started on line 185' do
-    first_commit = merge_request.commits.first
-    first_diff   = first_commit.diffs.first
     page.should have_content "#{current_user.name} started a discussion on this merge request diff"
-    page.should have_content "#{first_diff.b_path}:L185"
+    page.should have_content "app/assets/stylesheets/tree.scss:L185"
     page.should have_content "Line is wrong"
   end
 
   Then 'I should see a discussion has started on commit bcf03b5de6c:L185' do
-    first_commit = merge_request.commits.first
-    first_diff   = first_commit.diffs.first
     page.should have_content "#{current_user.name} started a discussion on commit"
-    page.should have_content first_commit.short_id(8)
-    page.should have_content "#{first_diff.b_path}:L185"
+    page.should have_content "app/assets/stylesheets/tree.scss:L185"
     page.should have_content "Line is wrong"
   end
 
   Then 'I should see a discussion has started on commit bcf03b5de6c' do
-    first_commit = merge_request.st_commits.first
-    first_diff   = first_commit.diffs.first
     page.should have_content "#{current_user.name} started a discussion on commit bcf03b5de6c"
-    page.should have_content first_commit.short_id(8)
     page.should have_content "One comment to rule them all"
-    page.should have_content "#{first_diff.b_path}:L185"
+    page.should have_content "app/assets/stylesheets/tree.scss:L185"
   end
 
   def project
@@ -148,4 +140,8 @@ class ProjectMergeRequests < Spinach::FeatureSteps
   def merge_request
     @merge_request ||= MergeRequest.find_by_title!("Bug NS-05")
   end
+
+  def init_diff_note
+    find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
+  end
 end
diff --git a/features/steps/project/project_team_management.rb b/features/steps/project/project_team_management.rb
index e8e054350dd..ffd2aa24676 100644
--- a/features/steps/project/project_team_management.rb
+++ b/features/steps/project/project_team_management.rb
@@ -24,34 +24,34 @@ class ProjectTeamManagement < Spinach::FeatureSteps
 
     select2(user.id, from: "#user_ids", multiple: true)
     within "#new_team_member" do
-      select "Reporter", :from => "project_access"
+      select "Reporter", from: "project_access"
     end
     click_button "Add users"
   end
 
   Then 'I should see "Mike" in team list as "Reporter"' do
-    user = User.find_by_name("Mike")
-    role_id = find(".user_#{user.id} #team_member_project_access").value
-    role_id.should == UsersProject.access_roles["Reporter"].to_s
+    within '.reporters' do
+      page.should have_content('Mike')
+    end
   end
 
   Given 'I should see "Sam" in team list as "Developer"' do
-    user = User.find_by_name("Sam")
-    role_id = find(".user_#{user.id} #team_member_project_access").value
-    role_id.should == UsersProject.access_roles["Developer"].to_s
+    within '.developers' do
+      page.should have_content('Sam')
+    end
   end
 
   And 'I change "Sam" role to "Reporter"' do
     user = User.find_by_name("Sam")
     within ".user_#{user.id}" do
-      select "Reporter", :from => "team_member_project_access"
+      select "Reporter", from: "team_member_project_access"
     end
   end
 
   And 'I should see "Sam" in team list as "Reporter"' do
-    user = User.find_by_name("Sam")
-    role_id = find(".user_#{user.id} #team_member_project_access").value
-    role_id.should == UsersProject.access_roles["Reporter"].to_s
+    within '.reporters' do
+      page.should have_content('Sam')
+    end
   end
 
   And 'I click link "Remove from team"' do
@@ -65,11 +65,11 @@ class ProjectTeamManagement < Spinach::FeatureSteps
   end
 
   And 'gitlab user "Mike"' do
-    create(:user, :name => "Mike")
+    create(:user, name: "Mike")
   end
 
   And 'gitlab user "Sam"' do
-    create(:user, :name => "Sam")
+    create(:user, name: "Sam")
   end
 
   And '"Sam" is "Shop" developer' do
@@ -79,7 +79,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps
   end
 
   Given 'I own project "Website"' do
-    @project = create(:project, :name => "Website")
+    @project = create(:project, name: "Website")
     @project.team << [@user, :master]
   end
 
diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb
index 446e3b9a8b3..617a077b914 100644
--- a/features/steps/shared/active_tab.rb
+++ b/features/steps/shared/active_tab.rb
@@ -3,9 +3,9 @@ module SharedActiveTab
 
   def ensure_active_main_tab(content)
     if content == "Home"
-      page.find('ul.main_menu li.active').should have_css('i.icon-home')
+      page.find('.main-nav li.active').should have_css('i.icon-home')
     else
-      page.find('ul.main_menu li.active').should have_content(content)
+      page.find('.main-nav li.active').should have_content(content)
     end
   end
 
@@ -14,7 +14,7 @@ module SharedActiveTab
   end
 
   And 'no other main tabs should be active' do
-    page.should have_selector('ul.main_menu li.active', count: 1)
+    page.should have_selector('.main-nav li.active', count: 1)
   end
 
   And 'no other sub tabs should be active' do
diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb
index 9dbbc553137..9c39a226e1b 100644
--- a/features/steps/shared/diff_note.rb
+++ b/features/steps/shared/diff_note.rb
@@ -3,15 +3,13 @@ module SharedDiffNote
 
   Given 'I cancel the diff comment' do
     within(".file") do
-      find(".js-close-discussion-note-form").trigger("click")
+      find(".js-close-discussion-note-form").click
     end
   end
 
   Given 'I delete a diff comment' do
-    sleep 1
-    within(".file") do
-      first(".js-note-delete").trigger("click")
-    end
+    find('.note').hover
+    find(".js-note-delete").click
   end
 
   Given 'I haven\'t written any diff comment text' do
@@ -21,17 +19,16 @@ module SharedDiffNote
   end
 
   Given 'I leave a diff comment like "Typo, please fix"' do
-    find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
+    find('a[data-line-code="586fb7c4e1add2d4d24e27566ed7064680098646_29_14"]').click
     within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_29_14']") do
       fill_in "note[note]", with: "Typo, please fix"
-      #click_button("Add Comment")
       find(".js-comment-button").trigger("click")
       sleep 0.05
     end
   end
 
   Given 'I preview a diff comment text like "Should fix it :smile:"' do
-    find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
+    find('a[data-line-code="586fb7c4e1add2d4d24e27566ed7064680098646_29_14"]').click
     within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_29_14']") do
       fill_in "note[note]", with: "Should fix it :smile:"
       find(".js-note-preview-button").trigger("click")
@@ -39,7 +36,8 @@ module SharedDiffNote
   end
 
   Given 'I preview another diff comment text like "DRY this up"' do
-    find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click")
+    find('a[data-line-code="586fb7c4e1add2d4d24e27566ed7064680098646_57_41"]').click
+
     within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_57_41']") do
       fill_in "note[note]", with: "DRY this up"
       find(".js-note-preview-button").trigger("click")
@@ -47,11 +45,11 @@ module SharedDiffNote
   end
 
   Given 'I open a diff comment form' do
-    find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
+    find('a[data-line-code="586fb7c4e1add2d4d24e27566ed7064680098646_29_14"]').click
   end
 
   Given 'I open another diff comment form' do
-    find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click")
+    find('a[data-line-code="586fb7c4e1add2d4d24e27566ed7064680098646_57_41"]').click
   end
 
   Given 'I write a diff comment like ":-1: I don\'t like this"' do
diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb
index e0ff52a7252..da08da9420d 100644
--- a/features/steps/shared/note.rb
+++ b/features/steps/shared/note.rb
@@ -2,8 +2,8 @@ module SharedNote
   include Spinach::DSL
 
   Given 'I delete a comment' do
-    sleep 1
-    first(".js-note-delete").trigger("click")
+    find('.note').hover
+    find(".js-note-delete").click
   end
 
   Given 'I haven\'t written any comment text' do
diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb
index 1af8b478155..27ca65b22dd 100644
--- a/features/steps/shared/paths.rb
+++ b/features/steps/shared/paths.rb
@@ -205,7 +205,7 @@ module SharedPaths
   end
 
   Given 'I visit blob file from repo' do
-    visit project_tree_path(@project, File.join(ValidCommit::ID, ValidCommit::BLOB_FILE_PATH))
+    visit project_blob_path(@project, File.join(ValidCommit::ID, ValidCommit::BLOB_FILE_PATH))
   end
 
   Given 'I visit project source page for "8470d70"' do
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index 81863a54f3d..b16032a8300 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -3,14 +3,14 @@ module SharedProject
 
   # Create a project without caring about what it's called
   And "I own a project" do
-    @project = create(:project)
+    @project = create(:project_with_code)
     @project.team << [@user, :master]
   end
 
   # Create a specific project called "Shop"
   And 'I own project "Shop"' do
     @project = Project.find_by_name "Shop"
-    @project ||= create(:project, name: "Shop")
+    @project ||= create(:project_with_code, name: "Shop")
     @project.team << [@user, :master]
   end
 
diff --git a/features/steps/userteams/userteams.rb b/features/steps/userteams/userteams.rb
index 70ad3cca43a..9a86572e1ac 100644
--- a/features/steps/userteams/userteams.rb
+++ b/features/steps/userteams/userteams.rb
@@ -132,7 +132,7 @@ class Userteams < Spinach::FeatureSteps
     team = UserTeam.last
     team.projects.each do |project|
       team.members.each do |member|
-        3.times { project.merge_requests << create(:merge_request, assignee: member) }
+        3.times { create(:merge_request, assignee: member, project: project) }
       end
     end
   end
@@ -157,7 +157,7 @@ class Userteams < Spinach::FeatureSteps
     team = UserTeam.last
     team.projects.each do |project|
       team.members.each do |member|
-        3.times { project.merge_requests << create(:merge_request, assignee: member) }
+        3.times { create(:merge_request, assignee: member, project: project) }
       end
     end
   end
diff --git a/features/support/env.rb b/features/support/env.rb
index 90a61dd16c6..1693a588993 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -14,7 +14,7 @@ require 'spinach/capybara'
 require 'sidekiq/testing/inline'
 
 
-%w(stubbed_repository valid_commit select2_helper).each do |f|
+%w(valid_commit select2_helper test_env).each do |f|
   require Rails.root.join('spec', 'support', f)
 end
 
@@ -30,18 +30,13 @@ Spinach.hooks.on_tag("javascript") do
   ::Capybara.current_driver = ::Capybara.javascript_driver
 end
 Capybara.default_wait_time = 10
-
+Capybara.ignore_hidden_elements = false
 
 DatabaseCleaner.strategy = :truncation
 
 Spinach.hooks.before_scenario do
-  # Use tmp dir for FS manipulations
-  Gitlab.config.gitlab_shell.stub(repos_path: Rails.root.join('tmp', 'test-git-base-path'))
-  Gitlab::Shell.any_instance.stub(:add_repository) do |path|
-    create_temp_repo("#{Rails.root}/tmp/test-git-base-path/#{path}.git")
-  end
-  FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path
-  FileUtils.mkdir_p Gitlab.config.gitlab_shell.repos_path
+  TestEnv.init(mailer: false)
+
   DatabaseCleaner.start
 end
 
@@ -54,9 +49,3 @@ Spinach.hooks.before_run do
 
   include FactoryGirl::Syntax::Methods
 end
-
-def create_temp_repo(path)
-  FileUtils.mkdir_p path
-  command = "git init --quiet --bare #{path};"
-  system(command)
-end
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index 81451638090..affe1be54dd 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -22,6 +22,7 @@ module Gitlab
         key = Key.find(params[:key_id])
         project = Project.find_with_namespace(project_path)
         git_cmd = params[:action]
+        return false unless project
 
 
         if key.is_deploy_key
@@ -32,7 +33,7 @@ module Gitlab
           return false if user.blocked?
 
           action = case git_cmd
-                   when 'git-upload-pack'
+                   when 'git-upload-pack', 'git-upload-archive'
                      then :download_code
                    when 'git-receive-pack'
                      then
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 234a005a998..d5595d5f16b 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -94,6 +94,8 @@ module Gitlab
 
         authorize! :modify_merge_request, merge_request
 
+        MergeRequestObserver.current_user = current_user
+
         if merge_request.update_attributes attrs
           merge_request.reload_code
           merge_request.mark_as_unchecked
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index d4f50fda1b5..75157e55730 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -372,7 +372,7 @@ module Gitlab
         ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
 
         commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
-        present CommitDecorator.decorate(commits), with: Entities::RepoCommit
+        present commits, with: Entities::RepoCommit
       end
 
       # Get a project snippets
@@ -493,14 +493,16 @@ module Gitlab
 
         ref = params[:sha]
 
-        commit = user_project.repository.commit ref
+        repo = user_project.repository
+
+        commit = repo.commit(ref)
         not_found! "Commit" unless commit
 
-        tree = Tree.new commit.tree, ref, params[:filepath]
-        not_found! "File" unless tree.try(:tree)
+        blob = Gitlab::Git::Blob.new(repo, commit.id, ref, params[:filepath])
+        not_found! "File" unless blob.exists?
 
-        content_type tree.mime_type
-        present tree.data
+        content_type blob.mime_type
+        present blob.data
       end
 
       # Get a specific project's keys
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 125a8624021..4198387d403 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -12,6 +12,7 @@ module Gitlab
         @users = User.scoped
         @users = @users.active if params[:active].present?
         @users = @users.search(params[:search]) if params[:search].present?
+        @users = paginate @users
         present @users, with: Entities::User
       end
 
diff --git a/lib/backup/database.rb b/lib/backup/database.rb
new file mode 100644
index 00000000000..cfa9971670c
--- /dev/null
+++ b/lib/backup/database.rb
@@ -0,0 +1,58 @@
+require 'yaml'
+
+module Backup
+  class Database
+    attr_reader :config, :db_dir
+
+    def initialize
+      @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
+      @db_dir = File.join(Gitlab.config.backup.path, 'db')
+      FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
+    end
+
+    def dump
+      case config["adapter"]
+      when /^mysql/ then
+        system("mysqldump #{mysql_args} #{config['database']} > #{db_file_name}")
+      when "postgresql" then
+        pg_env
+        system("pg_dump #{config['database']} > #{db_file_name}")
+      end
+    end
+
+    def restore
+      case config["adapter"]
+      when /^mysql/ then
+        system("mysql #{mysql_args} #{config['database']} < #{db_file_name}")
+      when "postgresql" then
+        pg_env
+        system("pg_restore #{config['database']} #{db_file_name}")
+      end
+    end
+
+    protected
+
+    def db_file_name
+      File.join(db_dir, 'database.sql')
+    end
+
+    def mysql_args
+      args = {
+        'host'      => '--host',
+        'port'      => '--port',
+        'socket'    => '--socket',
+        'username'  => '--user',
+        'encoding'  => '--default-character-set',
+        'password'  => '--password'
+      }
+      args.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact.join(' ')
+    end
+
+    def pg_env
+      ENV['PGUSER']     = config["username"] if config["username"]
+      ENV['PGHOST']     = config["host"] if config["host"]
+      ENV['PGPORT']     = config["port"].to_s if config["port"]
+      ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
+    end
+  end
+end
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
new file mode 100644
index 00000000000..62a510f2acc
--- /dev/null
+++ b/lib/backup/repository.rb
@@ -0,0 +1,105 @@
+require 'yaml'
+
+module Backup
+  class Repository
+    attr_reader :repos_path
+
+    def dump
+      prepare
+
+      Project.find_each(batch_size: 1000) do |project|
+        print " * #{project.path_with_namespace} ... "
+
+        if project.empty_repo?
+          puts "[SKIPPED]".cyan
+          next
+        end
+
+        # Create namespace dir if missing
+        FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.path)) if project.namespace
+
+        if system("cd #{path_to_repo(project)} > /dev/null 2>&1 && git bundle create #{path_to_bundle(project)} --all > /dev/null 2>&1")
+          puts "[DONE]".green
+        else
+          puts "[FAILED]".red
+        end
+
+        wiki = GollumWiki.new(project)
+
+        if File.exists?(path_to_repo(wiki))
+          print " * #{wiki.path_with_namespace} ... "
+          if system("cd #{path_to_repo(wiki)} > /dev/null 2>&1 && git bundle create #{path_to_bundle(wiki)} --all > /dev/null 2>&1")
+            puts " [DONE]".green
+          else
+            puts " [FAILED]".red
+          end
+        end
+      end
+    end
+
+    def restore
+      if File.exists?(repos_path)
+        # Move repos dir to 'repositories.old' dir
+        bk_repos_path = File.join(repos_path, '..', 'repositories.old.' + Time.now.to_i.to_s)
+        FileUtils.mv(repos_path, bk_repos_path)
+      end
+
+      FileUtils.mkdir_p(repos_path)
+
+      Project.find_each(batch_size: 1000) do |project|
+        print "#{project.path_with_namespace} ... "
+
+        project.namespace.ensure_dir_exist if project.namespace
+
+        if system("git clone --bare #{path_to_bundle(project)} #{path_to_repo(project)} > /dev/null 2>&1")
+          puts "[DONE]".green
+        else
+          puts "[FAILED]".red
+        end
+
+        wiki = GollumWiki.new(project)
+
+        if File.exists?(path_to_bundle(wiki))
+          print " * #{wiki.path_with_namespace} ... "
+          if system("git clone --bare #{path_to_bundle(wiki)} #{path_to_repo(wiki)} > /dev/null 2>&1")
+            puts " [DONE]".green
+          else
+            puts " [FAILED]".red
+          end
+        end
+      end
+
+      print 'Put GitLab hooks in repositories dirs'.yellow
+      gitlab_shell_user_home = File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
+      if system("#{gitlab_shell_user_home}/gitlab-shell/support/rewrite-hooks.sh")
+        puts " [DONE]".green
+      else
+        puts " [FAILED]".red
+      end
+
+    end
+
+    protected
+
+    def path_to_repo(project)
+      File.join(repos_path, project.path_with_namespace + '.git')
+    end
+
+    def path_to_bundle(project)
+      File.join(backup_repos_path, project.path_with_namespace + ".bundle")
+    end
+
+    def repos_path
+      Gitlab.config.gitlab_shell.repos_path
+    end
+
+    def backup_repos_path
+      File.join(Gitlab.config.backup.path, "repositories")
+    end
+
+    def prepare
+      FileUtils.rm_rf(backup_repos_path)
+      FileUtils.mkdir_p(backup_repos_path)
+    end
+  end
+end
diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb
new file mode 100644
index 00000000000..4a38af02522
--- /dev/null
+++ b/lib/backup/uploads.rb
@@ -0,0 +1,25 @@
+module Backup
+  class Uploads
+    attr_reader :app_uploads_dir, :backup_uploads_dir, :backup_dir
+
+    def initialize
+      @app_uploads_dir = Rails.root.join('public', 'uploads')
+      @backup_dir = Gitlab.config.backup.path
+      @backup_uploads_dir = File.join(Gitlab.config.backup.path, 'uploads')
+    end
+
+    # Copy uploads from public/uploads to backup/uploads
+    def dump
+      FileUtils.mkdir_p(backup_uploads_dir)
+      FileUtils.cp_r(app_uploads_dir, backup_dir)
+    end
+
+    def restore
+      if File.exists?(app_uploads_dir)
+        FileUtils.mv(app_uploads_dir, Rails.root.join('public', "uploads.#{Time.now.to_i}"))
+      end
+
+      FileUtils.cp_r(backup_uploads_dir, app_uploads_dir)
+    end
+  end
+end
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 66b2f450545..009c5fcada9 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -8,7 +8,7 @@ module ExtractsPath
 
   included do
     if respond_to?(:before_filter)
-      before_filter :assign_ref_vars, only: [:show]
+      before_filter :assign_ref_vars
     end
   end
 
@@ -33,7 +33,7 @@ module ExtractsPath
   #   extract_ref("v2.0.0/README.md")
   #   # => ['v2.0.0', 'README.md']
   #
-  #   extract_ref('/gitlab/vagrant/tree/master/app/models/project.rb')
+  #   extract_ref('master/app/models/project.rb')
   #   # => ['master', 'app/models/project.rb']
   #
   #   extract_ref('issues/1234/app/models/project.rb')
@@ -45,22 +45,12 @@ module ExtractsPath
   #
   # Returns an Array where the first value is the tree-ish and the second is the
   # path
-  def extract_ref(input)
+  def extract_ref(id)
     pair = ['', '']
 
     return pair unless @project
 
-    # Remove relative_url_root from path
-    input.gsub!(/^#{Gitlab.config.gitlab.relative_url_root}/, "")
-    # Remove project, actions and all other staff from path
-    input.gsub!(/^\/#{Regexp.escape(@project.path_with_namespace)}/, "")
-    input.gsub!(/^\/(tree|commits|blame|blob|refs|graph)\//, "") # remove actions
-    input.gsub!(/\?.*$/, "") # remove stamps suffix
-    input.gsub!(/.atom$/, "") # remove rss feed
-    input.gsub!(/.json$/, "") # remove json suffix
-    input.gsub!(/\/edit$/, "") # remove edit route part
-
-    if input.match(/^([[:alnum:]]{40})(.+)/)
+    if id.match(/^([[:alnum:]]{40})(.+)/)
       # If the ref appears to be a SHA, we're done, just split the string
       pair = $~.captures
     else
@@ -68,7 +58,6 @@ module ExtractsPath
       # branches and tags
 
       # Append a trailing slash if we only get a ref and no file path
-      id = input
       id += '/' unless id.ends_with?('/')
 
       valid_refs = @project.repository.ref_names
@@ -96,8 +85,8 @@ module ExtractsPath
   # - @id     - A string representing the joined ref and path
   # - @ref    - A string representing the ref (e.g., the branch, tag, or commit SHA)
   # - @path   - A string representing the filesystem path
-  # - @commit - A CommitDecorator representing the commit from the given ref
-  # - @tree   - A TreeDecorator representing the tree at the given ref/path
+  # - @commit - A Commit representing the commit from the given ref
+  # - @tree   - A Tree representing the tree at the given ref/path
   #
   # If the :id parameter appears to be requesting a specific response format,
   # that will be handled as well.
@@ -105,21 +94,17 @@ module ExtractsPath
   # Automatically renders `not_found!` if a valid tree path could not be
   # resolved (e.g., when a user inserts an invalid path or ref).
   def assign_ref_vars
-    path = CGI::unescape(request.fullpath.dup)
-
-    @ref, @path = extract_ref(path)
+    @id = params[:id]
 
-    @id = File.join(@ref, @path)
+    @ref, @path = extract_ref(@id)
 
     # It is used "@project.repository.commits(@ref, @path, 1, 0)",
     # because "@project.repository.commit(@ref)" returns wrong commit when @ref is tag name.
-    commits = @project.repository.commits(@ref, @path, 1, 0)
-    @commit = CommitDecorator.decorate(commits.first)
+    @commit = @project.repository.commits(@ref, @path, 1, 0).first
 
-    @tree = Tree.new(@commit.tree, @ref, @path)
-    @tree = TreeDecorator.new(@tree)
+    @tree = Tree.new(@project.repository, @commit.id, @ref, @path)
 
-    raise InvalidPathError if @tree.invalid?
+    raise InvalidPathError unless @tree.exists?
   rescue RuntimeError, NoMethodError, InvalidPathError
     not_found!
   end
diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index a230886b47c..bae87977e8d 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -65,13 +65,72 @@ module Gitlab
       system("#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys rm-key #{key_id} \"#{key_content}\"")
     end
 
+    # Add empty directory for storing repositories
+    #
+    # Ex.
+    #   add_namespace("gitlab")
+    #
+    def add_namespace(name)
+      FileUtils.mkdir(full_path(name), mode: 0770) unless exists?(name)
+    end
+
+    # Remove directory from repositories storage
+    # Every repository inside this directory will be removed too
+    #
+    # Ex.
+    #   rm_namespace("gitlab")
+    #
+    def rm_namespace(name)
+      FileUtils.rm_r(full_path(name), force: true)
+    end
+
+    # Move namespace directory inside repositories storage
+    #
+    # Ex.
+    #   mv_namespace("gitlab", "gitlabhq")
+    #
+    def mv_namespace(old_name, new_name)
+      return false if exists?(new_name) || !exists?(old_name)
+
+      FileUtils.mv(full_path(old_name), full_path(new_name))
+    end
+
+    # Remove GitLab Satellites for provided path (namespace or repo dir)
+    #
+    # Ex.
+    #   rm_satellites("gitlab")
+    #
+    #   rm_satellites("gitlab/gitlab-ci.git")
+    #
+    def rm_satellites(path)
+      raise ArgumentError.new("Path can't be blank") if path.blank?
+
+      satellites_path = File.join(Gitlab.config.satellites.path, path)
+      FileUtils.rm_r(satellites_path, force: true)
+    end
+
     def url_to_repo path
       Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git"
     end
 
+    protected
+
     def gitlab_shell_user_home
       File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
     end
 
+    def repos_path
+      Gitlab.config.gitlab_shell.repos_path
+    end
+
+    def full_path(dir_name)
+      raise ArgumentError.new("Directory name can't be blank") if dir_name.blank?
+
+      File.join(repos_path, dir_name)
+    end
+
+    def exists?(dir_name)
+      File.exists?(full_path(dir_name))
+    end
   end
 end
diff --git a/lib/gitlab/backend/shell_adapter.rb b/lib/gitlab/backend/shell_adapter.rb
new file mode 100644
index 00000000000..f247f4593d7
--- /dev/null
+++ b/lib/gitlab/backend/shell_adapter.rb
@@ -0,0 +1,12 @@
+# == GitLab Shell mixin
+#
+# Provide a shortcut to Gitlab::Shell instance by gitlab_shell
+#
+module Gitlab
+  module ShellAdapter
+    def gitlab_shell
+      Gitlab::Shell.new
+    end
+  end
+end
+
diff --git a/lib/gitlab/git/blame.rb b/lib/gitlab/git/blame.rb
new file mode 100644
index 00000000000..d7282c587aa
--- /dev/null
+++ b/lib/gitlab/git/blame.rb
@@ -0,0 +1,23 @@
+module Gitlab
+  module Git
+    class Blame
+
+      attr_accessor :repository, :sha, :path
+
+      def initialize(repository, sha, path)
+        @repository, @sha, @path = repository, sha, path
+      end
+
+      def each
+        raw_blame = Grit::Blob.blame(repository.repo, sha, path)
+
+        raw_blame.each do |commit, lines|
+          next unless commit
+
+          commit = Gitlab::Git::Commit.new(commit)
+          yield(commit, lines)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
new file mode 100644
index 00000000000..57b89912f2d
--- /dev/null
+++ b/lib/gitlab/git/blob.rb
@@ -0,0 +1,42 @@
+module Gitlab
+  module Git
+    class Blob
+      include Linguist::BlobHelper
+
+      attr_accessor :raw_blob
+
+      delegate :name, to: :raw_blob
+
+      def initialize(repository, sha, ref, path)
+        @repository, @sha, @ref = repository, sha, ref
+
+        @commit = @repository.commit(sha)
+        @raw_blob = @repository.tree(@commit, path)
+      end
+
+      def data
+        if raw_blob
+          raw_blob.data
+        else
+          nil
+        end
+      end
+
+      def exists?
+        raw_blob
+      end
+
+      def empty?
+        data.blank?
+      end
+
+      def mode
+        raw_blob.mode
+      end
+
+      def size
+        raw_blob.size
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
new file mode 100644
index 00000000000..a92c21a0da1
--- /dev/null
+++ b/lib/gitlab/git/commit.rb
@@ -0,0 +1,127 @@
+# Gitlab::Git::Commit is a wrapper around native Grit::Commit object
+# We dont want to use grit objects inside app/
+# It helps us easily migrate to rugged in future
+module Gitlab
+  module Git
+    class Commit
+      attr_accessor :raw_commit, :head, :refs,
+        :id, :authored_date, :committed_date, :message,
+        :author_name, :author_email, :parent_ids,
+        :committer_name, :committer_email
+
+      delegate :parents, :tree, :stats, :to_patch,
+        to: :raw_commit
+
+      def initialize(raw_commit, head = nil)
+        raise "Nil as raw commit passed" unless raw_commit
+
+        if raw_commit.is_a?(Hash)
+          init_from_hash(raw_commit)
+        else
+          init_from_grit(raw_commit)
+        end
+
+        @head = head
+      end
+
+      def serialize_keys
+        @serialize_keys ||= %w(id authored_date committed_date author_name author_email committer_name committer_email message parent_ids).map(&:to_sym)
+      end
+
+      def sha
+        id
+      end
+
+      def short_id(length = 10)
+        id.to_s[0..length]
+      end
+
+      def safe_message
+        @safe_message ||= message
+      end
+
+      def created_at
+        committed_date
+      end
+
+      # Was this commit committed by a different person than the original author?
+      def different_committer?
+        author_name != committer_name || author_email != committer_email
+      end
+
+      def parent_id
+        parent_ids.first
+      end
+
+      # Shows the diff between the commit's parent and the commit.
+      #
+      # Cuts out the header and stats from #to_patch and returns only the diff.
+      def to_diff
+        # see Grit::Commit#show
+        patch = to_patch
+
+        # discard lines before the diff
+        lines = patch.split("\n")
+        while !lines.first.start_with?("diff --git") do
+          lines.shift
+        end
+        lines.pop if lines.last =~ /^[\d.]+$/ # Git version
+          lines.pop if lines.last == "-- "      # end of diff
+        lines.join("\n")
+      end
+
+      def has_zero_stats?
+        stats.total.zero?
+      rescue
+        true
+      end
+
+      def no_commit_message
+        "--no commit message"
+      end
+
+      def to_hash
+        hash = {}
+
+        keys = serialize_keys
+
+        keys.each do |key|
+          hash[key] = send(key)
+        end
+
+        hash
+      end
+
+      def date
+        committed_date
+      end
+
+      def diffs
+        raw_commit.diffs.map { |diff| Gitlab::Git::Diff.new(diff) }
+      end
+
+      private
+
+      def init_from_grit(grit)
+        @raw_commit = grit
+        @id = grit.id
+        @message = grit.message
+        @authored_date = grit.authored_date
+        @committed_date = grit.committed_date
+        @author_name = grit.author.name
+        @author_email = grit.author.email
+        @committer_name = grit.committer.name
+        @committer_email = grit.committer.email
+        @parent_ids = grit.parents.map(&:id)
+      end
+
+      def init_from_hash(hash)
+        raw_commit = hash.symbolize_keys
+
+        serialize_keys.each do |key|
+          send(:"#{key}=", raw_commit[key.to_sym])
+        end
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git/compare.rb b/lib/gitlab/git/compare.rb
new file mode 100644
index 00000000000..e34f204e8bd
--- /dev/null
+++ b/lib/gitlab/git/compare.rb
@@ -0,0 +1,35 @@
+module Gitlab
+  module Git
+    class Compare
+      attr_accessor :commits, :commit, :diffs, :same
+
+      def initialize(repository, from, to)
+        @commits, @diffs = [], []
+        @commit = nil
+        @same = false
+
+        return unless from && to
+
+        first = repository.commit(to.try(:strip))
+        last = repository.commit(from.try(:strip))
+
+        return unless first && last
+
+        if first.id == last.id
+          @same = true
+          return
+        end
+
+        @commit = first
+        @commits = repository.commits_between(last.id, first.id)
+
+        @diffs = if @commits.size > 100
+                   []
+                 else
+                   repository.repo.diff(last.id, first.id) rescue []
+                 end
+      end
+    end
+  end
+end
+
diff --git a/lib/gitlab/git/diff.rb b/lib/gitlab/git/diff.rb
new file mode 100644
index 00000000000..45191dd3f91
--- /dev/null
+++ b/lib/gitlab/git/diff.rb
@@ -0,0 +1,63 @@
+# Gitlab::Git::Diff is a wrapper around native Grit::Diff object
+# We dont want to use grit objects inside app/
+# It helps us easily migrate to rugged in future
+module Gitlab
+  module Git
+    class Diff
+      BROKEN_DIFF = "--broken-diff"
+
+      attr_accessor :raw_diff
+
+      # Diff properties
+      attr_accessor :old_path, :new_path, :a_mode, :b_mode, :diff
+
+      # Stats properties
+      attr_accessor  :new_file, :renamed_file, :deleted_file
+
+      def initialize(raw_diff)
+        raise "Nil as raw diff passed" unless raw_diff
+
+        if raw_diff.is_a?(Hash)
+          init_from_hash(raw_diff)
+        else
+          init_from_grit(raw_diff)
+        end
+      end
+
+      def serialize_keys
+        @serialize_keys ||= %w(diff new_path old_path a_mode b_mode new_file renamed_file deleted_file).map(&:to_sym)
+      end
+
+      def to_hash
+        hash = {}
+
+        keys = serialize_keys
+
+        keys.each do |key|
+          hash[key] = send(key)
+        end
+
+        hash
+      end
+
+      private
+
+      def init_from_grit(grit)
+        @raw_diff = grit
+
+        serialize_keys.each do |key|
+          send(:"#{key}=", grit.send(key))
+        end
+      end
+
+      def init_from_hash(hash)
+        raw_diff = hash.symbolize_keys
+
+        serialize_keys.each do |key|
+          send(:"#{key}=", raw_diff[key.to_sym])
+        end
+      end
+    end
+  end
+end
+
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
new file mode 100644
index 00000000000..ddead51d443
--- /dev/null
+++ b/lib/gitlab/git/repository.rb
@@ -0,0 +1,212 @@
+# Gitlab::Git::Gitlab::Git::Commit is a wrapper around native Grit::Repository object
+# We dont want to use grit objects inside app/
+# It helps us easily migrate to rugged in future
+module Gitlab
+  module Git
+    class Repository
+      include Gitlab::Popen
+
+      class NoRepository < StandardError; end
+
+      # Repository directory name with namespace direcotry
+      # Examples:
+      #   gitlab/gitolite
+      #   diaspora
+      #
+      attr_accessor :path_with_namespace
+
+      # Grit repo object
+      attr_accessor :repo
+
+      # Default branch in the repository
+      attr_accessor :root_ref
+
+      def initialize(path_with_namespace, root_ref = 'master')
+        @root_ref = root_ref || "master"
+        @path_with_namespace = path_with_namespace
+
+        # Init grit repo object
+        repo
+      end
+
+      def raw
+        repo
+      end
+
+      def path_to_repo
+        @path_to_repo ||= File.join(repos_path, "#{path_with_namespace}.git")
+      end
+
+      def repos_path
+        Gitlab.config.gitlab_shell.repos_path
+      end
+
+      def repo
+        @repo ||= Grit::Repo.new(path_to_repo)
+      rescue Grit::NoSuchPathError
+        raise NoRepository.new('no repository for such path')
+      end
+
+      def commit(commit_id = nil)
+        commit = if commit_id
+                   repo.commit(commit_id)
+                 else
+                   repo.commits(root_ref).first
+                 end
+
+        decorate_commit(commit) if commit
+      end
+
+      def commits_with_refs(n = 20)
+        commits = repo.branches.map { |ref| decorate_commit(ref.commit, ref) }
+
+        commits.sort! do |x, y|
+          y.committed_date <=> x.committed_date
+        end
+
+        commits[0..n]
+      end
+
+      def commits(ref, path = nil, limit = nil, offset = nil)
+        if path.present?
+          repo.log(ref, path, max_count: limit, skip: offset, follow: true)
+        elsif limit && offset
+          repo.commits(ref, limit.to_i, offset.to_i)
+        else
+          repo.commits(ref)
+        end.map{ |c| decorate_commit(c) }
+      end
+
+      def commits_between(from, to)
+        repo.commits_between(from, to).map { |c| decorate_commit(c) }
+      end
+
+      def last_commit_for(ref, path = nil)
+        commits(ref, path, 1).first
+      end
+
+      # Returns an Array of branch names
+      # sorted by name ASC
+      def branch_names
+        branches.map(&:name)
+      end
+
+      # Returns an Array of Branches
+      def branches
+        repo.branches.sort_by(&:name)
+      end
+
+      # Returns an Array of tag names
+      def tag_names
+        repo.tags.collect(&:name).sort.reverse
+      end
+
+      # Returns an Array of Tags
+      def tags
+        repo.tags.sort_by(&:name).reverse
+      end
+
+      # Returns an Array of branch and tag names
+      def ref_names
+        [branch_names + tag_names].flatten
+      end
+
+      def heads
+        @heads ||= repo.heads
+      end
+
+      def tree(fcommit, path = nil)
+        fcommit = commit if fcommit == :head
+        tree = fcommit.tree
+        path ? (tree / path) : tree
+      end
+
+      def has_commits?
+        !!commit
+      rescue Grit::NoSuchPathError
+        false
+      end
+
+      def empty?
+        !has_commits?
+      end
+
+      # Discovers the default branch based on the repository's available branches
+      #
+      # - If no branches are present, returns nil
+      # - If one branch is present, returns its name
+      # - If two or more branches are present, returns the one that has a name
+      #   matching root_ref (default_branch or 'master' if default_branch is nil)
+      def discover_default_branch
+        if branch_names.length == 0
+          nil
+        elsif branch_names.length == 1
+          branch_names.first
+        else
+          branch_names.select { |v| v == root_ref }.first
+        end
+      end
+
+      # Archive Project to .tar.gz
+      #
+      # Already packed repo archives stored at
+      # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
+      #
+      def archive_repo(ref)
+        ref = ref || self.root_ref
+        commit = self.commit(ref)
+        return nil unless commit
+
+        # Build file path
+        file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"
+        storage_path = Rails.root.join("tmp", "repositories")
+        file_path = File.join(storage_path, self.path_with_namespace, file_name)
+
+        # Put files into a directory before archiving
+        prefix = File.basename(self.path_with_namespace) + "/"
+
+        # Create file if not exists
+        unless File.exists?(file_path)
+          FileUtils.mkdir_p File.dirname(file_path)
+          file = self.repo.archive_to_file(ref, prefix,  file_path)
+        end
+
+        file_path
+      end
+
+      # Return repo size in megabytes
+      # Cached in redis
+      def size
+        Rails.cache.fetch(cache_key(:size)) do
+          size = popen('du -s', path_to_repo).first.strip.to_i
+          (size.to_f / 1024).round(2)
+        end
+      end
+
+      def expire_cache
+        Rails.cache.delete(cache_key(:size))
+      end
+
+      def cache_key(type)
+        "#{type}:#{path_with_namespace}"
+      end
+
+      def diffs_between(source_branch, target_branch)
+        # Only show what is new in the source branch compared to the target branch, not the other way around.
+        # The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
+        # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
+        common_commit = repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
+        repo.diff(common_commit, source_branch).map { |diff| Gitlab::Git::Diff.new(diff) }
+
+      rescue Grit::Git::GitTimeout
+        [Gitlab::Git::Diff::BROKEN_DIFF]
+      end
+
+      protected
+
+      def decorate_commit(commit, ref = nil)
+        Gitlab::Git::Commit.new(commit, ref)
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git/stats.rb b/lib/gitlab/git/stats.rb
new file mode 100644
index 00000000000..c925c653342
--- /dev/null
+++ b/lib/gitlab/git/stats.rb
@@ -0,0 +1,75 @@
+module Gitlab
+  module Git
+    class Stats
+      attr_accessor :repo, :ref
+
+      def initialize repo, ref
+        @repo, @ref = repo, ref
+      end
+
+      def authors
+        @authors ||= collect_authors
+      end
+
+      def commits_count
+        @commits_count ||= repo.commit_count(ref)
+      end
+
+      def files_count
+        args = [ref, '-r', '--name-only' ]
+        repo.git.run(nil, 'ls-tree', nil, {}, args).split("\n").count
+      end
+
+      def authors_count
+        authors.size
+      end
+
+      def graph
+        @graph ||= build_graph
+      end
+
+      protected
+
+      def collect_authors
+        shortlog = repo.git.shortlog({e: true, s: true }, ref)
+
+        authors = []
+
+        lines = shortlog.split("\n")
+
+        lines.each do |line|
+          data = line.split("\t")
+          commits = data.first
+          author = Grit::Actor.from_string(data.last)
+
+          authors << OpenStruct.new(
+            name: author.name,
+            email: author.email,
+            commits: commits.to_i
+          )
+        end
+
+        authors.sort_by(&:commits).reverse
+      end
+
+      def build_graph n = 4
+        from, to = (Date.today - n.weeks), Date.today
+        args = ['--all', "--since=#{from.to_s(:date)}", '--format=%ad' ]
+        rev_list = repo.git.run(nil, 'rev-list', nil, {}, args).split("\n")
+
+        commits_dates = rev_list.values_at(* rev_list.each_index.select {|i| i.odd?})
+        commits_dates = commits_dates.map { |date_str| Time.parse(date_str).to_date.to_s(:date) }
+
+        commits_per_day = from.upto(to).map do |day|
+          commits_dates.count(day.to_date.to_s(:date))
+        end
+
+        OpenStruct.new(
+          labels: from.upto(to).map { |day| day.stamp('Aug 23') },
+          commits: commits_per_day,
+          weeks: n
+        )
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
new file mode 100644
index 00000000000..e6b500ba18c
--- /dev/null
+++ b/lib/gitlab/git/tree.rb
@@ -0,0 +1,52 @@
+module Gitlab
+  module Git
+    class Tree
+      attr_accessor :repository, :sha, :path, :ref, :raw_tree, :id
+
+      def initialize(repository, sha, ref = nil, path = nil)
+        @repository, @sha, @ref, @path = repository, sha, ref, path
+
+        @path = nil if @path.blank?
+
+        # Load tree from repository
+        @commit = @repository.commit(@sha)
+        @raw_tree = @repository.tree(@commit, @path)
+      end
+
+      def exists?
+        raw_tree
+      end
+
+      def empty?
+        data.blank?
+      end
+
+      def trees
+        entries.select { |t| t.is_a?(Grit::Tree) }
+      end
+
+      def blobs
+        entries.select { |t| t.is_a?(Grit::Blob) }
+      end
+
+      def is_blob?
+        raw_tree.is_a?(Grit::Blob)
+      end
+
+      def up_dir?
+        path.present?
+      end
+
+      def readme
+        @readme ||= blobs.find { |c| c.name =~ /^readme/i }
+      end
+
+      protected
+
+      def entries
+        raw_tree.contents
+      end
+    end
+  end
+end
+
diff --git a/lib/gitlab/git_stats.rb b/lib/gitlab/git_stats.rb
deleted file mode 100644
index 855bffb5dde..00000000000
--- a/lib/gitlab/git_stats.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-module Gitlab
-  class GitStats
-    attr_accessor :repo, :ref
-
-    def initialize repo, ref
-      @repo, @ref = repo, ref
-    end
-
-    def authors
-      @authors ||= collect_authors
-    end
-
-    def commits_count
-      @commits_count ||= repo.commit_count(ref)
-    end
-
-    def files_count
-      args = [ref, '-r', '--name-only' ]
-      repo.git.run(nil, 'ls-tree', nil, {}, args).split("\n").count
-    end
-
-    def authors_count
-      authors.size
-    end
-
-    def graph
-      @graph ||= build_graph
-    end
-
-    protected
-
-    def collect_authors
-      shortlog = repo.git.shortlog({e: true, s: true }, ref)
-
-      authors = []
-
-      lines = shortlog.split("\n")
-
-      lines.each do |line|
-        data = line.split("\t")
-        commits = data.first
-        author = Grit::Actor.from_string(data.last)
-
-        authors << OpenStruct.new(
-          name: author.name,
-          email: author.email,
-          commits: commits.to_i
-        )
-      end
-
-      authors.sort_by(&:commits).reverse
-    end
-
-    def build_graph n = 4
-      from, to = (Date.today - n.weeks), Date.today
-      args = ['--all', "--since=#{from.to_s(:date)}", '--format=%ad' ]
-      rev_list = repo.git.run(nil, 'rev-list', nil, {}, args).split("\n")
-
-      commits_dates = rev_list.values_at(* rev_list.each_index.select {|i| i.odd?})
-      commits_dates = commits_dates.map { |date_str| Time.parse(date_str).to_date.to_s(:date) }
-
-      commits_per_day = from.upto(to).map do |day|
-        commits_dates.count(day.to_date.to_s(:date))
-      end
-
-      OpenStruct.new(
-        labels: from.upto(to).map { |day| day.stamp('Aug 23') },
-        commits: commits_per_day,
-        weeks: n
-      )
-    end
-  end
-end
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index 762eb372980..ad6ba3e8fd6 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -187,7 +187,7 @@ module Gitlab
 
     def reference_commit(identifier)
       if @project.valid_repo? && commit = @project.repository.commit(identifier)
-        link_to(identifier, project_commit_url(@project, commit), html_options.merge(title: CommitDecorator.new(commit).link_title, class: "gfm gfm-commit #{html_options[:class]}"))
+        link_to(identifier, project_commit_url(@project, commit), html_options.merge(title: commit.link_title, class: "gfm gfm-commit #{html_options[:class]}"))
       end
     end
   end
diff --git a/lib/gitlab/user_team_manager.rb b/lib/gitlab/user_team_manager.rb
index 4127d5e1bd8..ad6b655a2ee 100644
--- a/lib/gitlab/user_team_manager.rb
+++ b/lib/gitlab/user_team_manager.rb
@@ -64,7 +64,7 @@ module Gitlab
 
       def rebuild_project_permissions_to_member(team, member)
         team.projects.each do |project|
-          update_team_user_access_in_project(team, member, project)
+          update_team_user_access_in_project(team, member, project, :updated)
         end
       end
 
diff --git a/lib/gitolited.rb b/lib/gitolited.rb
deleted file mode 100644
index a7fc4148106..00000000000
--- a/lib/gitolited.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# == Gitolited mixin
-#
-# Provide a shortcut to Gitlab::Shell instance by gitlab_shell
-#
-# Used by Project, UsersProject, etc
-#
-module Gitolited
-  def gitlab_shell
-    Gitlab::Shell.new
-  end
-end
diff --git a/lib/tasks/cache.rake b/lib/tasks/cache.rake
new file mode 100644
index 00000000000..8320b9b2576
--- /dev/null
+++ b/lib/tasks/cache.rake
@@ -0,0 +1,6 @@
+namespace :cache do
+  desc "GITLAB | Clear redis cache"
+  task :clear => :environment do
+    Rails.cache.clear
+  end
+end
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index 32acdcf56b5..f98aa54503d 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -9,6 +9,7 @@ namespace :gitlab do
 
       Rake::Task["gitlab:backup:db:create"].invoke
       Rake::Task["gitlab:backup:repo:create"].invoke
+      Rake::Task["gitlab:backup:uploads:create"].invoke
 
       Dir.chdir(Gitlab.config.backup.path)
 
@@ -25,7 +26,7 @@ namespace :gitlab do
 
       # create archive
       print "Creating backup archive: #{Time.now.to_i}_gitlab_backup.tar ... "
-      if Kernel.system("tar -cf #{Time.now.to_i}_gitlab_backup.tar repositories/ db/ backup_information.yml")
+      if Kernel.system("tar -cf #{Time.now.to_i}_gitlab_backup.tar repositories/ db/ uploads/ backup_information.yml")
         puts "done".green
       else
         puts "failed".red
@@ -33,7 +34,7 @@ namespace :gitlab do
 
       # cleanup: remove tmp files
       print "Deleting tmp directories ... "
-      if Kernel.system("rm -rf repositories/ db/ backup_information.yml")
+      if Kernel.system("rm -rf repositories/ db/ uploads/ backup_information.yml")
         puts "done".green
       else
         puts "failed".red
@@ -99,116 +100,58 @@ namespace :gitlab do
 
       Rake::Task["gitlab:backup:db:restore"].invoke
       Rake::Task["gitlab:backup:repo:restore"].invoke
+      Rake::Task["gitlab:backup:uploads:restore"].invoke
+      Rake::Task["gitlab:shell:setup"].invoke
 
       # cleanup: remove tmp files
       print "Deleting tmp directories ... "
-      if Kernel.system("rm -rf repositories/ db/ backup_information.yml")
+      if Kernel.system("rm -rf repositories/ db/ uploads/ backup_information.yml")
         puts "done".green
       else
         puts "failed".red
       end
     end
 
-    ################################################################################
-    ################################# invoked tasks ################################
-
-    ################################# REPOSITORIES #################################
-
     namespace :repo do
       task :create => :environment do
-        backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
-        FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
         puts "Dumping repositories ...".blue
-
-        Project.find_each(:batch_size => 1000) do |project|
-          print " * #{project.path_with_namespace} ... "
-
-          if project.empty_repo?
-            puts "[SKIPPED]".cyan
-            next
-          end
-
-          # Create namespace dir if missing
-          FileUtils.mkdir_p(File.join(backup_path_repo, project.namespace.path)) if project.namespace
-
-          # Build a destination path for backup
-          path_to_bundle  = File.join(backup_path_repo, project.path_with_namespace + ".bundle")
-
-          if Kernel.system("cd #{project.repository.path_to_repo} > /dev/null 2>&1 && git bundle create #{path_to_bundle} --all > /dev/null 2>&1")
-            puts "[DONE]".green
-          else
-            puts "[FAILED]".red
-          end
-        end
+        Backup::Repository.new.dump
+        puts "done".green
       end
 
       task :restore => :environment do
-        backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
-        repos_path = Gitlab.config.gitlab_shell.repos_path
-
-        puts "Restoring repositories ... "
-
-        Project.find_each(:batch_size => 1000) do |project|
-          print "#{project.path_with_namespace} ... "
-
-          if project.namespace
-            project.namespace.ensure_dir_exist
-          end
-
-          # Build a backup path
-          path_to_bundle  = File.join(backup_path_repo, project.path_with_namespace + ".bundle")
-
-          if Kernel.system("git clone --bare #{path_to_bundle} #{project.repository.path_to_repo} > /dev/null 2>&1")
-            puts "[DONE]".green
-          else
-            puts "[FAILED]".red
-          end
-        end
+        puts "Restoring repositories ...".blue
+        Backup::Repository.new.restore
+        puts "done".green
       end
     end
 
-    ###################################### DB ######################################
-
     namespace :db do
       task :create => :environment do
-        backup_path_db = File.join(Gitlab.config.backup.path, "db")
-        FileUtils.mkdir_p(backup_path_db) unless Dir.exists?(backup_path_db)
-
-        puts "Dumping database tables ... ".blue
-        ActiveRecord::Base.connection.tables.each do |tbl|
-          print " * #{tbl.yellow} ... "
-          count = 1
-          safe_tablename = ActiveRecord::Base.connection.quote_table_name(tbl)
-          File.open(File.join(backup_path_db, tbl + ".yml"), "w+") do |file|
-            ActiveRecord::Base.connection.select_all("SELECT * FROM #{safe_tablename}").each do |line|
-              line.delete_if{|k,v| v.blank?}
-              output = {tbl + '_' + count.to_s => line}
-              file << output.to_yaml.gsub(/^---\n/,'') + "\n"
-              count += 1
-            end
-            puts "done".green
-          end
-        end
+        puts "Dumping database ... ".blue
+        Backup::Database.new.dump
+        puts "done".green
       end
 
       task :restore => :environment do
-        backup_path_db = File.join(Gitlab.config.backup.path, "db")
-
-        puts "Restoring database tables (loading fixtures) ... "
-        Rake::Task["db:reset"].invoke
-
-        Dir.glob(File.join(backup_path_db, "*.yml") ).each do |dir|
-          fixture_file = File.basename(dir, ".*" )
-          print "#{fixture_file.yellow} ... "
-          if File.size(dir) > 0
-            ActiveRecord::Fixtures.create_fixtures(backup_path_db, fixture_file)
-            puts "done".green
-          else
-            puts "skipping".yellow
-          end
-        end
+        puts "Restoring database ... ".blue
+        Backup::Database.new.restore
+        puts "done".green
       end
     end
 
+    namespace :uploads do
+      task :create => :environment do
+        puts "Dumping uploads ... ".blue
+        Backup::Uploads.new.dump
+        puts "done".green
+      end
+
+      task :restore => :environment do
+        puts "Restoring uploads ... ".blue
+        Backup::Uploads.new.restore
+        puts "done".green
+      end
+    end
   end # namespace end: backup
 end # namespace end: gitlab
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 855227fb34f..94599ae880b 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -23,6 +23,7 @@ namespace :gitlab do
       check_init_script_exists
       check_init_script_up_to_date
       check_satellites_exist
+      check_redis_version
 
       finished_checking "GitLab"
     end
@@ -245,6 +246,23 @@ namespace :gitlab do
         fix_and_rerun
       end
     end
+
+    def check_redis_version
+      print "Redis version >= 2.0.0? ... "
+
+      if run_and_match("redis-cli --version", /redis-cli 2.\d.\d/)
+        puts "yes".green
+      else
+        puts "no".red
+        try_fixing_it(
+          "Update your redis server to a version >= 2.0.0"
+        )
+        for_more_information(
+          "gitlab-public-wiki/wiki/Trouble-Shooting-Guide in section sidekiq"
+        )
+        fix_and_rerun
+      end
+    end
   end
 
 
@@ -637,10 +655,10 @@ namespace :gitlab do
 
   def check_gitlab_shell
     print "GitLab Shell version? ... "
-    if gitlab_shell_version.strip == '1.1.0'
-      puts 'OK (1.1.0)'.green
+    if gitlab_shell_version.strip == '1.3.0'
+      puts 'OK (1.3.0)'.green
     else
-      puts 'FAIL. Please update gitlab-shell to v1.1.0'.red
+      puts 'FAIL. Please update gitlab-shell to v1.3.0'.red
     end
   end
 end
diff --git a/lib/tasks/gitlab/migrate_wiki.rake b/lib/tasks/gitlab/migrate_wiki.rake
deleted file mode 100644
index 5d9881e45db..00000000000
--- a/lib/tasks/gitlab/migrate_wiki.rake
+++ /dev/null
@@ -1,42 +0,0 @@
-namespace :gitlab do
-  namespace :wiki do
-
-    # This task will migrate all of the existing Wiki
-    # content stored in your database into the new
-    # Gollum Wiki system. A new repository named
-    # namespace/project.wiki.git will be created for
-    # each project that currently has Wiki pages in
-    # the database.
-    #
-    # Notes:
-    #  * The existing Wiki content will remain in your
-    #    database in-tact.
-    desc "GITLAB | Migrate Wiki content from database to Gollum repositories."
-    task :migrate => :environment do
-      wiki_migrator = WikiToGollumMigrator.new
-      wiki_migrator.migrate!
-    end
-
-    # This task will destroy all of the Wiki repos
-    # that the Wiki migration task created. Run this
-    # to clean up your environment if you experienced
-    # problems during the original migration. After
-    # executing this task, you can attempt the original
-    # migration again.
-    #
-    # Notes:
-    #  * This will not affect Wikis that have been created
-    #    as Gollum Wikis only. It will only remove the wikis
-    #    for the repositories that have old Wiki data in the
-    #    dataabase.
-    #  * If you have any repositories already named
-    #    namespace/project.wiki that you do not wish
-    #    to be removed you may want to perform a manual
-    #    cleanup instead.
-    desc "GITLAB | Remove the Wiki repositories created by the `gitlab:wiki:migrate` task."
-    task :rollback => :environment do
-      wiki_migrator = WikiToGollumMigrator.new
-      wiki_migrator.rollback!
-    end
-  end
-end
diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake
index cfab3670fb2..34a4a322c11 100644
--- a/lib/tasks/gitlab/task_helpers.rake
+++ b/lib/tasks/gitlab/task_helpers.rake
@@ -16,7 +16,7 @@ namespace :gitlab do
   # Check which OS is running
   #
   # It will primarily use lsb_relase to determine the OS.
-  # It has fallbacks to Debian, SuSE and OS X.
+  # It has fallbacks to Debian, SuSE, OS X and systems running systemd.
   def os_name
     os_name = run("lsb_release -irs")
     os_name ||= if File.readable?('/etc/system-release')
@@ -32,6 +32,9 @@ namespace :gitlab do
     os_name ||= if os_x_version = run("sw_vers -productVersion")
                   "Mac OS X #{os_x_version}"
                 end
+    os_name ||= if File.readable?('/etc/os-release')
+                  File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1]
+                end
     os_name.try(:squish!)
   end
 
diff --git a/lib/tasks/migrate/migrate_milestones.rake b/lib/tasks/migrate/migrate_milestones.rake
new file mode 100644
index 00000000000..14c70a3d1c7
--- /dev/null
+++ b/lib/tasks/migrate/migrate_milestones.rake
@@ -0,0 +1,4 @@
+desc "GITLAB | Migrate Milestones"
+task migrate_milestones: :environment do
+  Milestone.where(state: nil).update_all(state: 'active')
+end
diff --git a/lib/tasks/migrate/migrate_mr.rake b/lib/tasks/migrate/migrate_mr.rake
new file mode 100644
index 00000000000..74b1db03442
--- /dev/null
+++ b/lib/tasks/migrate/migrate_mr.rake
@@ -0,0 +1,18 @@
+# This taks will reload commits/diff for all merge requests
+desc "GITLAB | Migrate Merge Requests"
+task migrate_merge_requests: :environment do
+  puts "Since 5.1 old merge request serialization logic was replaced with a better one."
+  puts "It makes old merge request diff invalid for GitLab 5.1+"
+  puts "* * *"
+  puts "This will rebuild commits/diffs info for existing merge requests."
+  puts "You will lose merge request diff if its already merged."
+  ask_to_continue
+
+  MergeRequest.find_each(batch_size: 20) do |mr|
+    mr.st_commits = []
+    mr.save
+    mr.reload_code
+    print '.'
+  end
+end
+
diff --git a/lib/wiki_to_gollum_migrator.rb b/lib/wiki_to_gollum_migrator.rb
deleted file mode 100644
index ed6a1700631..00000000000
--- a/lib/wiki_to_gollum_migrator.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-class WikiToGollumMigrator
-
-  attr_reader :projects
-
-  def initialize
-    @projects = []
-
-    Project.find_in_batches(batch_size: 50) do |batch|
-      batch.each { |p| @projects << p if p.wikis.any? }
-    end
-  end
-
-  def migrate!
-    projects.each do |project|
-      log "\nMigrating Wiki for '#{project.path_with_namespace}'"
-      wiki = create_gollum_repo(project)
-      create_pages project, wiki
-      log "Project '#{project.path_with_namespace}' migrated. " + "[OK]".green
-    end
-  end
-
-  def rollback!
-    log "\nBeginning Wiki Migration Rollback..."
-    projects.each do |project|
-      destroy_gollum_repo project
-    end
-    log "\nWiki Rollback Complete."
-  end
-
-  private
-
-  def create_gollum_repo(project)
-    GollumWiki.new(project, nil).wiki
-  end
-
-  def destroy_gollum_repo(project)
-    log "  Removing Wiki repo for project: #{project.path_with_namespace}"
-    path = GollumWiki.new(project, nil).path_with_namespace
-    if Gitlab::Shell.new.remove_repository(path)
-      log "  Wiki destroyed successfully. " + "[OK}".green
-    else
-      log "  Problem destroying wiki. Please remove it manually. " + "[FAILED]".red
-    end
-  end
-
-  def create_pages(project, wiki)
-    pages = project.wikis.group(:slug).all
-
-    pages.each do |page|
-      create_page_and_revisions(project, page)
-    end
-  end
-
-  def create_page_and_revisions(project, page)
-    # Grab all revisions of the page
-    revisions = project.wikis.where(slug: page.slug).ordered.all
-
-    # Remove the first revision created from the array
-    # and use it to create the Gollum page. Each successive revision
-    # will then be applied to the new Gollum page as an update.
-    first_rev = revisions.pop
-
-    wiki = GollumWiki.new(project, page.user)
-    wiki_page = WikiPage.new(wiki)
-
-    attributes = extract_attributes_from_page(first_rev, project)
-
-    log "  Creating page '#{first_rev.title}'..."
-    if wiki_page.create(attributes)
-      log "  Created page '#{wiki_page.title}' " + "[OK]".green
-
-      # Reverse the revisions to create them in the correct
-      # chronological order.
-      create_revisions(project, wiki_page, revisions.reverse)
-    else
-      log "  Failed to create page '#{wiki_page.title}' " + "[FAILED]".red
-    end
-  end
-
-  def create_revisions(project, page, revisions)
-    log "    Creating revisions..."
-    revisions.each do |revision|
-      # Reinitialize a new GollumWiki instance for each page
-      # and revision created so the correct User is shown in
-      # the commit message.
-      wiki = GollumWiki.new(project, revision.user)
-      wiki_page = wiki.find_page(page.slug)
-
-      attributes = extract_attributes_from_page(revision, project)
-
-      content = attributes[:content]
-
-      if wiki_page.update(content)
-        log "    Created revision " + "[OK]".green
-      else
-        log "    Failed to create revision " + "[FAILED]".red
-      end
-    end
-  end
-
-  def extract_attributes_from_page(page, project)
-    attributes = page.attributes
-                     .with_indifferent_access
-                     .slice(:title, :content)
-
-    slug = page.slug
-
-    # Change 'index' pages to 'home' pages to match Gollum standards
-    if slug.downcase == "index"
-      attributes[:title] = "home" unless home_already_exists?(project)
-    end
-
-    attributes
-  end
-
-  def home_already_exists?(project)
-    project.wikis.where(slug: 'home').any? || project.wikis.where(slug: 'Home').any?
-  end
-
-  def log(message)
-    puts message
-  end
-
-end
diff --git a/spec/controllers/blob_controller_spec.rb b/spec/controllers/blob_controller_spec.rb
new file mode 100644
index 00000000000..fe113459470
--- /dev/null
+++ b/spec/controllers/blob_controller_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+
+describe BlobController do
+  let(:project) { create(:project_with_code) }
+  let(:user)    { create(:user) }
+
+  before do
+    sign_in(user)
+
+    project.team << [user, :master]
+
+    project.stub(:branches).and_return(['master', 'foo/bar/baz'])
+    project.stub(:tags).and_return(['v1.0.0', 'v2.0.0'])
+    controller.instance_variable_set(:@project, project)
+  end
+
+  describe "GET show" do
+    render_views
+
+    before { get :show, project_id: project.code, id: id }
+
+    context "valid branch, valid file" do
+      let(:id) { 'master/README.md' }
+      it { should respond_with(:success) }
+    end
+
+    context "valid branch, invalid file" do
+      let(:id) { 'master/invalid-path.rb' }
+      it { should respond_with(:not_found) }
+    end
+
+    context "invalid branch, valid file" do
+      let(:id) { 'invalid-branch/README.md' }
+      it { should respond_with(:not_found) }
+    end
+  end
+end
diff --git a/spec/controllers/commit_controller_spec.rb b/spec/controllers/commit_controller_spec.rb
index 7bf13822829..5fffbf0e5f3 100644
--- a/spec/controllers/commit_controller_spec.rb
+++ b/spec/controllers/commit_controller_spec.rb
@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe CommitController do
-  let(:project) { create(:project) }
+  let(:project) { create(:project_with_code) }
   let(:user)    { create(:user) }
   let(:commit)  { project.repository.last_commit_for("master") }
 
diff --git a/spec/controllers/commits_controller_spec.rb b/spec/controllers/commits_controller_spec.rb
index 99cbcd13d56..ce4029173a5 100644
--- a/spec/controllers/commits_controller_spec.rb
+++ b/spec/controllers/commits_controller_spec.rb
@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe CommitsController do
-  let(:project) { create(:project) }
+  let(:project) { create(:project_with_code) }
   let(:user)    { create(:user) }
 
   before do
diff --git a/spec/controllers/merge_requests_controller_spec.rb b/spec/controllers/merge_requests_controller_spec.rb
index 37e36efc1ca..796de23bfe3 100644
--- a/spec/controllers/merge_requests_controller_spec.rb
+++ b/spec/controllers/merge_requests_controller_spec.rb
@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe MergeRequestsController do
-  let(:project) { create(:project) }
+  let(:project) { create(:project_with_code) }
   let(:user)    { create(:user) }
   let(:merge_request) { create(:merge_request_with_diffs, project: project, target_branch: "bcf03b5d~3", source_branch: "bcf03b5d") }
 
@@ -12,7 +12,7 @@ describe MergeRequestsController do
   end
 
   describe "#show" do
-    shared_examples "export as" do |format|
+    shared_examples "export merge as" do |format|
       it "should generally work" do
         get :show, project_id: project.code, id: merge_request.id, format: format
 
@@ -44,7 +44,7 @@ describe MergeRequestsController do
     end
 
     describe "as diff" do
-      include_examples "export as", :diff
+      include_examples "export merge as", :diff
       let(:format) { :diff }
 
       it "should really only be a git diff" do
@@ -55,7 +55,7 @@ describe MergeRequestsController do
     end
 
     describe "as patch" do
-      include_examples "export as", :patch
+      include_examples "export merge as", :patch
       let(:format) { :patch }
 
       it "should really be a git email patch with commit" do
diff --git a/spec/controllers/tree_controller_spec.rb b/spec/controllers/tree_controller_spec.rb
index 81c7656d07a..f9fe4fe2010 100644
--- a/spec/controllers/tree_controller_spec.rb
+++ b/spec/controllers/tree_controller_spec.rb
@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe TreeController do
-  let(:project) { create(:project) }
+  let(:project) { create(:project_with_code) }
   let(:user)    { create(:user) }
 
   before do
@@ -26,17 +26,17 @@ describe TreeController do
     end
 
     context "valid branch, valid path" do
-      let(:id) { 'master/README.md' }
+      let(:id) { 'master/app/' }
       it { should respond_with(:success) }
     end
 
     context "valid branch, invalid path" do
-      let(:id) { 'master/invalid-path.rb' }
+      let(:id) { 'master/invalid-path/' }
       it { should respond_with(:not_found) }
     end
 
     context "invalid branch, valid path" do
-      let(:id) { 'invalid-branch/README.md' }
+      let(:id) { 'invalid-branch/app/' }
       it { should respond_with(:not_found) }
     end
   end
diff --git a/spec/factories.rb b/spec/factories.rb
index 41766859468..8f323161990 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -34,6 +34,10 @@ FactoryGirl.define do
     issues_tracker_id { "project_name_in_redmine" }
   end
 
+  factory :project_with_code, parent: :project do
+    path { 'gitlabhq' }
+  end
+
   factory :group do
     sequence(:name) { |n| "group#{n}" }
     path { name.downcase.gsub(/\s/, '_') }
@@ -73,7 +77,7 @@ FactoryGirl.define do
   factory :merge_request do
     title
     author
-    project
+    project factory: :project_with_code
     source_branch "master"
     target_branch "stable"
 
@@ -82,9 +86,11 @@ FactoryGirl.define do
       target_branch "master" # pretend bcf03b5d~3
       source_branch "stable" # pretend bcf03b5d
       st_commits do
-        [Commit.new(project.repo.commit('bcf03b5d')),
-         Commit.new(project.repo.commit('bcf03b5d~1')),
-         Commit.new(project.repo.commit('bcf03b5d~2'))]
+        [
+          project.repository.commit('bcf03b5d').to_hash,
+          project.repository.commit('bcf03b5d~1').to_hash,
+          project.repository.commit('bcf03b5d~2').to_hash
+        ]
       end
       st_diffs do
         project.repo.diff("bcf03b5d~3", "bcf03b5d")
@@ -116,6 +122,7 @@ FactoryGirl.define do
     factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff]
 
     trait :on_commit do
+      project factory: :project_with_code
       commit_id     "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
       noteable_type "Commit"
     end
@@ -125,6 +132,7 @@ FactoryGirl.define do
     end
 
     trait :on_merge_request do
+      project factory: :project_with_code
       noteable_id   1
       noteable_type "MergeRequest"
     end
@@ -190,12 +198,6 @@ FactoryGirl.define do
     url
   end
 
-  factory :wiki do
-    title
-    content
-    user
-  end
-
   factory :snippet do
     project
     author
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index bc0586b2712..102a1b928f5 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -12,7 +12,7 @@ describe "Admin::Hooks" do
   describe "GET /admin/hooks" do
     it "should be ok" do
       visit admin_root_path
-      within ".main_menu" do
+      within ".main-nav" do
         click_on "Hooks"
       end
       current_path.should == admin_hooks_path
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index c9ddf1f4534..23370891244 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -31,46 +31,4 @@ describe "Admin::Projects" do
       page.should have_content(@project.name)
     end
   end
-
-  describe "GET /admin/projects/:id/edit" do
-    before do
-      visit admin_projects_path
-      click_link "edit_project_#{@project.id}"
-    end
-
-    it "should have project edit page" do
-      page.should have_content("Edit project")
-      page.should have_button("Save Project")
-    end
-
-    describe "Update project" do
-      before do
-        fill_in "project_name", with: "Big Bang"
-        click_button "Save Project"
-        @project.reload
-      end
-
-      it "should show page with  new data" do
-        page.should have_content("Big Bang")
-      end
-
-      it "should change project entry" do
-        @project.name.should == "Big Bang"
-      end
-    end
-  end
-
-  describe "Add new team member" do
-    before do
-      @new_user = create(:user)
-      visit admin_project_path(@project)
-    end
-
-    it "should create new user" do
-      select @new_user.name, from: "user_ids"
-      expect { click_button "Add" }.to change { UsersProject.count }.by(1)
-      page.should have_content @new_user.name
-      current_path.should == admin_project_path(@project)
-    end
-  end
 end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 22d1ee91480..a6cf5299791 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -30,11 +30,11 @@ describe "Admin::Users" do
     end
 
     it "should create new user" do
-      expect { click_button "Save" }.to change {User.count}.by(1)
+      expect { click_button "Create user" }.to change {User.count}.by(1)
     end
 
     it "should create user with valid data" do
-      click_button "Save"
+      click_button "Create user"
       user = User.last
       user.name.should ==  "Big Bang"
       user.email.should == "bigbang@mail.com"
@@ -44,14 +44,14 @@ describe "Admin::Users" do
       Notify.should_receive(:new_user_email)
 
       User.observers.enable :user_observer do
-        click_button "Save"
+        click_button "Create user"
       end
     end
 
     it "should send valid email to user with email & password" do
       Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
       User.observers.enable :user_observer do
-        click_button "Save"
+        click_button "Create user"
         user = User.last
         email = ActionMailer::Base.deliveries.last
         email.subject.should have_content("Account was created")
@@ -63,7 +63,7 @@ describe "Admin::Users" do
     it "should send valid email to user with email without password when signup is enabled" do
       Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
       User.observers.enable :user_observer do
-        click_button "Save"
+        click_button "Create user"
         user = User.last
         email = ActionMailer::Base.deliveries.last
         email.subject.should have_content("Account was created")
@@ -102,7 +102,7 @@ describe "Admin::Users" do
         fill_in "user_name", with: "Big Bang"
         fill_in "user_email", with: "bigbang@mail.com"
         check "user_admin"
-        click_button "Save"
+        click_button "Save changes"
       end
 
       it "should show page with  new data" do
diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb
index a57e34ac5d2..aa72bcee005 100644
--- a/spec/features/gitlab_flavored_markdown_spec.rb
+++ b/spec/features/gitlab_flavored_markdown_spec.rb
@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe "Gitlab Flavored Markdown" do
-  let(:project) { create(:project) }
+  let(:project) { create(:project_with_code) }
   let(:issue) { create(:issue, project: project) }
   let(:merge_request) { create(:merge_request, project: project) }
   let(:fred) do
@@ -11,29 +11,10 @@ describe "Gitlab Flavored Markdown" do
   end
 
   before do
-    # add test branch
-    @branch_name = "gfm-test"
-    r = project.repo
-    i = r.index
-    # add test file
-    @test_file = "gfm_test_file"
-    i.add(@test_file, "foo\nbar\n")
-    # add commit with gfm
-    i.commit("fix ##{issue.id}\n\nask @#{fred.username} for details", head: @branch_name)
-
-    # add test tag
-    @tag_name = "gfm-test-tag"
-    r.git.native(:tag, {}, @tag_name, commit.id)
+    Commit.any_instance.stub(title: "fix ##{issue.id}\n\nask @#{fred.username} for details")
   end
 
-  after do
-    # delete test branch and tag
-    project.repo.git.native(:branch, {D: true}, @branch_name)
-    project.repo.git.native(:tag, {d: true}, @tag_name)
-    project.repo.gc_auto
-  end
-
-  let(:commit) { project.repository.commits(@branch_name).first }
+  let(:commit) { project.repository.commit }
 
   before do
     login_as :user
@@ -42,7 +23,7 @@ describe "Gitlab Flavored Markdown" do
 
   describe "for commits" do
     it "should render title in commits#index" do
-      visit project_commits_path(project, @branch_name, limit: 1)
+      visit project_commits_path(project, 'master', limit: 1)
 
       page.should have_link("##{issue.id}")
     end
@@ -59,23 +40,6 @@ describe "Gitlab Flavored Markdown" do
       page.should have_link("@#{fred.username}")
     end
 
-    it "should render title in refs#tree", js: true do
-      visit project_tree_path(project, @branch_name)
-
-      within(".tree_commit") do
-        page.should have_link("##{issue.id}")
-      end
-    end
-
-    # @wip
-    #it "should render title in refs#blame" do
-      #visit project_blame_path(project, File.join(@branch_name, @test_file))
-
-      #within(".blame_commit") do
-        #page.should have_link("##{issue.id}")
-      #end
-    #end
-
     it "should render title in repositories#branches" do
       visit branches_project_repository_path(project)
 
@@ -164,37 +128,4 @@ describe "Gitlab Flavored Markdown" do
       page.should have_link("@#{fred.username}")
     end
   end
-
-
-  describe "for notes" do
-    it "should render in commits#show", js: true do
-      visit project_commit_path(project, commit)
-      within ".new_note.js-main-target-form" do
-        fill_in "note_note", with: "see ##{issue.id}"
-        click_button "Add Comment"
-      end
-
-      page.should have_link("##{issue.id}")
-    end
-
-    it "should render in issue#show", js: true do
-      visit project_issue_path(project, issue)
-      within ".new_note.js-main-target-form" do
-        fill_in "note_note", with: "see ##{issue.id}"
-        click_button "Add Comment"
-      end
-
-      page.should have_link("##{issue.id}")
-    end
-
-    it "should render in merge_request#show", js: true do
-      visit project_merge_request_path(project, merge_request)
-      within ".new_note.js-main-target-form" do
-        fill_in "note_note", with: "see ##{issue.id}"
-        click_button "Add Comment"
-      end
-
-      page.should have_link("##{issue.id}")
-    end
-  end
 end
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index 670762e8005..24f5437efff 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -1,7 +1,7 @@
 require 'spec_helper'
 
 describe "On a merge request", js: true do
-  let!(:project) { create(:project) }
+  let!(:project) { create(:project_with_code) }
   let!(:merge_request) { create(:merge_request, project: project) }
 
   before do
@@ -14,20 +14,11 @@ describe "On a merge request", js: true do
   subject { page }
 
   describe "the note form" do
-    # main target form creation
-    it { should have_css(".js-main-target-form", visible: true, count: 1) }
-
-    # button initalization
-    it { find(".js-main-target-form input[type=submit]").value.should == "Add Comment" }
-    it { within(".js-main-target-form") { should_not have_link("Cancel") } }
-
-    # notifiactions
-    it { within(".js-main-target-form") { should have_unchecked_field("Notify team via email") } }
-    it { within(".js-main-target-form") { should_not have_checked_field("Notify commit author") } }
-    it { within(".js-main-target-form") { should_not have_unchecked_field("Notify commit author") } }
-
-    describe "without text" do
-      it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } }
+    it 'should be valid' do
+      should have_css(".js-main-target-form", visible: true, count: 1)
+      find(".js-main-target-form input[type=submit]").value.should == "Add Comment"
+      within(".js-main-target-form") { should_not have_link("Cancel") }
+      within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) }
     end
 
     describe "with text" do
@@ -37,9 +28,10 @@ describe "On a merge request", js: true do
         end
       end
 
-      it { within(".js-main-target-form") { should_not have_css(".js-comment-button[disabled]") } }
-
-      it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: true) } }
+      it 'should have enable submit button and preview button' do
+        within(".js-main-target-form") { should_not have_css(".js-comment-button[disabled]") }
+        within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: true) }
+      end
     end
 
     describe "with preview" do
@@ -50,10 +42,11 @@ describe "On a merge request", js: true do
         end
       end
 
-      it { within(".js-main-target-form") { should have_css(".js-note-preview", text: "This is awesome", visible: true) } }
-
-      it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } }
-      it { within(".js-main-target-form") { should have_css(".js-note-edit-button", visible: true) } }
+      it 'should have text and visible edit button' do
+        within(".js-main-target-form") { should have_css(".js-note-preview", text: "This is awesome", visible: true) }
+        within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) }
+        within(".js-main-target-form") { should have_css(".js-note-edit-button", visible: true) }
+      end
     end
   end
 
@@ -66,73 +59,57 @@ describe "On a merge request", js: true do
       end
     end
 
-    # note added
-    it { should have_content("This is awsome!") }
-
-    # reset form
-    it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!")  } }
-
-    # return from preview
-    it { within(".js-main-target-form") { should have_css(".js-note-preview", visible: false) } }
-    it { within(".js-main-target-form") { should have_css(".js-note-text", visible: true) } }
-
+    it 'should be added and form reset' do
+      should have_content("This is awsome!")
+      within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!")  }
+      within(".js-main-target-form") { should have_css(".js-note-preview", visible: false) }
+      within(".js-main-target-form") { should have_css(".js-note-text", visible: true) }
+    end
 
     it "should be removable" do
-      find(".js-note-delete").trigger("click")
-
+      find('.note').hover
+      find(".js-note-delete").click
       should_not have_css(".note")
     end
   end
 end
 
-
-
 describe "On a merge request diff", js: true, focus: true do
-  let!(:project) { create(:project) }
+  let!(:project) { create(:project_with_code) }
   let!(:merge_request) { create(:merge_request_with_diffs, project: project) }
 
   before do
     login_as :user
     project.team << [@user, :master]
-
     visit diffs_project_merge_request_path(project, merge_request)
-
-    within '.diffs-tab' do
-      click_link("Diff")
-    end
   end
 
   subject { page }
 
   describe "when adding a note" do
     before do
-      find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button").trigger("click")
+      find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
     end
 
     describe "the notes holder" do
-      it { should have_css("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder") }
+      it { should have_css(".js-temp-notes-holder") }
 
       it { within(".js-temp-notes-holder") { should have_css(".new_note") } }
     end
 
     describe "the note form" do
-      # set up hidden fields correctly
-      it { within(".js-temp-notes-holder") { find("#note_noteable_type").value.should == "MergeRequest" } }
-      it { within(".js-temp-notes-holder") { find("#note_noteable_id").value.should == merge_request.id.to_s } }
-      it { within(".js-temp-notes-holder") { find("#note_commit_id").value.should == "" } }
-      it { within(".js-temp-notes-holder") { find("#note_line_code").value.should == "4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185" } }
-
-      # buttons
-      it { should have_button("Add Comment") }
-      it { should have_css(".js-close-discussion-note-form", text: "Cancel") }
-
-      # notification options
-      it { should have_unchecked_field("Notify team via email") }
+      it 'should be valid' do
+        within(".js-temp-notes-holder") { find("#note_noteable_type").value.should == "MergeRequest" }
+        within(".js-temp-notes-holder") { find("#note_noteable_id").value.should == merge_request.id.to_s }
+        within(".js-temp-notes-holder") { find("#note_commit_id").value.should == "" }
+        within(".js-temp-notes-holder") { find("#note_line_code").value.should == "4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185" }
+        should have_css(".js-close-discussion-note-form", text: "Cancel")
+      end
 
       it "shouldn't add a second form for same row" do
-        find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button").trigger("click")
+        find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
 
-        should have_css("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder form", count: 1)
+        should have_css("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185'] + .js-temp-notes-holder form", count: 1)
       end
 
       it "should be removed when canceled" do
@@ -147,87 +124,95 @@ describe "On a merge request diff", js: true, focus: true do
 
   describe "with muliple note forms" do
     before do
-      find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button").trigger("click")
-      find("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder .js-add-diff-note-button").trigger("click")
+      find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
+      find('a[data-line-code="342e16cbbd482ac2047dc679b2749d248cc1428f_18_17"]').click
     end
 
-    # has two line forms
     it { should have_css(".js-temp-notes-holder", count: 2) }
 
     describe "previewing them separately" do
       before do
         # add two separate texts and trigger previews on both
-        within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder") do
+        within("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185'] + .js-temp-notes-holder") do
           fill_in "note[note]", with: "One comment on line 185"
           find(".js-note-preview-button").trigger("click")
         end
-        within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") do
+        within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
           fill_in "note[note]", with: "Another comment on line 17"
           find(".js-note-preview-button").trigger("click")
         end
       end
 
-      # check if previews were rendered separately
-      it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder") { should have_css(".js-note-preview", text: "One comment on line 185") } }
-      it { within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") { should have_css(".js-note-preview", text: "Another comment on line 17") } }
+      # TODO: fix
+      #it 'should check if previews were rendered separately' do
+        #within("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185'] + .js-temp-notes-holder") do
+          #should have_css(".js-note-preview", text: "One comment on line 185")
+        #end
+
+        #within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
+          #should have_css(".js-note-preview", text: "Another comment on line 17")
+        #end
+      #end
     end
 
     describe "posting a note" do
       before do
-        within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") do
+        within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
           fill_in "note[note]", with: "Another comment on line 17"
           click_button("Add Comment")
         end
       end
 
-      # removed form after submit
-      it { should have_no_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") }
-
-      # added discussion
-      it { should have_content("Another comment on line 17") }
-      it { should have_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .notes_holder") }
-      it { should have_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .notes_holder .note", count: 1) }
-      it { should have_link("Reply") }
-
-      it "should remove last note of a discussion" do
-        within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .notes_holder") do
-          find(".js-note-delete").trigger("click")
+      it do
+        within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
+          should have_no_css(".js-temp-notes-holder")
         end
-
-        # removed whole discussion
-        should_not have_css(".note_holder")
-        should have_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + #342e16cbbd482ac2047dc679b2749d248cc1428f_18_18.line_holder")
       end
-    end
-  end
 
-  describe "when replying to a note" do
-    before do
-      # create first note
-      find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder .js-add-diff-note-button").trigger("click")
-      within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .js-temp-notes-holder") do
-        fill_in "note[note]", with: "One comment on line 184"
-        click_button("Add Comment")
+      it 'should be added as discussion' do
+        should have_content("Another comment on line 17")
+        should have_css(".notes_holder")
+        should have_css(".notes_holder .note", count: 1)
+        should have_link("Reply")
       end
-      # create second note
-      within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") do
-        find(".js-discussion-reply-button").trigger("click")
-        fill_in "note[note]", with: "An additional comment in reply"
-        click_button("Add Comment")
-      end
-    end
 
-    # inserted note
-    it { should have_content("An additional comment in reply") }
-    it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") { should have_css(".note", count: 2) } }
+      # TODO: fix
+      #it "should remove last note of a discussion" do
+        #within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .notes-holder") do
+          #find(".js-note-delete").click
+        #end
 
-    # removed form after reply
-    it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") { should have_no_css("form") } }
-    it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") { should have_link("Reply") } }
+        #should_not have_css(".note_holder")
+      #end
+    end
   end
-end
-
 
+  # TODO: fix
+  #describe "when replying to a note" do
+    #before do
+      ## create first note
+      #find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184"]').click
+
+      #within(".js-temp-notes-holder") do
+        #fill_in "note[note]", with: "One comment on line 184"
+        #click_button("Add Comment")
+      #end
+
+      #within(".js-temp-notes-holder") do
+        #find(".js-discussion-reply-button").click
+        #fill_in "note[note]", with: "An additional comment in reply"
+        #click_button("Add Comment")
+      #end
+    #end
+
+    #it 'should be inserted and form removed from reply' do
+      #should have_content("An additional comment in reply")
+      #within(".notes_holder") { should have_css(".note", count: 2) }
+      #within(".notes_holder") { should have_no_css("form") }
+      #within(".notes_holder") { should have_link("Reply") }
+    #end
+  #end
+end
 
 describe "On merge request discussion", js: true do
   describe "with merge request diff note"
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index c18d8f921a3..d46882d4e42 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -1,6 +1,7 @@
 require 'spec_helper'
 
 describe "Profile account page" do
+  before(:each) { enable_observers }
   let(:user) { create(:user) }
 
   before do
@@ -12,8 +13,9 @@ describe "Profile account page" do
       Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
       visit account_profile_path
     end
+
     it { page.should have_content("Remove account") }
-    
+
     it "should delete the account", js: true do
       expect { click_link "Delete account" }.to change {User.count}.by(-1)
       current_path.should == new_user_session_path
@@ -45,4 +47,4 @@ describe "Profile account page" do
       current_path.should == account_profile_path
     end
   end
-end
\ No newline at end of file
+end
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 1ffc28bfa4e..f0a1f75e1e0 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -1,6 +1,7 @@
 require 'spec_helper'
 
 describe "Projects" do
+  before(:each) { enable_observers }
   before { login_as :user }
 
   describe "DELETE /projects/:id" do
diff --git a/spec/features/security/project_access_spec.rb b/spec/features/security/project_access_spec.rb
index b89844013c3..cfbb8f135ab 100644
--- a/spec/features/security/project_access_spec.rb
+++ b/spec/features/security/project_access_spec.rb
@@ -14,7 +14,7 @@ describe "Application access" do
   end
 
   describe "Project" do
-    let(:project)  { create(:project) }
+    let(:project)  { create(:project_with_code) }
 
     let(:master)   { create(:user) }
     let(:guest)    { create(:user) }
@@ -33,7 +33,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -44,7 +44,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -55,7 +55,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -66,7 +66,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -77,7 +77,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -88,7 +88,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -99,7 +99,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -114,7 +114,7 @@ describe "Application access" do
 
       it { @blob_path.should be_allowed_for master }
       it { @blob_path.should be_allowed_for reporter }
-      it { @blob_path.should be_denied_for :admin }
+      it { @blob_path.should be_allowed_for :admin }
       it { @blob_path.should be_denied_for guest }
       it { @blob_path.should be_denied_for :user }
       it { @blob_path.should be_denied_for :visitor }
@@ -125,7 +125,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_denied_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -136,7 +136,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_denied_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -147,7 +147,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -158,7 +158,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -169,7 +169,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -180,7 +180,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -196,7 +196,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -212,7 +212,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
@@ -223,7 +223,7 @@ describe "Application access" do
 
       it { should be_allowed_for master }
       it { should be_allowed_for reporter }
-      it { should be_denied_for :admin }
+      it { should be_allowed_for :admin }
       it { should be_denied_for guest }
       it { should be_denied_for :user }
       it { should be_denied_for :visitor }
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index b9025026c1b..4140ba484f0 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -4,10 +4,10 @@ describe GitlabMarkdownHelper do
   include ApplicationHelper
   include IssuesHelper
 
-  let!(:project) { create(:project) }
+  let!(:project) { create(:project_with_code) }
 
   let(:user)          { create(:user, username: 'gfm') }
-  let(:commit)        { CommitDecorator.decorate(project.repository.commit) }
+  let(:commit)        { project.repository.commit }
   let(:issue)         { create(:issue, project: project) }
   let(:merge_request) { create(:merge_request, project: project) }
   let(:snippet)       { create(:snippet, project: project) }
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index c9eb6591561..a1f23073582 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -76,4 +76,31 @@ describe IssuesHelper do
       url_for_issue(issue.id).should eq ""
     end
   end
+
+  describe :url_for_new_issue do
+    let(:issues_url) { Gitlab.config.issues_tracker.redmine.new_issue_url}
+    let(:ext_expected) do
+      issues_url.gsub(':project_id', ext_project.id.to_s)
+        .gsub(':issues_tracker_id', ext_project.issues_tracker_id.to_s)
+    end
+    let(:int_expected) { new_project_issue_path(project) }
+
+    it "should return internal path if used internal tracker" do
+      @project = project
+      url_for_new_issue.should match(int_expected)
+    end
+
+    it "should return path to external tracker" do
+      @project = ext_project
+
+      url_for_new_issue.should match(ext_expected)
+    end
+
+    it "should return empty string if project nil" do
+      @project = nil
+
+      url_for_new_issue.should eq ""
+    end
+  end
+
 end
diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb
new file mode 100644
index 00000000000..f97959ee8f4
--- /dev/null
+++ b/spec/helpers/notifications_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the NotificationsHelper. For example:
+#
+# describe NotificationsHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe NotificationsHelper do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index ee20ae79809..aac72c63ea5 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -54,47 +54,5 @@ describe ExtractsPath do
         extract_ref('stable/CHANGELOG').should == ['stable', 'CHANGELOG']
       end
     end
-
-    context "with a fullpath" do
-      it "extracts a valid branch" do
-        extract_ref('/gitlab/gitlab-ci/tree/foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', 'CHANGELOG']
-      end
-
-      it "extracts a valid tag" do
-        extract_ref('/gitlab/gitlab-ci/tree/v2.0.0/CHANGELOG').should == ['v2.0.0', 'CHANGELOG']
-      end
-
-      it "extracts a valid commit SHA" do
-        extract_ref('/gitlab/gitlab-ci/tree/f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should ==
-          ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
-      end
-
-      it "extracts a timestamp" do
-        extract_ref('/gitlab/gitlab-ci/tree/v2.0.0/CHANGELOG?_=12354435').should == ['v2.0.0', 'CHANGELOG']
-      end
-    end
-
-    context "with a fullpath and a relative_url_root" do
-      before do
-        Gitlab.config.gitlab.stub(relative_url_root: '/relative')
-      end
-
-      it "extracts a valid branch with relative_url_root" do
-        extract_ref('/relative/gitlab/gitlab-ci/tree/foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', 'CHANGELOG']
-      end
-
-      it "extracts a valid tag" do
-        extract_ref('/relative/gitlab/gitlab-ci/tree/v2.0.0/CHANGELOG').should == ['v2.0.0', 'CHANGELOG']
-      end
-
-      it "extracts a valid commit SHA" do
-        extract_ref('/relative/gitlab/gitlab-ci/tree/f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should ==
-          ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
-      end
-
-      it "extracts a timestamp" do
-        extract_ref('/relative/gitlab/gitlab-ci/tree/v2.0.0/CHANGELOG?_=12354435').should == ['v2.0.0', 'CHANGELOG']
-      end
-    end
   end
 end
diff --git a/spec/lib/shell_spec.rb b/spec/lib/gitlab/backend/shell_spec.rb
similarity index 100%
rename from spec/lib/shell_spec.rb
rename to spec/lib/gitlab/backend/shell_spec.rb
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
new file mode 100644
index 00000000000..bf2cd98eba1
--- /dev/null
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -0,0 +1,40 @@
+require "spec_helper"
+
+describe Gitlab::Git::Commit do
+  let(:commit) { create(:project_with_code).repository.commit }
+
+  describe "Commit info" do
+    before do
+      @committer = double(
+        email: 'mike@smith.com',
+        name: 'Mike Smith'
+      )
+
+      @author = double(
+        email: 'john@smith.com',
+        name: 'John Smith'
+      )
+
+      @raw_commit = double(
+        id: "bcf03b5de6abcf03b5de6c",
+        author: @author,
+        committer: @committer,
+        committed_date: Date.yesterday,
+        authored_date: Date.yesterday,
+        parents: [],
+        message: 'Refactoring specs'
+      )
+
+      @commit = Gitlab::Git::Commit.new(@raw_commit)
+    end
+
+    it { @commit.short_id.should == "bcf03b5de6a" }
+    it { @commit.safe_message.should == @raw_commit.message }
+    it { @commit.created_at.should == @raw_commit.committed_date }
+    it { @commit.author_email.should == @author.email }
+    it { @commit.author_name.should == @author.name }
+    it { @commit.committer_name.should == @committer.name }
+    it { @commit.committer_email.should == @committer.email }
+    it { @commit.different_committer?.should be_true }
+  end
+end
diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb
new file mode 100644
index 00000000000..5191b1190a6
--- /dev/null
+++ b/spec/lib/gitlab/git/diff_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+
+describe Gitlab::Git::Diff do
+  before do
+    @raw_diff_hash = {
+      diff: 'Hello world',
+      new_path: 'temp.rb',
+      old_path: 'test.rb',
+      a_mode: '100644',
+      b_mode: '100644',
+      new_file: false,
+      renamed_file: true,
+      deleted_file: false,
+    }
+
+    @grit_diff = double('Grit::Diff', @raw_diff_hash)
+  end
+
+  context 'init from grit' do
+    before do
+      @diff = Gitlab::Git::Diff.new(@raw_diff_hash)
+    end
+
+    it { @diff.to_hash.should == @raw_diff_hash }
+  end
+
+  context 'init from hash' do
+    before do
+      @diff = Gitlab::Git::Diff.new(@grit_diff)
+    end
+
+    it { @diff.to_hash.should == @raw_diff_hash }
+  end
+end
diff --git a/spec/models/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
similarity index 78%
rename from spec/models/repository_spec.rb
rename to spec/lib/gitlab/git/repository_spec.rb
index 71f9b964e70..2b0550aa72a 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -1,8 +1,7 @@
 require "spec_helper"
 
-describe Repository do
-  let(:project) { create(:project) }
-  let(:repository) { project.repository }
+describe Gitlab::Git::Repository do
+  let(:repository) { Gitlab::Git::Repository.new('gitlabhq', 'master') }
 
   describe "Respond to" do
     subject { repository }
@@ -15,8 +14,6 @@ describe Repository do
     it { should respond_to(:commits) }
     it { should respond_to(:commits_between) }
     it { should respond_to(:commits_with_refs) }
-    it { should respond_to(:commits_since) }
-    it { should respond_to(:commits_between) }
   end
 
 
@@ -85,10 +82,15 @@ describe Repository do
     end
   end
 
-  describe "fresh commits" do
-    it { repository.fresh_commits(3).count.should == 3 }
-    it { repository.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
-    it { repository.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
+  describe "commits" do
+    subject do
+      commits = repository.commits('master', 'app', 3, 1)
+      commits.map { |c| c.id }
+    end
+
+    it { should have(3).elements }
+    it { should include("8716fc78f3c65bbf7bcf7b574febd583bc5d2812") }
+    it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
   end
 
   describe "commits_between" do
@@ -102,4 +104,20 @@ describe Repository do
     it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
     it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
   end
+
+  describe "branch names" do
+    subject { repository.branch_names }
+
+    it { should have(32).elements }
+    it { should include("master") }
+    it { should_not include("branch-from-space") }
+  end
+
+  describe "tag names" do
+    subject { repository.tag_names }
+
+    it { should have(16).elements }
+    it { should include("v1.2.0") }
+    it { should_not include("v5.0.0") }
+  end
 end
diff --git a/spec/lib/gitlab/git/stats_spec.rb b/spec/lib/gitlab/git/stats_spec.rb
new file mode 100644
index 00000000000..96b04f17e91
--- /dev/null
+++ b/spec/lib/gitlab/git/stats_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+
+describe Gitlab::Git::Stats do
+  let(:repository) { Gitlab::Git::Repository.new('gitlabhq', 'master') }
+
+  before do
+    @stats = Gitlab::Git::Stats.new(repository.raw, 'master')
+  end
+
+  describe :authors do
+    let(:author) { @stats.authors.first }
+
+    it { author.name.should == 'Dmitriy Zaporozhets' }
+    it { author.email.should == 'dmitriy.zaporozhets@gmail.com' }
+    it { author.commits.should == 254 }
+  end
+
+  describe :graph do
+    let(:graph) { @stats.graph }
+
+    it { graph.labels.should include Date.today.stamp('Aug 23') }
+    it { graph.commits.should be_kind_of(Array) }
+    it { graph.weeks.should == 4 }
+  end
+
+  it { @stats.commits_count.should == 918 }
+  it { @stats.files_count.should == 550 }
+end
diff --git a/spec/lib/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb
similarity index 100%
rename from spec/lib/popen_spec.rb
rename to spec/lib/gitlab/popen_spec.rb
diff --git a/spec/lib/votes_spec.rb b/spec/lib/votes_spec.rb
index b49ed15b5c3..a3c353d5eab 100644
--- a/spec/lib/votes_spec.rb
+++ b/spec/lib/votes_spec.rb
@@ -1,132 +1,136 @@
 require 'spec_helper'
 
-describe MergeRequest do
-  let(:merge_request) { FactoryGirl.create(:merge_request_with_diffs) }
+describe Issue, 'Votes' do
+  let(:issue) { create(:issue) }
 
   describe "#upvotes" do
     it "with no notes has a 0/0 score" do
-      merge_request.upvotes.should == 0
+      issue.upvotes.should == 0
     end
 
     it "should recognize non-+1 notes" do
-      merge_request.notes << create(:note, note: "No +1 here")
-      merge_request.should have(1).note
-      merge_request.notes.first.upvote?.should be_false
-      merge_request.upvotes.should == 0
+      add_note "No +1 here"
+      issue.should have(1).note
+      issue.notes.first.upvote?.should be_false
+      issue.upvotes.should == 0
     end
 
     it "should recognize a single +1 note" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.upvotes.should == 1
+      add_note "+1 This is awesome"
+      issue.upvotes.should == 1
     end
 
     it "should recognize multiple +1 notes" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.notes << create(:note, note: "+1 I want this")
-      merge_request.upvotes.should == 2
+      add_note "+1 This is awesome"
+      add_note "+1 I want this"
+      issue.upvotes.should == 2
     end
   end
 
   describe "#downvotes" do
     it "with no notes has a 0/0 score" do
-      merge_request.downvotes.should == 0
+      issue.downvotes.should == 0
     end
 
     it "should recognize non--1 notes" do
-      merge_request.notes << create(:note, note: "Almost got a -1")
-      merge_request.should have(1).note
-      merge_request.notes.first.downvote?.should be_false
-      merge_request.downvotes.should == 0
+      add_note "Almost got a -1"
+      issue.should have(1).note
+      issue.notes.first.downvote?.should be_false
+      issue.downvotes.should == 0
     end
 
     it "should recognize a single -1 note" do
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.downvotes.should == 1
+      add_note "-1 This is bad"
+      issue.downvotes.should == 1
     end
 
     it "should recognize multiple -1 notes" do
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.notes << create(:note, note: "-1 Away with this")
-      merge_request.downvotes.should == 2
+      add_note "-1 This is bad"
+      add_note "-1 Away with this"
+      issue.downvotes.should == 2
     end
   end
 
   describe "#votes_count" do
     it "with no notes has a 0/0 score" do
-      merge_request.votes_count.should == 0
+      issue.votes_count.should == 0
     end
 
     it "should recognize non notes" do
-      merge_request.notes << create(:note, note: "No +1 here")
-      merge_request.should have(1).note
-      merge_request.votes_count.should == 0
+      add_note "No +1 here"
+      issue.should have(1).note
+      issue.votes_count.should == 0
     end
 
     it "should recognize a single +1 note" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.votes_count.should == 1
+      add_note "+1 This is awesome"
+      issue.votes_count.should == 1
     end
 
     it "should recognize a single -1 note" do
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.votes_count.should == 1
+      add_note "-1 This is bad"
+      issue.votes_count.should == 1
     end
 
     it "should recognize multiple notes" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.notes << create(:note, note: "+1 I want this")
-      merge_request.votes_count.should == 3
+      add_note "+1 This is awesome"
+      add_note "-1 This is bad"
+      add_note "+1 I want this"
+      issue.votes_count.should == 3
     end
   end
 
   describe "#upvotes_in_percent" do
     it "with no notes has a 0% score" do
-      merge_request.upvotes_in_percent.should == 0
+      issue.upvotes_in_percent.should == 0
     end
 
     it "should count a single 1 note as 100%" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.upvotes_in_percent.should == 100
+      add_note "+1 This is awesome"
+      issue.upvotes_in_percent.should == 100
     end
 
     it "should count multiple +1 notes as 100%" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.notes << create(:note, note: "+1 I want this")
-      merge_request.upvotes_in_percent.should == 100
+      add_note "+1 This is awesome"
+      add_note "+1 I want this"
+      issue.upvotes_in_percent.should == 100
     end
 
     it "should count fractions for multiple +1 and -1 notes correctly" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.notes << create(:note, note: "+1 I want this")
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.notes << create(:note, note: "+1 me too")
-      merge_request.upvotes_in_percent.should == 75
+      add_note "+1 This is awesome"
+      add_note "+1 I want this"
+      add_note "-1 This is bad"
+      add_note "+1 me too"
+      issue.upvotes_in_percent.should == 75
     end
   end
 
   describe "#downvotes_in_percent" do
     it "with no notes has a 0% score" do
-      merge_request.downvotes_in_percent.should == 0
+      issue.downvotes_in_percent.should == 0
     end
 
     it "should count a single -1 note as 100%" do
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.downvotes_in_percent.should == 100
+      add_note "-1 This is bad"
+      issue.downvotes_in_percent.should == 100
     end
 
     it "should count multiple -1 notes as 100%" do
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.notes << create(:note, note: "-1 Away with this")
-      merge_request.downvotes_in_percent.should == 100
+      add_note "-1 This is bad"
+      add_note "-1 Away with this"
+      issue.downvotes_in_percent.should == 100
     end
 
     it "should count fractions for multiple +1 and -1 notes correctly" do
-      merge_request.notes << create(:note, note: "+1 This is awesome")
-      merge_request.notes << create(:note, note: "+1 I want this")
-      merge_request.notes << create(:note, note: "-1 This is bad")
-      merge_request.notes << create(:note, note: "+1 me too")
-      merge_request.downvotes_in_percent.should == 25
+      add_note "+1 This is awesome"
+      add_note "+1 I want this"
+      add_note "-1 This is bad"
+      add_note "+1 me too"
+      issue.downvotes_in_percent.should == 25
     end
   end
+
+  def add_note(text)
+    issue.notes << create(:note, note: text, project: issue.project)
+  end
 end
diff --git a/spec/lib/wiki_to_gollum_migrator_spec.rb b/spec/lib/wiki_to_gollum_migrator_spec.rb
deleted file mode 100644
index f9b9c78ea01..00000000000
--- a/spec/lib/wiki_to_gollum_migrator_spec.rb
+++ /dev/null
@@ -1,219 +0,0 @@
-require "spec_helper"
-
-describe WikiToGollumMigrator do
-
-  def create_wiki_for(project)
-    3.times { @pages[project.id] << create_page(project) }
-  end
-
-  def create_revisions_for(project)
-    @pages[project.id].each do |page|
-      create_revision(page)
-    end
-  end
-
-  def create_page(project)
-    page = project.wikis.new(title: "Page #{rand(1000)}", content: "Content")
-    page.user = project.owner
-    page.slug = page.title.parameterize
-    page.save!
-    page
-  end
-
-  def create_revision(page)
-    revision = page.dup
-    revision.content = "Updated Content"
-    revision.save!
-  end
-
-  def create_temp_repo(path)
-    FileUtils.mkdir_p path
-    command = "git init --quiet --bare #{path};"
-    system(command)
-  end
-
-  before do
-    @repo_path = "#{Rails.root}/tmp/test-git-base-path"
-    @projects = []
-    @pages = Hash.new {|h,k| h[k] = Array.new }
-
-    @projects << create(:project)
-    @projects << create(:project)
-
-    @projects.each do |project|
-      create_wiki_for project
-      create_revisions_for project
-    end
-
-    @project_without_wiki = create(:project)
-  end
-
-  context "Before the migration" do
-    it "has two projects with valid wikis" do
-      @projects.each do |project|
-        pages = project.wikis.group(:slug).all
-        pages.count.should == 3
-      end
-    end
-
-    it "has two revision for each page" do
-      @projects.each do |project|
-        @pages[project.id].each do |page|
-          revisions = project.wikis.where(slug: page.slug)
-          revisions.count.should == 2
-        end
-      end
-    end
-  end
-
-  describe "#initialize" do
-    it "finds all projects that have existing wiki pages" do
-      Project.count.should == 3
-      subject.projects.count.should == 2
-    end
-  end
-
-  context "#migrate!" do
-    before do
-      Gitlab::Shell.any_instance.stub(:add_repository) do |path|
-        create_temp_repo("#{@repo_path}/#{path}.git")
-      end
-
-      subject.stub(:log).as_null_object
-
-      subject.migrate!
-    end
-
-    it "creates a new Gollum Wiki for each project" do
-      @projects.each do |project|
-        wiki_path = project.path_with_namespace + ".wiki.git"
-        full_path = @repo_path + "/" + wiki_path
-        File.exist?(full_path).should be_true
-        File.directory?(full_path).should be_true
-      end
-    end
-
-    it "creates a gollum page for each unique Wiki page" do
-      @projects.each do |project|
-        wiki = GollumWiki.new(project, nil)
-        wiki.pages.count.should == 3
-      end
-    end
-
-    it "creates a new revision for each old revision of the page" do
-      @projects.each do |project|
-        wiki = GollumWiki.new(project, nil)
-        wiki.pages.each do |page|
-          page.versions.count.should == 2
-        end
-      end
-    end
-
-    context "wikis with pages that have titles that do not match the slugs" do
-      before do
-        project = @projects.last
-        @page = project.wikis.new(title: "test page", content: "Invalid Page")
-        @page.slug = "totally-incorrect-slug"
-        @page.user = project.owner
-        @page.save!
-
-        create_revision(@page)
-
-        subject.rollback!
-        subject.migrate!
-      end
-
-      it "has a page with a title differing the slug" do
-        @page.slug.should_not == @page.title.parameterize
-      end
-
-      it "creates a new revision for each old revision of the page" do
-        @projects.each do |project|
-          wiki = GollumWiki.new(project, nil)
-          wiki.pages.each do |page|
-            page.versions.count.should == 2
-          end
-        end
-      end
-    end
-
-    context "changing wiki title from index to home" do
-      before do
-        @project = @projects.last
-        @page = @project.wikis.new(title: "Index", content: "Home Page")
-        @page.slug = "index"
-        @page.user = @project.owner
-        @page.save!
-
-        create_revision(@page)
-
-        subject.rollback!
-      end
-
-      it "creates a page called Home" do
-        subject.migrate!
-        wiki = GollumWiki.new(@project, nil)
-        page = wiki.find_page("home")
-        page.should be_present
-      end
-
-      context "when a page called Home already exists" do
-        before do
-        @index_page = @project.wikis.new(title: "Index", content: "Index Page")
-        @index_page.slug = "index"
-        @index_page.user = @project.owner
-        @index_page.save!
-
-        create_revision(@index_page)
-
-        @home_page = @project.wikis.new(title: "Home", content: "Home Page")
-        @home_page.slug = "home"
-        @home_page.user = @project.owner
-        @home_page.save!
-
-        create_revision(@home_page)
-        subject.migrate!
-        end
-
-        it "creates the index page" do
-          wiki = GollumWiki.new(@project, nil)
-          page = wiki.find_page("index")
-          page.should be_present
-        end
-
-        it "creates the home page" do
-          wiki = GollumWiki.new(@project, nil)
-          page = wiki.find_page("home")
-          page.should be_present
-        end
-      end
-    end
-  end
-
-  context "#rollback!" do
-    before do
-      Gitlab::Shell.any_instance.stub(:add_repository) do |path|
-        create_temp_repo("#{@repo_path}/#{path}.git")
-      end
-
-      Gitlab::Shell.any_instance.stub(:remove_repository) do |path|
-        FileUtils.rm_rf "#{@repo_path}/#{path}.git"
-      end
-
-      subject.stub(:log).as_null_object
-
-      subject.migrate!
-      subject.rollback!
-    end
-
-    it "destroys all of the wiki repositories that were created during migrate!" do
-      @projects.each do |project|
-        wiki_path = project.path_with_namespace + ".wiki.git"
-        full_path = @repo_path + "/" + wiki_path
-        File.exist?(full_path).should be_false
-      end
-    end
-  end
-
-
-end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 7867c4dd78e..84ce7e86d27 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -5,7 +5,7 @@ describe Notify do
   include EmailSpec::Matchers
 
   let(:recipient) { create(:user, email: 'recipient@example.com') }
-  let(:project) { create(:project) }
+  let(:project) { create(:project_with_code) }
 
   shared_examples 'a multiple recipients email' do
     it 'is sent to the given recipient' do
@@ -107,7 +107,7 @@ describe Notify do
         let(:issue) { create(:issue, assignee: assignee, project: project ) }
 
         describe 'that are new' do
-          subject { Notify.new_issue_email(issue.id) }
+          subject { Notify.new_issue_email(issue.assignee_id, issue.id) }
 
           it_behaves_like 'an assignee email'
 
@@ -172,7 +172,7 @@ describe Notify do
         let(:merge_request) { create(:merge_request, assignee: assignee, project: project) }
 
         describe 'that are new' do
-          subject { Notify.new_merge_request_email(merge_request.id) }
+          subject { Notify.new_merge_request_email(merge_request.assignee_id, merge_request.id) }
 
           it_behaves_like 'an assignee email'
 
@@ -277,14 +277,7 @@ describe Notify do
       end
 
       describe 'on a commit' do
-        let(:commit) do
-          mock(:commit).tap do |commit|
-            commit.stub(:id).and_return('fauxsha1')
-            commit.stub(:project).and_return(project)
-            commit.stub(:short_id).and_return('fauxsha1')
-            commit.stub(:safe_message).and_return('some message')
-          end
-        end
+        let(:commit) { project.repository.commit }
 
         before(:each) { note.stub(:noteable).and_return(commit) }
 
@@ -297,7 +290,7 @@ describe Notify do
         end
 
         it 'contains a link to the commit' do
-          should have_body_text /fauxsha1/
+          should have_body_text commit.short_id
         end
       end
 
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index 91301029e89..ad99d8a390b 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -1,83 +1,35 @@
 require 'spec_helper'
 
 describe Commit do
-  let(:commit) { create(:project).repository.commit }
+  let(:commit) { create(:project_with_code).repository.commit }
 
-  describe CommitDecorator do
-    let(:decorator) { CommitDecorator.new(commit) }
 
-    describe '#title' do
-      it "returns no_commit_message when safe_message is blank" do
-        decorator.stub(:safe_message).and_return('')
-        decorator.title.should == "--no commit message"
-      end
-
-      it "truncates a message without a newline at 70 characters" do
-        message = commit.safe_message * 10
-
-        decorator.stub(:safe_message).and_return(message)
-        decorator.title.should == "#{message[0..69]}&hellip;"
-      end
-
-      it "truncates a message with a newline before 80 characters at the newline" do
-        message = commit.safe_message.split(" ").first
-
-        decorator.stub(:safe_message).and_return(message + "\n" + message)
-        decorator.title.should == message
-      end
-
-      it "truncates a message with a newline after 80 characters at 70 characters" do
-        message = (commit.safe_message * 10) + "\n"
-
-        decorator.stub(:safe_message).and_return(message)
-        decorator.title.should == "#{message[0..69]}&hellip;"
-      end
+  describe '#title' do
+    it "returns no_commit_message when safe_message is blank" do
+      commit.stub(:safe_message).and_return('')
+      commit.title.should == "--no commit message"
     end
-  end
 
-  describe "Commit info" do
-    before do
-      @committer = double(
-        email: 'mike@smith.com',
-        name: 'Mike Smith'
-      )
+    it "truncates a message without a newline at 70 characters" do
+      message = commit.safe_message * 10
 
-      @author = double(
-        email: 'john@smith.com',
-        name: 'John Smith'
-      )
+      commit.stub(:safe_message).and_return(message)
+      commit.title.should == "#{message[0..69]}&hellip;"
+    end
 
-      @raw_commit = double(
-        id: "bcf03b5de6abcf03b5de6c",
-        author: @author,
-        committer: @committer,
-        committed_date: Date.yesterday,
-        message: 'Refactoring specs'
-      )
+    it "truncates a message with a newline before 80 characters at the newline" do
+      message = commit.safe_message.split(" ").first
 
-      @commit = Commit.new(@raw_commit)
+      commit.stub(:safe_message).and_return(message + "\n" + message)
+      commit.title.should == message
     end
 
-    it { @commit.short_id.should == "bcf03b5de6a" }
-    it { @commit.safe_message.should == @raw_commit.message }
-    it { @commit.created_at.should == @raw_commit.committed_date }
-    it { @commit.author_email.should == @author.email }
-    it { @commit.author_name.should == @author.name }
-    it { @commit.committer_name.should == @committer.name }
-    it { @commit.committer_email.should == @committer.email }
-    it { @commit.different_committer?.should be_true }
-  end
+    it "truncates a message with a newline after 80 characters at 70 characters" do
+      message = (commit.safe_message * 10) + "\n"
 
-  describe "Class methods" do
-    subject { Commit }
-
-    it { should respond_to(:find_or_first) }
-    it { should respond_to(:fresh_commits) }
-    it { should respond_to(:commits_with_refs) }
-    it { should respond_to(:commits_since) }
-    it { should respond_to(:commits_between) }
-    it { should respond_to(:commits) }
-    it { should respond_to(:compare) }
+      commit.stub(:safe_message).and_return(message)
+      commit.title.should == "#{message[0..69]}&hellip;"
+    end
   end
 
   describe "delegation" do
@@ -86,10 +38,10 @@ describe Commit do
     it { should respond_to(:message) }
     it { should respond_to(:authored_date) }
     it { should respond_to(:committed_date) }
+    it { should respond_to(:committer_email) }
+    it { should respond_to(:author_email) }
     it { should respond_to(:parents) }
     it { should respond_to(:date) }
-    it { should respond_to(:committer) }
-    it { should respond_to(:author) }
     it { should respond_to(:diffs) }
     it { should respond_to(:tree) }
     it { should respond_to(:id) }
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index cc78993905f..85bdf08ae64 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -72,6 +72,7 @@ describe Event do
 
     before {
       Event.should_receive :create
+      observer.stub(notification: stub.as_null_object)
     }
 
     describe "Joined project team" do
diff --git a/spec/models/gollum_wiki_spec.rb b/spec/models/gollum_wiki_spec.rb
index 87601683275..aa850dfd0a3 100644
--- a/spec/models/gollum_wiki_spec.rb
+++ b/spec/models/gollum_wiki_spec.rb
@@ -81,7 +81,7 @@ describe GollumWiki do
     end
 
     it "raises CouldNotCreateWikiError if it can't create the wiki repository" do
-      Gitlab::Shell.any_instance.stub(:add_repository).and_return(false)
+      GollumWiki.any_instance.stub(:init_repo).and_return(false)
       expect { GollumWiki.new(project, user).wiki }.to raise_exception(GollumWiki::CouldNotCreateWikiError)
     end
   end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 412e42aa675..b40a07951eb 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -60,7 +60,7 @@ describe Namespace do
     end
 
     it "should raise error when dirtory exists" do
-      expect { @namespace.move_dir }.to raise_error("Already exists")
+      expect { @namespace.move_dir }.to raise_error("namespace directory cannot be moved")
     end
 
     it "should move dir if path changed" do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 9423c7de6ec..fedf17b1ba0 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -18,6 +18,8 @@
 #  public                 :boolean          default(FALSE), not null
 #  issues_tracker         :string(255)      default("gitlab"), not null
 #  issues_tracker_id      :string(255)
+#  snippets_enabled       :boolean          default(TRUE), not null
+#  last_activity_at       :datetime
 #
 
 require 'spec_helper'
@@ -37,7 +39,6 @@ describe Project do
     it { should have_many(:snippets).dependent(:destroy) }
     it { should have_many(:deploy_keys).dependent(:destroy) }
     it { should have_many(:hooks).dependent(:destroy) }
-    it { should have_many(:wikis).dependent(:destroy) }
     it { should have_many(:protected_branches).dependent(:destroy) }
   end
 
@@ -95,6 +96,7 @@ describe Project do
   end
 
   describe "last_activity methods" do
+    before { enable_observers }
     let(:project)    { create(:project) }
     let(:last_event) { double(created_at: Time.now) }
 
@@ -107,8 +109,8 @@ describe Project do
 
     describe 'last_activity_date' do
       it 'returns the creation date of the project\'s last event if present' do
-        project.stub(last_event: last_event)
-        project.last_activity_date.should == last_event.created_at
+        last_activity_event = create(:event, project: project)
+        project.last_activity_at.to_i.should == last_event.created_at.to_i
       end
 
       it 'returns the project\'s last update date if it has no events' do
@@ -118,7 +120,7 @@ describe Project do
   end
 
   describe :update_merge_requests do
-    let(:project) { create(:project) }
+    let(:project) { create(:project_with_code) }
 
     before do
       @merge_request = create(:merge_request, project: project)
@@ -188,10 +190,6 @@ describe Project do
     it "should return valid repo" do
       project.repository.should be_kind_of(Repository)
     end
-
-    it "should return nil" do
-      Project.new(path: "empty").repository.should be_nil
-    end
   end
 
   describe :issue_exists? do
@@ -232,7 +230,7 @@ describe Project do
 
     it "should be true for projects with external issues tracker if issues enabled" do
       ext_project.can_have_issues_tracker_id?.should be_true
-    end 
+    end
 
     it "should be false for projects with internal issue tracker if issues enabled" do
       project.can_have_issues_tracker_id?.should be_false
@@ -246,4 +244,15 @@ describe Project do
       ext_project.can_have_issues_tracker_id?.should be_false
     end
   end
+
+  describe :open_branches do
+    let(:project) { create(:project_with_code) }
+
+    before do
+      project.protected_branches.create(name: 'master')
+    end
+
+    it { project.open_branches.map(&:name).should include('bootstrap') }
+    it { project.open_branches.map(&:name).should_not include('master') }
+  end
 end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 7d061bf28b2..380bbe7351f 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -33,6 +33,7 @@
 #  can_create_team        :boolean          default(TRUE), not null
 #  state                  :string(255)
 #  color_scheme_id        :integer          default(1), not null
+#  notification_level     :integer          default(1), not null
 #
 
 require 'spec_helper'
@@ -119,7 +120,7 @@ describe User do
     end
 
     it { @user.several_namespaces?.should be_true }
-    it { @user.namespaces.should == [@user.namespace, @group] }
+    it { @user.namespaces.should include(@user.namespace, @group) }
     it { @user.authorized_groups.should == [@group] }
     it { @user.owned_groups.should == [@group] }
   end
@@ -154,8 +155,8 @@ describe User do
 
     it { User.filter("admins").should == [@admin] }
     it { User.filter("blocked").should == [@blocked] }
-    it { User.filter("wop").should == [@user, @admin, @blocked] }
-    it { User.filter(nil).should == [@user, @admin] }
+    it { User.filter("wop").should include(@user, @admin, @blocked) }
+    it { User.filter(nil).should include(@user, @admin) }
   end
 
   describe :not_in_project do
@@ -165,7 +166,7 @@ describe User do
       @project = create :project
     end
 
-    it { User.not_in_project(@project).should == [@user, @project.owner] }
+    it { User.not_in_project(@project).should include(@user, @project.owner) }
   end
 
   describe 'normal user' do
diff --git a/spec/models/user_team_spec.rb b/spec/models/user_team_spec.rb
index 6cc2003e97d..d330bbf3e33 100644
--- a/spec/models/user_team_spec.rb
+++ b/spec/models/user_team_spec.rb
@@ -14,5 +14,24 @@
 require 'spec_helper'
 
 describe UserTeam do
-  pending "add some examples to (or delete) #{__FILE__}"
+  let(:team) { FactoryGirl.create :user_team }
+
+  context ".add_member" do
+    let(:user) { FactoryGirl.create :user }
+
+    it "should work" do
+      team.add_member(user, UsersProject::DEVELOPER, false)
+      team.members.should include(user)
+    end
+  end
+
+  context ".remove_member" do
+    let(:user) { FactoryGirl.create :user }
+    before { team.add_member(user, UsersProject::DEVELOPER, false) }
+
+    it "should work" do
+      team.remove_member(user)
+      team.members.should_not include(user)
+    end
+  end
 end
diff --git a/spec/models/users_project_spec.rb b/spec/models/users_project_spec.rb
index e8f5b647ce0..e289a592b03 100644
--- a/spec/models/users_project_spec.rb
+++ b/spec/models/users_project_spec.rb
@@ -2,12 +2,13 @@
 #
 # Table name: users_projects
 #
-#  id             :integer          not null, primary key
-#  user_id        :integer          not null
-#  project_id     :integer          not null
-#  created_at     :datetime         not null
-#  updated_at     :datetime         not null
-#  project_access :integer          default(0), not null
+#  id                 :integer          not null, primary key
+#  user_id            :integer          not null
+#  project_id         :integer          not null
+#  created_at         :datetime         not null
+#  updated_at         :datetime         not null
+#  project_access     :integer          default(0), not null
+#  notification_level :integer          default(3), not null
 #
 
 require 'spec_helper'
diff --git a/spec/models/wiki_spec.rb b/spec/models/wiki_spec.rb
deleted file mode 100644
index 9750b81d303..00000000000
--- a/spec/models/wiki_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# == Schema Information
-#
-# Table name: wikis
-#
-#  id         :integer          not null, primary key
-#  title      :string(255)
-#  content    :text
-#  project_id :integer
-#  created_at :datetime         not null
-#  updated_at :datetime         not null
-#  slug       :string(255)
-#  user_id    :integer
-#
-
-require 'spec_helper'
-
-describe Wiki do
-  describe "Associations" do
-    it { should belong_to(:project) }
-    it { should belong_to(:user) }
-    it { should have_many(:notes).dependent(:destroy) }
-  end
-
-  describe "Mass assignment" do
-    it { should_not allow_mass_assignment_of(:project_id) }
-    it { should_not allow_mass_assignment_of(:user_id) }
-  end
-
-  describe "Validation" do
-    it { should validate_presence_of(:title) }
-    it { should ensure_length_of(:title).is_within(1..250) }
-    it { should validate_presence_of(:content) }
-    it { should validate_presence_of(:user) }
-  end
-end
diff --git a/spec/observers/issue_observer_spec.rb b/spec/observers/issue_observer_spec.rb
index e4e66917e8a..3cc621013d2 100644
--- a/spec/observers/issue_observer_spec.rb
+++ b/spec/observers/issue_observer_spec.rb
@@ -4,36 +4,18 @@ describe IssueObserver do
   let(:some_user)      { create :user }
   let(:assignee)       { create :user }
   let(:author)         { create :user }
-  let(:mock_issue)     { double(:issue, id: 42, assignee: assignee, author: author) }
-  let(:assigned_issue)   { create(:issue, assignee: assignee, author: author) }
-  let(:unassigned_issue) { create(:issue, author: author) }
-  let(:closed_assigned_issue)   { create(:closed_issue, assignee: assignee, author: author) }
-  let(:closed_unassigned_issue) { create(:closed_issue, author: author) }
+  let(:mock_issue)     { create(:issue, assignee: assignee, author: author) }
 
 
-  before(:each) { subject.stub(:current_user).and_return(some_user) }
+  before { subject.stub(:current_user).and_return(some_user) }
+  before { subject.stub(notification: mock('NotificationService').as_null_object) }
+
 
   subject { IssueObserver.instance }
 
   describe '#after_create' do
-
-    it 'is called when an issue is created' do
-      subject.should_receive(:after_create)
-
-      Issue.observers.enable :issue_observer do
-        create(:issue, project: create(:project))
-      end
-    end
-
-    it 'sends an email to the assignee' do
-      Notify.should_receive(:new_issue_email).with(mock_issue.id)
-
-      subject.after_create(mock_issue)
-    end
-
-    it 'does not send an email to the assignee if assignee created the issue' do
-      subject.stub(:current_user).and_return(assignee)
-      Notify.should_not_receive(:new_issue_email)
+    it 'trigger notification to send emails' do
+      subject.should_receive(:notification)
 
       subject.after_create(mock_issue)
     end
@@ -41,44 +23,28 @@ describe IssueObserver do
 
   context '#after_close' do
     context 'a status "closed"' do
-      it 'note is created if the issue is being closed' do
-        Note.should_receive(:create_status_change_note).with(assigned_issue, some_user, 'closed')
+      before { mock_issue.stub(state: 'closed') }
 
-        assigned_issue.close
-      end
-
-      it 'notification is delivered if the issue being closed' do
-        Notify.should_receive(:issue_status_changed_email).twice
+      it 'note is created if the issue is being closed' do
+        Note.should_receive(:create_status_change_note).with(mock_issue, some_user, 'closed')
 
-        assigned_issue.close
+        subject.after_close(mock_issue, nil)
       end
 
-      it 'notification is delivered only to author if the issue being closed' do
-        Notify.should_receive(:issue_status_changed_email).once
-        Note.should_receive(:create_status_change_note).with(unassigned_issue, some_user, 'closed')
+      it 'trigger notification to send emails' do
+        subject.notification.should_receive(:close_issue).with(mock_issue, some_user)
 
-        unassigned_issue.close
+        subject.after_close(mock_issue, nil)
       end
     end
 
     context 'a status "reopened"' do
-      it 'note is created if the issue is being reopened' do
-        Note.should_receive(:create_status_change_note).with(closed_assigned_issue, some_user, 'reopened')
-
-        closed_assigned_issue.reopen
-      end
+      before { mock_issue.stub(state: 'reopened') }
 
-      it 'notification is delivered if the issue being reopened' do
-        Notify.should_receive(:issue_status_changed_email).twice
-
-        closed_assigned_issue.reopen
-      end
-
-      it 'notification is delivered only to author if the issue being reopened' do
-        Notify.should_receive(:issue_status_changed_email).once
-        Note.should_receive(:create_status_change_note).with(closed_unassigned_issue, some_user, 'reopened')
+      it 'note is created if the issue is being reopened' do
+        Note.should_receive(:create_status_change_note).with(mock_issue, some_user, 'reopened')
 
-        closed_unassigned_issue.reopen
+        subject.after_reopen(mock_issue, nil)
       end
     end
   end
@@ -88,71 +54,20 @@ describe IssueObserver do
       mock_issue.stub(:is_being_reassigned?).and_return(false)
     end
 
-    it 'is called when an issue is changed' do
-      changed = create(:issue, project: create(:project))
-      subject.should_receive(:after_update)
-
-      Issue.observers.enable :issue_observer do
-        changed.description = 'I changed'
-        changed.save
-      end
-    end
-
-    context 'a reassigned email' do
-      it 'is sent if the issue is being reassigned' do
+    context 'notification' do
+      it 'triggered if the issue is being reassigned' do
         mock_issue.should_receive(:is_being_reassigned?).and_return(true)
-        subject.should_receive(:send_reassigned_email).with(mock_issue)
+        subject.should_receive(:notification)
 
         subject.after_update(mock_issue)
       end
 
-      it 'is not sent if the issue is not being reassigned' do
+      it 'is not triggered if the issue is not being reassigned' do
         mock_issue.should_receive(:is_being_reassigned?).and_return(false)
-        subject.should_not_receive(:send_reassigned_email)
+        subject.should_not_receive(:notification)
 
         subject.after_update(mock_issue)
       end
     end
   end
-
-  describe '#send_reassigned_email' do
-    let(:previous_assignee) { double(:user, id: 3) }
-
-    before(:each) do
-      mock_issue.stub(:assignee_id).and_return(assignee.id)
-      mock_issue.stub(:assignee_id_was).and_return(previous_assignee.id)
-    end
-
-    def it_sends_a_reassigned_email_to(recipient)
-      Notify.should_receive(:reassigned_issue_email).with(recipient, mock_issue.id, previous_assignee.id)
-    end
-
-    def it_does_not_send_a_reassigned_email_to(recipient)
-      Notify.should_not_receive(:reassigned_issue_email).with(recipient, mock_issue.id, previous_assignee.id)
-    end
-
-    it 'sends a reassigned email to the previous and current assignees' do
-      it_sends_a_reassigned_email_to assignee.id
-      it_sends_a_reassigned_email_to previous_assignee.id
-
-      subject.send(:send_reassigned_email, mock_issue)
-    end
-
-    context 'does not send an email to the user who made the reassignment' do
-      it 'if the user is the assignee' do
-        subject.stub(:current_user).and_return(assignee)
-        it_sends_a_reassigned_email_to previous_assignee.id
-        it_does_not_send_a_reassigned_email_to assignee.id
-
-        subject.send(:send_reassigned_email, mock_issue)
-      end
-      it 'if the user is the previous assignee' do
-        subject.stub(:current_user).and_return(previous_assignee)
-        it_sends_a_reassigned_email_to assignee.id
-        it_does_not_send_a_reassigned_email_to previous_assignee.id
-
-        subject.send(:send_reassigned_email, mock_issue)
-      end
-    end
-  end
 end
diff --git a/spec/observers/merge_request_observer_spec.rb b/spec/observers/merge_request_observer_spec.rb
index 9d702107a89..24a05646cb5 100644
--- a/spec/observers/merge_request_observer_spec.rb
+++ b/spec/observers/merge_request_observer_spec.rb
@@ -10,29 +10,14 @@ describe MergeRequestObserver do
   let(:closed_assigned_mr)   { create(:closed_merge_request, assignee: assignee, author: author) }
   let(:closed_unassigned_mr) { create(:closed_merge_request, author: author) }
 
-  before(:each) { subject.stub(:current_user).and_return(some_user) }
+  before { subject.stub(:current_user).and_return(some_user) }
+  before { subject.stub(notification: mock('NotificationService').as_null_object) }
 
   subject { MergeRequestObserver.instance }
 
   describe '#after_create' do
-
-    it 'is called when a merge request is created' do
-      subject.should_receive(:after_create)
-
-      MergeRequest.observers.enable :merge_request_observer do
-        create(:merge_request, project: create(:project))
-      end
-    end
-
-    it 'sends an email to the assignee' do
-      Notify.should_receive(:new_merge_request_email).with(mr_mock.id)
-      subject.after_create(mr_mock)
-    end
-
-    it 'does not send an email to the assignee if assignee created the merge request' do
-      subject.stub(:current_user).and_return(assignee)
-      Notify.should_not_receive(:new_merge_request_email)
-
+    it 'trigger notification service' do
+      subject.should_receive(:notification)
       subject.after_create(mr_mock)
     end
   end
@@ -52,22 +37,21 @@ describe MergeRequestObserver do
       end
     end
 
-    context 'a reassigned email' do
+    context 'a notification' do
       it 'is sent if the merge request is being reassigned' do
         mr_mock.should_receive(:is_being_reassigned?).and_return(true)
-        subject.should_receive(:send_reassigned_email).with(mr_mock)
+        subject.should_receive(:notification)
 
         subject.after_update(mr_mock)
       end
 
       it 'is not sent if the merge request is not being reassigned' do
         mr_mock.should_receive(:is_being_reassigned?).and_return(false)
-        subject.should_not_receive(:send_reassigned_email)
+        subject.should_not_receive(:notification)
 
         subject.after_update(mr_mock)
       end
     end
-
   end
 
   context '#after_close' do
@@ -101,45 +85,4 @@ describe MergeRequestObserver do
       end
     end
   end
-
-  describe '#send_reassigned_email' do
-    let(:previous_assignee) { double(:user, id: 3) }
-
-    before(:each) do
-      mr_mock.stub(:assignee_id).and_return(assignee.id)
-      mr_mock.stub(:assignee_id_was).and_return(previous_assignee.id)
-    end
-
-    def it_sends_a_reassigned_email_to(recipient)
-      Notify.should_receive(:reassigned_merge_request_email).with(recipient, mr_mock.id, previous_assignee.id)
-    end
-
-    def it_does_not_send_a_reassigned_email_to(recipient)
-      Notify.should_not_receive(:reassigned_merge_request_email).with(recipient, mr_mock.id, previous_assignee.id)
-    end
-
-    it 'sends a reassigned email to the previous and current assignees' do
-      it_sends_a_reassigned_email_to assignee.id
-      it_sends_a_reassigned_email_to previous_assignee.id
-
-      subject.send(:send_reassigned_email, mr_mock)
-    end
-
-    context 'does not send an email to the user who made the reassignment' do
-      it 'if the user is the assignee' do
-        subject.stub(:current_user).and_return(assignee)
-        it_sends_a_reassigned_email_to previous_assignee.id
-        it_does_not_send_a_reassigned_email_to assignee.id
-
-        subject.send(:send_reassigned_email, mr_mock)
-      end
-      it 'if the user is the previous assignee' do
-        subject.stub(:current_user).and_return(previous_assignee)
-        it_sends_a_reassigned_email_to assignee.id
-        it_does_not_send_a_reassigned_email_to previous_assignee.id
-
-        subject.send(:send_reassigned_email, mr_mock)
-      end
-    end
-  end
 end
diff --git a/spec/observers/note_observer_spec.rb b/spec/observers/note_observer_spec.rb
index 8ad42c21d2c..9ada92704b6 100644
--- a/spec/observers/note_observer_spec.rb
+++ b/spec/observers/note_observer_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
 
 describe NoteObserver do
   subject { NoteObserver.instance }
+  before { subject.stub(notification: mock('NotificationService').as_null_object) }
 
   let(:team_without_author) { (1..2).map { |n| double :user, id: n } }
 
@@ -17,116 +18,9 @@ describe NoteObserver do
     end
 
     it 'sends out notifications' do
-      subject.should_receive(:send_notify_mails).with(note)
+      subject.should_receive(:notification)
 
       subject.after_create(note)
     end
   end
-
-  describe "#send_notify_mails" do
-    let(:note) { double :note, notify: false, notify_author: false }
-
-    it 'notifies team of new note when flagged to notify' do
-      note.stub(:notify).and_return(true)
-      subject.should_receive(:notify_team).with(note)
-
-      subject.after_create(note)
-    end
-
-    it 'does not notify team of new note when not flagged to notify' do
-      subject.should_not_receive(:notify_team).with(note)
-
-      subject.after_create(note)
-    end
-
-    it 'notifies the author of a commit when flagged to notify the author' do
-      note.stub(:notify_author).and_return(true)
-      note.stub(:noteable).and_return(double(author_email: 'test@test.com'))
-      note.stub(:id).and_return(42)
-      author = double :user, id: 1, email: 'test@test.com'
-      note.stub(:commit_author).and_return(author)
-      Notify.should_receive(:note_commit_email)
-
-      subject.after_create(note)
-    end
-
-    it 'does not notify the author of a commit when not flagged to notify the author' do
-      notify.should_not_receive(:note_commit_email)
-
-      subject.after_create(note)
-    end
-
-    it 'does nothing if no notify flags are set' do
-      subject.after_create(note).should be_nil
-    end
-  end
-
-  describe '#notify_team' do
-    let(:note) { double :note, id: 1 }
-
-    before :each do
-      subject.stub(:team_without_note_author).with(note).and_return(team_without_author)
-    end
-
-    context 'notifies team of a new note on' do
-      it 'a commit' do
-        note.stub(:noteable_type).and_return('Commit')
-        notify.should_receive(:note_commit_email).twice
-
-        subject.send(:notify_team, note)
-      end
-
-      it 'an issue' do
-        note.stub(:noteable_type).and_return('Issue')
-        notify.should_receive(:note_issue_email).twice
-
-        subject.send(:notify_team, note)
-      end
-
-      it 'a wiki page' do
-        note.stub(:noteable_type).and_return('Wiki')
-        notify.should_receive(:note_wiki_email).twice
-
-        subject.send(:notify_team, note)
-      end
-
-      it 'a merge request' do
-        note.stub(:noteable_type).and_return('MergeRequest')
-        notify.should_receive(:note_merge_request_email).twice
-
-        subject.send(:notify_team, note)
-      end
-
-      it 'a wall' do
-        # Note: wall posts have #noteable_type of nil
-        note.stub(:noteable_type).and_return(nil)
-        notify.should_receive(:note_wall_email).twice
-
-        subject.send(:notify_team, note)
-      end
-    end
-
-    it 'does nothing for a new note on a snippet' do
-      note.stub(:noteable_type).and_return('Snippet')
-
-      subject.send(:notify_team, note).should be_nil
-    end
-  end
-
-
-  describe '#team_without_note_author' do
-    let(:author) { double :user, id: 4 }
-
-    let(:users) { team_without_author + [author] }
-    let(:project)  { double :project, users: users }
-    let(:note) { double :note, project: project, author: author }
-
-    it 'returns the projects user without the note author included' do
-      subject.send(:team_without_note_author, note).should == team_without_author
-    end
-  end
-
-  def notify
-    Notify
-  end
 end
diff --git a/spec/observers/user_observer_spec.rb b/spec/observers/user_observer_spec.rb
index b58c5647ca6..e0902b7eaf3 100644
--- a/spec/observers/user_observer_spec.rb
+++ b/spec/observers/user_observer_spec.rb
@@ -1,7 +1,9 @@
 require 'spec_helper'
 
 describe UserObserver do
+  before(:each) { enable_observers }
   subject { UserObserver.instance }
+  before { subject.stub(notification: mock('NotificationService').as_null_object) }
 
   it 'calls #after_create when new users are created' do
     new_user = build(:user)
@@ -11,15 +13,10 @@ describe UserObserver do
 
   context 'when a new user is created' do
     it 'sends an email' do
-      Notify.should_receive(:new_user_email)
+      subject.should_receive(:notification)
       create(:user)
     end
 
-    it 'no email for external' do
-      Notify.should_not_receive(:new_user_email)
-      create(:user, extern_uid: '32442eEfsafada')
-    end
-
     it 'trigger logger' do
       user = double(:user, id: 42, password: 'P@ssword!', name: 'John', email: 'u@mail.local', extern_uid?: false)
       Gitlab::AppLogger.should_receive(:info)
diff --git a/spec/observers/users_project_observer_spec.rb b/spec/observers/users_project_observer_spec.rb
index 068688b0d1d..66d5c7d91af 100644
--- a/spec/observers/users_project_observer_spec.rb
+++ b/spec/observers/users_project_observer_spec.rb
@@ -1,9 +1,12 @@
 require 'spec_helper'
 
 describe UsersProjectObserver do
+  before(:each) { enable_observers }
+
   let(:user) { create(:user) }
   let(:project) { create(:project) }
   subject { UsersProjectObserver.instance }
+  before { subject.stub(notification: mock('NotificationService').as_null_object) }
 
   describe "#after_commit" do
     it "should called when UsersProject created" do
@@ -12,7 +15,7 @@ describe UsersProjectObserver do
     end
 
     it "should send email to user" do
-      Notify.should_receive(:project_access_granted_email).and_return(double(deliver: true))
+      subject.should_receive(:notification)
       Event.stub(:create => true)
 
       create(:users_project)
@@ -36,7 +39,7 @@ describe UsersProjectObserver do
     end
 
     it "should send email to user" do
-      Notify.should_receive(:project_access_granted_email)
+      subject.should_receive(:notification)
       @users_project.update_attribute(:project_access, UsersProject::MASTER)
     end
 
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index e7af056af8e..25bbd9860bd 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -4,7 +4,7 @@ describe Gitlab::API do
   include ApiHelpers
 
   let(:user) { create(:user ) }
-  let!(:project) { create(:project, namespace: user.namespace ) }
+  let!(:project) { create(:project_with_code, creator_id: user.id) }
   let!(:merge_request) { create(:merge_request, author: user, assignee: user, project: project, title: "Test") }
   before { project.team << [user, :reporters] }
 
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index c379e8a5307..c9a10417fff 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
 
 describe Gitlab::API do
   include ApiHelpers
+  before(:each) { enable_observers }
 
   let(:user) { create(:user) }
   let!(:project) { create(:project, namespace: user.namespace ) }
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index cddb7264018..362c116b64b 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -2,12 +2,13 @@ require 'spec_helper'
 
 describe Gitlab::API do
   include ApiHelpers
+  before(:each) { enable_observers }
 
   let(:user) { create(:user) }
   let(:user2) { create(:user) }
   let(:user3) { create(:user) }
   let(:admin) { create(:admin) }
-  let!(:project) { create(:project, namespace: user.namespace ) }
+  let!(:project) { create(:project_with_code, creator_id: user.id) }
   let!(:hook) { create(:project_hook, project: project, url: "http://example.com") }
   let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') }
   let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
diff --git a/spec/routing/admin_routing_spec.rb b/spec/routing/admin_routing_spec.rb
index 3e0e4bb3883..b6509fcb8b2 100644
--- a/spec/routing/admin_routing_spec.rb
+++ b/spec/routing/admin_routing_spec.rb
@@ -66,33 +66,13 @@ end
 #                           PUT    /admin/projects/:id(.:format)             admin/projects#update {:id=>/[^\/]+/}
 #                           DELETE /admin/projects/:id(.:format)             admin/projects#destroy {:id=>/[^\/]+/}
 describe Admin::ProjectsController, "routing" do
-  it "to #team" do
-    get("/admin/projects/gitlab/team").should route_to('admin/projects#team', id: 'gitlab')
-  end
-
-  it "to #team_update" do
-    put("/admin/projects/gitlab/team_update").should route_to('admin/projects#team_update', id: 'gitlab')
-  end
-
   it "to #index" do
     get("/admin/projects").should route_to('admin/projects#index')
   end
 
-  it "to #edit" do
-    get("/admin/projects/gitlab/edit").should route_to('admin/projects#edit', id: 'gitlab')
-  end
-
   it "to #show" do
     get("/admin/projects/gitlab").should route_to('admin/projects#show', id: 'gitlab')
   end
-
-  it "to #update" do
-    put("/admin/projects/gitlab").should route_to('admin/projects#update', id: 'gitlab')
-  end
-
-  it "to #destroy" do
-    delete("/admin/projects/gitlab").should route_to('admin/projects#destroy', id: 'gitlab')
-  end
 end
 
 # edit_admin_project_member GET      /admin/projects/:project_id/members/:id/edit(.:format)    admin/projects/members#edit {:id=>/[^\/]+/, :project_id=>/[^\/]+/}
diff --git a/spec/routing/notifications_routing_spec.rb b/spec/routing/notifications_routing_spec.rb
new file mode 100644
index 00000000000..6880d2819d1
--- /dev/null
+++ b/spec/routing/notifications_routing_spec.rb
@@ -0,0 +1,13 @@
+require "spec_helper"
+
+describe NotificationsController do
+  describe "routing" do
+    it "routes to #show" do
+      get("/profile/notifications").should route_to("notifications#show")
+    end
+
+    it "routes to #update" do
+      put("/profile/notifications").should route_to("notifications#update")
+    end
+  end
+end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 41533f8b4fe..064177f8f21 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -308,6 +308,7 @@ end
 #                          DELETE /:project_id/team_members/:id(.:format)      team_members#destroy
 describe TeamMembersController, "routing" do
   it_behaves_like "RESTful project resources" do
+    let(:actions)    { [:new, :create, :update, :destroy] }
     let(:controller) { 'team_members' }
   end
 end
@@ -344,18 +345,10 @@ end
 #                            PUT    /:project_id/issues/:id(.:format)         issues#update
 #                            DELETE /:project_id/issues/:id(.:format)         issues#destroy
 describe IssuesController, "routing" do
-  it "to #sort" do
-    post("/gitlabhq/issues/sort").should route_to('issues#sort', project_id: 'gitlabhq')
-  end
-
   it "to #bulk_update" do
     post("/gitlabhq/issues/bulk_update").should route_to('issues#bulk_update', project_id: 'gitlabhq')
   end
 
-  it "to #search" do
-    get("/gitlabhq/issues/search").should route_to('issues#search', project_id: 'gitlabhq')
-  end
-
   it_behaves_like "RESTful project resources" do
     let(:controller) { 'issues' }
     let(:actions) { [:index, :create, :new, :edit, :show, :update] }
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index 9fc5fd62531..286a8cdaa22 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
 
 describe GitPushService do
   let (:user)          { create :user }
-  let (:project)       { create :project }
+  let (:project)       { create :project_with_code }
   let (:service) { GitPushService.new }
 
   before do
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
new file mode 100644
index 00000000000..21e4202f4ee
--- /dev/null
+++ b/spec/services/notification_service_spec.rb
@@ -0,0 +1,243 @@
+require 'spec_helper'
+
+describe NotificationService do
+  let(:notification) { NotificationService.new }
+
+  describe 'Keys' do
+    describe :new_key do
+      let(:key) { create(:personal_key) }
+
+      it { notification.new_key(key).should be_true }
+
+      it 'should sent email to key owner' do
+        Notify.should_receive(:new_ssh_key_email).with(key.id)
+        notification.new_key(key)
+      end
+    end
+  end
+
+  describe 'Notes' do
+    context 'issue note' do
+      let(:issue) { create(:issue, assignee: create(:user)) }
+      let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id) }
+
+      before do
+        build_team(note.project)
+      end
+
+      describe :new_note do
+        it do
+          should_email(@u_watcher.id)
+          should_email(note.noteable.author_id)
+          should_email(note.noteable.assignee_id)
+          should_not_email(note.author_id)
+          should_not_email(@u_participating.id)
+          should_not_email(@u_disabled.id)
+          notification.new_note(note)
+        end
+
+        def should_email(user_id)
+          Notify.should_receive(:note_issue_email).with(user_id, note.id)
+        end
+
+        def should_not_email(user_id)
+          Notify.should_not_receive(:note_issue_email).with(user_id, note.id)
+        end
+      end
+    end
+
+    context 'commit note' do
+      let(:note) { create :note_on_commit }
+
+      before do
+        build_team(note.project)
+      end
+
+      describe :new_note do
+        it do
+          should_email(@u_watcher.id)
+          should_not_email(note.author_id)
+          should_not_email(@u_participating.id)
+          should_not_email(@u_disabled.id)
+          notification.new_note(note)
+        end
+
+        it do
+          create(:note_on_commit,
+                 author: @u_participating,
+                 project_id: note.project_id,
+                 commit_id: note.commit_id)
+
+          should_email(@u_watcher.id)
+          should_email(@u_participating.id)
+          should_not_email(note.author_id)
+          should_not_email(@u_disabled.id)
+          notification.new_note(note)
+        end
+
+        def should_email(user_id)
+          Notify.should_receive(:note_commit_email).with(user_id, note.id)
+        end
+
+        def should_not_email(user_id)
+          Notify.should_not_receive(:note_commit_email).with(user_id, note.id)
+        end
+      end
+    end
+  end
+
+  describe 'Issues' do
+    let(:issue) { create :issue, assignee: create(:user) }
+
+    before do
+      build_team(issue.project)
+    end
+
+    describe :new_issue do
+      it do
+        should_email(issue.assignee_id)
+        should_email(@u_watcher.id)
+        should_not_email(@u_participating.id)
+        should_not_email(@u_disabled.id)
+        notification.new_issue(issue, @u_disabled)
+      end
+
+      def should_email(user_id)
+        Notify.should_receive(:new_issue_email).with(user_id, issue.id)
+      end
+
+      def should_not_email(user_id)
+        Notify.should_not_receive(:new_issue_email).with(user_id, issue.id)
+      end
+    end
+
+    describe :reassigned_issue do
+      it 'should email new assignee' do
+        should_email(issue.assignee_id)
+        should_email(@u_watcher.id)
+        should_not_email(@u_participating.id)
+        should_not_email(@u_disabled.id)
+
+        notification.reassigned_issue(issue, @u_disabled)
+      end
+
+      def should_email(user_id)
+        Notify.should_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id)
+      end
+
+      def should_not_email(user_id)
+        Notify.should_not_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id)
+      end
+    end
+
+    describe :close_issue do
+      it 'should sent email to issue assignee and issue author' do
+        should_email(issue.assignee_id)
+        should_email(issue.author_id)
+        should_email(@u_watcher.id)
+        should_not_email(@u_participating.id)
+        should_not_email(@u_disabled.id)
+
+        notification.close_issue(issue, @u_disabled)
+      end
+
+      def should_email(user_id)
+        Notify.should_receive(:closed_issue_email).with(user_id, issue.id, @u_disabled.id)
+      end
+
+      def should_not_email(user_id)
+        Notify.should_not_receive(:closed_issue_email).with(user_id, issue.id, @u_disabled.id)
+      end
+    end
+  end
+
+  describe 'Merge Requests' do
+    let(:merge_request) { create :merge_request, assignee: create(:user) }
+
+    before do
+      build_team(merge_request.project)
+    end
+
+    describe :new_merge_request do
+      it do
+        should_email(merge_request.assignee_id)
+        should_email(@u_watcher.id)
+        should_not_email(@u_participating.id)
+        should_not_email(@u_disabled.id)
+        notification.new_merge_request(merge_request, @u_disabled)
+      end
+
+      def should_email(user_id)
+        Notify.should_receive(:new_merge_request_email).with(user_id, merge_request.id)
+      end
+
+      def should_not_email(user_id)
+        Notify.should_not_receive(:new_merge_request_email).with(user_id, merge_request.id)
+      end
+    end
+
+    describe :reassigned_merge_request do
+      it do
+        should_email(merge_request.assignee_id)
+        should_email(@u_watcher.id)
+        should_not_email(@u_participating.id)
+        should_not_email(@u_disabled.id)
+        notification.reassigned_merge_request(merge_request, merge_request.author)
+      end
+
+      def should_email(user_id)
+        Notify.should_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id)
+      end
+
+      def should_not_email(user_id)
+        Notify.should_not_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id)
+      end
+    end
+
+    describe :closed_merge_request do
+      it do
+        should_email(merge_request.assignee_id)
+        should_email(@u_watcher.id)
+        should_not_email(@u_participating.id)
+        should_not_email(@u_disabled.id)
+        notification.close_mr(merge_request, @u_disabled)
+      end
+
+      def should_email(user_id)
+        Notify.should_receive(:closed_merge_request_email).with(user_id, merge_request.id, @u_disabled.id)
+      end
+
+      def should_not_email(user_id)
+        Notify.should_not_receive(:closed_merge_request_email).with(user_id, merge_request.id, @u_disabled.id)
+      end
+    end
+
+    describe :merged_merge_request do
+      it do
+        should_email(merge_request.assignee_id)
+        should_email(@u_watcher.id)
+        should_not_email(@u_participating.id)
+        should_not_email(@u_disabled.id)
+        notification.merge_mr(merge_request)
+      end
+
+      def should_email(user_id)
+        Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id)
+      end
+
+      def should_not_email(user_id)
+        Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id)
+      end
+    end
+  end
+
+  def build_team(project)
+    @u_watcher = create(:user, notification_level: Notification::N_WATCH)
+    @u_participating = create(:user, notification_level: Notification::N_PARTICIPATING)
+    @u_disabled = create(:user, notification_level: Notification::N_DISABLED)
+
+    project.team << [@u_watcher, :master]
+    project.team << [@u_participating, :master]
+    project.team << [@u_disabled, :master]
+  end
+end
diff --git a/spec/services/project_transfer_service_spec.rb b/spec/services/project_transfer_service_spec.rb
index dea0b0b2998..7b11c9785a9 100644
--- a/spec/services/project_transfer_service_spec.rb
+++ b/spec/services/project_transfer_service_spec.rb
@@ -1,6 +1,8 @@
 require 'spec_helper'
 
 describe ProjectTransferService do
+  before(:each) { enable_observers }
+
   context 'namespace -> namespace' do
     let(:user) { create(:user) }
     let(:group) { create(:group) }
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 30518cc2b9f..3c318a4be82 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,46 +1,60 @@
-require 'simplecov' unless ENV['CI']
+require 'rubygems'
+require 'spork'
 
-if ENV['TRAVIS']
-  require 'coveralls'
-  Coveralls.wear!
-end
+Spork.prefork do
+  require 'simplecov' unless ENV['CI']
 
-# This file is copied to spec/ when you run 'rails generate rspec:install'
-ENV["RAILS_ENV"] ||= 'test'
-require File.expand_path("../../config/environment", __FILE__)
-require 'rspec/rails'
-require 'capybara/rails'
-require 'capybara/rspec'
-require 'webmock/rspec'
-require 'email_spec'
-require 'sidekiq/testing/inline'
-require 'capybara/poltergeist'
-Capybara.javascript_driver = :poltergeist
-
-# Requires supporting ruby files with custom matchers and macros, etc,
-# in spec/support/ and its subdirectories.
-Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
-
-WebMock.disable_net_connect!(allow_localhost: true)
-
-RSpec.configure do |config|
-  config.mock_with :rspec
-
-  config.include LoginHelpers, type: :feature
-  config.include LoginHelpers, type: :request
-  config.include FactoryGirl::Syntax::Methods
-  config.include Devise::TestHelpers, type: :controller
-
-  # If you're not using ActiveRecord, or you'd prefer not to run each of your
-  # examples within a transaction, remove the following line or assign false
-  # instead of true.
-  config.use_transactional_fixtures = false
-
-  config.before do
-    # Use tmp dir for FS manipulations
-    temp_repos_path = Rails.root.join('tmp', 'test-git-base-path')
-    Gitlab.config.gitlab_shell.stub(repos_path: temp_repos_path)
-    FileUtils.rm_rf temp_repos_path
-    FileUtils.mkdir_p temp_repos_path
+  if ENV['TRAVIS']
+    require 'coveralls'
+    Coveralls.wear!
   end
+
+  # This file is copied to spec/ when you run 'rails generate rspec:install'
+  ENV["RAILS_ENV"] ||= 'test'
+  require File.expand_path("../../config/environment", __FILE__)
+  require 'rspec/rails'
+  require 'capybara/rails'
+  require 'capybara/rspec'
+  require 'webmock/rspec'
+  require 'email_spec'
+  require 'sidekiq/testing/inline'
+  require 'capybara/poltergeist'
+
+  # Loading more in this block will cause your tests to run faster. However,
+
+  # if you change any configuration or code from libraries loaded here, you'll
+  # need to restart spork for it take effect.
+  Capybara.javascript_driver = :poltergeist
+  Capybara.default_wait_time = 10
+
+  # Requires supporting ruby files with custom matchers and macros, etc,
+  # in spec/support/ and its subdirectories.
+  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+
+  WebMock.disable_net_connect!(allow_localhost: true)
+
+  RSpec.configure do |config|
+    config.mock_with :rspec
+
+    config.include LoginHelpers, type: :feature
+    config.include LoginHelpers, type: :request
+    config.include FactoryGirl::Syntax::Methods
+    config.include Devise::TestHelpers, type: :controller
+
+    config.include TestEnv
+
+    # If you're not using ActiveRecord, or you'd prefer not to run each of your
+    # examples within a transaction, remove the following line or assign false
+    # instead of true.
+    config.use_transactional_fixtures = false
+
+    config.before do
+      TestEnv.init(observers: false)
+    end
+  end
+end
+
+Spork.each_run do
+  # This code will be run each time you run your specs.
+
 end
diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb
index 4579c971d47..d423ccf8a10 100644
--- a/spec/support/login_helpers.rb
+++ b/spec/support/login_helpers.rb
@@ -12,7 +12,7 @@ module LoginHelpers
   # user - User instance to login with
   def login_with(user)
     visit new_user_session_path
-    fill_in "user_email", with: user.email
+    fill_in "user_login", with: user.email
     fill_in "user_password", with: "123456"
     click_button "Sign in"
   end
diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb
index 29d16ecbac7..15fb47004e9 100644
--- a/spec/support/matchers.rb
+++ b/spec/support/matchers.rb
@@ -3,7 +3,7 @@ RSpec::Matchers.define :be_valid_commit do
     actual != nil
     actual.id == ValidCommit::ID
     actual.message == ValidCommit::MESSAGE
-    actual.author.name == ValidCommit::AUTHOR_FULL_NAME
+    actual.author_name == ValidCommit::AUTHOR_FULL_NAME
   end
 end
 
diff --git a/spec/support/stubbed_repository.rb b/spec/support/stubbed_repository.rb
deleted file mode 100644
index 6376c8d5ea1..00000000000
--- a/spec/support/stubbed_repository.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require "repository"
-require "project"
-require "merge_request"
-require "shell"
-
-# Stubs out all Git repository access done by models so that specs can run
-# against fake repositories without Grit complaining that they don't exist.
-class Project
-  def repository
-    if path == "empty" || !path
-      nil
-    else
-      GitLabTestRepo.new(path_with_namespace)
-    end
-  end
-
-  def satellite
-    FakeSatellite.new
-  end
-
-  class FakeSatellite
-    def exists?
-      true
-    end
-
-    def destroy
-      true
-    end
-
-    def create
-      true
-    end
-  end
-end
-
-class MergeRequest
-  def check_if_can_be_merged
-    true
-  end
-end
-
-class GitLabTestRepo < Repository
-  def repo
-    @repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq'))
-  end
-
-  # patch repo size (in mb)
-  def size
-    12.45
-  end
-end
-
-module Gitlab
-  class Shell
-    def add_repository name
-      true
-    end
-
-    def mv_repository name, new_name
-      true
-    end
-
-    def remove_repository name
-      true
-    end
-
-    def add_key id, key
-      true
-    end
-
-    def remove_key id, key
-      true
-    end
-  end
-end
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
new file mode 100644
index 00000000000..8a2e004f824
--- /dev/null
+++ b/spec/support/test_env.rb
@@ -0,0 +1,91 @@
+require 'rspec/mocks'
+
+module TestEnv
+  extend self
+
+  # Test environment
+  #
+  # all repositories and namespaces stored at
+  # RAILS_APP/tmp/test-git-base-path
+  #
+  # Next shell methods are stubbed and return true
+  # -  mv_repository
+  # -  remove_repository
+  # -  add_key
+  # -  remove_key
+  #
+  def init(opts = {})
+    RSpec::Mocks::setup(self)
+
+    # Disable observers to improve test speed
+    #
+    # You can enable it in whole test case where needed by next string:
+    #
+    #   before(:each) { enable_observers }
+    #
+    disable_observers if opts[:observers] == false
+
+    # Disable mailer for spinach tests
+    disable_mailer if opts[:mailer] == false
+
+
+    # Use tmp dir for FS manipulations
+    repos_path = Rails.root.join('tmp', 'test-git-base-path')
+    Gitlab.config.gitlab_shell.stub(repos_path: repos_path)
+
+    GollumWiki.any_instance.stub(:init_repo) do |path|
+      create_temp_repo(File.join(repos_path, "#{path}.git"))
+    end
+
+    Gitlab::Shell.any_instance.stub(
+      add_repository: true,
+      mv_repository: true,
+      remove_repository: true,
+      add_key: true,
+      remove_key: true
+    )
+
+    Gitlab::Satellite::Satellite.any_instance.stub(
+      exists?: true,
+      destroy: true,
+      create: true
+    )
+
+    MergeRequest.any_instance.stub(
+      check_if_can_be_merged: true
+    )
+
+    Repository.any_instance.stub(
+      size: 12.45
+    )
+
+    # Remove tmp/test-git-base-path
+    FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path
+
+    # Recreate tmp/test-git-base-path
+    FileUtils.mkdir_p Gitlab.config.gitlab_shell.repos_path
+
+    # Symlink tmp/repositories/gitlabhq to tmp/test-git-base-path/gitlabhq
+    seed_repo = Rails.root.join('tmp', 'repositories', 'gitlabhq')
+    target_repo = File.join(repos_path, 'gitlabhq.git')
+    system("ln -s #{seed_repo} #{target_repo}")
+  end
+
+  def create_temp_repo(path)
+    FileUtils.mkdir_p path
+    command = "git init --quiet --bare #{path};"
+    system(command)
+  end
+
+  def enable_observers
+    ActiveRecord::Base.observers.enable(:all)
+  end
+
+  def disable_observers
+    ActiveRecord::Base.observers.disable(:all)
+  end
+
+  def disable_mailer
+    NotificationService.any_instance.stub(mailer: double.as_null_object)
+  end
+end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index a4751bd0baf..46e86dbe00a 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -9,7 +9,7 @@ describe PostReceive do
   end
 
   context "web hook" do
-    let(:project) { create(:project) }
+    let(:project) { create(:project_with_code) }
     let(:key) { create(:key, user: project.owner) }
     let(:key_id) { key.shell_id }
 
-- 
GitLab


From d4c0b48d6006efecf4e3e40fbeb102b1a54761d0 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Thu, 25 Apr 2013 23:25:46 +0300
Subject: [PATCH 27/83] Update README.md

---
 README.md | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 4771ed9803e..9203252b199 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,11 @@ You can browse a live example at http://git.hoa.ro (you won't be able to create
 _Disclaimer_: I do not provide any support on GitLab itself. I only contribute to the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
 
 You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
+## Changelog
+
+  * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable)
+  * [2013-04-11] : MySQL support
+  * [2013-04-01] : First commit for Public GitLab (only PostgreSQL)
 
 ## Installation
 
@@ -40,6 +45,8 @@ At this point, every GitLab components are installed. You still can not access t
 
 The SQL script below will create a default `guest` user for anonymous access. It will also create a default team (`pgl_reporters`) which allows `reporter` permission to every new _future_ users, for all public projects.
 
+> Note that your DB user need to be granted with TRIGGER permission on your database (this is specific to Public GitLab).
+
 #### PostgreSQL
 You have to patch GitLab your database with `pgl_script_postgres.sql`:
 
@@ -86,4 +93,4 @@ Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
 
 Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-0-stable/LICENSE) as the original sofware.
 
-This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
\ No newline at end of file
+This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
-- 
GitLab


From b54e33b1893d0efe64be5ee5ae0ca4963f207eca Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Thu, 25 Apr 2013 23:28:58 +0300
Subject: [PATCH 28/83] Update README.md

---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 9203252b199..6ab3a889c3f 100644
--- a/README.md
+++ b/README.md
@@ -19,13 +19,13 @@ _Disclaimer_: I do not provide any support on GitLab itself. I only contribute t
 You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
 ## Changelog
 
-  * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable)
+  * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/5.0-to-5.1.md)
   * [2013-04-11] : MySQL support
   * [2013-04-01] : First commit for Public GitLab (only PostgreSQL)
 
 ## Installation
 
-During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
+During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-1-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
 
 **Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-0-stable.zip).
 
@@ -38,7 +38,7 @@ During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-0-
     cd /home/git/gitlab
 
     # Checkout to stable release
-    sudo -u git -H git checkout 5-0-stable
+    sudo -u git -H git checkout 5-1-stable
 
 ### Post installation
 At this point, every GitLab components are installed. You still can not access to GitLab yet though.
@@ -91,6 +91,6 @@ If there is a new stable branch, please do not open an issue to ask update. [Con
 
 Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
 
-Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-0-stable/LICENSE) as the original sofware.
+Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/LICENSE) as the original sofware.
 
 This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
-- 
GitLab


From dd624839b754f6b3885d8592f631d6ef6e4fb3d9 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Fri, 26 Apr 2013 13:26:00 +0300
Subject: [PATCH 29/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6ab3a889c3f..0d25da2dabe 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ You should also be aware that **Public GitLab** only applies to the lastest [sta
 
 During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-1-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
 
-**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-0-stable.zip).
+**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-1-stable.zip).
 
 ### Clone the Source
 
-- 
GitLab


From 48540877ad616367d47bb7d4a0b6bd0933ee683d Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 29 Apr 2013 17:15:54 +0300
Subject: [PATCH 30/83] Update README.md

---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
index 0d25da2dabe..37d7181f78e 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,9 @@ You should also be aware that **Public GitLab** only applies to the lastest [sta
 ## Changelog
 
   * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/5.0-to-5.1.md)
+
+> Warning: GitLab 5.1 does not work properly with old version of Git (ok on 1.7.10+). [More here](https://github.com/gitlabhq/gitlabhq/issues/3666). 
+  
   * [2013-04-11] : MySQL support
   * [2013-04-01] : First commit for Public GitLab (only PostgreSQL)
 
-- 
GitLab


From 60b97423c535fd6e8f67e2d4b35b138dfe863ccf Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Tue, 30 Apr 2013 18:12:23 +0300
Subject: [PATCH 31/83] Update CONTRIBUTING.md

---
 CONTRIBUTING.md | 57 +++++--------------------------------------------
 1 file changed, 5 insertions(+), 52 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 79e57558084..1d4f6923388 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,56 +1,9 @@
-# Contribute to GitLab
+# Reporting issues
 
-This guide details how to use issues and pull requests to improve GitLab.
+If you have issues with Public GitLab, you can report them with the Github issues module.
 
-## Closing policy for issues and pull requests
+Please rememberer to privide as much information as you can (e.g. which database you are using).
 
-Issues and pull requests not in line with the guidelines listed in this document will be closed with just a link to this paragraph. GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. To get support for your problems please use other channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
+Disclaimer: I do not provide any support on GitLab itself. I only contribute to the _public part_. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
 
-## Issue tracker
-
-The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the master branch of GitLab. When submitting an issue please conform to the issue submission guidelines listed below.
-
-Do not use the issue tracker for feature requests. We have a specific
-[Feedback and suggestions forum](http://feedback.gitlab.com) for this purpose.
-
-Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there.
-
-### Issue tracker guidelines
-
-**Search** for similar entries before submitting your own, there's a good chance somebody else had the same issue or idea. Show your support with `:+1:` and/or join the discussion.
-
-* Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
-* Describe your issue in detail
-* How can we reproduce the issue on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: vagrant destroy && vagrant up && vagrant ssh)
-* Add the last commit sha1 of the GitLab version you used to replicate the issue
-* Add logs or screen shots when possible
-* Link to the line of code that might be responsible for the problem
-* Describe your setup (use relevant parts from `sudo -u gitlab -H bundle exec rake gitlab:env:info`)
-
-## Pull requests
-
-We welcome pull request with improvements to GitLab code and/or documentation. The issues we would really like a pull request for are listed with the [status 'accepting merge/pull requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome.
-
-### Pull request guidelines
-
- If you can please submit a pull request with the fix including tests. The workflow to make a pull request is as follows:
-
-1. Fork the project on GitHub
-1. Create a feature branch
-1. Write tests and code
-1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
-1. Push the commit to your fork
-1. Submit a pull request
-
-We will accept pull requests if:
-
-* The code has proper tests and all tests pass
-* It can be merged without problems (if not please use: git rebase master)
-* It doesn't break any existing functionality
-* It's quality code that conforms to the [Rails style guide](https://github.com/bbatsov/rails-style-guide) and best practices
-* The description includes a motive for your change and the method you used to achieve it
-* It keeps the GitLab code base clean and well structured
-* We think other users will need the same functionality
-* If it makes changes to the UI the pull request should include screenshots
-
-For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
+If there is a new stable branch, please do not open an issue to ask update. Contact me instead.
-- 
GitLab


From 09317521992a8e8816d7c283ed920cbe4ba5a1d4 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 16:07:05 +0300
Subject: [PATCH 32/83] #2 PostgreSQL Fix

---
 pgl/pgl_script_postgres.sql | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/pgl/pgl_script_postgres.sql b/pgl/pgl_script_postgres.sql
index 4dff5bbca5f..d4a121b8857 100755
--- a/pgl/pgl_script_postgres.sql
+++ b/pgl/pgl_script_postgres.sql
@@ -41,8 +41,10 @@ AS $$
 			LIMIT 1;
 
 			FOR m_users_id IN SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id  LOOP
-				INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
-				VALUES (m_users_id, NEW.id, now(), now(), 20);
+				IF m_users_id <> NEW.creator_id THEN
+					INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
+					VALUES (m_users_id, NEW.id, now(), now(), 20);
+				END IF;
 			END LOOP;
 
 			INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now());			
-- 
GitLab


From eeb8c42720edba80062f2ec14bc3ee84a49cf939 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 16:36:24 +0200
Subject: [PATCH 33/83] Fixes #2 and spit pgl script to handle updates

---
 README.md                                     | 34 +++++++++++++++----
 pgl/pgl_mysql_insert.sql                      |  5 +++
 ...script_mysql.sql => pgl_mysql_trigger.sql} | 14 +++-----
 pgl/pgl_pgsql_insert.sql                      |  5 +++
 ...ipt_postgres.sql => pgl_pgsql_trigger.sql} | 13 +++----
 5 files changed, 47 insertions(+), 24 deletions(-)
 create mode 100755 pgl/pgl_mysql_insert.sql
 rename pgl/{pgl_script_mysql.sql => pgl_mysql_trigger.sql} (71%)
 mode change 100755 => 100644
 create mode 100755 pgl/pgl_pgsql_insert.sql
 rename pgl/{pgl_script_postgres.sql => pgl_pgsql_trigger.sql} (69%)
 mode change 100755 => 100644

diff --git a/README.md b/README.md
index 37d7181f78e..34837d5cce8 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ _Disclaimer_: I do not provide any support on GitLab itself. I only contribute t
 You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
 ## Changelog
 
+  * [2013-05-03] : Bugfix (you need to update your DB triggers)
   * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/5.0-to-5.1.md)
 
 > Warning: GitLab 5.1 does not work properly with old version of Git (ok on 1.7.10+). [More here](https://github.com/gitlabhq/gitlabhq/issues/3666). 
@@ -51,18 +52,20 @@ The SQL script below will create a default `guest` user for anonymous access. It
 > Note that your DB user need to be granted with TRIGGER permission on your database (this is specific to Public GitLab).
 
 #### PostgreSQL
-You have to patch GitLab your database with `pgl_script_postgres.sql`:
+You have to patch GitLab your database with 2 SQL scripts:
 
     cd /home/git/gitlab/pgl
-    psql -h host -U user database < pgl_script_postgres.sql
+    psql -h host -U user database < pgl_postgres_insert.sql
+    psql -h host -U user database < pgl_postgres_trigger.sql
 
 #### MySQL
-You have to patch GitLab your database with `pgl_script_mysql.sql`:
+You have to patch GitLab your database with 2 SQL scripts:
 
     cd /home/git/gitlab/pgl
     mysql -hhost -uuser -p
     use database
-    source pgl_script_mysql.sql
+    source pgl_mysql_insert.sql
+    source pgl_mysql_trigger.sql
 
 ### Allow signup
 
@@ -82,11 +85,28 @@ Remember to restart GitLab after all these changes :
 
 Then enjoy !
 
-## Reporting issues
+## Update Public GitLab
+
+You need to refer to official [update guides](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/) to upgrade GitLab version.
+
+If the changelog on this README indicate any SQL update, you need to update your database :
+
+* PostgreSQL
+
+    cd /home/git/gitlab/pgl
+    psql -h host -U user database < pgl_postgres_trigger.sql
 
-If you have issues with Public GitLab, you can report them with the [Github issues module](https://github.com/ArthurHoaro/Public-GitLab/issues). 
+* MySQL
+
+    cd /home/git/gitlab/pgl
+    mysql -hhost -uuser -p
+    use database
+    source pgl_mysql_trigger.sql
+    
+
+## Reporting issues
 
-Please rememberer to tell us which database you are using.
+See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/CONTRIBUTING.md).
 
 If there is a new stable branch, please do not open an issue to ask update. [Contact me](http://hoa.ro/static6/contact) instead.
 
diff --git a/pgl/pgl_mysql_insert.sql b/pgl/pgl_mysql_insert.sql
new file mode 100755
index 00000000000..f47d6c25484
--- /dev/null
+++ b/pgl/pgl_mysql_insert.sql
@@ -0,0 +1,5 @@
+INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin )
+VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+
+INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
+VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)');
\ No newline at end of file
diff --git a/pgl/pgl_script_mysql.sql b/pgl/pgl_mysql_trigger.sql
old mode 100755
new mode 100644
similarity index 71%
rename from pgl/pgl_script_mysql.sql
rename to pgl/pgl_mysql_trigger.sql
index 061e5dbc234..143beebe092
--- a/pgl/pgl_script_mysql.sql
+++ b/pgl/pgl_mysql_trigger.sql
@@ -1,9 +1,3 @@
-INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin )
-VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
-
-INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
-VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)');
-
 DROP TRIGGER IF EXISTS pgl_new_user;
 delimiter //
 
@@ -52,11 +46,13 @@ BEGIN
                 LEAVE ins_loop;
             END IF;
 
-            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access)
-            VALUES (m_users_id, NEW.id, now(), now(), 20);
+            IF m_users_id <> NEW.creator_id THEN
+                INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access)
+                VALUES (m_users_id, NEW.id, now(), now(), 20);
+            END IF;
         END LOOP;
     CLOSE cur;
 
     INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());            
 END//
-DELIMITER ;
+DELIMITER ;
\ No newline at end of file
diff --git a/pgl/pgl_pgsql_insert.sql b/pgl/pgl_pgsql_insert.sql
new file mode 100755
index 00000000000..bd72b86b867
--- /dev/null
+++ b/pgl/pgl_pgsql_insert.sql
@@ -0,0 +1,5 @@
+INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
+VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+
+INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
+VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)');
diff --git a/pgl/pgl_script_postgres.sql b/pgl/pgl_pgsql_trigger.sql
old mode 100755
new mode 100644
similarity index 69%
rename from pgl/pgl_script_postgres.sql
rename to pgl/pgl_pgsql_trigger.sql
index d4a121b8857..059f287e82e
--- a/pgl/pgl_script_postgres.sql
+++ b/pgl/pgl_pgsql_trigger.sql
@@ -1,10 +1,7 @@
-INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) 
-VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f');
+DROP TRIGGER IF EXISTS pgl_new_user ON users;
+DROP TRIGGER IF EXISTS pgl_new_project ON projects;
 
-INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description)
-VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)');
-
-CREATE FUNCTION pgl_create_user_team_rs() RETURNS trigger
+CREATE OR REPLACE FUNCTION pgl_create_user_team_rs() RETURNS trigger
 LANGUAGE plpgsql
 AS $$
 	DECLARE m_user_team_id integer;
@@ -27,7 +24,7 @@ AS $$
 $$;
 CREATE TRIGGER pgl_new_user AFTER INSERT ON users FOR EACH ROW EXECUTE PROCEDURE pgl_create_user_team_rs();
 
-CREATE FUNCTION pgl_create_project_team_rs() RETURNS trigger
+CREATE OR REPLACE FUNCTION pgl_create_project_team_rs() RETURNS trigger
 LANGUAGE plpgsql
 AS $$
 	DECLARE m_user_team_id integer;
@@ -52,4 +49,4 @@ AS $$
 		RETURN new;
 	END;
 $$;
-CREATE TRIGGER pgl_new_project AFTER INSERT ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_create_project_team_rs();
+CREATE TRIGGER pgl_new_project AFTER INSERT ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_create_project_team_rs();
\ No newline at end of file
-- 
GitLab


From ff0c7a209388c81530fc50eaf6c4d1629695de6b Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 16:48:57 +0200
Subject: [PATCH 34/83] Update readme

---
 README.md | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 34837d5cce8..43f3537a12a 100644
--- a/README.md
+++ b/README.md
@@ -102,7 +102,7 @@ If the changelog on this README indicate any SQL update, you need to update your
     mysql -hhost -uuser -p
     use database
     source pgl_mysql_trigger.sql
-    
+
 
 ## Reporting issues
 
@@ -110,6 +110,21 @@ See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/
 
 If there is a new stable branch, please do not open an issue to ask update. [Contact me](http://hoa.ro/static6/contact) instead.
 
+## Troubleshooting
+
+### Removing root user
+
+The reporters team created by Public GitLab is owned by the root user (Administrator). If you delete this user, it will create several issues in your GitLab installation.
+
+If you _really_ need to remove `root`, you need to change the `pgl_reporters` team's owner in GitLab administration.
+
+If you have alrealdy deleted root user, you have to manually change Public GitLab SQL `insert` to :
+
+    INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description) 
+    VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'YOU_NEW_ADMIN_USERNAME'), now(), now(), 'Default new users team (reporter permission)'); 
+
+Read more at issues [#3](https://github.com/ArthurHoaro/Public-GitLab/issues/3) and [#4](https://github.com/ArthurHoaro/Public-GitLab/issues/4).
+
 ## License
 
 Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
-- 
GitLab


From 8aa895cb72d6fef99c1511e2f6bf3e2ecd845e2b Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 17:51:44 +0300
Subject: [PATCH 35/83] Update README.md

---
 README.md | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 43f3537a12a..6aace8421cf 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ _Disclaimer_: I do not provide any support on GitLab itself. I only contribute t
 You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
 ## Changelog
 
-  * [2013-05-03] : Bugfix (you need to update your DB triggers)
+  * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab/edit/5-1-stable/README.md#update-public-gitlab) your DB triggers)
   * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/5.0-to-5.1.md)
 
 > Warning: GitLab 5.1 does not work properly with old version of Git (ok on 1.7.10+). [More here](https://github.com/gitlabhq/gitlabhq/issues/3666). 
@@ -91,17 +91,17 @@ You need to refer to official [update guides](https://github.com/ArthurHoaro/Pub
 
 If the changelog on this README indicate any SQL update, you need to update your database :
 
-* PostgreSQL
+* PostgreSQL:
 
-    cd /home/git/gitlab/pgl
-    psql -h host -U user database < pgl_postgres_trigger.sql
+     cd /home/git/gitlab/pgl
+     psql -h host -U user database < pgl_postgres_trigger.sql
 
-* MySQL
+* MySQL:
 
-    cd /home/git/gitlab/pgl
-    mysql -hhost -uuser -p
-    use database
-    source pgl_mysql_trigger.sql
+     cd /home/git/gitlab/pgl
+     mysql -hhost -uuser -p
+     use database
+     source pgl_mysql_trigger.sql
 
 
 ## Reporting issues
@@ -116,7 +116,7 @@ If there is a new stable branch, please do not open an issue to ask update. [Con
 
 The reporters team created by Public GitLab is owned by the root user (Administrator). If you delete this user, it will create several issues in your GitLab installation.
 
-If you _really_ need to remove `root`, you need to change the `pgl_reporters` team's owner in GitLab administration.
+If you _really_ need to remove `root`, you need to change the `pgl_reporters` team's owner in GitLab administration before deleting it.
 
 If you have alrealdy deleted root user, you have to manually change Public GitLab SQL `insert` to :
 
-- 
GitLab


From 33d3c63811d2582a0b98065a9c27102ce0199146 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 17:53:24 +0300
Subject: [PATCH 36/83] Update README.md

---
 README.md | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 6aace8421cf..d8dc560a55f 100644
--- a/README.md
+++ b/README.md
@@ -91,17 +91,20 @@ You need to refer to official [update guides](https://github.com/ArthurHoaro/Pub
 
 If the changelog on this README indicate any SQL update, you need to update your database :
 
-* PostgreSQL:
+PostgreSQL:
+
 
      cd /home/git/gitlab/pgl
      psql -h host -U user database < pgl_postgres_trigger.sql
+     
 
-* MySQL:
+MySQL:
 
-     cd /home/git/gitlab/pgl
-     mysql -hhost -uuser -p
-     use database
-     source pgl_mysql_trigger.sql
+
+    cd /home/git/gitlab/pgl
+    mysql -hhost -uuser -p
+    use database
+    source pgl_mysql_trigger.sql
 
 
 ## Reporting issues
-- 
GitLab


From 695828feb16b72ceab5827be4b4c9b071ff8d6f1 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 17:08:24 +0200
Subject: [PATCH 37/83] Fixes #6

---
 pgl/pgl_mysql_trigger.sql | 34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/pgl/pgl_mysql_trigger.sql b/pgl/pgl_mysql_trigger.sql
index 143beebe092..43c70b666b8 100644
--- a/pgl/pgl_mysql_trigger.sql
+++ b/pgl/pgl_mysql_trigger.sql
@@ -39,20 +39,22 @@ BEGIN
     DECLARE cur CURSOR FOR SELECT user_id FROM user_team_user_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters");
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
 
-    OPEN cur;
-        ins_loop: LOOP
-            FETCH cur INTO m_users_id;
-            IF done THEN
-                LEAVE ins_loop;
-            END IF;
-
-            IF m_users_id <> NEW.creator_id THEN
-                INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access)
-                VALUES (m_users_id, NEW.id, now(), now(), 20);
-            END IF;
-        END LOOP;
-    CLOSE cur;
-
-    INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());            
+    IF NEW.public = 1 THEN
+        OPEN cur;
+            ins_loop: LOOP
+                FETCH cur INTO m_users_id;
+                IF done THEN
+                    LEAVE ins_loop;
+                END IF;
+
+                IF m_users_id <> NEW.creator_id THEN
+                    INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access)
+                    VALUES (m_users_id, NEW.id, now(), now(), 20);
+                END IF;
+            END LOOP;
+        CLOSE cur;
+
+        INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());
+    END IF;
 END//
-DELIMITER ;
\ No newline at end of file
+DELIMITER ;
-- 
GitLab


From b8ee120186d593b62c74f79989942607a7c51595 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 18:01:44 +0200
Subject: [PATCH 38/83] PostgreSQL fix for #1

---
 pgl/pgl_pgsql_trigger.sql | 49 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 pgl/pgl_pgsql_trigger.sql

diff --git a/pgl/pgl_pgsql_trigger.sql b/pgl/pgl_pgsql_trigger.sql
old mode 100644
new mode 100755
index 059f287e82e..eba4a56e032
--- a/pgl/pgl_pgsql_trigger.sql
+++ b/pgl/pgl_pgsql_trigger.sql
@@ -1,5 +1,6 @@
 DROP TRIGGER IF EXISTS pgl_new_user ON users;
 DROP TRIGGER IF EXISTS pgl_new_project ON projects;
+DROP TRIGGER IF EXISTS pgl_update_project ON projects;
 
 CREATE OR REPLACE FUNCTION pgl_create_user_team_rs() RETURNS trigger
 LANGUAGE plpgsql
@@ -49,4 +50,50 @@ AS $$
 		RETURN new;
 	END;
 $$;
-CREATE TRIGGER pgl_new_project AFTER INSERT ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_create_project_team_rs();
\ No newline at end of file
+CREATE TRIGGER pgl_new_project AFTER INSERT ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_create_project_team_rs();
+
+CREATE OR REPLACE FUNCTION pgl_update_project_team_rs() RETURNS trigger
+LANGUAGE plpgsql
+AS $$
+	DECLARE 
+		m_user_team_id integer;
+		m_users_id integer;
+		temprec RECORD;
+		tmpint  INTEGER := 0;
+	BEGIN
+		IF NEW.public <> OLD.public THEN
+			m_user_team_id := 0;
+			SELECT "id" INTO m_user_team_id
+			  	FROM "user_teams" p
+			WHERE p.name = 'pgl_reporters'
+			LIMIT 1;
+
+			IF NEW.public = 't' THEN	
+				FOR m_users_id IN SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id  LOOP
+					IF m_users_id <> OLD.creator_id THEN
+						SELECT user_id FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id INTO temprec;
+						GET DIAGNOSTICS tmpint = ROW_COUNT;
+						IF tmpint = 0 THEN
+							INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) 
+							VALUES (m_users_id, OLD.id, now(), now(), 20);
+						END IF;
+					END IF;
+				END LOOP;
+
+				INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (OLD.id, m_user_team_id, 20, now(), now());			
+
+			ELSE
+				FOR m_users_id IN SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id LOOP
+					SELECT project_access INTO tmpint FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id LIMIT 1;
+					-- If project permission is reporter (20), or lower
+					IF tmpint < 21 THEN
+						DELETE FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id;
+					END IF;
+				END LOOP;
+				DELETE FROM user_team_project_relationships WHERE user_team_id = m_user_team_id AND project_id = OLD.id;
+			END IF;
+		END IF;
+		RETURN new;
+	END;
+$$;
+CREATE TRIGGER pgl_update_project AFTER UPDATE ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_update_project_team_rs();
\ No newline at end of file
-- 
GitLab


From 69ef43cc957783ddd13ac506bf51b6ce3bd61baa Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 4 May 2013 18:39:11 +0200
Subject: [PATCH 39/83] Fixes #1

---
 pgl/pgl_mysql_trigger.sql | 58 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 3 deletions(-)
 mode change 100644 => 100755 pgl/pgl_mysql_trigger.sql

diff --git a/pgl/pgl_mysql_trigger.sql b/pgl/pgl_mysql_trigger.sql
old mode 100644
new mode 100755
index 43c70b666b8..ec23fbfd6f5
--- a/pgl/pgl_mysql_trigger.sql
+++ b/pgl/pgl_mysql_trigger.sql
@@ -1,4 +1,7 @@
 DROP TRIGGER IF EXISTS pgl_new_user;
+DROP TRIGGER IF EXISTS pgl_new_project;
+DROP TRIGGER IF EXISTS pgl_update_project;
+
 delimiter //
 
 CREATE TRIGGER pgl_new_user
@@ -25,9 +28,6 @@ BEGIN
 END//
 
 DELIMITER ;
-
-DROP TRIGGER IF EXISTS pgl_new_project;
-
 delimiter //
 
 CREATE TRIGGER pgl_new_project
@@ -57,4 +57,56 @@ BEGIN
         INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());
     END IF;
 END//
+
 DELIMITER ;
+delimiter //
+
+CREATE TRIGGER pgl_update_project
+AFTER UPDATE ON projects FOR EACH ROW
+BEGIN
+    DECLARE m_users_id integer;
+    DECLARE done INT DEFAULT FALSE;
+    DECLARE rows INT;
+    DECLARE cur CURSOR FOR SELECT user_id FROM user_team_user_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters");
+    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
+
+    IF NEW.public <> OLD.public THEN
+        if NEW.public = 1 THEN
+
+            OPEN cur;
+                ins_loop: LOOP
+                    FETCH cur INTO m_users_id;
+                    IF done THEN
+                        LEAVE ins_loop;
+                    END IF;
+
+                    IF m_users_id <> NEW.creator_id THEN
+                        SELECT count(*) INTO rows FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id;
+                        IF rows = 0 THEN
+                            INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access)
+                            VALUES (m_users_id, NEW.id, now(), now(), 20);
+                        END IF;
+                    END IF;
+                END LOOP;
+            CLOSE cur;
+            INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now());
+        ELSE
+            OPEN cur;
+                ins_loop: LOOP
+                    FETCH cur INTO m_users_id;
+                    IF done THEN
+                        LEAVE ins_loop;
+                    END IF;
+
+                    SELECT project_access INTO rows FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id LIMIT 1;
+                    -- If project permission is reporter (20), or lower
+                    IF rows < 21 THEN
+                        DELETE FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id;
+                    END IF;
+                END LOOP;
+            CLOSE cur;
+            DELETE FROM user_team_project_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters") AND project_id = OLD.id;
+        END IF;
+    END IF;
+END//
+DELIMITER ;
\ No newline at end of file
-- 
GitLab


From f0a84f3abcafcb8faad71ae97e216c2bbf877322 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 6 May 2013 03:37:30 +0300
Subject: [PATCH 40/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d8dc560a55f..2034dfd3231 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ _Disclaimer_: I do not provide any support on GitLab itself. I only contribute t
 You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
 ## Changelog
 
-  * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab/edit/5-1-stable/README.md#update-public-gitlab) your DB triggers)
+  * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers)
   * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/5.0-to-5.1.md)
 
 > Warning: GitLab 5.1 does not work properly with old version of Git (ok on 1.7.10+). [More here](https://github.com/gitlabhq/gitlabhq/issues/3666). 
-- 
GitLab


From fbba9b40c94edf274fc19e8814f1da6c801f216d Mon Sep 17 00:00:00 2001
From: Justin Clift <jclift@redhat.com>
Date: Tue, 7 May 2013 09:21:31 +0200
Subject: [PATCH 41/83] Fix some minor typos in the README

---
 README.md | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md
index 2034dfd3231..b253d247297 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 ## Presentation
 
-Public GitLab is a fork of the official [GitLab](https://github.com/gitlabhq/gitlabhq) software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects). With this fork, I'm trying to reproduce Github behavior.
+Public GitLab is a fork of the official [GitLab](https://github.com/gitlabhq/gitlabhq) software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects). With this fork, I'm trying to reproduce Github behaviour.
 
 So by public I mean:
 
@@ -14,9 +14,9 @@ With these features, GitLab can be a self-hosted Github competitor.
 
 You can browse a live example at http://git.hoa.ro (you won't be able to create projects).
 
-_Disclaimer_: I do not provide any support on GitLab itself. I only contribute to the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
+_Disclaimer_: I do not provide any support on GitLab itself.  I only contribute to the _public_ part.  Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
 
-You should also be aware that **Public GitLab** only applies to the lastest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. `master` branch on this repo have high chance to be broken.
+You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
   * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers)
@@ -29,9 +29,9 @@ You should also be aware that **Public GitLab** only applies to the lastest [sta
 
 ## Installation
 
-During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-1-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
+During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/5-1-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
 
-**Warning**: Remember that you _need_ to use the lastest **stable branch**, even if you want to dowload it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-1-stable.zip).
+**Warning**: Remember that you _need_ to use the latest **stable branch**, even if you want to download it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-1-stable.zip).
 
 ### Clone the Source
 
@@ -45,21 +45,21 @@ During the [official intallation](https://github.com/gitlabhq/gitlabhq/blob/5-1-
     sudo -u git -H git checkout 5-1-stable
 
 ### Post installation
-At this point, every GitLab components are installed. You still can not access to GitLab yet though.
+At this point, all of the GitLab components are installed.  You still can't access GitLab though.
 
-The SQL script below will create a default `guest` user for anonymous access. It will also create a default team (`pgl_reporters`) which allows `reporter` permission to every new _future_ users, for all public projects.
+The SQL script below creates a default `guest` user for anonymous access.  It also creates a default team (`pgl_reporters`), giving `reporter` permission to all _future_ users for all public projects.
 
-> Note that your DB user need to be granted with TRIGGER permission on your database (this is specific to Public GitLab).
+> Note that your DB user needs to have the TRIGGER permission on your database (this is specific to Public GitLab).
 
 #### PostgreSQL
-You have to patch GitLab your database with 2 SQL scripts:
+You have to patch your GitLab database with 2 SQL scripts:
 
     cd /home/git/gitlab/pgl
     psql -h host -U user database < pgl_postgres_insert.sql
     psql -h host -U user database < pgl_postgres_trigger.sql
 
 #### MySQL
-You have to patch GitLab your database with 2 SQL scripts:
+You have to patch your GitLab database with 2 SQL scripts:
 
     cd /home/git/gitlab/pgl
     mysql -hhost -uuser -p
@@ -73,7 +73,7 @@ In the file ~/gitlab/config/gitlab.yml, uncomment:
 
     signup_enabled: true
 
-Note: Keep in mind that if you do not allow signup, guest wouldn't be able to report issues. 
+Note: Keep in mind that if you do not allow signups, guests won't be able to report issues. 
 
 If you do not want guest users to create projects on your GitLab installation, set `default_projects_limit: 0` in `config/gitlab.yaml`.
 
@@ -89,7 +89,7 @@ Then enjoy !
 
 You need to refer to official [update guides](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/) to upgrade GitLab version.
 
-If the changelog on this README indicate any SQL update, you need to update your database :
+If the changelog on this README indicates any SQL update, you need to update your database :
 
 PostgreSQL:
 
@@ -111,17 +111,17 @@ MySQL:
 
 See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/CONTRIBUTING.md).
 
-If there is a new stable branch, please do not open an issue to ask update. [Contact me](http://hoa.ro/static6/contact) instead.
+If there is a new stable branch, please do not open an issue to ask for an update.  [Contact me](http://hoa.ro/static6/contact) instead.
 
 ## Troubleshooting
 
 ### Removing root user
 
-The reporters team created by Public GitLab is owned by the root user (Administrator). If you delete this user, it will create several issues in your GitLab installation.
+The reporters team created by Public GitLab is owned by the root user (Administrator).  If you delete this user, it will create several issues in your GitLab installation.
 
 If you _really_ need to remove `root`, you need to change the `pgl_reporters` team's owner in GitLab administration before deleting it.
 
-If you have alrealdy deleted root user, you have to manually change Public GitLab SQL `insert` to :
+If you have already deleted the root user, you have to manually change Public GitLab SQL `insert` to :
 
     INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description) 
     VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'YOU_NEW_ADMIN_USERNAME'), now(), now(), 'Default new users team (reporter permission)'); 
-- 
GitLab


From 6313268b0697edf2dbbcf8ea6b223c5f97677294 Mon Sep 17 00:00:00 2001
From: Justin Clift <jclift@redhat.com>
Date: Wed, 8 May 2013 14:17:37 +0200
Subject: [PATCH 42/83] A few extra minor typo fixes. :)

---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index b253d247297..9e4c6b962e0 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@ If there is a new stable branch, please do not open an issue to ask for an updat
 
 ### Removing root user
 
-The reporters team created by Public GitLab is owned by the root user (Administrator).  If you delete this user, it will create several issues in your GitLab installation.
+The reporters team created by Public GitLab is owned by the root user (Administrator).  If you delete this user, it will cause problems in your GitLab installation.
 
 If you _really_ need to remove `root`, you need to change the `pgl_reporters` team's owner in GitLab administration before deleting it.
 
@@ -130,8 +130,8 @@ Read more at issues [#3](https://github.com/ArthurHoaro/Public-GitLab/issues/3)
 
 ## License
 
-Public GitLab is provided and maintain by [Arthur Hoaro](http://hoa.ro).
+Public GitLab is provided and maintained by [Arthur Hoaro](http://hoa.ro).
 
-Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/LICENSE) as the original sofware.
+Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/LICENSE) as the original software.
 
 This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
-- 
GitLab


From 9ad6f6133d98d599030b0a9c024a30dc48c5b97d Mon Sep 17 00:00:00 2001
From: Justin Clift <jclift@redhat.com>
Date: Wed, 8 May 2013 14:21:09 +0200
Subject: [PATCH 43/83] Small adjustments for the contributing page too. :)

---
 CONTRIBUTING.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1d4f6923388..0a9e80e42c7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,8 +2,8 @@
 
 If you have issues with Public GitLab, you can report them with the Github issues module.
 
-Please rememberer to privide as much information as you can (e.g. which database you are using).
+Please remember to provide as much information as you can (e.g. which database you are using).
 
 Disclaimer: I do not provide any support on GitLab itself. I only contribute to the _public part_. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself.
 
-If there is a new stable branch, please do not open an issue to ask update. Contact me instead.
+If there is a new stable branch, please do not open an issue to ask for an update.  [Contact me](http://hoa.ro/static6/contact) instead.
-- 
GitLab


From 905aa634de8201a00d245a814c9931786b313bcb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=89=E5=A5=BD=E8=89=AF=E5=92=8C?=
 <y.miyoshi@gloops.com>
Date: Thu, 23 May 2013 18:32:37 +0900
Subject: [PATCH 44/83] Fixed "recipe_content" path for 5-2-stable

---
 lib/tasks/gitlab/check.rake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 5e4a74b6260..94fd8b03016 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -144,7 +144,7 @@ namespace :gitlab do
         return
       end
 
-      recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab 2>/dev/null`
+      recipe_content = `curl https://raw.github.com/gitlabhq/gitlabhq/5-2-stable/lib/support/init.d/gitlab 2>/dev/null`
       script_content = File.read(script_path)
 
       if recipe_content == script_content
-- 
GitLab


From 37c6348d332d3eaaf70149be2ccfc62ae4d00eb0 Mon Sep 17 00:00:00 2001
From: Ben Bodenmiller <bbodenmiller@hotmail.com>
Date: Fri, 24 May 2013 16:53:32 -0700
Subject: [PATCH 45/83] update upgrade guide with backup, db specific commands,
 config changes, check, and restore

---
 doc/update/5.1-to-5.2.md | 59 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/doc/update/5.1-to-5.2.md b/doc/update/5.1-to-5.2.md
index 8f2116837b8..3f874555f49 100644
--- a/doc/update/5.1-to-5.2.md
+++ b/doc/update/5.1-to-5.2.md
@@ -1,5 +1,15 @@
 # From 5.1 to 5.2
 
+### 0. Backup
+
+It's useful to make a backup just in case things go south:
+(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create
+```
+
 ### 1. Stop server
 
     sudo service gitlab stop
@@ -20,14 +30,59 @@ sudo -u git -H git fetch
 sudo -u git -H git checkout v1.4.0
 ```
 
-### 4. Install libs, migrations etc
+### 4. Install libs, migrations, etc.
 
 ```bash
 cd /home/git/gitlab
+
+# MySQL
 sudo -u git -H bundle install --without development test postgres --deployment
+
+#PostgreSQL
+sudo -u git -H bundle install --without development test mysql --deployment
+
 sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
 ```
 
-### 5. Start application
+### 5. Update config files
+
+* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/gitlab.yml.example but with your settings.
+* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/puma.rb.example but with your settings.
+
+### 6. Update Init script
+
+```bash
+sudo rm /etc/init.d/gitlab
+sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-2-stable/lib/support/init.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
+```
+
+### 6. Start application
 
     sudo service gitlab start
+    sudo service nginx restart
+
+### 7. Check application status
+
+Check if GitLab and its environment are configured correctly:
+
+    sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
+
+To make sure you didn't miss anything run a more thorough check with:
+
+    sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+
+If all items are green, then congratulations upgrade complete!
+
+## Things went south? Revert to previous version (5.1)
+
+### 1. Revert the code to the previous version
+Follow the [`upgrade guide from 5.0 to 5.1`](5.0-to-5.1.md), except for the database migration 
+(The backup is already migrated to the previous version)
+
+### 2. Restore from the backup:
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore
+```
-- 
GitLab


From a9975336e8bf26c64345aa7eb067d9fee52602c3 Mon Sep 17 00:00:00 2001
From: MeiHui FAN <mhfan@ustc.edu>
Date: Thu, 16 May 2013 11:59:26 +0800
Subject: [PATCH 46/83] improve regrex for match(sidekiq) robustness

e.g.: the sidekiq in my Debian box is v2.11.1
---
 lib/tasks/gitlab/check.rake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 94fd8b03016..4c3a607a713 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -588,7 +588,7 @@ namespace :gitlab do
     def check_sidekiq_running
       print "Running? ... "
 
-      if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d\.\d\.\d.+$/)
+      if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d+\.\d+\.\d+.+$/)
         puts "yes".green
       else
         puts "no".red
-- 
GitLab


From 65d4cf3758f47154bf16a217b0147d71558e4729 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Wed, 29 May 2013 20:06:13 +0200
Subject: [PATCH 47/83] readme

---
 README.md | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
 mode change 100644 => 100755 README.md

diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index 9e4c6b962e0..67583b932b4
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ _Disclaimer_: I do not provide any support on GitLab itself.  I only contribute
 You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
+  * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/5-2-stable/doc/update/5.1-to-5.2.md)
   * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers)
   * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/5.0-to-5.1.md)
 
@@ -29,9 +30,9 @@ You should also be aware that **Public GitLab** only applies to the latest [stab
 
 ## Installation
 
-During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/5-1-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
+During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
 
-**Warning**: Remember that you _need_ to use the latest **stable branch**, even if you want to download it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-1-stable.zip).
+**Warning**: Remember that you _need_ to use the latest **stable branch**, even if you want to download it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-2-stable.zip).
 
 ### Clone the Source
 
@@ -42,7 +43,7 @@ During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/5-1
     cd /home/git/gitlab
 
     # Checkout to stable release
-    sudo -u git -H git checkout 5-1-stable
+    sudo -u git -H git checkout 5-2-stable
 
 ### Post installation
 At this point, all of the GitLab components are installed.  You still can't access GitLab though.
@@ -87,7 +88,7 @@ Then enjoy !
 
 ## Update Public GitLab
 
-You need to refer to official [update guides](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/doc/update/) to upgrade GitLab version.
+You need to refer to official [update guides](https://github.com/ArthurHoaro/Public-GitLab/blob/5-2-stable/doc/update/) to upgrade GitLab version.
 
 If the changelog on this README indicates any SQL update, you need to update your database :
 
@@ -109,7 +110,7 @@ MySQL:
 
 ## Reporting issues
 
-See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/CONTRIBUTING.md).
+See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/5-2-stable/CONTRIBUTING.md).
 
 If there is a new stable branch, please do not open an issue to ask for an update.  [Contact me](http://hoa.ro/static6/contact) instead.
 
@@ -132,6 +133,6 @@ Read more at issues [#3](https://github.com/ArthurHoaro/Public-GitLab/issues/3)
 
 Public GitLab is provided and maintained by [Arthur Hoaro](http://hoa.ro).
 
-Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-1-stable/LICENSE) as the original software.
+Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-2-stable/LICENSE) as the original software.
 
 This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
-- 
GitLab


From 90dbab5508f1286b9ca4f5561df93545589a0efa Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sun, 2 Jun 2013 15:31:02 +0200
Subject: [PATCH 48/83] Fixes #10: add download ability to guests

---
 app/models/ability.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/models/ability.rb b/app/models/ability.rb
index 3d76bd79b8b..ab3f197c13e 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -71,7 +71,7 @@ class Ability
     end
 
     def project_guest_rules
-      project_anon_rules + [
+      project_anon_and_download_rules + [
         :write_project,
         :write_issue,
         :write_note
-- 
GitLab


From 1d1df01e3792198e1368efc7b555284f732e5bd3 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Wed, 19 Jun 2013 18:32:04 +0200
Subject: [PATCH 49/83] Fixes #12 - Head signup link

---
 app/views/layouts/_head_panel.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 7d294b65047..8729935b9cf 100755
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -29,7 +29,7 @@
               %i.icon-user
             - if Gitlab.config.gitlab.signup_enabled
               %li
-                = link_to "#{request.protocol}#{request.host}:#{request.port}/users/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
+                = link_to "#{user_registration_path}/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up'  do
                   %i.icon-briefcase
           - else
             %li
-- 
GitLab


From 5c74c31484d48bc1c8a9867d89e0c433d574b257 Mon Sep 17 00:00:00 2001
From: Robert Schilling <rschilling@student.tugraz.at>
Date: Sat, 22 Jun 2013 13:34:34 +0200
Subject: [PATCH 50/83] Add fixed update docs

---
 doc/update/5.2-to-5.3.md | 80 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 doc/update/5.2-to-5.3.md

diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md
new file mode 100644
index 00000000000..764312d0986
--- /dev/null
+++ b/doc/update/5.2-to-5.3.md
@@ -0,0 +1,80 @@
+# From 5.2 to 5.3
+
+### 0. Backup
+
+It's useful to make a backup just in case things go south:
+(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create
+```
+
+### 1. Stop server
+
+    sudo service gitlab stop
+
+### 2. Get latest code
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H git fetch
+sudo -u git -H git checkout 5-3-stable
+```
+
+### 3. Install libs, migrations, etc.
+
+```bash
+cd /home/git/gitlab
+
+# MySQL
+sudo -u git -H bundle install --without development test postgres --deployment
+
+#PostgreSQL
+sudo -u git -H bundle install --without development test mysql --deployment
+
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+```
+
+### 4. Update config files
+
+* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/gitlab.yml.example but with your settings.
+* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/puma.rb.example but with your settings.
+
+### 5. Update Init script
+
+```bash
+sudo rm /etc/init.d/gitlab
+sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-3-stable/lib/support/init.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
+```
+
+### 6. Start application
+
+    sudo service gitlab start
+    sudo service nginx restart
+
+### 7. Check application status
+
+Check if GitLab and its environment are configured correctly:
+
+    sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
+
+To make sure you didn't miss anything run a more thorough check with:
+
+    sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+
+If all items are green, then congratulations upgrade complete!
+
+## Things went south? Revert to previous version (5.2)
+
+### 1. Revert the code to the previous version
+Follow the [`upgrade guide from 5.1 to 5.2`](5.1-to-5.2.md), except for the database migration 
+(The backup is already migrated to the previous version)
+
+### 2. Restore from the backup:
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore
+```
\ No newline at end of file
-- 
GitLab


From ff2af99ca796bab3b780d2263e7255b2a02db103 Mon Sep 17 00:00:00 2001
From: Martin Lauer <martin.lauer@b13.de>
Date: Tue, 25 Jun 2013 14:32:52 +0200
Subject: [PATCH 51/83] raise App Version to stable Branch 5.3

---
 lib/support/init.d/gitlab | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab
index f4ca07b3676..faab0743168 100644
--- a/lib/support/init.d/gitlab
+++ b/lib/support/init.d/gitlab
@@ -2,7 +2,7 @@
 
 # GITLAB
 # Maintainer: @randx
-# App Version: 5.2
+# App Version: 5.3
 
 ### BEGIN INIT INFO
 # Provides:          gitlab
-- 
GitLab


From bbe40f8bded7b61b843fa459ce3ed4145a137b2d Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sun, 30 Jun 2013 21:07:25 +0200
Subject: [PATCH 52/83] New beta feature. Check it out on README's changelog.

---
 README.md                                     |  2 ++
 app/models/project.rb                         | 10 ++++++--
 app/models/user.rb                            | 23 +++++++++++++++++--
 app/views/admin/users/_form.html.haml         |  4 ++++
 app/views/profiles/show.html.haml             | 14 ++++++++++-
 config/gitlab.yml.example                     |  1 +
 config/initializers/1_settings.rb             |  1 +
 .../20130630204200_add_private_limit.rb       |  5 ++++
 db/schema.rb                                  |  3 ++-
 9 files changed, 57 insertions(+), 6 deletions(-)
 create mode 100644 db/migrate/20130630204200_add_private_limit.rb

diff --git a/README.md b/README.md
index 257bb3e0745..cb4fa09dd72 100755
--- a/README.md
+++ b/README.md
@@ -19,6 +19,8 @@ _Disclaimer_: I do not provide any support on GitLab itself.  I only contribute
 You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
+  * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to Mike for the idea.
+  Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
   * [2013-06-30] : Public GitLab supports GitLab 5.3 (stable) - [Upgrade 5.2 to 5.3](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.2-to-5.3.md)
   * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.1-to-5.2.md)
   * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers)
diff --git a/app/models/project.rb b/app/models/project.rb
index 382e2ab11a0..23a9d83ef77 100755
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -160,8 +160,14 @@ class Project < ActiveRecord::Base
   end
 
   def check_limit
-    unless creator.can_create_project?
-      errors[:limit_reached] << ("Your own projects limit is #{creator.projects_limit}! Please contact administrator to increase it")
+    if self.public
+      unless creator.can_create_project?
+        errors[:limit_reached] << ("Your own public projects limit is #{creator.projects_limit}! Please contact administrator to increase it")
+      end
+    else
+      unless creator.can_create_project_priv?
+        errors[:limit_reached] << ("Your own private projects limit is #{creator.projects_limit_priv}! Please contact administrator to increase it")
+      end
     end
   rescue
     errors[:base] << ("Can't check your ability to create project")
diff --git a/app/models/user.rb b/app/models/user.rb
index cd58f5bb6e9..3f2d6bb6c17 100755
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -18,6 +18,7 @@
 #  name                   :string(255)
 #  admin                  :boolean          default(FALSE), not null
 #  projects_limit         :integer          default(10)
+#  projects_limit_priv    :integer          default(10)
 #  skype                  :string(255)      default(""), not null
 #  linkedin               :string(255)      default(""), not null
 #  twitter                :string(255)      default(""), not null
@@ -45,7 +46,7 @@ class User < ActiveRecord::Base
                   :extern_uid, :provider, :password_expires_at,
                   as: [:default, :admin]
 
-  attr_accessible :projects_limit, :can_create_team, :can_create_group,
+  attr_accessible :projects_limit, :projects_limit_priv, :can_create_team, :can_create_group,
                   as: :admin
 
   attr_accessor :force_random_password
@@ -96,7 +97,10 @@ class User < ActiveRecord::Base
   has_many :master_projects,          through: :users_projects, source: :project,
                                       conditions: { users_projects: { project_access: UsersProject::MASTER } }
   has_many :own_projects,             foreign_key: :creator_id, class_name: 'Project'
-  has_many :owned_projects,           through: :namespaces, source: :projects
+  has_many :owned_projects,           through: :namespaces, source: :projects,
+                                      conditions: { projects: { public: true } }
+  has_many :owned_projects_priv,      through: :namespaces, source: :projects,
+                                      conditions: { projects: { public: false } }
 
   #
   # Validations
@@ -106,6 +110,7 @@ class User < ActiveRecord::Base
   validates :bio, length: { within: 0..255 }
   validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
   validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
+  validates :projects_limit_priv, presence: true, numericality: {greater_than_or_equal_to: 0}
   validates :username, presence: true, uniqueness: true,
             exclusion: { in: Gitlab::Blacklist.path },
             format: { with: Gitlab::Regex.username_regex,
@@ -206,6 +211,7 @@ class User < ActiveRecord::Base
   def with_defaults
     tap do |u|
       u.projects_limit = Gitlab.config.gitlab.default_projects_limit
+      u.projects_limit_priv = Gitlab.config.gitlab.default_projects_limit_private
       u.can_create_group = Gitlab.config.gitlab.default_can_create_group
       u.can_create_team = Gitlab.config.gitlab.default_can_create_team
     end
@@ -288,6 +294,10 @@ class User < ActiveRecord::Base
     projects_limit > owned_projects.count
   end
 
+  def can_create_project_priv?
+    projects_limit_priv > owned_projects_priv.count
+  end
+
   def can_create_group?
     can?(:create_group, nil)
   end
@@ -325,6 +335,15 @@ class User < ActiveRecord::Base
     (owned_projects.count.to_f / projects_limit) * 100
   end
 
+  def projects_limit_left_priv
+    projects_limit_priv - owned_projects_priv.count
+  end
+
+  def projects_limit_percent_priv
+    return 100 if projects_limit_priv.zero?
+    (owned_projects_priv.count.to_f / projects_limit_priv) * 100
+  end
+
   def recent_push project_id = nil
     # Get push events not earlier than 2 hours ago
     events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index fdf37965091..2a3572bcc13 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -52,6 +52,10 @@
             = f.label :projects_limit
             .input= f.number_field :projects_limit
 
+          .clearfix
+            = f.label :projects_limit_priv
+            .input= f.number_field :projects_limit_priv
+
           .clearfix
             = f.label :can_create_group
             .input= f.check_box :can_create_group
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index d4793da8987..4f85f07f92f 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -76,7 +76,7 @@
       - unless current_user.projects_limit_left > 100
         %fieldset
           %legend
-            Owned projects:
+            Owned public projects:
             %small.pull-right
               %span= current_user.owned_projects.count
               of
@@ -85,6 +85,18 @@
             .progress
               .bar{style: "width: #{current_user.projects_limit_percent}%;"}
 
+      - unless current_user.projects_limit_left > 100
+        %fieldset
+          %legend
+            Owned private projects:
+            %small.pull-right
+              %span= current_user.owned_projects_priv.count
+              of
+              %span= current_user.projects_limit_priv
+          .padded
+            .progress
+              .bar{style: "width: #{current_user.projects_limit_percent_priv}%;"}
+
       %fieldset
         %legend
           SSH public keys:
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index a612102ab1c..9b1fef7f1ea 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -34,6 +34,7 @@ production: &base
 
     ## User settings
     default_projects_limit: 10
+    default_projects_limit_private: 5
     # default_can_create_group: false  # default: true
     # default_can_create_team: false   # default: true
     # username_changing_enabled: false # default: true - User can change her username/namespace
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 4afe50f1814..ae278721a7f 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -49,6 +49,7 @@ Settings['issues_tracker']  ||= {}
 #
 Settings['gitlab'] ||= Settingslogic.new({})
 Settings.gitlab['default_projects_limit'] ||= 10
+Settings.gitlab['default_projects_limit_private'] ||= 5
 Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_can_create_group'].nil?
 Settings.gitlab['default_can_create_team']  = true if Settings.gitlab['default_can_create_team'].nil?
 Settings.gitlab['host']       ||= 'localhost'
diff --git a/db/migrate/20130630204200_add_private_limit.rb b/db/migrate/20130630204200_add_private_limit.rb
new file mode 100644
index 00000000000..639798b9ab7
--- /dev/null
+++ b/db/migrate/20130630204200_add_private_limit.rb
@@ -0,0 +1,5 @@
+class AddPrivateLimit < ActiveRecord::Migration
+  def change
+    add_column :users, :projects_limit_priv, :integer, default: 5, null: true
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f7ced1a277b..aba34c96615 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20130614132337) do
+ActiveRecord::Schema.define(:version => 20130630204200) do
 
   create_table "deploy_keys_projects", :force => true do |t|
     t.integer  "deploy_key_id", :null => false
@@ -292,6 +292,7 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
     t.integer  "notification_level",                    :default => 1,     :null => false
     t.datetime "password_expires_at"
     t.integer  "created_by_id"
+    t.integer  "projects_limit_priv",                   :default => 5
   end
 
   add_index "users", ["admin"], :name => "index_users_on_admin"
-- 
GitLab


From a0ef6a87971992b1591d22087856c3dce062557d Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sun, 30 Jun 2013 21:11:15 +0200
Subject: [PATCH 53/83] README

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index cb4fa09dd72..4e8693837a3 100755
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ You should also be aware that **Public GitLab** only applies to the latest [stab
 ## Changelog
 
   * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to Mike for the idea.
-  Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
+  > Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
   * [2013-06-30] : Public GitLab supports GitLab 5.3 (stable) - [Upgrade 5.2 to 5.3](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.2-to-5.3.md)
   * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.1-to-5.2.md)
   * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers)
-- 
GitLab


From 7c32aa8ffbf22b7560a7b708abf21b1c9cefe298 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sun, 30 Jun 2013 21:11:53 +0200
Subject: [PATCH 54/83] README

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 4e8693837a3..4c5c2980137 100755
--- a/README.md
+++ b/README.md
@@ -20,7 +20,9 @@ You should also be aware that **Public GitLab** only applies to the latest [stab
 ## Changelog
 
   * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to Mike for the idea.
+  
   > Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
+  
   * [2013-06-30] : Public GitLab supports GitLab 5.3 (stable) - [Upgrade 5.2 to 5.3](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.2-to-5.3.md)
   * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.1-to-5.2.md)
   * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers)
-- 
GitLab


From 49927b7e4696d43c225761520f9cb2f2d464a2f5 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 1 Jul 2013 07:38:42 +0200
Subject: [PATCH 55/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 4c5c2980137..d73fe4e3b3c 100755
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ _Disclaimer_: I do not provide any support on GitLab itself.  I only contribute
 You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
-  * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to Mike for the idea.
+  * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to (Mike)[https://github.com/MJSmith5] for the idea.
   
   > Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
   
-- 
GitLab


From 507076bccab4c6ca94eafbd5c72df49b6381f985 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 1 Jul 2013 07:39:21 +0200
Subject: [PATCH 56/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d73fe4e3b3c..1d7d05dfddc 100755
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ _Disclaimer_: I do not provide any support on GitLab itself.  I only contribute
 You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
-  * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to (Mike)[https://github.com/MJSmith5] for the idea.
+  * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to [Mike](https://github.com/MJSmith5) for the idea.
   
   > Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
   
-- 
GitLab


From 2afce699f848b7a1466df70f1231c31b8825cb6b Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 1 Jul 2013 12:57:07 +0200
Subject: [PATCH 57/83] Bugfix

---
 app/views/layouts/_head_panel.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index dd6a6a15a13..e6bcb40b8b7 100755
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -26,7 +26,7 @@
             %li
               = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do
                 %i.icon-cogs
-          - if current_user.can_create_project?
+          - if current_user.can_create_project? || current_user.can_create_project_priv?
             %li
               = link_to new_project_path, title: "Create New Project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project'  do
                 %i.icon-plus
-- 
GitLab


From c85fdc625ad4ebb8a3dc8111f6b97a70e870b39c Mon Sep 17 00:00:00 2001
From: Michael Smith <MikeJSmith5@Gmail.com>
Date: Fri, 5 Jul 2013 23:51:34 -0400
Subject: [PATCH 58/83] Fixed check on number of private projects left

---
 app/views/profiles/show.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 4f85f07f92f..a71dc571d4c 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -85,7 +85,7 @@
             .progress
               .bar{style: "width: #{current_user.projects_limit_percent}%;"}
 
-      - unless current_user.projects_limit_left > 100
+      - unless current_user.projects_limit_left_priv > 100
         %fieldset
           %legend
             Owned private projects:
-- 
GitLab


From b6c2bce4d89a24217f4cc8f6e3ded70d1df96a3e Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 6 Jul 2013 12:37:13 +0200
Subject: [PATCH 59/83] label

---
 app/views/admin/users/_form.html.haml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index 2a3572bcc13..78119b3f24c 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -49,11 +49,11 @@
       .row
         .span8
           .clearfix
-            = f.label :projects_limit
+            = f.label :projects_limit_public
             .input= f.number_field :projects_limit
 
           .clearfix
-            = f.label :projects_limit_priv
+            = f.label :projects_limit_private
             .input= f.number_field :projects_limit_priv
 
           .clearfix
-- 
GitLab


From 84093fb545d1ebfafa9c461c1da00fe8135211ed Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sat, 6 Jul 2013 12:42:11 +0200
Subject: [PATCH 60/83] README

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 1d7d05dfddc..b5f0eb1e82b 100755
--- a/README.md
+++ b/README.md
@@ -19,9 +19,10 @@ _Disclaimer_: I do not provide any support on GitLab itself.  I only contribute
 You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
-  * [2013-06-30] : New beta feature ! Added a different projects number limit per user for private and public projects. Thanks to [Mike](https://github.com/MJSmith5) for the idea.
+  * [2013-07-06] : [New feature](https://github.com/ArthurHoaro/Public-GitLab/pull/19) ! Added a different projects number limit per user for private and public projects. Thanks to [Mike](https://github.com/MJSmith5) for the idea.
   
   > Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
+  > Warning: New option in `config/gitlab.yml.example` (`default_projects_limit_private`).
   
   * [2013-06-30] : Public GitLab supports GitLab 5.3 (stable) - [Upgrade 5.2 to 5.3](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.2-to-5.3.md)
   * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/5-3-stable/doc/update/5.1-to-5.2.md)
-- 
GitLab


From f24c6e835314676aec02f9349fedfd2f3d61b4a7 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 18 Jul 2013 19:32:13 +0300
Subject: [PATCH 61/83] Doc for update from 5.3 to 5.4

---
 doc/update/5.3-to-5.4.md | 80 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 doc/update/5.3-to-5.4.md

diff --git a/doc/update/5.3-to-5.4.md b/doc/update/5.3-to-5.4.md
new file mode 100644
index 00000000000..67f32f66a97
--- /dev/null
+++ b/doc/update/5.3-to-5.4.md
@@ -0,0 +1,80 @@
+# From 5.3 to 5.4
+
+### 0. Backup
+
+It's useful to make a backup just in case things go south:
+(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create
+```
+
+### 1. Stop server
+
+    sudo service gitlab stop
+
+### 2. Get latest code
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H git fetch
+sudo -u git -H git checkout 5-4-stable
+```
+
+### 3. Install libs, migrations, etc.
+
+```bash
+cd /home/git/gitlab
+
+# MySQL
+sudo -u git -H bundle install --without development test postgres --deployment
+
+#PostgreSQL
+sudo -u git -H bundle install --without development test mysql --deployment
+
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+```
+
+### 4. Update config files
+
+* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/gitlab.yml.example but with your settings.
+* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/puma.rb.example but with your settings.
+
+### 5. Update Init script
+
+```bash
+sudo rm /etc/init.d/gitlab
+sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-4-stable/lib/support/init.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
+```
+
+### 6. Start application
+
+    sudo service gitlab start
+    sudo service nginx restart
+
+### 7. Check application status
+
+Check if GitLab and its environment are configured correctly:
+
+    sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
+
+To make sure you didn't miss anything run a more thorough check with:
+
+    sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+
+If all items are green, then congratulations upgrade complete!
+
+## Things went south? Revert to previous version (5.3)
+
+### 1. Revert the code to the previous version
+Follow the [`upgrade guide from 5.2 to 5.3`](5.2-to-5.3.md), except for the database migration 
+(The backup is already migrated to the previous version)
+
+### 2. Restore from the backup:
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore
+```
-- 
GitLab


From 7a165d2056941c90ed806e6a79941445df385ab9 Mon Sep 17 00:00:00 2001
From: Lukas Schauer <lukas2511@xxpro.net>
Date: Thu, 18 Jul 2013 18:52:24 +0200
Subject: [PATCH 62/83] Update installation.md

fixed branch-name (5-3 -> 5-4)
---
 doc/install/installation.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/install/installation.md b/doc/install/installation.md
index 6cad280acaf..d8a18c12058 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -150,7 +150,7 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install
     cd /home/git/gitlab
 
     # Checkout to stable release
-    sudo -u git -H git checkout 5-3-stable
+    sudo -u git -H git checkout 5-4-stable
 
 **Note:**
 You can change `5-3-stable` to `master` if you want the *bleeding edge* version, but do so with caution!
-- 
GitLab


From a5a7555c1d8796d385de5101e34d35705b7249f4 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 19 Jul 2013 12:27:09 +0000
Subject: [PATCH 63/83] Update VERSION to 5.4.0

---
 VERSION | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/VERSION b/VERSION
index 6b372fac825..1e20ec35c64 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.4.0.rc1
+5.4.0
\ No newline at end of file
-- 
GitLab


From 94a814d3acd3cb87823adf64aca54d7087c0b2d4 Mon Sep 17 00:00:00 2001
From: Jacob Vosmaer <contact@jacobvosmaer.nl>
Date: Mon, 22 Jul 2013 10:50:36 +0200
Subject: [PATCH 64/83] Update references to 5-3-stable in install guide

---
 doc/install/installation.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/doc/install/installation.md b/doc/install/installation.md
index d8a18c12058..96500971d35 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -153,7 +153,7 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install
     sudo -u git -H git checkout 5-4-stable
 
 **Note:**
-You can change `5-3-stable` to `master` if you want the *bleeding edge* version, but do so with caution!
+You can change `5-4-stable` to `master` if you want the *bleeding edge* version, but do so with caution!
 
 ## Configure it
 
@@ -357,10 +357,10 @@ GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already
 
 These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation.
 
-* Add `gem "omniauth-your-auth-provider"` to the [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/Gemfile#L18)
+* Add `gem "omniauth-your-auth-provider"` to the [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/Gemfile#L19)
 * Run `sudo -u git -H bundle install` to install the new gem(s)
-* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/gitlab.yml.example#L53) as a reference)
-* Add icons for the new provider into the [vendor/assets/images/authbuttons](https://github.com/gitlabhq/gitlabhq/tree/5-3-stable/vendor/assets/images/authbuttons) directory (you can find some more popular ones over at https://github.com/intridea/authbuttons)
+* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/gitlab.yml.example#L113) as a reference)
+* Add icons for the new provider into the [vendor/assets/images/authbuttons](https://github.com/gitlabhq/gitlabhq/tree/5-4-stable/vendor/assets/images/authbuttons) directory (you can find some more popular ones over at https://github.com/intridea/authbuttons)
 * Restart GitLab
 
 ### Examples
-- 
GitLab


From bcea5aa08f4d1ac56f576881325688e3382d101a Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Wed, 24 Jul 2013 13:12:44 +0200
Subject: [PATCH 65/83] Fixing ability code (relative to #20)

---
 app/models/ability.rb | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/app/models/ability.rb b/app/models/ability.rb
index 1e737b06199..cd1143c4b81 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -42,12 +42,12 @@ class Ability
         rules << project_guest_rules
 
       elsif project.is_public?
-        rules << project_anon_and_download_rules
+        rules << project_anon_rules 
       end
 
-      if project.public?
-        rules << public_project_rules
-      end
+      # if project.public?
+      #   rules << public_project_rules
+      # end
 
       if project.owner == user || user.admin?
         rules << project_admin_rules
@@ -83,17 +83,12 @@ class Ability
         :read_team_member,
         :read_merge_request,
         :read_note,
-      ]
-    end
-
-    def project_anon_and_download_rules
-      project_anon_rules + [
         :download_code
       ]
     end
 
     def project_guest_rules
-      project_anon_and_download_rules + [
+      project_anon_rules + [
         :write_project,
         :write_issue,
         :write_note
-- 
GitLab


From 6131540f8d821af761c4758bd3cd771b181833de Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 29 Jul 2013 19:35:04 +0200
Subject: [PATCH 66/83] Fixes #22

---
 app/models/ability.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/models/ability.rb b/app/models/ability.rb
index cd1143c4b81..c718566ca73 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -79,7 +79,7 @@ class Ability
         :read_wiki,
         :read_issue,
         :read_milestone,
-        :read_snippet,
+        :read_project_snippet,
         :read_team_member,
         :read_merge_request,
         :read_note,
-- 
GitLab


From 206b4a4881ee4a2cf69f0e99efb33a51735afa03 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 29 Jul 2013 20:05:42 +0200
Subject: [PATCH 67/83] remove /lib/gitlab/git

---
 lib/gitlab/git/blame.rb      |  23 ----
 lib/gitlab/git/blob.rb       |  42 -------
 lib/gitlab/git/commit.rb     | 127 ---------------------
 lib/gitlab/git/compare.rb    |  35 ------
 lib/gitlab/git/diff.rb       |  63 -----------
 lib/gitlab/git/repository.rb | 212 -----------------------------------
 lib/gitlab/git/stats.rb      |  75 -------------
 lib/gitlab/git/tree.rb       |  52 ---------
 8 files changed, 629 deletions(-)
 delete mode 100644 lib/gitlab/git/blame.rb
 delete mode 100644 lib/gitlab/git/blob.rb
 delete mode 100644 lib/gitlab/git/commit.rb
 delete mode 100644 lib/gitlab/git/compare.rb
 delete mode 100644 lib/gitlab/git/diff.rb
 delete mode 100644 lib/gitlab/git/repository.rb
 delete mode 100644 lib/gitlab/git/stats.rb
 delete mode 100644 lib/gitlab/git/tree.rb

diff --git a/lib/gitlab/git/blame.rb b/lib/gitlab/git/blame.rb
deleted file mode 100644
index d7282c587aa..00000000000
--- a/lib/gitlab/git/blame.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-module Gitlab
-  module Git
-    class Blame
-
-      attr_accessor :repository, :sha, :path
-
-      def initialize(repository, sha, path)
-        @repository, @sha, @path = repository, sha, path
-      end
-
-      def each
-        raw_blame = Grit::Blob.blame(repository.repo, sha, path)
-
-        raw_blame.each do |commit, lines|
-          next unless commit
-
-          commit = Gitlab::Git::Commit.new(commit)
-          yield(commit, lines)
-        end
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
deleted file mode 100644
index 57b89912f2d..00000000000
--- a/lib/gitlab/git/blob.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-module Gitlab
-  module Git
-    class Blob
-      include Linguist::BlobHelper
-
-      attr_accessor :raw_blob
-
-      delegate :name, to: :raw_blob
-
-      def initialize(repository, sha, ref, path)
-        @repository, @sha, @ref = repository, sha, ref
-
-        @commit = @repository.commit(sha)
-        @raw_blob = @repository.tree(@commit, path)
-      end
-
-      def data
-        if raw_blob
-          raw_blob.data
-        else
-          nil
-        end
-      end
-
-      def exists?
-        raw_blob
-      end
-
-      def empty?
-        data.blank?
-      end
-
-      def mode
-        raw_blob.mode
-      end
-
-      def size
-        raw_blob.size
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
deleted file mode 100644
index a92c21a0da1..00000000000
--- a/lib/gitlab/git/commit.rb
+++ /dev/null
@@ -1,127 +0,0 @@
-# Gitlab::Git::Commit is a wrapper around native Grit::Commit object
-# We dont want to use grit objects inside app/
-# It helps us easily migrate to rugged in future
-module Gitlab
-  module Git
-    class Commit
-      attr_accessor :raw_commit, :head, :refs,
-        :id, :authored_date, :committed_date, :message,
-        :author_name, :author_email, :parent_ids,
-        :committer_name, :committer_email
-
-      delegate :parents, :tree, :stats, :to_patch,
-        to: :raw_commit
-
-      def initialize(raw_commit, head = nil)
-        raise "Nil as raw commit passed" unless raw_commit
-
-        if raw_commit.is_a?(Hash)
-          init_from_hash(raw_commit)
-        else
-          init_from_grit(raw_commit)
-        end
-
-        @head = head
-      end
-
-      def serialize_keys
-        @serialize_keys ||= %w(id authored_date committed_date author_name author_email committer_name committer_email message parent_ids).map(&:to_sym)
-      end
-
-      def sha
-        id
-      end
-
-      def short_id(length = 10)
-        id.to_s[0..length]
-      end
-
-      def safe_message
-        @safe_message ||= message
-      end
-
-      def created_at
-        committed_date
-      end
-
-      # Was this commit committed by a different person than the original author?
-      def different_committer?
-        author_name != committer_name || author_email != committer_email
-      end
-
-      def parent_id
-        parent_ids.first
-      end
-
-      # Shows the diff between the commit's parent and the commit.
-      #
-      # Cuts out the header and stats from #to_patch and returns only the diff.
-      def to_diff
-        # see Grit::Commit#show
-        patch = to_patch
-
-        # discard lines before the diff
-        lines = patch.split("\n")
-        while !lines.first.start_with?("diff --git") do
-          lines.shift
-        end
-        lines.pop if lines.last =~ /^[\d.]+$/ # Git version
-          lines.pop if lines.last == "-- "      # end of diff
-        lines.join("\n")
-      end
-
-      def has_zero_stats?
-        stats.total.zero?
-      rescue
-        true
-      end
-
-      def no_commit_message
-        "--no commit message"
-      end
-
-      def to_hash
-        hash = {}
-
-        keys = serialize_keys
-
-        keys.each do |key|
-          hash[key] = send(key)
-        end
-
-        hash
-      end
-
-      def date
-        committed_date
-      end
-
-      def diffs
-        raw_commit.diffs.map { |diff| Gitlab::Git::Diff.new(diff) }
-      end
-
-      private
-
-      def init_from_grit(grit)
-        @raw_commit = grit
-        @id = grit.id
-        @message = grit.message
-        @authored_date = grit.authored_date
-        @committed_date = grit.committed_date
-        @author_name = grit.author.name
-        @author_email = grit.author.email
-        @committer_name = grit.committer.name
-        @committer_email = grit.committer.email
-        @parent_ids = grit.parents.map(&:id)
-      end
-
-      def init_from_hash(hash)
-        raw_commit = hash.symbolize_keys
-
-        serialize_keys.each do |key|
-          send(:"#{key}=", raw_commit[key.to_sym])
-        end
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/git/compare.rb b/lib/gitlab/git/compare.rb
deleted file mode 100644
index e34f204e8bd..00000000000
--- a/lib/gitlab/git/compare.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-module Gitlab
-  module Git
-    class Compare
-      attr_accessor :commits, :commit, :diffs, :same
-
-      def initialize(repository, from, to)
-        @commits, @diffs = [], []
-        @commit = nil
-        @same = false
-
-        return unless from && to
-
-        first = repository.commit(to.try(:strip))
-        last = repository.commit(from.try(:strip))
-
-        return unless first && last
-
-        if first.id == last.id
-          @same = true
-          return
-        end
-
-        @commit = first
-        @commits = repository.commits_between(last.id, first.id)
-
-        @diffs = if @commits.size > 100
-                   []
-                 else
-                   repository.repo.diff(last.id, first.id) rescue []
-                 end
-      end
-    end
-  end
-end
-
diff --git a/lib/gitlab/git/diff.rb b/lib/gitlab/git/diff.rb
deleted file mode 100644
index 45191dd3f91..00000000000
--- a/lib/gitlab/git/diff.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# Gitlab::Git::Diff is a wrapper around native Grit::Diff object
-# We dont want to use grit objects inside app/
-# It helps us easily migrate to rugged in future
-module Gitlab
-  module Git
-    class Diff
-      BROKEN_DIFF = "--broken-diff"
-
-      attr_accessor :raw_diff
-
-      # Diff properties
-      attr_accessor :old_path, :new_path, :a_mode, :b_mode, :diff
-
-      # Stats properties
-      attr_accessor  :new_file, :renamed_file, :deleted_file
-
-      def initialize(raw_diff)
-        raise "Nil as raw diff passed" unless raw_diff
-
-        if raw_diff.is_a?(Hash)
-          init_from_hash(raw_diff)
-        else
-          init_from_grit(raw_diff)
-        end
-      end
-
-      def serialize_keys
-        @serialize_keys ||= %w(diff new_path old_path a_mode b_mode new_file renamed_file deleted_file).map(&:to_sym)
-      end
-
-      def to_hash
-        hash = {}
-
-        keys = serialize_keys
-
-        keys.each do |key|
-          hash[key] = send(key)
-        end
-
-        hash
-      end
-
-      private
-
-      def init_from_grit(grit)
-        @raw_diff = grit
-
-        serialize_keys.each do |key|
-          send(:"#{key}=", grit.send(key))
-        end
-      end
-
-      def init_from_hash(hash)
-        raw_diff = hash.symbolize_keys
-
-        serialize_keys.each do |key|
-          send(:"#{key}=", raw_diff[key.to_sym])
-        end
-      end
-    end
-  end
-end
-
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
deleted file mode 100644
index ddead51d443..00000000000
--- a/lib/gitlab/git/repository.rb
+++ /dev/null
@@ -1,212 +0,0 @@
-# Gitlab::Git::Gitlab::Git::Commit is a wrapper around native Grit::Repository object
-# We dont want to use grit objects inside app/
-# It helps us easily migrate to rugged in future
-module Gitlab
-  module Git
-    class Repository
-      include Gitlab::Popen
-
-      class NoRepository < StandardError; end
-
-      # Repository directory name with namespace direcotry
-      # Examples:
-      #   gitlab/gitolite
-      #   diaspora
-      #
-      attr_accessor :path_with_namespace
-
-      # Grit repo object
-      attr_accessor :repo
-
-      # Default branch in the repository
-      attr_accessor :root_ref
-
-      def initialize(path_with_namespace, root_ref = 'master')
-        @root_ref = root_ref || "master"
-        @path_with_namespace = path_with_namespace
-
-        # Init grit repo object
-        repo
-      end
-
-      def raw
-        repo
-      end
-
-      def path_to_repo
-        @path_to_repo ||= File.join(repos_path, "#{path_with_namespace}.git")
-      end
-
-      def repos_path
-        Gitlab.config.gitlab_shell.repos_path
-      end
-
-      def repo
-        @repo ||= Grit::Repo.new(path_to_repo)
-      rescue Grit::NoSuchPathError
-        raise NoRepository.new('no repository for such path')
-      end
-
-      def commit(commit_id = nil)
-        commit = if commit_id
-                   repo.commit(commit_id)
-                 else
-                   repo.commits(root_ref).first
-                 end
-
-        decorate_commit(commit) if commit
-      end
-
-      def commits_with_refs(n = 20)
-        commits = repo.branches.map { |ref| decorate_commit(ref.commit, ref) }
-
-        commits.sort! do |x, y|
-          y.committed_date <=> x.committed_date
-        end
-
-        commits[0..n]
-      end
-
-      def commits(ref, path = nil, limit = nil, offset = nil)
-        if path.present?
-          repo.log(ref, path, max_count: limit, skip: offset, follow: true)
-        elsif limit && offset
-          repo.commits(ref, limit.to_i, offset.to_i)
-        else
-          repo.commits(ref)
-        end.map{ |c| decorate_commit(c) }
-      end
-
-      def commits_between(from, to)
-        repo.commits_between(from, to).map { |c| decorate_commit(c) }
-      end
-
-      def last_commit_for(ref, path = nil)
-        commits(ref, path, 1).first
-      end
-
-      # Returns an Array of branch names
-      # sorted by name ASC
-      def branch_names
-        branches.map(&:name)
-      end
-
-      # Returns an Array of Branches
-      def branches
-        repo.branches.sort_by(&:name)
-      end
-
-      # Returns an Array of tag names
-      def tag_names
-        repo.tags.collect(&:name).sort.reverse
-      end
-
-      # Returns an Array of Tags
-      def tags
-        repo.tags.sort_by(&:name).reverse
-      end
-
-      # Returns an Array of branch and tag names
-      def ref_names
-        [branch_names + tag_names].flatten
-      end
-
-      def heads
-        @heads ||= repo.heads
-      end
-
-      def tree(fcommit, path = nil)
-        fcommit = commit if fcommit == :head
-        tree = fcommit.tree
-        path ? (tree / path) : tree
-      end
-
-      def has_commits?
-        !!commit
-      rescue Grit::NoSuchPathError
-        false
-      end
-
-      def empty?
-        !has_commits?
-      end
-
-      # Discovers the default branch based on the repository's available branches
-      #
-      # - If no branches are present, returns nil
-      # - If one branch is present, returns its name
-      # - If two or more branches are present, returns the one that has a name
-      #   matching root_ref (default_branch or 'master' if default_branch is nil)
-      def discover_default_branch
-        if branch_names.length == 0
-          nil
-        elsif branch_names.length == 1
-          branch_names.first
-        else
-          branch_names.select { |v| v == root_ref }.first
-        end
-      end
-
-      # Archive Project to .tar.gz
-      #
-      # Already packed repo archives stored at
-      # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
-      #
-      def archive_repo(ref)
-        ref = ref || self.root_ref
-        commit = self.commit(ref)
-        return nil unless commit
-
-        # Build file path
-        file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"
-        storage_path = Rails.root.join("tmp", "repositories")
-        file_path = File.join(storage_path, self.path_with_namespace, file_name)
-
-        # Put files into a directory before archiving
-        prefix = File.basename(self.path_with_namespace) + "/"
-
-        # Create file if not exists
-        unless File.exists?(file_path)
-          FileUtils.mkdir_p File.dirname(file_path)
-          file = self.repo.archive_to_file(ref, prefix,  file_path)
-        end
-
-        file_path
-      end
-
-      # Return repo size in megabytes
-      # Cached in redis
-      def size
-        Rails.cache.fetch(cache_key(:size)) do
-          size = popen('du -s', path_to_repo).first.strip.to_i
-          (size.to_f / 1024).round(2)
-        end
-      end
-
-      def expire_cache
-        Rails.cache.delete(cache_key(:size))
-      end
-
-      def cache_key(type)
-        "#{type}:#{path_with_namespace}"
-      end
-
-      def diffs_between(source_branch, target_branch)
-        # Only show what is new in the source branch compared to the target branch, not the other way around.
-        # The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
-        # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
-        common_commit = repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
-        repo.diff(common_commit, source_branch).map { |diff| Gitlab::Git::Diff.new(diff) }
-
-      rescue Grit::Git::GitTimeout
-        [Gitlab::Git::Diff::BROKEN_DIFF]
-      end
-
-      protected
-
-      def decorate_commit(commit, ref = nil)
-        Gitlab::Git::Commit.new(commit, ref)
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/git/stats.rb b/lib/gitlab/git/stats.rb
deleted file mode 100644
index c925c653342..00000000000
--- a/lib/gitlab/git/stats.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-module Gitlab
-  module Git
-    class Stats
-      attr_accessor :repo, :ref
-
-      def initialize repo, ref
-        @repo, @ref = repo, ref
-      end
-
-      def authors
-        @authors ||= collect_authors
-      end
-
-      def commits_count
-        @commits_count ||= repo.commit_count(ref)
-      end
-
-      def files_count
-        args = [ref, '-r', '--name-only' ]
-        repo.git.run(nil, 'ls-tree', nil, {}, args).split("\n").count
-      end
-
-      def authors_count
-        authors.size
-      end
-
-      def graph
-        @graph ||= build_graph
-      end
-
-      protected
-
-      def collect_authors
-        shortlog = repo.git.shortlog({e: true, s: true }, ref)
-
-        authors = []
-
-        lines = shortlog.split("\n")
-
-        lines.each do |line|
-          data = line.split("\t")
-          commits = data.first
-          author = Grit::Actor.from_string(data.last)
-
-          authors << OpenStruct.new(
-            name: author.name,
-            email: author.email,
-            commits: commits.to_i
-          )
-        end
-
-        authors.sort_by(&:commits).reverse
-      end
-
-      def build_graph n = 4
-        from, to = (Date.today - n.weeks), Date.today
-        args = ['--all', "--since=#{from.to_s(:date)}", '--format=%ad' ]
-        rev_list = repo.git.run(nil, 'rev-list', nil, {}, args).split("\n")
-
-        commits_dates = rev_list.values_at(* rev_list.each_index.select {|i| i.odd?})
-        commits_dates = commits_dates.map { |date_str| Time.parse(date_str).to_date.to_s(:date) }
-
-        commits_per_day = from.upto(to).map do |day|
-          commits_dates.count(day.to_date.to_s(:date))
-        end
-
-        OpenStruct.new(
-          labels: from.upto(to).map { |day| day.stamp('Aug 23') },
-          commits: commits_per_day,
-          weeks: n
-        )
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
deleted file mode 100644
index e6b500ba18c..00000000000
--- a/lib/gitlab/git/tree.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module Gitlab
-  module Git
-    class Tree
-      attr_accessor :repository, :sha, :path, :ref, :raw_tree, :id
-
-      def initialize(repository, sha, ref = nil, path = nil)
-        @repository, @sha, @ref, @path = repository, sha, ref, path
-
-        @path = nil if @path.blank?
-
-        # Load tree from repository
-        @commit = @repository.commit(@sha)
-        @raw_tree = @repository.tree(@commit, @path)
-      end
-
-      def exists?
-        raw_tree
-      end
-
-      def empty?
-        data.blank?
-      end
-
-      def trees
-        entries.select { |t| t.is_a?(Grit::Tree) }
-      end
-
-      def blobs
-        entries.select { |t| t.is_a?(Grit::Blob) }
-      end
-
-      def is_blob?
-        raw_tree.is_a?(Grit::Blob)
-      end
-
-      def up_dir?
-        path.present?
-      end
-
-      def readme
-        @readme ||= blobs.find { |c| c.name =~ /^readme/i }
-      end
-
-      protected
-
-      def entries
-        raw_tree.contents
-      end
-    end
-  end
-end
-
-- 
GitLab


From b2a4b4765cbe5707cdd04aa09ee1b74d67efffaf Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 29 Jul 2013 20:16:12 +0200
Subject: [PATCH 68/83] README (changelog)

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index aa3abdd5d3a..2b77143c85e 100755
--- a/README.md
+++ b/README.md
@@ -19,6 +19,10 @@ _Disclaimer_: I do not provide any support on GitLab itself.  I only contribute
 You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
+  * [2013-07-29] : Fixes 2 issues (more at #22)
+
+  > You need to [update your bundles](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.3-to-5.4.md#3-install-libs-migrations-etc) depending on your DBMS
+
   * [2013-07-24] : Public GitLab supports GitLab 5.4 (stable) - [Upgrade 5.3 to 5.4](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.3-to-5.4.md)
   * [2013-07-06] : [New feature](https://github.com/ArthurHoaro/Public-GitLab/pull/19) ! Added a different projects number limit per user for private and public projects. Thanks to [Mike](https://github.com/MJSmith5) for the idea.
   
-- 
GitLab


From 0b6996fc9a255ca2628c372a539e610a4af73e4b Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Mon, 29 Jul 2013 20:21:56 +0200
Subject: [PATCH 69/83] Actually it's not mandatory to get bundles again

---
 README.md | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/README.md b/README.md
index 2b77143c85e..d030c200078 100755
--- a/README.md
+++ b/README.md
@@ -20,9 +20,6 @@ You should also be aware that **Public GitLab** only applies to the latest [stab
 ## Changelog
 
   * [2013-07-29] : Fixes 2 issues (more at #22)
-
-  > You need to [update your bundles](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.3-to-5.4.md#3-install-libs-migrations-etc) depending on your DBMS
-
   * [2013-07-24] : Public GitLab supports GitLab 5.4 (stable) - [Upgrade 5.3 to 5.4](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.3-to-5.4.md)
   * [2013-07-06] : [New feature](https://github.com/ArthurHoaro/Public-GitLab/pull/19) ! Added a different projects number limit per user for private and public projects. Thanks to [Mike](https://github.com/MJSmith5) for the idea.
   
-- 
GitLab


From 4d50c1ebc55a59a1fd75f6e1ef9a4edcc3d61a31 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Fri, 16 Aug 2013 17:33:59 +0200
Subject: [PATCH 70/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d030c200078..4835a422e2d 100755
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/5-4
     cd /home/git/gitlab
 
     # Checkout to stable release
-    sudo -u git -H git checkout 5-2-stable
+    sudo -u git -H git checkout 5-4-stable
 
 ### Post installation
 At this point, all of the GitLab components are installed.  You still can't access GitLab though.
-- 
GitLab


From a9de805eb177828a4613442d13e32c8b73bfaa3c Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Tue, 20 Aug 2013 22:12:42 +0300
Subject: [PATCH 71/83] Fix bug in installation doc with non-install unicorn

---
 doc/install/installation.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/install/installation.md b/doc/install/installation.md
index 8ec0998e5bd..cbaeeda0437 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -232,10 +232,10 @@ Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup.
     sudo gem install charlock_holmes --version '0.6.9.4'
 
     # For MySQL (note, the option says "without ... postgres")
-    sudo -u git -H bundle install --deployment --without development test postgres unicorn aws
+    sudo -u git -H bundle install --deployment --without development test postgres aws
 
     # Or for PostgreSQL (note, the option says "without ... mysql")
-    sudo -u git -H bundle install --deployment --without development test mysql unicorn aws
+    sudo -u git -H bundle install --deployment --without development test mysql aws
 
 
 ## Initialize Database and Activate Advanced Features
-- 
GitLab


From 5246d63f83887dba61a02cbfdc631169a074eba3 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Tue, 20 Aug 2013 22:14:22 +0300
Subject: [PATCH 72/83] Fix wrong branch in install docs

---
 doc/install/installation.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/install/installation.md b/doc/install/installation.md
index cbaeeda0437..6523961d4d5 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -153,10 +153,10 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install
     cd /home/git/gitlab
 
     # Checkout to stable release
-    sudo -u git -H git checkout 5-4-stable
+    sudo -u git -H git checkout 6-0-stable
 
 **Note:**
-You can change `5-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
+You can change `6-0-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
 
 ## Configure it
 
-- 
GitLab


From 4c8f3699f1f1334f1b7ed964d4b6ca985796211a Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Wed, 21 Aug 2013 12:36:38 +0300
Subject: [PATCH 73/83] Fix branch name for update docs

---
 doc/update/5.4-to-6.0.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md
index 94799852549..5f4e21acb31 100644
--- a/doc/update/5.4-to-6.0.md
+++ b/doc/update/5.4-to-6.0.md
@@ -36,7 +36,7 @@ sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create
 ```bash
 cd /home/git/gitlab
 sudo -u git -H git fetch
-sudo -u git -H git checkout 6-0-dev
+sudo -u git -H git checkout 6-0-stable
 ```
 
 ### 3. Install additional packages
-- 
GitLab


From 2afd4aaa1779165e8fb36aeedb456e0b00919b4b Mon Sep 17 00:00:00 2001
From: Chris Roemmich <chris@cr-wd.com>
Date: Tue, 20 Aug 2013 14:13:49 -0500
Subject: [PATCH 74/83] Update to gitlab-shell 1.7.0 during 5.4-6.0 update

---
 doc/update/5.4-to-6.0.md | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md
index 5f4e21acb31..23993d05535 100644
--- a/doc/update/5.4-to-6.0.md
+++ b/doc/update/5.4-to-6.0.md
@@ -39,14 +39,22 @@ sudo -u git -H git fetch
 sudo -u git -H git checkout 6-0-stable
 ```
 
-### 3. Install additional packages
+### 3. Update gitlab-shell
+
+```bash
+cd /home/git/gitlab-shell
+sudo -u git -H git fetch
+sudo -u git -H git checkout v1.7.0
+```
+
+### 4. Install additional packages
 
 ```bash
 # For reStructuredText markup language support install required package:
 sudo apt-get install python-docutils
 ```
 
-### 4. Install libs, migrations, etc.
+### 5. Install libs, migrations, etc.
 
 ```bash
 cd /home/git/gitlab
@@ -65,14 +73,14 @@ sudo -u git -H bundle exec rake migrate_inline_notes RAILS_ENV=production
 
 ```
 
-### 5. Update config files
+### 6. Update config files
 
 Note: We switched from Puma in GitLab 5.4 to unicorn in GitLab 6.0.
 
 * Make `/home/git/gitlab/config/gitlab.yml` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/gitlab.yml.example but with your settings.
 * Make `/home/git/gitlab/config/unicorn.rb` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/unicorn.rb.example but with your settings.
 
-### 6. Update Init script
+### 7. Update Init script
 
 ```bash
 sudo rm /etc/init.d/gitlab
@@ -80,12 +88,12 @@ sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/m
 sudo chmod +x /etc/init.d/gitlab
 ```
 
-### 7. Start application
+### 8. Start application
 
     sudo service gitlab start
     sudo service nginx restart
 
-### 8. Check application status
+### 9. Check application status
 
 Check if GitLab and its environment are configured correctly:
 
-- 
GitLab


From 86c9737307fb2fe61f5e4c2dab79d1cf08c4bdac Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 22 Aug 2013 17:50:24 +0300
Subject: [PATCH 75/83] Fix issue when project owner cant close MR from forked
 project

---
 app/models/merge_request.rb | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b7df2e40a16..d525ad17537 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -250,6 +250,10 @@ class MergeRequest < ActiveRecord::Base
     (source_project.root_ref? source_branch) || for_fork?
   end
 
+  def project
+    target_project
+  end
+
   private
 
   def dump_commits(commits)
-- 
GitLab


From 1ac6078b051da30d26185ba95933d21f30bb73fc Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Sat, 24 Aug 2013 22:42:52 +0300
Subject: [PATCH 76/83] Fixed 500 error when try to remove group

---
 app/controllers/groups_controller.rb | 1 -
 1 file changed, 1 deletion(-)

diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 1190dd40b73..60fc3f6b551 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -87,7 +87,6 @@ class GroupsController < ApplicationController
   end
 
   def destroy
-    @group.truncate_teams
     @group.destroy
 
     redirect_to root_path, notice: 'Group was removed.'
-- 
GitLab


From 6a474db8ea495bc9f7e9838e4919c829c7465b6c Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Sun, 25 Aug 2013 14:16:04 +0200
Subject: [PATCH 77/83] update permissions

---
 app/models/ability.rb | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/models/ability.rb b/app/models/ability.rb
index 4f49be1849b..31e9120f6da 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -86,15 +86,15 @@ class Ability
         :read_team_member,
         :read_merge_request,
         :read_note,
-        :download_code
+        :download_code,
+	:write_issue,
+        :write_note
       ]
     end
 
     def project_guest_rules
       project_anon_rules + [
         :write_project,
-        :write_issue,
-        :write_note
       ]
     end
 
-- 
GitLab


From 061a86059d51b49e0640f282b9640b7fc8a8c65b Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Sun, 25 Aug 2013 14:24:42 +0200
Subject: [PATCH 78/83] Allow anon writing

---
 app/views/projects/notes/_notes_with_form.html.haml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/app/views/projects/notes/_notes_with_form.html.haml b/app/views/projects/notes/_notes_with_form.html.haml
index cebf7d14479..ac28c7432ef 100644
--- a/app/views/projects/notes/_notes_with_form.html.haml
+++ b/app/views/projects/notes/_notes_with_form.html.haml
@@ -3,8 +3,7 @@
 
 .js-main-target-form
 - if can? current_user, :write_note, @project
-  - unless current_user.is_guest?
-    = render "projects/notes/form"
+  = render "projects/notes/form"
 
 :javascript
   NoteList.init("#{@target_id}", "#{@target_type}", "#{project_notes_path(@project)}");
-- 
GitLab


From 4bda64cd789c3aba3a0d53c6f580e7cb70717da4 Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Sun, 25 Aug 2013 15:15:22 +0200
Subject: [PATCH 79/83] Handle anon notes (edit/remove disabled)

---
 app/models/ability.rb                     | 4 ++--
 app/views/projects/issues/index.html.haml | 7 +++----
 app/views/projects/notes/_note.html.haml  | 2 +-
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/app/models/ability.rb b/app/models/ability.rb
index 31e9120f6da..48fb1575db1 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -169,14 +169,14 @@ class Ability
 
     [:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name|
       define_method "#{name}_abilities" do |user, subject|
-        if subject.author == user
+        if subject.author == user && subject.author.username != "guest"
           [
             :"read_#{name}",
             :"write_#{name}",
             :"modify_#{name}",
             :"admin_#{name}"
           ]
-        elsif subject.respond_to?(:assignee) && subject.assignee == user
+        elsif subject.respond_to?(:assignee) && subject.assignee == user && subject.author.username != "guest"
           [
             :"read_#{name}",
             :"write_#{name}",
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index bcb9a59d102..ea8ccca4c9c 100755
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -6,10 +6,9 @@
     .pull-right
       .span6
         - if can? current_user, :write_issue, @project
-          - unless current_user.is_guest?
-            = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-right", title: "New Issue", id: "new_issue_link" do
-              %i.icon-plus
-              New Issue
+          = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-right", title: "New Issue", id: "new_issue_link" do
+            %i.icon-plus
+            New Issue
 
         = form_tag project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: 'pull-right'  do
           = hidden_field_tag :status, params[:status], id: 'search_status'
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index fbc924c4e1d..a7df6284fa2 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -5,7 +5,7 @@
         %i.icon-link
         Link here
       &nbsp;
-      - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)
+      - if(note.author_id == current_user.id && current_user.username != "guest") || can?(current_user, :admin_note, @project)
         = link_to "#", title: "Edit comment", class: "js-note-edit" do
           %i.icon-edit
           Edit
-- 
GitLab


From c67e54d6eebb1b03dbe9d01f8f7740bcc0a938d9 Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Sun, 25 Aug 2013 19:55:42 +0200
Subject: [PATCH 80/83] Filter personal project on user view

---
 app/controllers/users_controller.rb |  2 +-
 app/models/user.rb                  | 12 +++++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 4947c33f959..9b934a34fd0 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -3,7 +3,7 @@ class UsersController < ApplicationController
 
   def show
     @user = User.find_by_username!(params[:username])
-    @projects = @user.authorized_projects.where('projects.id in (?)', current_user.authorized_projects.map(&:id))
+    @projects = @user.authorized_personal_projects.where('projects.id in (?)', current_user.authorized_projects.map(&:id))
     @events = @user.recent_events.where(project_id: @projects.map(&:id)).limit(20)
 
     @title = @user.name
diff --git a/app/models/user.rb b/app/models/user.rb
index cb7b4de94c4..2ab054a31b6 100755
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -99,7 +99,6 @@ class User < ActiveRecord::Base
                                       conditions: { projects: { public: true } }
   has_many :owned_projects_priv,      through: :namespaces, source: :projects,
                                       conditions: { projects: { public: false } }
-
   #
   # Validations
   #
@@ -248,11 +247,18 @@ class User < ActiveRecord::Base
   # Projects user has access to
   def authorized_projects
     @authorized_projects ||= begin
-                               project_ids = (owned_projects.pluck(:id) + groups_projects.pluck(:id) + projects.pluck(:id).uniq + public_projects.pluck(:id)).uniq
+                               project_ids = (owned_projects.pluck(:id) + owned_projects_priv.pluck(:id) + groups_projects.pluck(:id) + projects.pluck(:id) + public_projects.pluck(:id)) .uniq
                                Project.where(id: project_ids).joins(:namespace).order('namespaces.name ASC')
                              end
   end
-  
+ 
+  def authorized_personal_projects
+    @authorized_personal_projects ||= begin
+                       		        project_ids = (owned_projects.pluck(:id) + groups_projects.pluck(:id) + owned_projects_priv.pluck(:id) + users_projects.where("project_access > 20").pluck(:project_id)).uniq
+                         		 Project.where(id: project_ids).joins(:namespace).order('namespaces.name ASC')
+	                             end
+  end
+ 
   def public_projects
     Project.where("projects.public = true")
   end
-- 
GitLab


From cc5ea6cf5d592a1032da22c79622c4a685bb9fb5 Mon Sep 17 00:00:00 2001
From: Arthur <arthur@hoa.ro>
Date: Sun, 25 Aug 2013 20:16:40 +0200
Subject: [PATCH 81/83] Update README.md

---
 README.md | 46 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/README.md b/README.md
index 4835a422e2d..4dbeef2fd18 100755
--- a/README.md
+++ b/README.md
@@ -19,17 +19,21 @@ _Disclaimer_: I do not provide any support on GitLab itself.  I only contribute
 You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab.  So, use the *-stable branches!  The `master` branch on this repo has a high chance to be broken.
 ## Changelog
 
+  * [2013-08-25] : Public GitLab supports GitLab 6.0 (stable) - [Upgrade 5.4 to 6.0](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/doc/update/5.4-to-6.0.md)
+  
+  > Note: Follow [@PGitLab](https://twitter.com/PGitLab) to get news on the project (or [RSS feed here](http://rssbridge.org/b/Twitter/Atom/u/pgitlab/)).
+
   * [2013-07-29] : Fixes 2 issues (more at #22)
-  * [2013-07-24] : Public GitLab supports GitLab 5.4 (stable) - [Upgrade 5.3 to 5.4](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.3-to-5.4.md)
+  * [2013-07-24] : Public GitLab supports GitLab 5.4 (stable) - [Upgrade 5.3 to 5.4](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/doc/update/5.3-to-5.4.md)
   * [2013-07-06] : [New feature](https://github.com/ArthurHoaro/Public-GitLab/pull/19) ! Added a different projects number limit per user for private and public projects. Thanks to [Mike](https://github.com/MJSmith5) for the idea.
   
   > Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ).
   > Warning: New option in `config/gitlab.yml.example` (`default_projects_limit_private`).
   
-  * [2013-06-30] : Public GitLab supports GitLab 5.3 (stable) - [Upgrade 5.2 to 5.3](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.2-to-5.3.md)
-  * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.1-to-5.2.md)
+  * [2013-06-30] : Public GitLab supports GitLab 5.3 (stable) - [Upgrade 5.2 to 5.3](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/doc/update/5.2-to-5.3.md)
+  * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/doc/update/5.1-to-5.2.md)
   * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers)
-  * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/5.0-to-5.1.md)
+  * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/doc/update/5.0-to-5.1.md)
 
 > Warning: GitLab 5.1 does not work properly with old version of Git (ok on 1.7.10+). [More here](https://github.com/gitlabhq/gitlabhq/issues/3666). 
   
@@ -38,9 +42,11 @@ You should also be aware that **Public GitLab** only applies to the latest [stab
 
 ## Installation
 
-During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. 
+During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/6-0-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_.
 
-**Warning**: Remember that you _need_ to use the latest **stable branch**, even if you want to download it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/5-4-stable.zip).
+**Warning**: Remember that you _need_ to use the latest **stable branch**, even if you want to download it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/6-0-stable.zip).
+
+> Note: You can also use my [GitLab install scripts](http://git.hoa.ro/arthur/gitlab-install) for CentOS.
 
 ### Clone the Source
 
@@ -51,7 +57,7 @@ During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/5-4
     cd /home/git/gitlab
 
     # Checkout to stable release
-    sudo -u git -H git checkout 5-4-stable
+    sudo -u git -H git checkout 6-0-stable
 
 ### Post installation
 At this point, all of the GitLab components are installed.  You still can't access GitLab though.
@@ -64,8 +70,8 @@ The SQL script below creates a default `guest` user for anonymous access.  It al
 You have to patch your GitLab database with 2 SQL scripts:
 
     cd /home/git/gitlab/pgl
-    psql -h host -U user database < pgl_postgres_insert.sql
-    psql -h host -U user database < pgl_postgres_trigger.sql
+    psql -h host -U user database < pgl_pgsql_insert.sql
+    psql -h host -U user database < pgl_pgsql_trigger.sql
 
 #### MySQL
 You have to patch your GitLab database with 2 SQL scripts:
@@ -96,14 +102,14 @@ Then enjoy !
 
 ## Update Public GitLab
 
-You need to refer to official [update guides](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/doc/update/) to upgrade GitLab version.
+You need to refer to official [update guides](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/doc/update/) to upgrade GitLab version.
 
 If the changelog on this README indicates any SQL update, you need to update your database :
 
 PostgreSQL:
 
      cd /home/git/gitlab/pgl
-     psql -h host -U user database < pgl_postgres_trigger.sql
+     psql -h host -U user database < pgl_pgsql_trigger.sql
      
 
 MySQL:
@@ -116,7 +122,7 @@ MySQL:
 
 ## Reporting issues
 
-See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/CONTRIBUTING.md).
+See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/CONTRIBUTING.md).
 
 If there is a new stable branch, please do not open an issue to ask for an update.  [Contact me](http://hoa.ro/static6/contact) instead.
 
@@ -135,10 +141,24 @@ If you have already deleted the root user, you have to manually change Public Gi
 
 Read more at issues [#3](https://github.com/ArthurHoaro/Public-GitLab/issues/3) and [#4](https://github.com/ArthurHoaro/Public-GitLab/issues/4).
 
+### Styles don't apply properly
+
+I had an issue with styles while upgrading from 5.4 to 6.0, so if it can help, here is what to do :
+
+  * Stop your Public-GitLab instance.
+  * Execute :
+
+```
+RAILS_ENV=production bundle exec rake assets:clean
+RAILS_ENV=production bundle exec rake assets:precompile
+```
+
+  * Restart your Public-GitLab instance.
+
 ## License
 
 Public GitLab is provided and maintained by [Arthur Hoaro](http://hoa.ro).
 
-Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/5-4-stable/LICENSE) as the original software.
+Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/6-0-stable/LICENSE) as the original software.
 
 This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426).
-- 
GitLab


From fe21901a94ea43eedd9e4aac0ab9871c4a50120e Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Mon, 26 Aug 2013 22:30:26 +0200
Subject: [PATCH 82/83] schema conflicts

---
 db/schema.rb | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/db/schema.rb b/db/schema.rb
index 621536a6ad6..9c4c1353c49 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,11 +11,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-<<<<<<< HEAD
-ActiveRecord::Schema.define(:version => 20130630204200) do
-=======
 ActiveRecord::Schema.define(:version => 20130812143708) do
->>>>>>> 0e387919c3827260434aed48e1f28ee02ce5e58d
 
   create_table "deploy_keys_projects", :force => true do |t|
     t.integer  "deploy_key_id", :null => false
@@ -77,13 +73,8 @@ ActiveRecord::Schema.define(:version => 20130812143708) do
 
   create_table "keys", :force => true do |t|
     t.integer  "user_id"
-<<<<<<< HEAD
-    t.datetime "created_at"
-    t.datetime "updated_at"
-=======
     t.datetime "created_at",  :null => false
     t.datetime "updated_at",  :null => false
->>>>>>> 0e387919c3827260434aed48e1f28ee02ce5e58d
     t.text     "key"
     t.string   "title"
     t.string   "type"
@@ -93,18 +84,6 @@ ActiveRecord::Schema.define(:version => 20130812143708) do
   add_index "keys", ["user_id"], :name => "index_keys_on_user_id"
 
   create_table "merge_requests", :force => true do |t|
-<<<<<<< HEAD
-    t.string   "target_branch", :null => false
-    t.string   "source_branch", :null => false
-    t.integer  "project_id",    :null => false
-    t.integer  "author_id"
-    t.integer  "assignee_id"
-    t.string   "title"
-    t.datetime "created_at"
-    t.datetime "updated_at"
-    t.text     "st_commits"
-    t.text     "st_diffs"
-=======
     t.string   "target_branch",                           :null => false
     t.string   "source_branch",                           :null => false
     t.integer  "source_project_id",                       :null => false
@@ -115,7 +94,6 @@ ActiveRecord::Schema.define(:version => 20130812143708) do
     t.datetime "updated_at",                              :null => false
     t.text     "st_commits",        :limit => 2147483647
     t.text     "st_diffs",          :limit => 2147483647
->>>>>>> 0e387919c3827260434aed48e1f28ee02ce5e58d
     t.integer  "milestone_id"
     t.string   "state"
     t.string   "merge_status"
@@ -236,13 +214,8 @@ ActiveRecord::Schema.define(:version => 20130812143708) do
     t.text     "content",    :limit => 2147483647
     t.integer  "author_id",                                          :null => false
     t.integer  "project_id"
-<<<<<<< HEAD
-    t.datetime "created_at"
-    t.datetime "updated_at"
-=======
     t.datetime "created_at",                                         :null => false
     t.datetime "updated_at",                                         :null => false
->>>>>>> 0e387919c3827260434aed48e1f28ee02ce5e58d
     t.string   "file_name"
     t.datetime "expires_at"
     t.boolean  "private",                          :default => true, :null => false
-- 
GitLab


From 650db83680f83ca5f6719ca0b02abc0feb525746 Mon Sep 17 00:00:00 2001
From: Kevin Krauss <earlkrauss@gmail.com>
Date: Tue, 1 Oct 2013 11:51:43 -0700
Subject: [PATCH 83/83] Update gitlab

---
 lib/support/nginx/gitlab | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
index 3e929c52990..54bf6fb9059 100644
--- a/lib/support/nginx/gitlab
+++ b/lib/support/nginx/gitlab
@@ -1,6 +1,6 @@
 # GITLAB
 # Maintainer: @randx
-# App Version: 5.0
+# App Version: 6.1
 
 upstream gitlab {
   server unix:/home/git/gitlab/tmp/sockets/gitlab.socket;
-- 
GitLab