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 01/59] 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


From 73558dd64ed80c730c20a3b3d499f133bd0a4e0b 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 02/59] 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 7f367588b23..f59da89b964 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -268,6 +268,10 @@ class MergeRequest < ActiveRecord::Base
     "merge request !#{iid}"
   end
 
+  def project
+    target_project
+  end
+
   private
 
   def dump_commits(commits)
-- 
GitLab


From 8bd30d890b99c5a657c9e58e5f8d20a48bcf7906 Mon Sep 17 00:00:00 2001
From: connor <connor@prodege.com>
Date: Thu, 29 Aug 2013 10:14:07 -0700
Subject: [PATCH 03/59] dev can accept merge request

---
 app/controllers/projects/merge_requests_controller.rb | 4 +++-
 app/helpers/merge_requests_helper.rb                  | 2 +-
 app/models/ability.rb                                 | 4 ++--
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 3bc50b0418f..081a6eab845 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -181,7 +181,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController
   end
 
   def allowed_to_merge?
-    action = if project.protected_branch?(@merge_request.target_branch)
+    action = if @merge_request.assignee == current_user
+               :push_code
+             elsif project.protected_branch?(@merge_request.target_branch)
                :push_code_to_protected_branches
              else
                :push_code
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 4ba48aa4339..b0687782b5a 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -19,7 +19,7 @@ module MergeRequestsHelper
       target_project_id: target_project.id,
       source_branch: event.branch_name,
       target_branch: target_project.repository.root_ref,
-      title: event.branch_name.titleize
+      title: event.branch_name
     }
   end
 
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 8335829f919..7007907184b 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -102,7 +102,8 @@ class Ability
       project_report_rules + [
         :write_merge_request,
         :write_wiki,
-        :push_code
+        :push_code,
+		:modify_merge_request
       ]
     end
 
@@ -111,7 +112,6 @@ class Ability
         :push_code_to_protected_branches,
         :modify_issue,
         :modify_project_snippet,
-        :modify_merge_request,
         :admin_issue,
         :admin_milestone,
         :admin_project_snippet,
-- 
GitLab


From 9bf08498a7cafd919fbe4c0d2363dfe5b01e4a8e Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Thu, 3 Oct 2013 14:01:55 +0400
Subject: [PATCH 04/59] Allow to filter merge requests by group

---
 app/contexts/merge_requests_load_context.rb   | 12 ++++++
 .../projects/merge_requests_controller.rb     |  4 ++
 .../projects/merge_requests/index.html.haml   | 38 +++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb
index c3408db6e11..a9a3f84f2bb 100644
--- a/app/contexts/merge_requests_load_context.rb
+++ b/app/contexts/merge_requests_load_context.rb
@@ -30,6 +30,18 @@ class MergeRequestsLoadContext < BaseContext
       merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
     end
 
+    # Filter by specific assigned_group_id (or lack thereof)?
+    # We suppose that assigned to group means "assigned to any user from the group"
+    if params[:assigned_group_id].present?
+      merge_requests = merge_requests.joins(assignee: :users_groups).where(users_groups: {group_id: params[:assigned_group_id]})
+    end
+
+    # Filter by specific created_group_id (or lack thereof)?
+    # We suppose that created by group means "created by any user from the group"
+    if params[:created_group_id].present?
+      merge_requests = merge_requests.joins(author: :users_groups).where(users_groups: {group_id: params[:created_group_id]})
+    end
+
     merge_requests
   end
 end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 081a6eab845..ea82d5ec32b 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -19,8 +19,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController
   def index
     @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
     assignee_id, milestone_id = params[:assignee_id], params[:milestone_id]
+    assigned_group_id, created_group_id = params[:assigned_group_id], params[:created_group_id]
     @assignee = @project.team.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero?
     @milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero?
+    @user_groups = current_user.users_groups
+    @assigned_group = @user_groups.where(group_id: assigned_group_id).first.group if assigned_group_id.present?
+    @created_group = @user_groups.where(group_id: created_group_id).first.group if created_group_id.present?
   end
 
   def show
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 2bd5a027a02..8aef4e51703 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -38,6 +38,44 @@
                     = image_tag gravatar_icon(user.email), class: "avatar s16", alt: ''
                     = user.name
 
+          .dropdown.inline.prepend-left-10
+            %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"}
+              %i.icon-group
+              %span.light assigned to group:
+              - if @assigned_group.present?
+                %strong= @assigned_group.name
+              - else
+                Any
+              %b.caret
+            %ul.dropdown-menu
+              %li
+                = link_to project_filter_path(assigned_group_id: nil) do
+                  Any
+              - @user_groups.each do |user_group|
+                - group = user_group.group
+                %li
+                  = link_to project_filter_path(assigned_group_id: group.id) do
+                    = group.name
+
+          .dropdown.inline.prepend-left-10
+            %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"}
+              %i.icon-group
+              %span.light created by group:
+              - if @created_group.present?
+                %strong= @created_group.name
+              - else
+                Any
+              %b.caret
+            %ul.dropdown-menu
+              %li
+                = link_to project_filter_path(created_group_id: nil) do
+                  Any
+              - @user_groups.each do |user_group|
+                - group = user_group.group
+                %li
+                  = link_to project_filter_path(created_group_id: group.id) do
+                    = group.name
+
           .dropdown.inline.prepend-left-10
             %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"}
               %i.icon-time
-- 
GitLab


From 44872b84f6ab97c83d081e70808a3cc510c8761c Mon Sep 17 00:00:00 2001
From: connor <connor@prodege.com>
Date: Mon, 7 Oct 2013 07:25:15 -0700
Subject: [PATCH 05/59] don't titleize merge requests

---
 app/views/projects/merge_requests/branch_from.js.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml
index ec4d7f2121b..7079eb50f8e 100644
--- a/app/views/projects/merge_requests/branch_from.js.haml
+++ b/app/views/projects/merge_requests/branch_from.js.haml
@@ -3,5 +3,5 @@
   var mrTitle = $('#merge_request_title');
 
   if(mrTitle.val().length == 0) {
-    mrTitle.val("#{params[:ref].titleize}");
+    mrTitle.val("#{params[:ref]}");
   }
-- 
GitLab


From 976185db97d767db2dc88a1a39d1bc53606af311 Mon Sep 17 00:00:00 2001
From: Jacob Vosmaer <contact@jacobvosmaer.nl>
Date: Wed, 9 Oct 2013 15:44:25 +0200
Subject: [PATCH 06/59] Always shut down sidekiq before starting

---
 lib/tasks/sidekiq.rake | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/lib/tasks/sidekiq.rake b/lib/tasks/sidekiq.rake
index d0e9dfe46a1..e71cf0380ed 100644
--- a/lib/tasks/sidekiq.rake
+++ b/lib/tasks/sidekiq.rake
@@ -5,7 +5,15 @@ namespace :sidekiq do
   end
 
   desc "GITLAB | Start sidekiq"
-  task :start do
+  task :start => :restart
+
+  desc 'GitLab | Restart sidekiq'
+  task :restart do
+    if File.exist?(pidfile)
+      puts 'Shutting down existing sidekiq process.'
+      Rake::Task['sidekiq:stop'].invoke
+      puts 'Starting new sidekiq process.'
+    end
     system "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e #{Rails.env} -P #{pidfile} >> #{Rails.root.join("log", "sidekiq.log")} 2>&1 &"
   end
 
-- 
GitLab


From a02a4dfa3793dad1a3ac5ede2c606824dbd58dee Mon Sep 17 00:00:00 2001
From: Jacob Vosmaer <contact@jacobvosmaer.nl>
Date: Wed, 9 Oct 2013 15:46:00 +0200
Subject: [PATCH 07/59] Remove duplicate log path generation

---
 lib/tasks/sidekiq.rake | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/tasks/sidekiq.rake b/lib/tasks/sidekiq.rake
index e71cf0380ed..46caffd0754 100644
--- a/lib/tasks/sidekiq.rake
+++ b/lib/tasks/sidekiq.rake
@@ -14,15 +14,19 @@ namespace :sidekiq do
       Rake::Task['sidekiq:stop'].invoke
       puts 'Starting new sidekiq process.'
     end
-    system "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e #{Rails.env} -P #{pidfile} >> #{Rails.root.join("log", "sidekiq.log")} 2>&1 &"
+    system "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e #{Rails.env} -P #{pidfile} >> #{log_file} 2>&1 &"
   end
 
   desc "GITLAB | Start sidekiq with launchd on Mac OS X"
   task :launchd do
-    system "bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e #{Rails.env} -P #{pidfile} >> #{Rails.root.join("log", "sidekiq.log")} 2>&1"
+    system "bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e #{Rails.env} -P #{pidfile} >> #{log_file} 2>&1"
   end
 
   def pidfile
     Rails.root.join("tmp", "pids", "sidekiq.pid")
   end
+
+  def log_file
+    Rails.root.join("log", "sidekiq.log")
+  end
 end
-- 
GitLab


From 70563a780f6db9a13b380ab6aed79915fe9d3f56 Mon Sep 17 00:00:00 2001
From: Jacob Vosmaer <contact@jacobvosmaer.nl>
Date: Wed, 9 Oct 2013 15:48:28 +0200
Subject: [PATCH 08/59] Use built-in sidekiq deamonization

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

diff --git a/lib/tasks/sidekiq.rake b/lib/tasks/sidekiq.rake
index 46caffd0754..ba79b6e035d 100644
--- a/lib/tasks/sidekiq.rake
+++ b/lib/tasks/sidekiq.rake
@@ -14,7 +14,7 @@ namespace :sidekiq do
       Rake::Task['sidekiq:stop'].invoke
       puts 'Starting new sidekiq process.'
     end
-    system "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e #{Rails.env} -P #{pidfile} >> #{log_file} 2>&1 &"
+    system "bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e #{Rails.env} -P #{pidfile} -d -L #{log_file} >> #{log_file} 2>&1"
   end
 
   desc "GITLAB | Start sidekiq with launchd on Mac OS X"
-- 
GitLab


From 08fd2b957da83e467c77db759f7964a94d26622e Mon Sep 17 00:00:00 2001
From: Alex Yoder <alexyoder@gmail.com>
Date: Mon, 21 Oct 2013 13:00:05 -0400
Subject: [PATCH 09/59] change 6-1-stable to 6-2-stable

---
 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 d0be2325aac..c89ae57f710 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 6-1-stable
+    sudo -u git -H git checkout 6-2-stable
 
 **Note:**
-You can change `6-1-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
+You can change `6-2-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
 
 ## Configure it
 
-- 
GitLab


From 7dbcc1e660b655523cd577a5db4525ddc1aa7414 Mon Sep 17 00:00:00 2001
From: Jacob Vosmaer <contact@jacobvosmaer.nl>
Date: Tue, 22 Oct 2013 10:22:45 +0200
Subject: [PATCH 10/59] Use `2>&1` because Bash 3 does not support `&>>`

---
 script/background_jobs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/script/background_jobs b/script/background_jobs
index e0beb3df815..623e26a2831 100755
--- a/script/background_jobs
+++ b/script/background_jobs
@@ -8,7 +8,7 @@ gitlab_user=$(ls -l config.ru | awk '{print $3}')
 
 function stop
 {
-  bundle exec sidekiqctl stop $sidekiq_pidfile &>> $sidekiq_logfile
+  bundle exec sidekiqctl stop $sidekiq_pidfile >> $sidekiq_logfile 2>&1
 }
 
 function killall
@@ -32,7 +32,7 @@ function start_no_deamonize
 
 function start_sidekiq
 {
-  bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e $RAILS_ENV -P $sidekiq_pidfile $@ &>> $sidekiq_logfile
+  bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e $RAILS_ENV -P $sidekiq_pidfile $@ >> $sidekiq_logfile 2>&1
 }
 
 case "$1" in
-- 
GitLab


From f5df4fce836ccbe2194594948ef613536749d696 Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Tue, 22 Oct 2013 22:33:27 +0400
Subject: [PATCH 11/59] Allow for accept without merge

---
 app/contexts/merge_requests_load_context.rb   |  2 +-
 .../projects/merge_requests_controller.rb     | 27 ++++++++++++++++---
 app/mailers/emails/merge_requests.rb          |  6 +++++
 app/models/ability.rb                         |  4 ++-
 app/models/event.rb                           |  7 +++++
 app/models/merge_request.rb                   | 15 +++++++++--
 app/observers/merge_request_observer.rb       |  5 ++++
 app/services/notification_service.rb          | 10 +++++++
 app/views/layouts/nav/_project.html.haml      |  2 +-
 .../accepted_merge_request_email.html.haml    |  9 +++++++
 .../accepted_merge_request_email.text.haml    |  8 ++++++
 .../merge_requests/_merge_request.html.haml   |  1 +
 .../accept_without_merge.js.haml              |  7 +++++
 .../merge_requests/show/_mr_accept.html.haml  |  5 ++++
 .../merge_requests/show/_mr_title.html.haml   |  2 +-
 config/routes.rb                              |  1 +
 ...722_add_accepted_state_to_merge_request.rb |  7 +++++
 .../20131022131759_add_accepted_event.rb      |  8 ++++++
 db/schema.rb                                  |  2 +-
 19 files changed, 117 insertions(+), 11 deletions(-)
 create mode 100644 app/views/notify/accepted_merge_request_email.html.haml
 create mode 100644 app/views/notify/accepted_merge_request_email.text.haml
 create mode 100644 app/views/projects/merge_requests/accept_without_merge.js.haml
 create mode 100644 db/migrate/20131022131722_add_accepted_state_to_merge_request.rb
 create mode 100644 db/migrate/20131022131759_add_accepted_event.rb

diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb
index a9a3f84f2bb..28c795b3c65 100644
--- a/app/contexts/merge_requests_load_context.rb
+++ b/app/contexts/merge_requests_load_context.rb
@@ -7,7 +7,7 @@ class MergeRequestsLoadContext < BaseContext
     merge_requests = case params[:state]
                      when 'all' then merge_requests
                      when 'closed' then merge_requests.closed
-                     else merge_requests.opened
+                     else merge_requests.not_closed
                      end
 
     merge_requests = case params[:scope]
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index ea82d5ec32b..4aee69eb4cb 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -2,7 +2,7 @@ require 'gitlab/satellite/satellite'
 
 class Projects::MergeRequestsController < Projects::ApplicationController
   before_filter :module_enabled
-  before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
+  before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status, :accept_without_merge]
   before_filter :closes_issues, only: [:edit, :update, :show, :commits, :diffs]
   before_filter :validates_merge_request, only: [:show, :diffs]
   before_filter :define_show_vars, only: [:show, :diffs]
@@ -101,7 +101,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
   def automerge
     return access_denied! unless allowed_to_merge?
 
-    if @merge_request.opened? && @merge_request.can_be_merged?
+    if (@merge_request.opened? || @merge_request.accepted?) && @merge_request.can_be_merged?
       @merge_request.should_remove_source_branch = params[:should_remove_source_branch]
       @merge_request.automerge!(current_user)
       @status = true
@@ -110,6 +110,17 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     end
   end
 
+  def accept_without_merge
+    return access_denied! unless allowed_to_accept?
+
+    if @merge_request.opened?
+      @merge_request.accept!
+      @status = true
+    else
+      @status = false
+    end
+  end
+
   def branch_from
     #This is always source
     @source_project = @merge_request.nil? ? @project : @merge_request.source_project
@@ -178,7 +189,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @commits = @merge_request.commits
 
     @allowed_to_merge = allowed_to_merge?
-    @show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge
+    @show_merge_controls = (@merge_request.opened? || @merge_request.accepted?) && @commits.any? && @allowed_to_merge
+    @allowed_to_accept = allowed_to_accept?
+    @show_accept_control = @merge_request.opened? && @commits.any? && @allowed_to_accept
 
     @target_type = :merge_request
     @target_id = @merge_request.id
@@ -193,7 +206,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
                :push_code
              end
 
-    can?(current_user, action, @project)
+    can_push_code = can?(current_user, action, @project)
+    can_merge = can?(current_user, :merge_merge_request, @project)
+    return can_push_code && can_merge
+  end
+
+  def allowed_to_accept?
+    can?(current_user, :accept_merge_request, @project)
   end
 
   def invalid_mr
diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index 57c1925fa47..c85f5538a5c 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -17,6 +17,12 @@ module Emails
       mail(to: recipient(recipient_id), subject: subject("Closed merge request !#{@merge_request.iid}", @merge_request.title))
     end
 
+    def accepted_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
+      @merge_request = MergeRequest.find(merge_request_id)
+      @updated_by = User.find updated_by_user_id
+      mail(to: recipient(recipient_id), subject: subject("Accepted (without merge) merge request !#{@merge_request.iid}", @merge_request.title))
+    end
+
     def merged_merge_request_email(recipient_id, merge_request_id)
       @merge_request = MergeRequest.find(merge_request_id)
       mail(to: recipient(recipient_id), subject: subject("Accepted merge request !#{@merge_request.iid}", @merge_request.title))
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 7007907184b..05ffb732987 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -103,7 +103,8 @@ class Ability
         :write_merge_request,
         :write_wiki,
         :push_code,
-		:modify_merge_request
+        :modify_merge_request,
+        :accept_merge_request
       ]
     end
 
@@ -112,6 +113,7 @@ class Ability
         :push_code_to_protected_branches,
         :modify_issue,
         :modify_project_snippet,
+        :merge_merge_request,
         :admin_issue,
         :admin_milestone,
         :admin_project_snippet,
diff --git a/app/models/event.rb b/app/models/event.rb
index 095a06c956b..62b48e190f9 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -29,6 +29,7 @@ class Event < ActiveRecord::Base
   MERGED    = 7
   JOINED    = 8 # User joined project
   LEFT      = 9 # User left project
+  ACCEPTED  = 101 # User accepted merge request
 
   delegate :name, :email, to: :author, prefix: true, allow_nil: true
   delegate :title, to: :issue, prefix: true, allow_nil: true
@@ -141,6 +142,10 @@ class Event < ActiveRecord::Base
     action == LEFT
   end
 
+  def accepted?
+     action == ACCEPTED
+  end
+
   def membership_changed?
     joined? || left?
   end
@@ -162,6 +167,8 @@ class Event < ActiveRecord::Base
       'joined'
     elsif left?
       'left'
+    elsif accepted?
+      'accepted (without merge)'
     else
       "opened"
     end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index f59da89b964..d8b5f8aa071 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -36,11 +36,15 @@ class MergeRequest < ActiveRecord::Base
 
   state_machine :state, initial: :opened do
     event :close do
-      transition [:reopened, :opened] => :closed
+      transition [:reopened, :opened, :accepted] => :closed
     end
 
     event :merge do
-      transition [:reopened, :opened] => :merged
+      transition [:reopened, :opened, :accepted] => :merged
+    end
+
+    event :accept do
+      transition [:reopened, :opened] => :accepted
     end
 
     event :reopen do
@@ -54,6 +58,8 @@ class MergeRequest < ActiveRecord::Base
     state :closed
 
     state :merged
+
+    state :accepted
   end
 
   state_machine :merge_status, initial: :unchecked do
@@ -98,6 +104,7 @@ class MergeRequest < ActiveRecord::Base
   # Closed scope for merge request should return
   # both merged and closed mr's
   scope :closed, -> { with_states(:closed, :merged) }
+  scope :not_closed, -> { with_states(:opened, :reopened, :accepted) }
 
   def validate_branches
     if target_project==source_project && target_branch == source_branch
@@ -204,6 +211,10 @@ class MergeRequest < ActiveRecord::Base
     commits
   end
 
+  def accept_without_merge!
+    self.accept
+  end
+
   def merge!(user_id)
     self.author_id_of_changes = user_id
     self.merge
diff --git a/app/observers/merge_request_observer.rb b/app/observers/merge_request_observer.rb
index d70da514cd2..07589c61eca 100644
--- a/app/observers/merge_request_observer.rb
+++ b/app/observers/merge_request_observer.rb
@@ -33,6 +33,11 @@ class MergeRequestObserver < ActivityObserver
     )
   end
 
+  def after_accept(merge_request, transition)
+    notification.accept_mr(merge_request, current_user)
+    create_event(merge_request, Event::ACCEPTED)
+  end
+
   def after_reopen(merge_request, transition)
     create_event(merge_request, Event::REOPENED)
     Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 750a71aea6b..a655673101f 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -73,6 +73,16 @@ class NotificationService
     close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email')
   end
 
+  # When we accept 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 accept_mr(merge_request, current_user)
+    close_resource_email(merge_request, merge_request.target_project, current_user, 'accepted_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
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index e9d535f6972..14971bf0164 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -30,7 +30,7 @@
     = 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
+        %span.count.merge_counter= @project.merge_requests.not_closed.count
 
   - if project_nav_tab? :wiki
     = nav_link(controller: :wikis) do
diff --git a/app/views/notify/accepted_merge_request_email.html.haml b/app/views/notify/accepted_merge_request_email.html.haml
new file mode 100644
index 00000000000..0a02b2906cd
--- /dev/null
+++ b/app/views/notify/accepted_merge_request_email.html.haml
@@ -0,0 +1,9 @@
+%p
+  = "Merge Request #{@merge_request.iid} was accepted (without merge)"
+%p
+  = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request)
+%p
+  != merge_path_description(@merge_request, '&rarr;')
+%p
+  Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
+
diff --git a/app/views/notify/accepted_merge_request_email.text.haml b/app/views/notify/accepted_merge_request_email.text.haml
new file mode 100644
index 00000000000..c2d0fead3f7
--- /dev/null
+++ b/app/views/notify/accepted_merge_request_email.text.haml
@@ -0,0 +1,8 @@
+= "Merge Request #{@merge_request.iid} was accepted (without merge)"
+
+Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
+
+= merge_path_description(@merge_request, 'to')
+
+Author: #{@merge_request.author_name}
+Assignee: #{@merge_request.assignee_name}
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 933d78bcbfb..a2d87fd3e16 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -2,6 +2,7 @@
   .merge-request-title
     %span.light= "##{merge_request.iid}"
     = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.target_project, merge_request), class: "row_title"
+    %span.light= "(#{merge_request.state})"
     - if merge_request.merged?
       %small.pull-right
         %i.icon-ok
diff --git a/app/views/projects/merge_requests/accept_without_merge.js.haml b/app/views/projects/merge_requests/accept_without_merge.js.haml
new file mode 100644
index 00000000000..ffcd7c1690e
--- /dev/null
+++ b/app/views/projects/merge_requests/accept_without_merge.js.haml
@@ -0,0 +1,7 @@
+-if @status
+  :plain
+    location.reload();
+-else
+  :plain
+    alert('Failed to accept without merge!');
+
diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml
index 299e1bc1e08..62950154ea0 100644
--- a/app/views/projects/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml
@@ -51,3 +51,8 @@
       %i.icon-refresh.icon-spin
       &nbsp;
       Merge is in progress. Please wait. Page will be automatically reloaded. &nbsp;
+
+- elsif @show_accept_control
+  %span
+    = form_for [:accept_without_merge, @project, @merge_request], remote: true, method: :get do |f|
+      = f.submit "Accept Without Merge", class: "btn btn-create accept_without_merge"
diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml
index 096a9167645..27176679916 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_title.html.haml
@@ -1,5 +1,5 @@
 %h3.page-title
-  = "Merge Request ##{@merge_request.iid}:"
+  = "Merge Request ##{@merge_request.iid} (#{@merge_request.state}):"
   &nbsp;
   -if @merge_request.for_fork?
     %span.label-branch
diff --git a/config/routes.rb b/config/routes.rb
index 2b444c2a296..7e48b8bc67d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -253,6 +253,7 @@ Gitlab::Application.routes.draw do
           get :automerge
           get :automerge_check
           get :ci_status
+          get :accept_without_merge
         end
 
         collection do
diff --git a/db/migrate/20131022131722_add_accepted_state_to_merge_request.rb b/db/migrate/20131022131722_add_accepted_state_to_merge_request.rb
new file mode 100644
index 00000000000..401ea7fc61b
--- /dev/null
+++ b/db/migrate/20131022131722_add_accepted_state_to_merge_request.rb
@@ -0,0 +1,7 @@
+class AddAcceptedStateToMergeRequest < ActiveRecord::Migration
+  # We don't need the forward ("up") data migration
+  def down
+    # Return all 'accepted' MR's back to the 'opened' state
+    MergeRequest.where(state: :accepted).update_all(state: :opened)
+  end
+end
diff --git a/db/migrate/20131022131759_add_accepted_event.rb b/db/migrate/20131022131759_add_accepted_event.rb
new file mode 100644
index 00000000000..2e463d0535d
--- /dev/null
+++ b/db/migrate/20131022131759_add_accepted_event.rb
@@ -0,0 +1,8 @@
+class AddAcceptedEvent < ActiveRecord::Migration
+  # We don't need the forward ("up") data migration
+  def down
+    # Remove all 'ACCEPTED' events
+    # 101 == Event::ACCEPTED, but I'm not sure whether that constant is supposed to be available when db:rollback is executed
+    Event.where(action: 101).delete_all
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d5effe40ea1..d9421f6a6b1 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 => 20130909132950) do
+ActiveRecord::Schema.define(:version => 20131022131759) do
 
   create_table "deploy_keys_projects", :force => true do |t|
     t.integer  "deploy_key_id", :null => false
-- 
GitLab


From 9d58e81e4f89b132451d79a65ee5e676b8629620 Mon Sep 17 00:00:00 2001
From: connor <connor@prodege.com>
Date: Tue, 22 Oct 2013 21:14:30 -0700
Subject: [PATCH 12/59] use default branch

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

diff --git a/app/models/repository.rb b/app/models/repository.rb
index 97b4330092a..406bca36996 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -5,7 +5,7 @@ class Repository
 
   def initialize(path_with_namespace, default_branch)
     @path_with_namespace = path_with_namespace
-    @raw_repository = Gitlab::Git::Repository.new(path_to_repo) if path_with_namespace
+    @raw_repository = Gitlab::Git::Repository.new(path_to_repo, default_branch) if path_with_namespace
   rescue Gitlab::Git::Repository::NoRepository
     nil
   end
-- 
GitLab


From 1a1b59272a1bfb6be784b3eb2391e3a8cf4c4e35 Mon Sep 17 00:00:00 2001
From: connor <connor@prodege.com>
Date: Tue, 22 Oct 2013 21:25:32 -0700
Subject: [PATCH 13/59] revert default_branch

---
 app/models/project.rb    | 2 +-
 app/models/repository.rb | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/models/project.rb b/app/models/project.rb
index d2dcf26ac69..bef6c840a08 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -303,7 +303,7 @@ class Project < ActiveRecord::Base
   def discover_default_branch
     # Discover the default branch, but only if it hasn't already been set to
     # something else
-    if repository.exists? && default_branch.nil?
+    if false && repository.exists? && default_branch.nil?
       update_attributes(default_branch: self.repository.discover_default_branch)
     end
   end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 406bca36996..97b4330092a 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -5,7 +5,7 @@ class Repository
 
   def initialize(path_with_namespace, default_branch)
     @path_with_namespace = path_with_namespace
-    @raw_repository = Gitlab::Git::Repository.new(path_to_repo, default_branch) if path_with_namespace
+    @raw_repository = Gitlab::Git::Repository.new(path_to_repo) if path_with_namespace
   rescue Gitlab::Git::Repository::NoRepository
     nil
   end
-- 
GitLab


From 2f47049ddcee447878dc241158943b4d6463ab7e Mon Sep 17 00:00:00 2001
From: arul <arul@battlezone.cz>
Date: Thu, 24 Oct 2013 19:27:23 +0200
Subject: [PATCH 14/59] Fix for issue #5431

---
 app/controllers/admin/users_controller.rb | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index dccbfa2f709..c9875b96321 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -47,6 +47,7 @@ class Admin::UsersController < Admin::ApplicationController
     @user = User.build_user(params[:user].merge(opts), as: :admin)
     @user.admin = (admin && admin.to_i > 0)
     @user.created_by_id = current_user.id
+    @user.generate_password
     @user.confirm!
 
     respond_to do |format|
-- 
GitLab


From f2a77a82b832cbe697ae67762c4fc17d5c918905 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 28 Oct 2013 13:14:29 +0200
Subject: [PATCH 15/59] Version 6.2.1

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

diff --git a/VERSION b/VERSION
index 6abaeb2f907..024b066c0bb 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.2.0
+6.2.1
-- 
GitLab


From 1dfefb4e17bdb64cf867f33fcb0dc4fce061fcd1 Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Wed, 30 Oct 2013 12:35:04 +0400
Subject: [PATCH 16/59] Fix: show edit/close buttons for all not closed MRs
 (not only to opened ones)

---
 app/models/merge_request.rb                                | 4 ++++
 app/views/projects/merge_requests/show/_mr_title.html.haml | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 2e9f2b8461b..7270e9df726 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -107,6 +107,10 @@ class MergeRequest < ActiveRecord::Base
   scope :closed, -> { with_states(:closed, :merged) }
   scope :not_closed, -> { with_states(:opened, :reopened, :accepted) }
 
+  def not_closed?
+    return !closed? && !merged?
+  end
+
   def validate_branches
     if target_project==source_project && target_branch == source_branch
       errors.add :branch_conflict, "You can not use same project/branch for source and target"
diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml
index 27176679916..a7603113407 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_title.html.haml
@@ -14,7 +14,7 @@
 
   %span.pull-right
     - if can?(current_user, :modify_merge_request, @merge_request)
-      - if @merge_request.opened?
+      - if @merge_request.not_closed?
         .left.btn-group
           %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} }
             %i.icon-download-alt
-- 
GitLab


From 21154576a75ac9c6f13607576f1376707253a3cc Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Wed, 30 Oct 2013 13:58:50 +0400
Subject: [PATCH 17/59] Add 'rejected' and 'fixed' states to merge requests;
 allow to switch between the review statuses (accepted, rejected, fixed) back
 and forth

---
 .../projects/merge_requests_controller.rb     | 35 +++++++++++++------
 app/mailers/emails/merge_requests.rb          |  5 +--
 app/models/ability.rb                         |  2 +-
 app/models/event.rb                           | 14 ++++++++
 app/models/merge_request.rb                   | 33 ++++++++++++-----
 app/observers/merge_request_observer.rb       | 12 ++++++-
 app/services/notification_service.rb          | 16 +++++++--
 ...=> reviewed_merge_request_email.html.haml} |  2 +-
 ...=> reviewed_merge_request_email.text.haml} |  2 +-
 .../merge_requests/mark_fixed.js.haml         |  7 ++++
 .../projects/merge_requests/reject.js.haml    |  7 ++++
 .../merge_requests/show/_mr_accept.html.haml  | 17 ++++++---
 config/routes.rb                              |  2 ++
 ...ected_and_fixed_states_to_merge_request.rb |  7 ++++
 ...029200011_add_rejected_and_fixed_events.rb |  9 +++++
 db/schema.rb                                  |  2 +-
 16 files changed, 140 insertions(+), 32 deletions(-)
 rename app/views/notify/{accepted_merge_request_email.html.haml => reviewed_merge_request_email.html.haml} (79%)
 rename app/views/notify/{accepted_merge_request_email.text.haml => reviewed_merge_request_email.text.haml} (76%)
 create mode 100644 app/views/projects/merge_requests/mark_fixed.js.haml
 create mode 100644 app/views/projects/merge_requests/reject.js.haml
 create mode 100644 db/migrate/20131029195936_add_rejected_and_fixed_states_to_merge_request.rb
 create mode 100644 db/migrate/20131029200011_add_rejected_and_fixed_events.rb

diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 63b3238e30b..42434ce4c78 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -2,7 +2,7 @@ require 'gitlab/satellite/satellite'
 
 class Projects::MergeRequestsController < Projects::ApplicationController
   before_filter :module_enabled
-  before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status, :accept_without_merge]
+  before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status, :accept_without_merge, :reject, :mark_fixed]
   before_filter :closes_issues, only: [:edit, :update, :show, :commits, :diffs]
   before_filter :validates_merge_request, only: [:show, :diffs]
   before_filter :define_show_vars, only: [:show, :diffs]
@@ -110,17 +110,29 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     end
   end
 
-  def accept_without_merge
-    return access_denied! unless allowed_to_accept?
+  def change_review_status(appropriate_current_statuses, change_status_method)
+    return access_denied! unless allowed_to_review?
 
-    if @merge_request.opened?
-      @merge_request.accept!
+    if appropriate_current_statuses.include?(@merge_request.state)
+      @merge_request.send(change_status_method)
       @status = true
     else
       @status = false
     end
   end
 
+  def accept_without_merge
+    change_review_status(MergeRequest::VALID_STATES_FOR_ACCEPT, :accept)
+  end
+
+  def reject
+    change_review_status(MergeRequest::VALID_STATES_FOR_REJECT, :reject)
+  end
+
+  def mark_fixed
+    change_review_status(MergeRequest::VALID_STATES_FOR_MARK_FIXED, :mark_fixed)
+  end
+
   def branch_from
     #This is always source
     @source_project = @merge_request.nil? ? @project : @merge_request.source_project
@@ -192,9 +204,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @commits = @merge_request.commits
 
     @allowed_to_merge = allowed_to_merge?
-    @show_merge_controls = (@merge_request.opened? || @merge_request.accepted?) && @commits.any? && @allowed_to_merge
-    @allowed_to_accept = allowed_to_accept?
-    @show_accept_control = @merge_request.opened? && @commits.any? && @allowed_to_accept
+    @show_merge_controls = MergeRequest::VALID_STATES_FOR_MERGE.include?(@merge_request.state) && @commits.any? && @allowed_to_merge
+
+    @allowed_to_review = allowed_to_review?
+    @show_accept_button = MergeRequest::VALID_STATES_FOR_ACCEPT.include?(@merge_request.state) && @allowed_to_review
+    @show_reject_button = MergeRequest::VALID_STATES_FOR_REJECT.include?(@merge_request.state) && @allowed_to_review
+    @show_mark_fixed_button = MergeRequest::VALID_STATES_FOR_MARK_FIXED.include?(@merge_request.state) && @allowed_to_review
 
     @target_type = :merge_request
     @target_id = @merge_request.id
@@ -214,8 +229,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     return can_push_code && can_merge
   end
 
-  def allowed_to_accept?
-    can?(current_user, :accept_merge_request, @project)
+  def allowed_to_review?
+    can?(current_user, :review_merge_request, @project)
   end
 
   def invalid_mr
diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index c85f5538a5c..00a0033b28a 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -17,10 +17,11 @@ module Emails
       mail(to: recipient(recipient_id), subject: subject("Closed merge request !#{@merge_request.iid}", @merge_request.title))
     end
 
-    def accepted_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
+    def reviewed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id, action)
       @merge_request = MergeRequest.find(merge_request_id)
       @updated_by = User.find updated_by_user_id
-      mail(to: recipient(recipient_id), subject: subject("Accepted (without merge) merge request !#{@merge_request.iid}", @merge_request.title))
+      @action = action
+      mail(to: recipient(recipient_id), subject: subject("#{action.capitalize} merge request !#{@merge_request.iid}", @merge_request.title))
     end
 
     def merged_merge_request_email(recipient_id, merge_request_id)
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 79cc163fd40..1b6bfdada93 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -123,7 +123,7 @@ class Ability
         :write_wiki,
         :push_code,
         :modify_merge_request,
-        :accept_merge_request
+        :review_merge_request
       ]
     end
 
diff --git a/app/models/event.rb b/app/models/event.rb
index 62b48e190f9..11cf1f3009e 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -30,6 +30,8 @@ class Event < ActiveRecord::Base
   JOINED    = 8 # User joined project
   LEFT      = 9 # User left project
   ACCEPTED  = 101 # User accepted merge request
+  REJECTED  = 102 # User rejected merge request
+  FIXED     = 103 # User fixed merge request
 
   delegate :name, :email, to: :author, prefix: true, allow_nil: true
   delegate :title, to: :issue, prefix: true, allow_nil: true
@@ -146,6 +148,14 @@ class Event < ActiveRecord::Base
      action == ACCEPTED
   end
 
+  def rejected?
+     action == REJECTED
+  end
+
+  def fixed?
+    action == FIXED
+  end
+
   def membership_changed?
     joined? || left?
   end
@@ -169,6 +179,10 @@ class Event < ActiveRecord::Base
       'left'
     elsif accepted?
       'accepted (without merge)'
+    elsif rejected?
+      'rejected'
+    elsif fixed?
+      'fixed'
     else
       "opened"
     end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 7270e9df726..c955a153061 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -37,21 +37,30 @@ class MergeRequest < ActiveRecord::Base
 
   state_machine :state, initial: :opened do
     event :close do
-      transition [:reopened, :opened, :accepted] => :closed
+      transition [:reopened, :opened, :accepted, :rejected, :fixed] => :closed
     end
 
     event :merge do
-      transition [:reopened, :opened, :accepted] => :merged
+      transition [:reopened, :opened, :accepted, :rejected, :fixed] => :merged
     end
 
     event :accept do
-      transition [:reopened, :opened] => :accepted
+      transition [:reopened, :opened, :fixed, :rejected] => :accepted
+    end
+
+    event :reject do
+      transition [:reopened, :opened, :fixed, :accepted] => :rejected
+    end
+
+    event :mark_fixed do
+      transition [:rejected] => :fixed
     end
 
     event :reopen do
       transition closed: :reopened
     end
 
+    # New (not reviewed merge request)
     state :opened
 
     state :reopened
@@ -60,7 +69,14 @@ class MergeRequest < ActiveRecord::Base
 
     state :merged
 
+    # Reviewed and without issues which should be fixed, but not merged yet
     state :accepted
+
+    # Reviewed and containing some issues
+    state :rejected
+
+    # Fixed after review
+    state :fixed
   end
 
   state_machine :merge_status, initial: :unchecked do
@@ -105,7 +121,12 @@ class MergeRequest < ActiveRecord::Base
   # Closed scope for merge request should return
   # both merged and closed mr's
   scope :closed, -> { with_states(:closed, :merged) }
-  scope :not_closed, -> { with_states(:opened, :reopened, :accepted) }
+  scope :not_closed, -> { with_states(:opened, :reopened, :accepted, :rejected, :fixed) }
+
+  VALID_STATES_FOR_MERGE = ["opened", "reopened", "accepted", "rejected", "fixed"]
+  VALID_STATES_FOR_ACCEPT = ["opened", "reopened", "rejected", "fixed"]
+  VALID_STATES_FOR_REJECT = ["opened", "reopened", "accepted", "fixed"]
+  VALID_STATES_FOR_MARK_FIXED = ["rejected"]
 
   def not_closed?
     return !closed? && !merged?
@@ -216,10 +237,6 @@ class MergeRequest < ActiveRecord::Base
     commits
   end
 
-  def accept_without_merge!
-    self.accept
-  end
-
   def merge!(user_id)
     self.author_id_of_changes = user_id
     self.merge
diff --git a/app/observers/merge_request_observer.rb b/app/observers/merge_request_observer.rb
index 07589c61eca..38b617d1797 100644
--- a/app/observers/merge_request_observer.rb
+++ b/app/observers/merge_request_observer.rb
@@ -34,10 +34,20 @@ class MergeRequestObserver < ActivityObserver
   end
 
   def after_accept(merge_request, transition)
-    notification.accept_mr(merge_request, current_user)
+    notification.review_mr(merge_request, current_user, 'accepted (without merge)')
     create_event(merge_request, Event::ACCEPTED)
   end
 
+  def after_reject(merge_request, transition)
+    notification.review_mr(merge_request, current_user, 'rejected')
+    create_event(merge_request, Event::REJECTED)
+  end
+
+  def after_mark_fixed(merge_request, transition)
+    notification.review_mr(merge_request, current_user, 'fixed')
+    create_event(merge_request, Event::FIXED)
+  end
+
   def after_reopen(merge_request, transition)
     create_event(merge_request, Event::REOPENED)
     Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index a655673101f..db2fe829479 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -73,14 +73,14 @@ class NotificationService
     close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email')
   end
 
-  # When we accept a merge request we should send next emails:
+  # When we change a merge request's review state 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 accept_mr(merge_request, current_user)
-    close_resource_email(merge_request, merge_request.target_project, current_user, 'accepted_merge_request_email')
+  def review_mr(merge_request, current_user, action)
+    review_mr_email(merge_request, merge_request.target_project, current_user, action)
   end
 
   # When we merge a merge request we should send next emails:
@@ -228,6 +228,16 @@ class NotificationService
     end
   end
 
+  def review_mr_email(target, project, current_user, action)
+    recipients = reject_muted_users([target.author, target.assignee], project)
+    recipients = recipients.concat(project_watchers(project)).uniq
+    recipients.delete(current_user)
+
+    recipients.each do |recipient|
+      mailer.send('reviewed_merge_request_email', recipient.id, target.id, current_user.id, action)
+    end
+  end
+
   def close_resource_email(target, project, current_user, method)
     recipients = reject_muted_users([target.author, target.assignee], project)
     recipients = recipients.concat(project_watchers(project)).uniq
diff --git a/app/views/notify/accepted_merge_request_email.html.haml b/app/views/notify/reviewed_merge_request_email.html.haml
similarity index 79%
rename from app/views/notify/accepted_merge_request_email.html.haml
rename to app/views/notify/reviewed_merge_request_email.html.haml
index 0a02b2906cd..26bb7052a50 100644
--- a/app/views/notify/accepted_merge_request_email.html.haml
+++ b/app/views/notify/reviewed_merge_request_email.html.haml
@@ -1,5 +1,5 @@
 %p
-  = "Merge Request #{@merge_request.iid} was accepted (without merge)"
+  = "Merge Request #{@merge_request.iid} was #{@action}"
 %p
   = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request)
 %p
diff --git a/app/views/notify/accepted_merge_request_email.text.haml b/app/views/notify/reviewed_merge_request_email.text.haml
similarity index 76%
rename from app/views/notify/accepted_merge_request_email.text.haml
rename to app/views/notify/reviewed_merge_request_email.text.haml
index c2d0fead3f7..0b9c2239171 100644
--- a/app/views/notify/accepted_merge_request_email.text.haml
+++ b/app/views/notify/reviewed_merge_request_email.text.haml
@@ -1,4 +1,4 @@
-= "Merge Request #{@merge_request.iid} was accepted (without merge)"
+= "Merge Request #{@merge_request.iid} was #{@action}"
 
 Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
 
diff --git a/app/views/projects/merge_requests/mark_fixed.js.haml b/app/views/projects/merge_requests/mark_fixed.js.haml
new file mode 100644
index 00000000000..e65223d9ba7
--- /dev/null
+++ b/app/views/projects/merge_requests/mark_fixed.js.haml
@@ -0,0 +1,7 @@
+-if @status
+  :plain
+    location.reload();
+-else
+  :plain
+    alert('Failed to mark the merge request as fixed!');
+
diff --git a/app/views/projects/merge_requests/reject.js.haml b/app/views/projects/merge_requests/reject.js.haml
new file mode 100644
index 00000000000..1483a5215f5
--- /dev/null
+++ b/app/views/projects/merge_requests/reject.js.haml
@@ -0,0 +1,7 @@
+-if @status
+  :plain
+    location.reload();
+-else
+  :plain
+    alert('Failed to reject the merge request!');
+
diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml
index 62950154ea0..9d80ada24b2 100644
--- a/app/views/projects/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml
@@ -52,7 +52,16 @@
       &nbsp;
       Merge is in progress. Please wait. Page will be automatically reloaded. &nbsp;
 
-- elsif @show_accept_control
-  %span
-    = form_for [:accept_without_merge, @project, @merge_request], remote: true, method: :get do |f|
-      = f.submit "Accept Without Merge", class: "btn btn-create accept_without_merge"
+- if @allowed_to_review
+  - if @show_accept_button
+    %span
+      = form_for [:accept_without_merge, @project, @merge_request], remote: true, method: :get do |f|
+        = f.submit "Accept Without Merge", class: "btn btn-success accept_without_merge"
+  - if @show_reject_button
+    %span
+      = form_for [:reject, @project, @merge_request], remote: true, method: :get do |f|
+        = f.submit "Reject", class: "btn btn-danger reject"
+  - if @show_mark_fixed_button
+    %span
+      = form_for [:mark_fixed, @project, @merge_request], remote: true, method: :get do |f|
+        = f.submit "Mark as fixed", class: "btn btn-success mark_fixed"
diff --git a/config/routes.rb b/config/routes.rb
index b2884d6b674..b209a7ef882 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -255,6 +255,8 @@ Gitlab::Application.routes.draw do
           get :automerge_check
           get :ci_status
           get :accept_without_merge
+          get :reject
+          get :mark_fixed
         end
 
         collection do
diff --git a/db/migrate/20131029195936_add_rejected_and_fixed_states_to_merge_request.rb b/db/migrate/20131029195936_add_rejected_and_fixed_states_to_merge_request.rb
new file mode 100644
index 00000000000..80bff7d7637
--- /dev/null
+++ b/db/migrate/20131029195936_add_rejected_and_fixed_states_to_merge_request.rb
@@ -0,0 +1,7 @@
+class AddRejectedAndFixedStatesToMergeRequest < ActiveRecord::Migration
+  # We don't need the forward ("up") data migration
+  def down
+    # Return all rejected and fixed MR's back to the 'opened' state
+    MergeRequest.where(state: [:rejected, :fixed]).update_all(state: :opened)
+  end
+end
diff --git a/db/migrate/20131029200011_add_rejected_and_fixed_events.rb b/db/migrate/20131029200011_add_rejected_and_fixed_events.rb
new file mode 100644
index 00000000000..512e3e3f95c
--- /dev/null
+++ b/db/migrate/20131029200011_add_rejected_and_fixed_events.rb
@@ -0,0 +1,9 @@
+class AddRejectedAndFixedEvents < ActiveRecord::Migration
+  # We don't need the forward ("up") data migration
+  def down
+    # Remove all 'REJECTED' and 'FIXED' events
+    # 102 == Event::REJECTED
+    # 103 == Event::FIXED
+    Event.where(action: [102, 103]).delete_all
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a51f4aa0a83..28720e9cac0 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 => 20131022131759) do
+ActiveRecord::Schema.define(:version => 20131029200011) do
 
   create_table "deploy_keys_projects", :force => true do |t|
     t.integer  "deploy_key_id", :null => false
-- 
GitLab


From 10a914bc4f2f0e997bf1e59d68236b22d641a980 Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Wed, 30 Oct 2013 13:59:20 +0400
Subject: [PATCH 18/59] Allow to filter merge requests by state

---
 app/contexts/merge_requests_load_context.rb     |  5 +++++
 .../projects/merge_requests_controller.rb       |  4 ++++
 .../projects/merge_requests/index.html.haml     | 17 +++++++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb
index 28c795b3c65..f0b3a7e265f 100644
--- a/app/contexts/merge_requests_load_context.rb
+++ b/app/contexts/merge_requests_load_context.rb
@@ -42,6 +42,11 @@ class MergeRequestsLoadContext < BaseContext
       merge_requests = merge_requests.joins(author: :users_groups).where(users_groups: {group_id: params[:created_group_id]})
     end
 
+    # Filter by specific state
+    if params[:state].present?
+      merge_requests = merge_requests.where(state: params[:state])
+    end
+
     merge_requests
   end
 end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 42434ce4c78..e9756c2932b 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -25,6 +25,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @user_groups = current_user.users_groups
     @assigned_group = @user_groups.where(group_id: assigned_group_id).first.group if assigned_group_id.present?
     @created_group = @user_groups.where(group_id: created_group_id).first.group if created_group_id.present?
+    # Merge request states, which will be available in the corresponding filter.
+    # We want to display all states, which displayed in the list MRs can have (i.e. everything what can be merged).
+    @available_states = MergeRequest::VALID_STATES_FOR_MERGE
+    @state = params[:state]
   end
 
   def show
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 568032d2ff5..be4879db2c8 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -99,6 +99,23 @@
                     %strong= milestone.title
                     %small.light= milestone.expires_at
 
+          .dropdown.inline.prepend-left-10
+            %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"}
+              %span.light state:
+              - if @state.present?
+                %strong= @state.capitalize
+              - else
+                Any
+              %b.caret
+            %ul.dropdown-menu
+              %li
+                = link_to project_filter_path(state: nil) do
+                  Any
+              - @available_states.each do |state|
+                %li
+                  = link_to project_filter_path(state: state) do
+                    = state.capitalize
+
       %ul.well-list.mr-list
         = render @merge_requests
         - if @merge_requests.blank?
-- 
GitLab


From e61df77b1538654b4bc69e62b24ae368e493fcfd Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Wed, 30 Oct 2013 16:46:23 +0400
Subject: [PATCH 19/59] Show name of user who changed MR's review state in
 email subject and body

---
 app/mailers/emails/merge_requests.rb                    | 2 +-
 app/views/notify/reviewed_merge_request_email.html.haml | 2 +-
 app/views/notify/reviewed_merge_request_email.text.haml | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index 00a0033b28a..47626e7c714 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -21,7 +21,7 @@ module Emails
       @merge_request = MergeRequest.find(merge_request_id)
       @updated_by = User.find updated_by_user_id
       @action = action
-      mail(to: recipient(recipient_id), subject: subject("#{action.capitalize} merge request !#{@merge_request.iid}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{@updated_by.name} #{action} merge request !#{@merge_request.iid}", @merge_request.title))
     end
 
     def merged_merge_request_email(recipient_id, merge_request_id)
diff --git a/app/views/notify/reviewed_merge_request_email.html.haml b/app/views/notify/reviewed_merge_request_email.html.haml
index 26bb7052a50..681da7c49ab 100644
--- a/app/views/notify/reviewed_merge_request_email.html.haml
+++ b/app/views/notify/reviewed_merge_request_email.html.haml
@@ -1,5 +1,5 @@
 %p
-  = "Merge Request #{@merge_request.iid} was #{@action}"
+  = "Merge Request #{@merge_request.iid} was #{@action} by #{@updated_by.name}"
 %p
   = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request)
 %p
diff --git a/app/views/notify/reviewed_merge_request_email.text.haml b/app/views/notify/reviewed_merge_request_email.text.haml
index 0b9c2239171..b3d1134a84c 100644
--- a/app/views/notify/reviewed_merge_request_email.text.haml
+++ b/app/views/notify/reviewed_merge_request_email.text.haml
@@ -1,4 +1,4 @@
-= "Merge Request #{@merge_request.iid} was #{@action}"
+= "Merge Request #{@merge_request.iid} was #{@action} by #{@updated_by.name}"
 
 Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
 
-- 
GitLab


From a4d65885e7e2b92f21c36a64195509a8852ff1c4 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 31 Oct 2013 10:42:15 +0200
Subject: [PATCH 20/59] Update gitlab_git to recent version

---
 Gemfile      | 2 +-
 Gemfile.lock | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Gemfile b/Gemfile
index faa7f362be4..a86b7dcd4e0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -24,7 +24,7 @@ gem 'omniauth-github'
 
 # Extracting information from a git repository
 # Provide access to Gitlab::Git library
-gem "gitlab_git", "~> 3.0.0.rc1"
+gem "gitlab_git", "~> 3.0.0.rc2"
 
 # Ruby/Rack Git Smart-HTTP Server Handler
 gem 'gitlab-grack', '~> 1.0.1', require: 'grack'
diff --git a/Gemfile.lock b/Gemfile.lock
index 38d53eca14e..f919e6eb5bc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -171,7 +171,7 @@ GEM
       stringex (~> 1.5.1)
     gitlab-grack (1.0.1)
       rack (~> 1.4.1)
-    gitlab-grit (2.6.0)
+    gitlab-grit (2.6.1)
       charlock_holmes (~> 0.6.9)
       diff-lcs (~> 1.1)
       mime-types (~> 1.15)
@@ -179,10 +179,10 @@ GEM
     gitlab-pygments.rb (0.3.2)
       posix-spawn (~> 0.3.6)
       yajl-ruby (~> 1.1.0)
-    gitlab_git (3.0.0.rc1)
+    gitlab_git (3.0.0.rc2)
       activesupport (~> 3.2.13)
       github-linguist (~> 2.3.4)
-      gitlab-grit (~> 2.6.0)
+      gitlab-grit (~> 2.6.1)
     gitlab_meta (6.0)
     gitlab_omniauth-ldap (1.0.3)
       net-ldap (~> 0.3.1)
@@ -581,7 +581,7 @@ DEPENDENCIES
   gitlab-gollum-lib (~> 1.0.1)
   gitlab-grack (~> 1.0.1)
   gitlab-pygments.rb (~> 0.3.2)
-  gitlab_git (~> 3.0.0.rc1)
+  gitlab_git (~> 3.0.0.rc2)
   gitlab_meta (= 6.0)
   gitlab_omniauth-ldap (= 1.0.3)
   gon
-- 
GitLab


From 9c3e95f6d9fea769bb1c23e0d74e7f82cc59810b Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 31 Oct 2013 11:28:25 +0200
Subject: [PATCH 21/59] Version to 6.2.2

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

diff --git a/VERSION b/VERSION
index 024b066c0bb..ca06394388d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.2.1
+6.2.2
-- 
GitLab


From bb2f3ec701e71f2474f2526679c272fd3a48dc5c Mon Sep 17 00:00:00 2001
From: connor <connor@prodege.com>
Date: Thu, 31 Oct 2013 07:14:59 -0700
Subject: [PATCH 22/59] revert reverting default branch

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

diff --git a/app/models/project.rb b/app/models/project.rb
index bef6c840a08..d2dcf26ac69 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -303,7 +303,7 @@ class Project < ActiveRecord::Base
   def discover_default_branch
     # Discover the default branch, but only if it hasn't already been set to
     # something else
-    if false && repository.exists? && default_branch.nil?
+    if repository.exists? && default_branch.nil?
       update_attributes(default_branch: self.repository.discover_default_branch)
     end
   end
-- 
GitLab


From 4a0cf53760704938708c58a743380e55dff75021 Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Thu, 31 Oct 2013 22:24:23 +0400
Subject: [PATCH 23/59] Fix: force reload the page after changing the review
 state; remove unnecessary code duplication in the review action views

---
 app/controllers/projects/merge_requests_controller.rb  | 10 ++++++----
 app/views/projects/merge_requests/_review.js.haml      |  7 +++++++
 .../merge_requests/accept_without_merge.js.haml        |  7 -------
 app/views/projects/merge_requests/mark_fixed.js.haml   |  7 -------
 app/views/projects/merge_requests/reject.js.haml       |  7 -------
 5 files changed, 13 insertions(+), 25 deletions(-)
 create mode 100644 app/views/projects/merge_requests/_review.js.haml
 delete mode 100644 app/views/projects/merge_requests/accept_without_merge.js.haml
 delete mode 100644 app/views/projects/merge_requests/mark_fixed.js.haml
 delete mode 100644 app/views/projects/merge_requests/reject.js.haml

diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index e9756c2932b..0e47316fffa 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -114,7 +114,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     end
   end
 
-  def change_review_status(appropriate_current_statuses, change_status_method)
+  def change_review_status(appropriate_current_statuses, change_status_method, review_action)
     return access_denied! unless allowed_to_review?
 
     if appropriate_current_statuses.include?(@merge_request.state)
@@ -123,18 +123,20 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     else
       @status = false
     end
+    @review_action = review_action
+    render "_review"
   end
 
   def accept_without_merge
-    change_review_status(MergeRequest::VALID_STATES_FOR_ACCEPT, :accept)
+    change_review_status(MergeRequest::VALID_STATES_FOR_ACCEPT, :accept, 'accept (without merge)')
   end
 
   def reject
-    change_review_status(MergeRequest::VALID_STATES_FOR_REJECT, :reject)
+    change_review_status(MergeRequest::VALID_STATES_FOR_REJECT, :reject, 'reject')
   end
 
   def mark_fixed
-    change_review_status(MergeRequest::VALID_STATES_FOR_MARK_FIXED, :mark_fixed)
+    change_review_status(MergeRequest::VALID_STATES_FOR_MARK_FIXED, :mark_fixed, 'mark as fixed')
   end
 
   def branch_from
diff --git a/app/views/projects/merge_requests/_review.js.haml b/app/views/projects/merge_requests/_review.js.haml
new file mode 100644
index 00000000000..30c05d44ed3
--- /dev/null
+++ b/app/views/projects/merge_requests/_review.js.haml
@@ -0,0 +1,7 @@
+-if @status
+  :plain
+    location.reload(true);
+-else
+  :plain
+    alert("Failed to #{@review_action} the merge request!");
+
diff --git a/app/views/projects/merge_requests/accept_without_merge.js.haml b/app/views/projects/merge_requests/accept_without_merge.js.haml
deleted file mode 100644
index ffcd7c1690e..00000000000
--- a/app/views/projects/merge_requests/accept_without_merge.js.haml
+++ /dev/null
@@ -1,7 +0,0 @@
--if @status
-  :plain
-    location.reload();
--else
-  :plain
-    alert('Failed to accept without merge!');
-
diff --git a/app/views/projects/merge_requests/mark_fixed.js.haml b/app/views/projects/merge_requests/mark_fixed.js.haml
deleted file mode 100644
index e65223d9ba7..00000000000
--- a/app/views/projects/merge_requests/mark_fixed.js.haml
+++ /dev/null
@@ -1,7 +0,0 @@
--if @status
-  :plain
-    location.reload();
--else
-  :plain
-    alert('Failed to mark the merge request as fixed!');
-
diff --git a/app/views/projects/merge_requests/reject.js.haml b/app/views/projects/merge_requests/reject.js.haml
deleted file mode 100644
index 1483a5215f5..00000000000
--- a/app/views/projects/merge_requests/reject.js.haml
+++ /dev/null
@@ -1,7 +0,0 @@
--if @status
-  :plain
-    location.reload();
--else
-  :plain
-    alert('Failed to reject the merge request!');
-
-- 
GitLab


From 7d0d9c650e3cbbb1bf05a6fc62dfcd75aa03df39 Mon Sep 17 00:00:00 2001
From: Jacob Vosmaer <contact@jacobvosmaer.nl>
Date: Fri, 25 Oct 2013 09:39:31 +0200
Subject: [PATCH 24/59] Restore sidekiq rake tasks

---
 lib/tasks/sidekiq.rake | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/tasks/sidekiq.rake b/lib/tasks/sidekiq.rake
index 23d41f8ed24..e91678473a8 100644
--- a/lib/tasks/sidekiq.rake
+++ b/lib/tasks/sidekiq.rake
@@ -4,11 +4,13 @@ namespace :sidekiq do
     system "script/background_jobs stop"
   end
 
-  desc "GITLAB | Start sidekiq" do
+  desc "GITLAB | Start sidekiq"
+  task :start do
     system "script/background_jobs start"
   end
 
-  desc 'GitLab | Restart sidekiq' do
+  desc 'GitLab | Restart sidekiq'
+  task :restart do
     system "script/background_jobs restart"
   end
 
-- 
GitLab


From 03141bfccca2b61721a12f3bb17eb6308cfb0ec4 Mon Sep 17 00:00:00 2001
From: Nigel Kukard <nkukard@lbsd.net>
Date: Tue, 29 Oct 2013 18:06:10 +0000
Subject: [PATCH 25/59] Escape strings

Signed-off-by: Nigel Kukard <nkukard@lbsd.net>
---
 lib/gitlab/backend/shell.rb | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index c819ce56ac9..bcd57ac79bc 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -1,3 +1,5 @@
+require "shellwords"
+
 module Gitlab
   class Shell
     class AccessDenied < StandardError; end
@@ -10,7 +12,7 @@ module Gitlab
     #   add_repository("gitlab/gitlab-ci")
     #
     def add_repository(name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", "#{name}.git"
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", Shellwords.shellwords("#{name}.git")
     end
 
     # Import repository
@@ -21,7 +23,7 @@ module Gitlab
     #   import_repository("gitlab/gitlab-ci", "https://github.com/randx/six.git")
     #
     def import_repository(name, url)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", "#{name}.git", url
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", Shellwords.shellwords("#{name}.git"), Shellwords.shellwords(url)
     end
 
     # Move repository
@@ -33,7 +35,7 @@ module Gitlab
     #   mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git")
     #
     def mv_repository(path, new_path)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", "#{path}.git", "#{new_path}.git"
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords("#{new_path}.git")
     end
 
     # Update HEAD for repository
@@ -45,7 +47,7 @@ module Gitlab
     #  update_repository_head("gitlab/gitlab-ci", "3-1-stable")
     #
     def update_repository_head(path, branch)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", "#{path}.git", branch
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch)
     end
 
     # Fork repository to new namespace
@@ -57,7 +59,7 @@ module Gitlab
     #  fork_repository("gitlab/gitlab-ci", "randx")
     #
     def fork_repository(path, fork_namespace)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", "#{path}.git", fork_namespace
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(fork_namespace)
     end
 
     # Remove repository from file system
@@ -68,7 +70,7 @@ module Gitlab
     #   remove_repository("gitlab/gitlab-ci")
     #
     def remove_repository(name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", "#{name}.git"
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", Shellwords.shellwords("#{name}.git")
     end
 
     # Add repository branch from passed ref
@@ -81,7 +83,7 @@ module Gitlab
     #   add_branch("gitlab/gitlab-ci", "4-0-stable", "master")
     #
     def add_branch(path, branch_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", "#{path}.git", branch_name, ref
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name), Shellwords.shellwords(ref)
     end
 
     # Remove repository branch
@@ -93,7 +95,7 @@ module Gitlab
     #   rm_branch("gitlab/gitlab-ci", "4-0-stable")
     #
     def rm_branch(path, branch_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", "#{path}.git", branch_name
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name)
     end
 
     # Add repository tag from passed ref
@@ -106,7 +108,7 @@ module Gitlab
     #   add_tag("gitlab/gitlab-ci", "v4.0", "master")
     #
     def add_tag(path, tag_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", "#{path}.git", tag_name, ref
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name), Shellwords.shellwords(ref)
     end
 
     # Remove repository tag
@@ -118,7 +120,7 @@ module Gitlab
     #   rm_tag("gitlab/gitlab-ci", "v4.0")
     #
     def rm_tag(path, tag_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", "#{path}.git", tag_name
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name)
     end
 
     # Add new key to gitlab-shell
@@ -127,7 +129,7 @@ module Gitlab
     #   add_key("key-42", "sha-rsa ...")
     #
     def add_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", key_id, key_content
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
     end
 
     # Remove ssh key from gitlab shell
@@ -136,7 +138,7 @@ module Gitlab
     #   remove_key("key-342", "sha-rsa ...")
     #
     def remove_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", key_id, key_content
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
     end
 
     # Remove all ssh keys from gitlab shell
-- 
GitLab


From 1ab324cb6721e374e11f4aac0fab0140f7fdacc5 Mon Sep 17 00:00:00 2001
From: Nigel Kukard <nkukard@lbsd.net>
Date: Thu, 31 Oct 2013 07:34:11 +0000
Subject: [PATCH 26/59] Best to escape strings not split them

Signed-off-by: Nigel Kukard <nkukard@lbsd.net>
---
 lib/gitlab/backend/shell.rb | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index bcd57ac79bc..4e2a5cd168f 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -12,7 +12,7 @@ module Gitlab
     #   add_repository("gitlab/gitlab-ci")
     #
     def add_repository(name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", Shellwords.shellwords("#{name}.git")
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", Shellwords.shellescape("#{name}.git")
     end
 
     # Import repository
@@ -23,7 +23,7 @@ module Gitlab
     #   import_repository("gitlab/gitlab-ci", "https://github.com/randx/six.git")
     #
     def import_repository(name, url)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", Shellwords.shellwords("#{name}.git"), Shellwords.shellwords(url)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", Shellwords.shellescape("#{name}.git"), Shellwords.shellescape(url)
     end
 
     # Move repository
@@ -35,7 +35,7 @@ module Gitlab
     #   mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git")
     #
     def mv_repository(path, new_path)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords("#{new_path}.git")
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape("#{new_path}.git")
     end
 
     # Update HEAD for repository
@@ -47,7 +47,7 @@ module Gitlab
     #  update_repository_head("gitlab/gitlab-ci", "3-1-stable")
     #
     def update_repository_head(path, branch)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(branch)
     end
 
     # Fork repository to new namespace
@@ -59,18 +59,18 @@ module Gitlab
     #  fork_repository("gitlab/gitlab-ci", "randx")
     #
     def fork_repository(path, fork_namespace)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(fork_namespace)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(fork_namespace)
     end
 
     # Remove repository from file system
     #
-    # name - project path with namespace
+    # path - project path with namespace
     #
     # Ex.
     #   remove_repository("gitlab/gitlab-ci")
     #
-    def remove_repository(name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", Shellwords.shellwords("#{name}.git")
+    def remove_repository(path)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", Shellwords.shellescape("#{path}.git")
     end
 
     # Add repository branch from passed ref
@@ -83,7 +83,7 @@ module Gitlab
     #   add_branch("gitlab/gitlab-ci", "4-0-stable", "master")
     #
     def add_branch(path, branch_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name), Shellwords.shellwords(ref)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(branch_name), Shellwords.shellescape(ref)
     end
 
     # Remove repository branch
@@ -95,7 +95,7 @@ module Gitlab
     #   rm_branch("gitlab/gitlab-ci", "4-0-stable")
     #
     def rm_branch(path, branch_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(branch_name)
     end
 
     # Add repository tag from passed ref
@@ -108,7 +108,7 @@ module Gitlab
     #   add_tag("gitlab/gitlab-ci", "v4.0", "master")
     #
     def add_tag(path, tag_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name), Shellwords.shellwords(ref)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(tag_name), Shellwords.shellescape(ref)
     end
 
     # Remove repository tag
@@ -120,7 +120,7 @@ module Gitlab
     #   rm_tag("gitlab/gitlab-ci", "v4.0")
     #
     def rm_tag(path, tag_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(tag_name)
     end
 
     # Add new key to gitlab-shell
@@ -129,7 +129,7 @@ module Gitlab
     #   add_key("key-42", "sha-rsa ...")
     #
     def add_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", Shellwords.shellescape(key_id), Shellwords.shellescape(key_content)
     end
 
     # Remove ssh key from gitlab shell
@@ -138,7 +138,7 @@ module Gitlab
     #   remove_key("key-342", "sha-rsa ...")
     #
     def remove_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", Shellwords.shellescape(key_id), Shellwords.shellescape(key_content)
     end
 
     # Remove all ssh keys from gitlab shell
-- 
GitLab


From 1bace9da9abdacb7df91421548a8f3c66031ddfd Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 31 Oct 2013 19:48:39 +0200
Subject: [PATCH 27/59] Require gitlab-shell v1.7.3

---
 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 e01f3b23d03..c4f1eba9b9e 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -736,7 +736,7 @@ namespace :gitlab do
   end
 
   def check_gitlab_shell
-    required_version = Gitlab::VersionInfo.new(1, 7, 1)
+    required_version = Gitlab::VersionInfo.new(1, 7, 3)
     current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
 
     print "GitLab Shell version >= #{required_version} ? ... "
-- 
GitLab


From a476bc7bc7bd902e4bc2dbf9d49d3f6cb9e61537 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 31 Oct 2013 11:25:08 +0200
Subject: [PATCH 28/59] Shell escape code search

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

diff --git a/app/contexts/search_context.rb b/app/contexts/search_context.rb
index 48def0784fd..ff322978559 100644
--- a/app/contexts/search_context.rb
+++ b/app/contexts/search_context.rb
@@ -6,7 +6,7 @@ class SearchContext
   end
 
   def execute
-    query = params[:search]
+    query = Shellwords.shellescape(params[:search])
 
     return result unless query.present?
 
-- 
GitLab


From 31736e9be83da6cf45d5331790bd39b230bbc1f6 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 31 Oct 2013 16:35:06 +0200
Subject: [PATCH 29/59] Correctly escape search query

---
 app/contexts/search_context.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/contexts/search_context.rb b/app/contexts/search_context.rb
index ff322978559..c07fdfe4c39 100644
--- a/app/contexts/search_context.rb
+++ b/app/contexts/search_context.rb
@@ -6,7 +6,8 @@ class SearchContext
   end
 
   def execute
-    query = Shellwords.shellescape(params[:search])
+    query = params[:search]
+    query = Shellwords.shellescape(query) if query.present?
 
     return result unless query.present?
 
-- 
GitLab


From 9f9d9cff0dbec92a31296da85460c82c9f826b8a Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 1 Nov 2013 16:30:18 +0200
Subject: [PATCH 30/59] Revert "Best to escape strings not split them"

This reverts commit 1ab324cb6721e374e11f4aac0fab0140f7fdacc5.
---
 lib/gitlab/backend/shell.rb | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index 4e2a5cd168f..bcd57ac79bc 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -12,7 +12,7 @@ module Gitlab
     #   add_repository("gitlab/gitlab-ci")
     #
     def add_repository(name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", Shellwords.shellescape("#{name}.git")
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", Shellwords.shellwords("#{name}.git")
     end
 
     # Import repository
@@ -23,7 +23,7 @@ module Gitlab
     #   import_repository("gitlab/gitlab-ci", "https://github.com/randx/six.git")
     #
     def import_repository(name, url)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", Shellwords.shellescape("#{name}.git"), Shellwords.shellescape(url)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", Shellwords.shellwords("#{name}.git"), Shellwords.shellwords(url)
     end
 
     # Move repository
@@ -35,7 +35,7 @@ module Gitlab
     #   mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git")
     #
     def mv_repository(path, new_path)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape("#{new_path}.git")
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords("#{new_path}.git")
     end
 
     # Update HEAD for repository
@@ -47,7 +47,7 @@ module Gitlab
     #  update_repository_head("gitlab/gitlab-ci", "3-1-stable")
     #
     def update_repository_head(path, branch)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(branch)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch)
     end
 
     # Fork repository to new namespace
@@ -59,18 +59,18 @@ module Gitlab
     #  fork_repository("gitlab/gitlab-ci", "randx")
     #
     def fork_repository(path, fork_namespace)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(fork_namespace)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(fork_namespace)
     end
 
     # Remove repository from file system
     #
-    # path - project path with namespace
+    # name - project path with namespace
     #
     # Ex.
     #   remove_repository("gitlab/gitlab-ci")
     #
-    def remove_repository(path)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", Shellwords.shellescape("#{path}.git")
+    def remove_repository(name)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", Shellwords.shellwords("#{name}.git")
     end
 
     # Add repository branch from passed ref
@@ -83,7 +83,7 @@ module Gitlab
     #   add_branch("gitlab/gitlab-ci", "4-0-stable", "master")
     #
     def add_branch(path, branch_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(branch_name), Shellwords.shellescape(ref)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name), Shellwords.shellwords(ref)
     end
 
     # Remove repository branch
@@ -95,7 +95,7 @@ module Gitlab
     #   rm_branch("gitlab/gitlab-ci", "4-0-stable")
     #
     def rm_branch(path, branch_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(branch_name)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name)
     end
 
     # Add repository tag from passed ref
@@ -108,7 +108,7 @@ module Gitlab
     #   add_tag("gitlab/gitlab-ci", "v4.0", "master")
     #
     def add_tag(path, tag_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(tag_name), Shellwords.shellescape(ref)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name), Shellwords.shellwords(ref)
     end
 
     # Remove repository tag
@@ -120,7 +120,7 @@ module Gitlab
     #   rm_tag("gitlab/gitlab-ci", "v4.0")
     #
     def rm_tag(path, tag_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", Shellwords.shellescape("#{path}.git"), Shellwords.shellescape(tag_name)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name)
     end
 
     # Add new key to gitlab-shell
@@ -129,7 +129,7 @@ module Gitlab
     #   add_key("key-42", "sha-rsa ...")
     #
     def add_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", Shellwords.shellescape(key_id), Shellwords.shellescape(key_content)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
     end
 
     # Remove ssh key from gitlab shell
@@ -138,7 +138,7 @@ module Gitlab
     #   remove_key("key-342", "sha-rsa ...")
     #
     def remove_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", Shellwords.shellescape(key_id), Shellwords.shellescape(key_content)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
     end
 
     # Remove all ssh keys from gitlab shell
-- 
GitLab


From 33b041a346795b80d48ed1b200227d0ab4c4bcca Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 1 Nov 2013 16:30:29 +0200
Subject: [PATCH 31/59] Revert "Escape strings"

This reverts commit 03141bfccca2b61721a12f3bb17eb6308cfb0ec4.
---
 lib/gitlab/backend/shell.rb | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index bcd57ac79bc..c819ce56ac9 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -1,5 +1,3 @@
-require "shellwords"
-
 module Gitlab
   class Shell
     class AccessDenied < StandardError; end
@@ -12,7 +10,7 @@ module Gitlab
     #   add_repository("gitlab/gitlab-ci")
     #
     def add_repository(name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", Shellwords.shellwords("#{name}.git")
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "add-project", "#{name}.git"
     end
 
     # Import repository
@@ -23,7 +21,7 @@ module Gitlab
     #   import_repository("gitlab/gitlab-ci", "https://github.com/randx/six.git")
     #
     def import_repository(name, url)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", Shellwords.shellwords("#{name}.git"), Shellwords.shellwords(url)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "import-project", "#{name}.git", url
     end
 
     # Move repository
@@ -35,7 +33,7 @@ module Gitlab
     #   mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git")
     #
     def mv_repository(path, new_path)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords("#{new_path}.git")
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "mv-project", "#{path}.git", "#{new_path}.git"
     end
 
     # Update HEAD for repository
@@ -47,7 +45,7 @@ module Gitlab
     #  update_repository_head("gitlab/gitlab-ci", "3-1-stable")
     #
     def update_repository_head(path, branch)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "update-head", "#{path}.git", branch
     end
 
     # Fork repository to new namespace
@@ -59,7 +57,7 @@ module Gitlab
     #  fork_repository("gitlab/gitlab-ci", "randx")
     #
     def fork_repository(path, fork_namespace)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(fork_namespace)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "fork-project", "#{path}.git", fork_namespace
     end
 
     # Remove repository from file system
@@ -70,7 +68,7 @@ module Gitlab
     #   remove_repository("gitlab/gitlab-ci")
     #
     def remove_repository(name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", Shellwords.shellwords("#{name}.git")
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", "#{name}.git"
     end
 
     # Add repository branch from passed ref
@@ -83,7 +81,7 @@ module Gitlab
     #   add_branch("gitlab/gitlab-ci", "4-0-stable", "master")
     #
     def add_branch(path, branch_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name), Shellwords.shellwords(ref)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", "#{path}.git", branch_name, ref
     end
 
     # Remove repository branch
@@ -95,7 +93,7 @@ module Gitlab
     #   rm_branch("gitlab/gitlab-ci", "4-0-stable")
     #
     def rm_branch(path, branch_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(branch_name)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", "#{path}.git", branch_name
     end
 
     # Add repository tag from passed ref
@@ -108,7 +106,7 @@ module Gitlab
     #   add_tag("gitlab/gitlab-ci", "v4.0", "master")
     #
     def add_tag(path, tag_name, ref)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name), Shellwords.shellwords(ref)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", "#{path}.git", tag_name, ref
     end
 
     # Remove repository tag
@@ -120,7 +118,7 @@ module Gitlab
     #   rm_tag("gitlab/gitlab-ci", "v4.0")
     #
     def rm_tag(path, tag_name)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", Shellwords.shellwords("#{path}.git"), Shellwords.shellwords(tag_name)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", "#{path}.git", tag_name
     end
 
     # Add new key to gitlab-shell
@@ -129,7 +127,7 @@ module Gitlab
     #   add_key("key-42", "sha-rsa ...")
     #
     def add_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "add-key", key_id, key_content
     end
 
     # Remove ssh key from gitlab shell
@@ -138,7 +136,7 @@ module Gitlab
     #   remove_key("key-342", "sha-rsa ...")
     #
     def remove_key(key_id, key_content)
-      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", Shellwords.shellwords(key_id), Shellwords.shellwords(key_content)
+      system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", key_id, key_content
     end
 
     # Remove all ssh keys from gitlab shell
-- 
GitLab


From 2d56ef52d255f44e63c7db9b23bad723867beb49 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Fri, 1 Nov 2013 16:58:24 +0200
Subject: [PATCH 32/59] Require gitlab-shell 1.7.4

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 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 c4f1eba9b9e..3c92dac8b82 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -736,7 +736,7 @@ namespace :gitlab do
   end
 
   def check_gitlab_shell
-    required_version = Gitlab::VersionInfo.new(1, 7, 3)
+    required_version = Gitlab::VersionInfo.new(1, 7, 4)
     current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
 
     print "GitLab Shell version >= #{required_version} ? ... "
-- 
GitLab


From 05deff01340bb8c036957d2aade5405a1f060a37 Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Fri, 1 Nov 2013 19:24:28 +0400
Subject: [PATCH 33/59] Bugfix: hack the opened merge request state to include
 MRs in the review states (accepted, rejected, fixed); revert previously
 introduced not_closed method and scope

---
 app/contexts/merge_requests_load_context.rb              | 2 +-
 app/controllers/projects/merge_requests_controller.rb    | 2 +-
 app/models/merge_request.rb                              | 9 +++++----
 app/views/layouts/nav/_project.html.haml                 | 2 +-
 .../projects/merge_requests/show/_mr_title.html.haml     | 2 +-
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb
index f0b3a7e265f..a40954b9896 100644
--- a/app/contexts/merge_requests_load_context.rb
+++ b/app/contexts/merge_requests_load_context.rb
@@ -7,7 +7,7 @@ class MergeRequestsLoadContext < BaseContext
     merge_requests = case params[:state]
                      when 'all' then merge_requests
                      when 'closed' then merge_requests.closed
-                     else merge_requests.not_closed
+                     else merge_requests.opened
                      end
 
     merge_requests = case params[:scope]
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index e9756c2932b..b367984440c 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -105,7 +105,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
   def automerge
     return access_denied! unless allowed_to_merge?
 
-    if (@merge_request.opened? || @merge_request.accepted?) && @merge_request.can_be_merged?
+    if @merge_request.opened? && @merge_request.can_be_merged?
       @merge_request.should_remove_source_branch = params[:should_remove_source_branch]
       @merge_request.automerge!(current_user)
       @status = true
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index c955a153061..c80bc0a6b07 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -110,7 +110,8 @@ class MergeRequest < ActiveRecord::Base
 
   scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) }
   scope :of_user_team, ->(team) { where("(source_project_id in (:team_project_ids) OR target_project_id in (:team_project_ids) AND assignee_id in (:team_member_ids))", team_project_ids: team.project_ids, team_member_ids: team.member_ids) }
-  scope :opened, -> { with_state(:opened) }
+  # Hack: we want the review states ('accepted', 'rejected', 'fixed') to behave in the same way as the 'opened' one
+  scope :opened, -> { with_states(:opened, :accepted, :rejected, :fixed) }
   scope :closed, -> { with_state(:closed) }
   scope :merged, -> { with_state(:merged) }
   scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) }
@@ -121,15 +122,15 @@ class MergeRequest < ActiveRecord::Base
   # Closed scope for merge request should return
   # both merged and closed mr's
   scope :closed, -> { with_states(:closed, :merged) }
-  scope :not_closed, -> { with_states(:opened, :reopened, :accepted, :rejected, :fixed) }
 
   VALID_STATES_FOR_MERGE = ["opened", "reopened", "accepted", "rejected", "fixed"]
   VALID_STATES_FOR_ACCEPT = ["opened", "reopened", "rejected", "fixed"]
   VALID_STATES_FOR_REJECT = ["opened", "reopened", "accepted", "fixed"]
   VALID_STATES_FOR_MARK_FIXED = ["rejected"]
 
-  def not_closed?
-    return !closed? && !merged?
+  # Hack: we want the review states ('accepted', 'rejected', 'fixed') to behave in the same way as the 'opened' one
+  def opened?
+    return state == "opened" || accepted? || rejected? || fixed?
   end
 
   def validate_branches
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index 14971bf0164..e9d535f6972 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -30,7 +30,7 @@
     = nav_link(controller: :merge_requests) do
       = link_to project_merge_requests_path(@project) do
         Merge Requests
-        %span.count.merge_counter= @project.merge_requests.not_closed.count
+        %span.count.merge_counter= @project.merge_requests.opened.count
 
   - if project_nav_tab? :wiki
     = nav_link(controller: :wikis) do
diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml
index a7603113407..27176679916 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_title.html.haml
@@ -14,7 +14,7 @@
 
   %span.pull-right
     - if can?(current_user, :modify_merge_request, @merge_request)
-      - if @merge_request.not_closed?
+      - if @merge_request.opened?
         .left.btn-group
           %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} }
             %i.icon-download-alt
-- 
GitLab


From 867785b492011894df1c1660150f105f80ccc30f Mon Sep 17 00:00:00 2001
From: Jacob Vosmaer <contact@jacobvosmaer.nl>
Date: Fri, 1 Nov 2013 16:34:00 +0100
Subject: [PATCH 34/59] Use gitlab-shell 1.7.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 c89ae57f710..f7bea2727d6 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -122,7 +122,7 @@ GitLab Shell is an ssh access and repository management software developed speci
     cd gitlab-shell
 
     # switch to right version
-    sudo -u git -H git checkout v1.7.1
+    sudo -u git -H git checkout v1.7.4
 
     sudo -u git -H cp config.yml.example config.yml
 
-- 
GitLab


From 5ed6e86e01b843bf8d9930771235ca3cdc97f168 Mon Sep 17 00:00:00 2001
From: Alexander Olkhovskiy <alexander.o@prodege.com>
Date: Fri, 1 Nov 2013 19:35:54 +0400
Subject: [PATCH 35/59] Bugfix: add a data migration to update commits and
 diffs for all merge requests in the review states

---
 .../20131101150042_update_reviewed_merge_requests.rb      | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 db/migrate/20131101150042_update_reviewed_merge_requests.rb

diff --git a/db/migrate/20131101150042_update_reviewed_merge_requests.rb b/db/migrate/20131101150042_update_reviewed_merge_requests.rb
new file mode 100644
index 00000000000..1bf00666621
--- /dev/null
+++ b/db/migrate/20131101150042_update_reviewed_merge_requests.rb
@@ -0,0 +1,8 @@
+class UpdateReviewedMergeRequests < ActiveRecord::Migration
+  def up
+    # Update all merge requests in the review states (:accepted, :rejected, :fixed)
+    # This is normally done in Project.update_merge_requests(oldrev, newrev, ref, user) via a push hook,
+    # but only opened MRs were updated before, so we need to update the reviewed ones now
+    MergeRequest.where(state: [:accepted, :rejected, :fixed]).each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
+  end
+end
-- 
GitLab


From 675e5203cc00b6b6b5159bc798b593429869aa9b Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 4 Nov 2013 14:41:30 +0200
Subject: [PATCH 36/59] Version 6.2.3

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 VERSION | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/VERSION b/VERSION
index ca06394388d..bee94338174 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.2.2
+6.2.3
-- 
GitLab


From 9ed3ac32bb1c8cd9ad015b9d669b68a2e3187c15 Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Wed, 11 Dec 2013 11:20:09 +0400
Subject: [PATCH 37/59] Some gitlab updates (SWAG-522)

---
 .../stylesheets/sections/merge_requests.scss   |  5 +++++
 .../projects/merge_requests_controller.rb      |  2 ++
 app/helpers/projects_helper.rb                 |  3 +++
 .../merge_requests/show/_mr_accept.html.haml   | 18 ++++++++++--------
 4 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index aa61cae4b9a..941abf5a523 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -116,3 +116,8 @@
 .merge-request-form-info {
   padding: 15px 0;
 }
+
+.merge-request-review-button {
+  float: left;
+  margin-right: 8px;
+}
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index e9756c2932b..83c1fae7188 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -217,6 +217,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
 
     @target_type = :merge_request
     @target_id = @merge_request.id
+
+    @protected_source_branch = project.protected_branch?(@merge_request.source_branch)
   end
 
   def allowed_to_merge?
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 864f6c9af95..95b01eb3e5a 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -63,6 +63,9 @@ module ProjectsHelper
 
   def project_filter_path(options={})
     exist_opts = {
+      assignee_id: params[:assignee_id],
+      assigned_group_id: params[:assigned_group_id],
+      created_group_id: params[:created_group_id],
       state: params[:state],
       scope: params[:scope],
       label_name: params[:label_name],
diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml
index 9d80ada24b2..5b18ad495ed 100644
--- a/app/views/projects/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml
@@ -16,11 +16,12 @@
             for instructions
           .accept_group
             = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request"
-            - unless @merge_request.disallow_source_branch_removal?
-              .remove_branch_holder
-                = label_tag :should_remove_source_branch, class: "checkbox" do
-                  = check_box_tag :should_remove_source_branch
-                  Remove source-branch
+            - unless @protected_source_branch
+              - unless @merge_request.disallow_source_branch_removal?
+                .remove_branch_holder
+                  = label_tag :should_remove_source_branch, class: "checkbox" do
+                    = check_box_tag :should_remove_source_branch
+                    Remove source-branch
           .clearfix
 
 
@@ -54,14 +55,15 @@
 
 - if @allowed_to_review
   - if @show_accept_button
-    %span
+    %span.merge-request-review-button
       = form_for [:accept_without_merge, @project, @merge_request], remote: true, method: :get do |f|
         = f.submit "Accept Without Merge", class: "btn btn-success accept_without_merge"
   - if @show_reject_button
-    %span
+    %span.merge-request-review-button
       = form_for [:reject, @project, @merge_request], remote: true, method: :get do |f|
         = f.submit "Reject", class: "btn btn-danger reject"
   - if @show_mark_fixed_button
-    %span
+    %span.merge-request-review-button
       = form_for [:mark_fixed, @project, @merge_request], remote: true, method: :get do |f|
         = f.submit "Mark as fixed", class: "btn btn-success mark_fixed"
+  .clearfix
-- 
GitLab


From 5582ae145d3b27b8e1713f966dff62fc3ba2307b Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 23 Dec 2013 13:24:10 +0200
Subject: [PATCH 38/59] Fix project transfer feature

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 app/views/projects/edit.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index c56919e792c..44f722d9e15 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -130,7 +130,7 @@
           .title Transfer project
           .errors-holder
           .form-holder
-            = form_for(@project, url: transfer_project_path(@project), remote: true, html: { class: 'transfer-project' }) do |f|
+            = form_for(@project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'transfer-project' }) do |f|
               .control-group
                 = f.label :namespace_id do
                   %span Namespace
-- 
GitLab


From cc51931d1f4a205de412ed8dfca98b832f4c5c91 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 23 Dec 2013 13:19:13 +0200
Subject: [PATCH 39/59] Fix 500 error when rename repository

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 app/contexts/projects/update_context.rb |  2 +-
 features/project/project.feature        |  5 +++++
 features/steps/project/project.rb       | 15 ++++++++++++---
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/app/contexts/projects/update_context.rb b/app/contexts/projects/update_context.rb
index ed0d451a31a..94de10de0f6 100644
--- a/app/contexts/projects/update_context.rb
+++ b/app/contexts/projects/update_context.rb
@@ -9,7 +9,7 @@ module Projects
 
       new_branch = params[:project].delete(:default_branch)
 
-      if project.repository.exists? && new_branch != project.default_branch
+      if project.repository.exists? && new_branch && new_branch != project.default_branch
         project.change_head(new_branch)
       end
 
diff --git a/features/project/project.feature b/features/project/project.feature
index 59eda4a781d..d8bb1d55e2d 100644
--- a/features/project/project.feature
+++ b/features/project/project.feature
@@ -19,3 +19,8 @@ Feature: Project Feature
     And change project settings
     And I save project
     Then I should see project with new settings
+
+  Scenario: I change project path
+    When I visit edit project "Shop" page
+    And change project path settings
+    Then I should see project with new path settings
diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb
index a96b086fae5..92728d474b2 100644
--- a/features/steps/project/project.rb
+++ b/features/steps/project/project.rb
@@ -3,16 +3,25 @@ class ProjectFeature < Spinach::FeatureSteps
   include SharedProject
   include SharedPaths
 
-  And 'change project settings' do
+  step 'change project settings' do
     fill_in 'project_name', with: 'NewName'
     uncheck 'project_issues_enabled'
   end
 
-  And 'I save project' do
+  step 'I save project' do
     click_button 'Save changes'
   end
 
-  Then 'I should see project with new settings' do
+  step 'I should see project with new settings' do
     find_field('project_name').value.should == 'NewName'
   end
+
+  step 'change project path settings' do
+    fill_in "project_path", with: "new-path"
+    click_button "Rename"
+  end
+
+  step 'I should see project with new path settings' do
+    project.path.should == "new-path"
+  end
 end
-- 
GitLab


From 6bc3b5dfa12ef28c2f11ebe003e45b2a051ae2b5 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 23 Dec 2013 14:21:40 +0200
Subject: [PATCH 40/59] Version to 6.4.1

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 VERSION | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/VERSION b/VERSION
index 19b860c1872..4c77920fd2c 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.4.0
+6.4.1
-- 
GitLab


From 58472180b358dc893e2361908a7965d1e9185ddc Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 23 Dec 2013 18:01:51 +0200
Subject: [PATCH 41/59] Fix upgrader

It created branch based on current branch which is an old version

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 lib/gitlab/upgrader.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/gitlab/upgrader.rb b/lib/gitlab/upgrader.rb
index 1de681a97ff..859923cb563 100644
--- a/lib/gitlab/upgrader.rb
+++ b/lib/gitlab/upgrader.rb
@@ -51,7 +51,7 @@ module Gitlab
       {
         "Stash changed files" => "git stash",
         "Get latest code" => "git fetch",
-        "Switch to new version" => "git checkout -b v#{latest_version}",
+        "Switch to new version" => "git checkout v#{latest_version}",
         "Install gems" => "bundle",
         "Migrate DB" => "bundle exec rake db:migrate RAILS_ENV=production",
         "Recompile assets" => "bundle exec rake assets:clean assets:precompile RAILS_ENV=production",
-- 
GitLab


From 214a013bb2395883ae04e819ca703f839b1f63c4 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 23 Dec 2013 18:11:40 +0200
Subject: [PATCH 42/59] Version to 6.4.2

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 VERSION | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/VERSION b/VERSION
index 4c77920fd2c..a4c853ea2ea 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.4.1
+6.4.2
-- 
GitLab


From 221af222d685dfcd34c99b1f5d757a04ce1409e2 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 23 Dec 2013 18:29:10 +0200
Subject: [PATCH 43/59] Add 6.4.1 and 6.4.2 CHANGELOG

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>

Conflicts:
	CHANGELOG
---
 CHANGELOG | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/CHANGELOG b/CHANGELOG
index d3119846760..acbee9c067b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+v6.4.2
+  - Fixed wrong behaviour of script/upgrade.rb
+
+v6.4.1 
+  - Fixed bug with repository rename
+  - Fixed bug with project transfer
+
 v 6.4.0
   - Added sorting to project issues page (Jason Blanchard)
   - Assembla integration (Carlos Paramio)
-- 
GitLab


From 84093385d6f70946dae0772a0913e19ab6a16db0 Mon Sep 17 00:00:00 2001
From: James Newton <james@Zaphyous.com>
Date: Fri, 20 Dec 2013 10:30:34 -0600
Subject: [PATCH 44/59] don't use unicorn worker killer if PhusionPassenger is
 defined

---
 config.ru | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/config.ru b/config.ru
index 1edcd391e45..f7e5e091534 100644
--- a/config.ru
+++ b/config.ru
@@ -1,10 +1,12 @@
 # This file is used by Rack-based servers to start the application.
 
-# Unicorn self-process killer
-require 'unicorn/worker_killer'
+unless defined?(PhusionPassenger)
+  # Unicorn self-process killer
+  require 'unicorn/worker_killer'
 
-# # Max memory size (RSS) per worker
-use Unicorn::WorkerKiller::Oom, (200 * (1 << 20)), (250 * (1 << 20))
+  # Max memory size (RSS) per worker
+  use Unicorn::WorkerKiller::Oom, (200 * (1 << 20)), (250 * (1 << 20))
+end
 
 require ::File.expand_path('../config/environment',  __FILE__)
 
-- 
GitLab


From 42131d0189bbc0e88be72e6a76405140cbd79fc8 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Mon, 23 Dec 2013 20:43:59 +0200
Subject: [PATCH 45/59] Version to 6.4.3

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 VERSION | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/VERSION b/VERSION
index a4c853ea2ea..133cad286fd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.4.2
+6.4.3
-- 
GitLab


From eae84c0c37878675f6068190b14e428d6ee9b0b4 Mon Sep 17 00:00:00 2001
From: Manly Florido <manly.florido@gmail.com>
Date: Mon, 30 Dec 2013 15:24:47 +0800
Subject: [PATCH 46/59] Update Gemfile

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

diff --git a/Gemfile b/Gemfile
index 2019cae8f96..d34603e8ce1 100644
--- a/Gemfile
+++ b/Gemfile
@@ -154,7 +154,7 @@ gem "raphael-rails", "~> 2.1.2"
 gem 'bootstrap-sass', '~> 2.3'
 gem "font-awesome-rails", '~> 3.2'
 gem "gemoji", "~> 1.3.0"
-gem "gon", git: "https://github.com/gitlabhq/gon.git", ref: '58ca8e17273051cb370182cabd3602d1da6783ab'
+gem "gon", "~> 5.0.0"
 
 group :development do
   gem "annotate", "~> 2.6.0.beta2"
-- 
GitLab


From 5b2ac3fa26cb2c7ba92f76537133f6334b8bc47c Mon Sep 17 00:00:00 2001
From: Manly Florido <manly.florido@gmail.com>
Date: Mon, 30 Dec 2013 15:33:15 +0800
Subject: [PATCH 47/59] Update Gemfile.lock

---
 Gemfile.lock | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/Gemfile.lock b/Gemfile.lock
index 8aad7c8c424..29eb52a5bd7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,12 +1,3 @@
-GIT
-  remote: https://github.com/gitlabhq/gon.git
-  revision: 58ca8e17273051cb370182cabd3602d1da6783ab
-  ref: 58ca8e17273051cb370182cabd3602d1da6783ab
-  specs:
-    gon (4.1.1)
-      actionpack (>= 2.3.0)
-      json
-
 GEM
   remote: https://rubygems.org/
   specs:
@@ -206,6 +197,9 @@ GEM
       omniauth (~> 1.0)
       pyu-ruby-sasl (~> 0.0.3.1)
       rubyntlm (~> 0.1.1)
+    gon (5.0.0)
+      actionpack (>= 2.3.0)
+      json
     grape (0.6.1)
       activesupport
       builder
-- 
GitLab


From 1150bad21fc37f0ed3864eb64f96fac29433c70c Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 23 Jan 2014 10:08:26 +0200
Subject: [PATCH 48/59] Fix selectbox when submit MR from fork to origin

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 app/controllers/projects/merge_requests_controller.rb     | 4 ++++
 app/views/projects/merge_requests/update_branches.js.haml | 8 ++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 0792dbf041f..c66f3de6263 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -152,6 +152,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @target_project = selected_target_project
     @target_branches = @target_project.repository.branch_names
     @target_branches
+
+    respond_to do |format|
+      format.js
+    end
   end
 
   def ci_status
diff --git a/app/views/projects/merge_requests/update_branches.js.haml b/app/views/projects/merge_requests/update_branches.js.haml
index 6a21551e811..ca21b3bc0de 100644
--- a/app/views/projects/merge_requests/update_branches.js.haml
+++ b/app/views/projects/merge_requests/update_branches.js.haml
@@ -1,5 +1,9 @@
 :plain
   $(".target_branch").html("#{escape_javascript(options_for_select(@target_branches))}");
-  $(".target_branch").trigger("select2:updated");
+
+  $('select.target_branch').select2({
+    width: 'resolve',
+    dropdownAutoWidth: true
+  });
+
   $(".mr_target_commit").html("");
-  $(".target_branch").trigger("change");
-- 
GitLab


From 6f6f1588ba5123f156ee3b0635a061745b71fcde Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Thu, 23 Jan 2014 10:13:23 +0200
Subject: [PATCH 49/59] Version 6.5.1

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 CHANGELOG | 3 +++
 VERSION   | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG b/CHANGELOG
index 981fd0e77ab..2e5cd78c8a8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+v 6.5.1
+  - Fix branch selectbox when create merge request from fork
+
 v 6.5.0
   - Dropdown menus on issue#show page for assignee and milestone (Jason Blanchard)
   - Add color custimization and previewing to broadcast messages
diff --git a/VERSION b/VERSION
index f22d756da39..a194c18e86e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.5.0
+6.5.1
-- 
GitLab


From 37df583e818a7d377474bff5ba64a30141bc5701 Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Wed, 5 Feb 2014 15:41:23 +0400
Subject: [PATCH 50/59] merge request "state" param is renamed to "mr_state" in
 filter, added closed and merged states to "state" item of filter

---
 app/contexts/merge_requests_load_context.rb          |  4 ++--
 .../projects/merge_requests_controller.rb            |  2 +-
 app/helpers/projects_helper.rb                       |  1 +
 app/models/merge_request.rb                          |  2 +-
 app/views/projects/merge_requests/index.html.haml    | 12 ++++++------
 5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb
index a40954b9896..6ded67a2de0 100644
--- a/app/contexts/merge_requests_load_context.rb
+++ b/app/contexts/merge_requests_load_context.rb
@@ -43,8 +43,8 @@ class MergeRequestsLoadContext < BaseContext
     end
 
     # Filter by specific state
-    if params[:state].present?
-      merge_requests = merge_requests.where(state: params[:state])
+    if params[:mr_state].present?
+      merge_requests = merge_requests.where(state: params[:mr_state])
     end
 
     merge_requests
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index ff3e19d50dc..ba5420578a1 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -28,7 +28,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     # Merge request states, which will be available in the corresponding filter.
     # We want to display all states, which displayed in the list MRs can have (i.e. everything what can be merged).
     @available_states = MergeRequest::VALID_STATES_FOR_MERGE
-    @state = params[:state]
+    @mr_state = params[:mr_state]
   end
 
   def show
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 22ca3b9ac23..e3036ad7a55 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -70,6 +70,7 @@ module ProjectsHelper
       assigned_group_id: params[:assigned_group_id],
       created_group_id: params[:created_group_id],
       state: params[:state],
+      mr_state: params[:mr_state],
       scope: params[:scope],
       label_name: params[:label_name],
       milestone_id: params[:milestone_id],
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index e31f73b2317..aa3d6826dd2 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -127,7 +127,7 @@ class MergeRequest < ActiveRecord::Base
   # both merged and closed mr's
   scope :closed, -> { with_states(:closed, :merged) }
 
-  VALID_STATES_FOR_MERGE = ["opened", "reopened", "accepted", "rejected", "fixed"]
+  VALID_STATES_FOR_MERGE = ["opened", "reopened", "accepted", "rejected", "fixed", "closed", "merged"]
   VALID_STATES_FOR_ACCEPT = ["opened", "reopened", "rejected", "fixed"]
   VALID_STATES_FOR_REJECT = ["opened", "reopened", "accepted", "fixed"]
   VALID_STATES_FOR_MARK_FIXED = ["rejected"]
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index be4879db2c8..f3523952992 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -102,19 +102,19 @@
           .dropdown.inline.prepend-left-10
             %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"}
               %span.light state:
-              - if @state.present?
-                %strong= @state.capitalize
+              - if @mr_state.present?
+                %strong= @mr_state.capitalize
               - else
                 Any
               %b.caret
             %ul.dropdown-menu
               %li
-                = link_to project_filter_path(state: nil) do
+                = link_to project_filter_path(mr_state: nil) do
                   Any
-              - @available_states.each do |state|
+              - @available_states.each do |mr_state|
                 %li
-                  = link_to project_filter_path(state: state) do
-                    = state.capitalize
+                  = link_to project_filter_path(mr_state: mr_state) do
+                    = mr_state.capitalize
 
       %ul.well-list.mr-list
         = render @merge_requests
-- 
GitLab


From 0aaee3f4b296807390e2800e292eb2a0c6bf78ad Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Wed, 5 Feb 2014 15:43:39 +0400
Subject: [PATCH 51/59] added new group of permissions - extended developer

---
 app/models/ability.rb                |  9 +++++++++
 app/models/project_team.rb           |  4 ++++
 app/models/users_group.rb            |  1 +
 app/models/users_project.rb          |  1 +
 app/views/help/permissions.html.haml |  2 ++
 lib/gitlab/access.rb                 | 13 ++++++++-----
 6 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/app/models/ability.rb b/app/models/ability.rb
index 3a086ee91d3..43ea4fdf617 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -61,6 +61,9 @@ class Ability
       if team.masters.include?(user)
         rules += project_master_rules
 
+      elsif team.extended_developers.include?(user)
+        rules += project_ext_dev_rules
+
       elsif team.developers.include?(user)
         rules += project_dev_rules
 
@@ -131,6 +134,12 @@ class Ability
       ]
     end
 
+    def project_ext_dev_rules
+      project_dev_rules + [
+        :merge_merge_request
+      ]
+    end
+
     def project_archived_rules
       [
         :write_merge_request,
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 83416a08164..f6db92f56ec 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -80,6 +80,10 @@ class ProjectTeam
     @developers ||= fetch_members(:developers)
   end
 
+  def extended_developers
+    @extended_developers ||= fetch_members(:extended_developers)
+  end
+
   def masters
     @masters ||= fetch_members(:masters)
   end
diff --git a/app/models/users_group.rb b/app/models/users_group.rb
index 181bf322283..172f71edda3 100644
--- a/app/models/users_group.rb
+++ b/app/models/users_group.rb
@@ -27,6 +27,7 @@ class UsersGroup < ActiveRecord::Base
   scope :guests, -> { where(group_access: GUEST) }
   scope :reporters, -> { where(group_access: REPORTER) }
   scope :developers, -> { where(group_access: DEVELOPER) }
+  scope :extended_developers, -> { where(group_access: EXTENDED_DEVELOPER) }
   scope :masters,  -> { where(group_access: MASTER) }
   scope :owners,  -> { where(group_access: OWNER) }
 
diff --git a/app/models/users_project.rb b/app/models/users_project.rb
index 6f147859a5c..fe2eb7ed497 100644
--- a/app/models/users_project.rb
+++ b/app/models/users_project.rb
@@ -31,6 +31,7 @@ class UsersProject < ActiveRecord::Base
   scope :guests, -> { where(project_access: GUEST) }
   scope :reporters, -> { where(project_access: REPORTER) }
   scope :developers, -> { where(project_access: DEVELOPER) }
+  scope :extended_developers, -> { where(project_access: EXTENDED_DEVELOPER) }
   scope :masters,  -> { where(project_access: MASTER) }
 
   scope :in_project, ->(project) { where(project_id: project.id) }
diff --git a/app/views/help/permissions.html.haml b/app/views/help/permissions.html.haml
index 15e3bf3a135..11a6521c1ee 100644
--- a/app/views/help/permissions.html.haml
+++ b/app/views/help/permissions.html.haml
@@ -13,6 +13,7 @@
         %th Guest
         %th Reporter
         %th Developer
+        %th Extended Developer
         %th Master
         %th Owner
     %tbody
@@ -172,6 +173,7 @@
         %th Guest
         %th Reporter
         %th Developer
+        %th Extended Developer
         %th Master
         %th Owner
     %tbody
diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb
index 87f9cfab608..b0d7fc1b172 100644
--- a/lib/gitlab/access.rb
+++ b/lib/gitlab/access.rb
@@ -5,11 +5,12 @@
 #
 module Gitlab
   module Access
-    GUEST     = 10
-    REPORTER  = 20
-    DEVELOPER = 30
-    MASTER    = 40
-    OWNER     = 50
+    GUEST              = 10
+    REPORTER           = 20
+    DEVELOPER          = 30
+    EXTENDED_DEVELOPER = 31
+    MASTER             = 40
+    OWNER              = 50
 
     class << self
       def values
@@ -21,6 +22,7 @@ module Gitlab
           "Guest"     => GUEST,
           "Reporter"  => REPORTER,
           "Developer" => DEVELOPER,
+          "Extended Developer" => EXTENDED_DEVELOPER,
           "Master"    => MASTER,
         }
       end
@@ -36,6 +38,7 @@ module Gitlab
           guest:     GUEST,
           reporter:  REPORTER,
           developer: DEVELOPER,
+          extended_developer: EXTENDED_DEVELOPER,
           master:    MASTER,
         }
       end
-- 
GitLab


From db1c4af00950ce1458ea6f86378ba3d57e48079b Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Thu, 6 Feb 2014 17:28:38 +0400
Subject: [PATCH 52/59] fixed after merge with 6-5-stable

---
 app/assets/stylesheets/sections/merge_requests.scss        | 2 +-
 app/views/projects/merge_requests/show/_mr_title.html.haml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index f073fbafec0..22ee2f81824 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -105,5 +105,5 @@
 
 .merge-request-review-button {
   float: left;
-  margin-right: 8px;
+  margin: 0 8px 15px 0;
 }
diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml
index ba9bfda698f..2a04b87241f 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_title.html.haml
@@ -1,5 +1,5 @@
 %h3.page-title
-  = "Merge Request ##{@merge_request.iid} (#{@merge_request.state}):"
+  = "Merge Request ##{@merge_request.iid} (#{@merge_request.state})"
   %small
     created #{time_ago_with_tooltip(@merge_request.created_at)}
 
-- 
GitLab


From 57424729a0b51d8483af2417636738409ff0b221 Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Thu, 6 Feb 2014 17:29:02 +0400
Subject: [PATCH 53/59] fixed mr filters after merge with 6-5-stable

---
 app/services/filtering_service.rb | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/app/services/filtering_service.rb b/app/services/filtering_service.rb
index b339065890b..7ee61d7db94 100644
--- a/app/services/filtering_service.rb
+++ b/app/services/filtering_service.rb
@@ -31,6 +31,9 @@ class FilteringService
     items = by_search(items)
     items = by_milestone(items)
     items = by_assignee(items)
+    items = by_assigned_group_id(items)
+    items = by_created_group_id(items)
+    items = by_mr_state(items)
     items = by_label(items)
     items = sort(items)
   end
@@ -113,6 +116,30 @@ class FilteringService
     items
   end
 
+  def by_assigned_group_id(items)
+    if params[:assigned_group_id].present?
+      items = items.joins(assignee: :users_groups).where(users_groups: {group_id: params[:assigned_group_id]})
+    end
+
+    items
+  end
+
+  def by_created_group_id(items)
+    if params[:created_group_id].present?
+      items = items.joins(author: :users_groups).where(users_groups: {group_id: params[:created_group_id]})
+    end
+
+    items
+  end
+
+  def by_mr_state(items)
+    if params[:mr_state].present?
+      items = items.where(state: params[:mr_state])
+    end
+
+    items
+  end
+
   def by_label(items)
     if params[:label_name].present?
       items = items.tagged_with(params[:label_name])
-- 
GitLab


From 403154ee1030458b8a43ece590bbcb477b82addb Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Wed, 12 Feb 2014 17:34:41 +0400
Subject: [PATCH 54/59] updated email subjects for merge requests

---
 app/mailers/emails/merge_requests.rb    | 10 +++++-----
 app/mailers/emails/notes.rb             |  2 +-
 app/observers/merge_request_observer.rb |  2 +-
 app/services/notification_service.rb    |  6 +++---
 spec/mailers/notify_spec.rb             |  3 ++-
 5 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index 15286676587..cf8bcac6067 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -6,11 +6,11 @@ module Emails
       mail(to: recipient(recipient_id), subject: subject("New merge request ##{@merge_request.iid}", @merge_request.title))
     end
 
-    def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
+    def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, assigned_by)
       @merge_request = MergeRequest.find(merge_request_id)
       @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
       @project = @merge_request.project
-      mail(to: recipient(recipient_id), subject: subject("Changed merge request ##{@merge_request.iid}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{assigned_by.name} reassigned ##{@merge_request.iid} to #{@merge_request.assignee.name}", @merge_request.title))
     end
 
     def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
@@ -24,13 +24,13 @@ module Emails
       @merge_request = MergeRequest.find(merge_request_id)
       @updated_by = User.find updated_by_user_id
       @action = action
-      mail(to: recipient(recipient_id), subject: subject("#{@updated_by.name} #{action} merge request !#{@merge_request.iid}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{@updated_by.name} #{action} !#{@merge_request.iid}", @merge_request.title))
     end
 
-    def merged_merge_request_email(recipient_id, merge_request_id)
+    def merged_merge_request_email(recipient_id, merge_request_id, merged_by)
       @merge_request = MergeRequest.find(merge_request_id)
       @project = @merge_request.project
-      mail(to: recipient(recipient_id), subject: subject("Accepted merge request ##{@merge_request.iid}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{merged_by.name} merged ##{@merge_request.iid}", @merge_request.title))
     end
   end
 
diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb
index e967cf6dc73..6630672bd24 100644
--- a/app/mailers/emails/notes.rb
+++ b/app/mailers/emails/notes.rb
@@ -18,7 +18,7 @@ module Emails
       @note = Note.find(note_id)
       @merge_request = @note.noteable
       @project = @note.project
-      mail(to: recipient(recipient_id), subject: subject("Note for merge request ##{@merge_request.iid}"))
+      mail(to: recipient(recipient_id), subject: subject("#{@note.author_name} commented on ##{@merge_request.iid}", @merge_request.title))
     end
 
     def note_wall_email(recipient_id, note_id)
diff --git a/app/observers/merge_request_observer.rb b/app/observers/merge_request_observer.rb
index df84e8d6d01..2131c4da825 100644
--- a/app/observers/merge_request_observer.rb
+++ b/app/observers/merge_request_observer.rb
@@ -19,7 +19,7 @@ class MergeRequestObserver < ActivityObserver
   end
 
   def after_merge(merge_request, transition)
-    notification.merge_mr(merge_request)
+    notification.merge_mr(merge_request, current_user)
     # Since MR can be merged via sidekiq
     # to prevent event duplication do this check
     return true if merge_request.merge_event
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index e7cf7d6ea80..e0e7f13f6ff 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -89,12 +89,12 @@ class NotificationService
   #  * merge_request assignee if their notification level is not Disabled
   #  * project team members with notification level higher then Participating
   #
-  def merge_mr(merge_request)
+  def merge_mr(merge_request, current_user)
     recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project)
     recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq
 
     recipients.each do |recipient|
-      mailer.merged_merge_request_email(recipient.id, merge_request.id)
+      mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user)
     end
   end
 
@@ -270,7 +270,7 @@ class NotificationService
     recipients.delete(current_user)
 
     recipients.each do |recipient|
-      mailer.send(method, recipient.id, target.id, target.assignee_id_was)
+      mailer.send(method, recipient.id, target.id, target.assignee_id_was, current_user)
     end
   end
 
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index b1e53486816..7253af094a2 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -192,9 +192,10 @@ describe Notify do
         end
 
         describe 'that are reassigned' do
+          let(:current_user) { create(:user, email: "current@email.com") }
           before(:each) { merge_request.stub(:assignee_id_was).and_return(previous_assignee.id) }
 
-          subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id) }
+          subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user) }
 
           it_behaves_like 'a multiple recipients email'
 
-- 
GitLab


From 5881861df17035dd2a1eee3d8bd8e0c1ca24660a Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Thu, 13 Feb 2014 11:26:24 +0400
Subject: [PATCH 55/59] renamed group "Extended Developer" to "Developer with
 merge"

---
 app/models/ability.rb       |  6 +++---
 app/models/project_team.rb  |  4 ++--
 app/models/users_group.rb   |  2 +-
 app/models/users_project.rb |  2 +-
 lib/gitlab/access.rb        | 16 ++++++++--------
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/app/models/ability.rb b/app/models/ability.rb
index 43ea4fdf617..65e5b00950f 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -61,8 +61,8 @@ class Ability
       if team.masters.include?(user)
         rules += project_master_rules
 
-      elsif team.extended_developers.include?(user)
-        rules += project_ext_dev_rules
+      elsif team.developers_with_merge.include?(user)
+        rules += project_dev_with_merge_rules
 
       elsif team.developers.include?(user)
         rules += project_dev_rules
@@ -134,7 +134,7 @@ class Ability
       ]
     end
 
-    def project_ext_dev_rules
+    def project_dev_with_merge_rules
       project_dev_rules + [
         :merge_merge_request
       ]
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 347998354b4..956944a86e6 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -84,8 +84,8 @@ class ProjectTeam
     @developers ||= fetch_members(:developers)
   end
 
-  def extended_developers
-    @extended_developers ||= fetch_members(:extended_developers)
+  def developers_with_merge
+    @developers_with_merge ||= fetch_members(:developers_with_merge)
   end
 
   def masters
diff --git a/app/models/users_group.rb b/app/models/users_group.rb
index 172f71edda3..1a14100e43a 100644
--- a/app/models/users_group.rb
+++ b/app/models/users_group.rb
@@ -27,7 +27,7 @@ class UsersGroup < ActiveRecord::Base
   scope :guests, -> { where(group_access: GUEST) }
   scope :reporters, -> { where(group_access: REPORTER) }
   scope :developers, -> { where(group_access: DEVELOPER) }
-  scope :extended_developers, -> { where(group_access: EXTENDED_DEVELOPER) }
+  scope :developers_with_merge, -> { where(group_access: DEVELOPER_WITH_MERGE) }
   scope :masters,  -> { where(group_access: MASTER) }
   scope :owners,  -> { where(group_access: OWNER) }
 
diff --git a/app/models/users_project.rb b/app/models/users_project.rb
index fe2eb7ed497..8ac2eaab612 100644
--- a/app/models/users_project.rb
+++ b/app/models/users_project.rb
@@ -31,7 +31,7 @@ class UsersProject < ActiveRecord::Base
   scope :guests, -> { where(project_access: GUEST) }
   scope :reporters, -> { where(project_access: REPORTER) }
   scope :developers, -> { where(project_access: DEVELOPER) }
-  scope :extended_developers, -> { where(project_access: EXTENDED_DEVELOPER) }
+  scope :developers_with_merge, -> { where(project_access: DEVELOPER_WITH_MERGE) }
   scope :masters,  -> { where(project_access: MASTER) }
 
   scope :in_project, ->(project) { where(project_id: project.id) }
diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb
index b0d7fc1b172..f22d33a39c9 100644
--- a/lib/gitlab/access.rb
+++ b/lib/gitlab/access.rb
@@ -5,12 +5,12 @@
 #
 module Gitlab
   module Access
-    GUEST              = 10
-    REPORTER           = 20
-    DEVELOPER          = 30
-    EXTENDED_DEVELOPER = 31
-    MASTER             = 40
-    OWNER              = 50
+    GUEST                = 10
+    REPORTER             = 20
+    DEVELOPER            = 30
+    DEVELOPER_WITH_MERGE = 31
+    MASTER               = 40
+    OWNER                = 50
 
     class << self
       def values
@@ -22,7 +22,7 @@ module Gitlab
           "Guest"     => GUEST,
           "Reporter"  => REPORTER,
           "Developer" => DEVELOPER,
-          "Extended Developer" => EXTENDED_DEVELOPER,
+          "Developer with merge" => DEVELOPER_WITH_MERGE,
           "Master"    => MASTER,
         }
       end
@@ -38,7 +38,7 @@ module Gitlab
           guest:     GUEST,
           reporter:  REPORTER,
           developer: DEVELOPER,
-          extended_developer: EXTENDED_DEVELOPER,
+          developer_with_merge: DEVELOPER_WITH_MERGE,
           master:    MASTER,
         }
       end
-- 
GitLab


From 21cba379be40a6d2bf5e2ed6b7f5604810ed5157 Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Fri, 14 Feb 2014 14:39:19 +0400
Subject: [PATCH 56/59] fixed markup in mr filter panel

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

diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 0537e343781..60582ec51b5 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -115,8 +115,7 @@
                   = link_to project_filter_path(mr_state: mr_state) do
                     = mr_state.capitalize
 
-          .pull-right
-            = render 'shared/sort_dropdown'
+          = render 'shared/sort_dropdown'
 
       %ul.well-list.mr-list
         = render @merge_requests
-- 
GitLab


From 9b740d8c2beea855873a00534a9cb38ae9eeec7c Mon Sep 17 00:00:00 2001
From: Sergey Sorokin <s.sorokin@prodege.com>
Date: Tue, 18 Feb 2014 18:18:34 +0400
Subject: [PATCH 57/59] some fixes email subjects when we create/close mr

---
 app/mailers/emails/merge_requests.rb | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index cf8bcac6067..e839d509dda 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -2,22 +2,23 @@ module Emails
   module MergeRequests
     def new_merge_request_email(recipient_id, merge_request_id)
       @merge_request = MergeRequest.find(merge_request_id)
+      @author = User.find(@merge_request.author_id)
       @project = @merge_request.project
-      mail(to: recipient(recipient_id), subject: subject("New merge request ##{@merge_request.iid}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{@author.name} created merge request !#{@merge_request.iid}", @merge_request.title))
     end
 
     def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, assigned_by)
       @merge_request = MergeRequest.find(merge_request_id)
       @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
       @project = @merge_request.project
-      mail(to: recipient(recipient_id), subject: subject("#{assigned_by.name} reassigned ##{@merge_request.iid} to #{@merge_request.assignee.name}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{assigned_by.name} reassigned !#{@merge_request.iid} | #{@merge_request.title} to #{@merge_request.assignee.name}"))
     end
 
     def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
       @merge_request = MergeRequest.find(merge_request_id)
       @updated_by = User.find updated_by_user_id
       @project = @merge_request.project
-      mail(to: recipient(recipient_id), subject: subject("Closed merge request ##{@merge_request.iid}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{@updated_by.name} closed merge request !#{@merge_request.iid}", @merge_request.title))
     end
 
     def reviewed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id, action)
@@ -30,7 +31,7 @@ module Emails
     def merged_merge_request_email(recipient_id, merge_request_id, merged_by)
       @merge_request = MergeRequest.find(merge_request_id)
       @project = @merge_request.project
-      mail(to: recipient(recipient_id), subject: subject("#{merged_by.name} merged ##{@merge_request.iid}", @merge_request.title))
+      mail(to: recipient(recipient_id), subject: subject("#{merged_by.name} merged !#{@merge_request.iid}", @merge_request.title))
     end
   end
 
-- 
GitLab


From 2a2a9acc699df001f61e0aeed80361674a749580 Mon Sep 17 00:00:00 2001
From: devblueray <devblueray@gmail.com>
Date: Mon, 28 Apr 2014 01:06:36 -0400
Subject: [PATCH 58/59] Refactor Parallel Diff feature and add scrollbars

Also now removed lines relating to unused comments feature
---
 app/assets/stylesheets/sections/diff.scss     | 350 ++++++++++++++++++
 app/helpers/commits_helper.rb                 |  76 +++-
 app/models/diff_line.rb                       |   3 +
 .../projects/commits/_parallel_view.html.haml | 114 +++---
 4 files changed, 474 insertions(+), 69 deletions(-)
 create mode 100644 app/assets/stylesheets/sections/diff.scss
 create mode 100644 app/models/diff_line.rb

diff --git a/app/assets/stylesheets/sections/diff.scss b/app/assets/stylesheets/sections/diff.scss
new file mode 100644
index 00000000000..eb272f20f40
--- /dev/null
+++ b/app/assets/stylesheets/sections/diff.scss
@@ -0,0 +1,350 @@
+.diff-file {
+  border: 1px solid #CCC;
+  margin-bottom: 1em;
+
+  .diff-header {
+    @extend .clearfix;
+    background: #DDD;
+    border-bottom: 1px solid #CCC;
+    padding: 5px 5px 5px 10px;
+    color: #555;
+
+    > span {
+      font-family: $monospace_font;
+      font-size: 14px;
+      line-height: 2;
+    }
+
+    .diff-btn-group {
+      float: right;
+
+      .btn {
+        background-color: #EEE;
+        color: #666;
+        font-weight: bolder;
+      }
+    }
+
+    .commit-short-id {
+      font-family: $monospace_font;
+      font-size: smaller;
+    }
+
+    .file-mode {
+      font-family: $monospace_font;
+    }
+  }
+  .diff-content {
+    overflow: auto;
+    overflow-y: hidden;
+    background: #FFF;
+    color: #333;
+    font-size: 12px;
+    .old {
+      span.idiff {
+        background-color: #FAA;
+      }
+    }
+    .new {
+      span.idiff {
+        background-color: #AFA;
+      }
+    }
+
+    table {
+      width: 100%;
+      font-family: $monospace_font;
+      border: none;
+      margin: 0px;
+      padding: 0px;
+      td {
+        line-height: 18px;
+        font-size: 12px;
+      }
+    }
+
+    .text-file-parallel div {
+      display: inline-block;
+      padding-bottom: 16px;
+    }
+    .diff-side {
+      overflow-x: scroll;
+      width: 508px;
+      height: 700px;
+    }
+    .diff-side.diff-side-left{
+      overflow-y:hidden;
+    }
+    .diff-side table, td.diff-middle table {
+      height: 700px;
+    }
+    .diff-middle {
+      width: 114px;
+      vertical-align: top;
+      height: 700px;
+      overflow: hidden
+    }
+
+    .old_line, .new_line, .diff_line {
+      margin: 0px;
+      padding: 0px;
+      border: none;
+      background: #EEE;
+      color: #666;
+      padding: 0px 5px;
+      border-right: 1px solid #ccc;
+      text-align: right;
+      min-width: 35px;
+      max-width: 50px;
+      width: 35px;
+      @include user-select(none);
+      a {
+        float: left;
+        width: 35px;
+        font-weight: normal;
+        color: #666;
+        &:hover {
+          text-decoration: underline;
+        }
+      }
+      &.new {
+        background: #CFD;
+      }
+      &.old {
+        background: #FDD;
+      }
+    }
+    .diff_line {
+      padding: 0;
+    }
+    .line_holder {
+      &.old .old_line,
+      &.old .new_line {
+        background: #FCC;
+        border-color: #E7BABA;
+      }
+      &.new .old_line,
+      &.new .new_line {
+        background: #CFC;
+        border-color: #B9ECB9;
+      }
+    }
+    .line_content {
+      display: block;
+      white-space: pre;
+      height: 18px;
+      margin: 0px;
+      padding: 0px 0.5em;
+      border: none;
+      &.new {
+        background: #CFD;
+      }
+      &.old {
+        background: #FDD;
+      }
+      &.matched {
+        color: #ccc;
+        background: #fafafa;
+      }
+      &.parallel {
+        display: table-cell;
+      }
+    }
+  }
+  .image {
+    background: #ddd;
+    text-align: center;
+    padding: 30px;
+    .wrap{
+      display: inline-block;
+    }
+
+    .frame {
+      display: inline-block;
+      background-color: #fff;
+      line-height: 0;
+      img{
+        border: 1px solid #FFF;
+        background: image-url('trans_bg.gif');
+        max-width: 100%;
+      }
+      &.deleted {
+        border: 1px solid $deleted;
+      }
+
+      &.added {
+        border: 1px solid $added;
+      }
+    }
+    .image-info{
+      font-size: 12px;
+      margin: 5px 0 0 0;
+      color: grey;
+    }
+
+    .view.swipe{
+      position: relative;
+
+      .swipe-frame{
+        display: block;
+        margin: auto;
+        position: relative;
+      }
+      .swipe-wrap{
+        overflow: hidden;
+        border-left: 1px solid #999;
+        position: absolute;
+        display: block;
+        top: 13px;
+        right: 7px;
+      }
+      .frame{
+        top: 0;
+        right: 0;
+        position: absolute;
+        &.deleted{
+          margin: 0;
+          display: block;
+          top: 13px;
+          right: 7px;
+        }
+      }
+      .swipe-bar{
+        display: block;
+        height: 100%;
+        width: 15px;
+        z-index: 100;
+        position: absolute;
+        cursor: pointer;
+        &:hover{
+          .top-handle{
+            background-position: -15px 3px;
+          }
+          .bottom-handle{
+            background-position: -15px -11px;
+          }
+        };
+        .top-handle{
+          display: block;
+          height: 14px;
+          width: 15px;
+          position: absolute;
+          top: 0px;
+          background: image-url('swipemode_sprites.gif') 0 3px no-repeat;
+        }
+        .bottom-handle{
+          display: block;
+          height: 14px;
+          width: 15px;
+          position: absolute;
+          bottom: 0px;
+          background: image-url('swipemode_sprites.gif') 0 -11px no-repeat;
+        }
+      }
+    } //.view.swipe
+    .view.onion-skin{
+      .onion-skin-frame{
+        display: block;
+        margin: auto;
+        position: relative;
+      }
+      .frame.added, .frame.deleted {
+        position: absolute;
+        display: block;
+        top: 0px;
+        left: 0px;
+      }
+      .controls{
+        display: block;
+        height: 14px;
+        width: 300px;
+        z-index: 100;
+        position: absolute;
+        bottom: 0px;
+        left: 50%;
+        margin-left: -150px;
+
+        .drag-track{
+          display: block;
+          position: absolute;
+          left: 12px;
+          height: 10px;
+          width: 276px;
+          background: image-url('onion_skin_sprites.gif') -4px -20px repeat-x;
+        }
+
+        .dragger {
+          display: block;
+          position: absolute;
+          left: 0px;
+          top: 0px;
+          height: 14px;
+          width: 14px;
+          background: image-url('onion_skin_sprites.gif') 0px -34px repeat-x;
+          cursor: pointer;
+        }
+
+        .transparent {
+          display: block;
+          position: absolute;
+          top: 2px;
+          right: 0px;
+          height: 10px;
+          width: 10px;
+          background: image-url('onion_skin_sprites.gif') -2px 0px no-repeat;
+        }
+
+        .opaque {
+          display: block;
+          position: absolute;
+          top: 2px;
+          left: 0px;
+          height: 10px;
+          width: 10px;
+          background: image-url('onion_skin_sprites.gif') -2px -10px no-repeat;
+        }
+      }
+    } //.view.onion-skin
+  }
+  .view-modes{
+
+    padding: 10px;
+    text-align: center;
+
+    background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
+    background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
+    background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
+    background-image: -ms-linear-gradient(#eee 6.6%, #dfdfdf);
+    background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
+
+    ul, li{
+      list-style: none;
+      margin: 0;
+      padding: 0;
+      display: inline-block;
+    }
+
+    li{
+      color: grey;
+      border-left: 1px solid #c1c1c1;
+      padding: 0 12px 0 16px;
+      cursor: pointer;
+      &:first-child{
+        border-left: none;
+      }
+      &:hover{
+        text-decoration: underline;
+      }
+      &.active{
+        &:hover{
+          text-decoration: none;
+        }
+        cursor: default;
+        color: #333;
+      }
+      &.disabled{
+        display: none;
+      }
+    }
+  }
+}
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 663369e4584..f8ec8e10fd1 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -105,8 +105,80 @@ module CommitsHelper
     branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe
   end
 
-  def get_old_file(project, commit, diff)
-    project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id
+  def parallel_diff_lines(project, commit, diff, file)
+    old_file = project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id
+    deleted_lines = {}
+    added_lines = {}
+    each_diff_line(diff, 0) do |line, type, line_code, line_new, line_old|
+      if type == "old"
+        deleted_lines[line_old] = { line_code: line_code, type: type, line: line }
+      elsif type == "new"
+        added_lines[line_new]   = { line_code: line_code, type: type, line: line }
+      end
+    end
+    max_length = old_file ? old_file.sloc + added_lines.length : file.sloc
+
+    offset1 = 0
+    offset2 = 0
+    old_lines = []
+    new_lines = []
+
+    max_length.times do |line_index|
+      line_index1 = line_index - offset1
+      line_index2 = line_index - offset2
+      deleted_line = deleted_lines[line_index1 + 1]
+      added_line = added_lines[line_index2 + 1]
+      old_line = old_file.lines[line_index1] if old_file
+      new_line = file.lines[line_index2]
+
+      if deleted_line && added_line
+      elsif deleted_line
+        new_line = nil
+        offset2 += 1
+      elsif added_line
+        old_line = nil
+        offset1 += 1
+      end
+
+      old_lines[line_index] = DiffLine.new
+      new_lines[line_index] = DiffLine.new
+
+      # old
+      if line_index == 0 && diff.new_file
+        old_lines[line_index].type = :file_created
+        old_lines[line_index].content = 'File was created'
+      elsif deleted_line
+        old_lines[line_index].type = :deleted
+        old_lines[line_index].content = old_line
+        old_lines[line_index].num = line_index1 + 1
+        old_lines[line_index].code = deleted_line[:line_code]
+      elsif old_line
+        old_lines[line_index].type = :no_change
+        old_lines[line_index].content = old_line
+        old_lines[line_index].num = line_index1 + 1
+      else
+        old_lines[line_index].type = :added
+      end
+
+      # new
+      if line_index == 0 && diff.deleted_file
+        new_lines[line_index].type = :file_deleted
+        new_lines[line_index].content = "File was deleted"
+      elsif added_line
+        new_lines[line_index].type = :added
+        new_lines[line_index].num = line_index2 + 1
+        new_lines[line_index].content = new_line
+        new_lines[line_index].code = added_line[:line_code]
+      elsif new_line
+        new_lines[line_index].type = :no_change
+        new_lines[line_index].num = line_index2 + 1
+        new_lines[line_index].content = new_line
+      else
+        new_lines[line_index].type = :deleted
+      end
+    end
+
+    return old_lines, new_lines
   end
 
   protected
diff --git a/app/models/diff_line.rb b/app/models/diff_line.rb
new file mode 100644
index 00000000000..ad37945874a
--- /dev/null
+++ b/app/models/diff_line.rb
@@ -0,0 +1,3 @@
+class DiffLine
+  attr_accessor :type, :content, :num, :code
+end
diff --git a/app/views/projects/commits/_parallel_view.html.haml b/app/views/projects/commits/_parallel_view.html.haml
index 3234e9da0ac..5b60ab80ba4 100644
--- a/app/views/projects/commits/_parallel_view.html.haml
+++ b/app/views/projects/commits/_parallel_view.html.haml
@@ -1,75 +1,55 @@
 / Side-by-side diff view
-- old_file = get_old_file(project, @commit, diff)
-- deleted_lines = {}
-- added_lines = {}
-- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|
-  - if type == "old"
-    - deleted_lines[line_old] = { line_code: line_code, type: type, line: line }
-  - elsif type == "new"
-    - added_lines[line_new]   = { line_code: line_code, type: type, line: line }
-
-- max_length = old_file.sloc + added_lines.length if old_file
-- max_length ||= file.sloc
-- offset1 = 0
-- offset2 = 0
+- old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file)
+- num_lines = old_lines.length
 
 %div.text-file-parallel
-  %table{ style: "table-layout: fixed;" }
-    - max_length.times do |line_index|
-      - line_index1 = line_index - offset1
-      - line_index2 = line_index - offset2
-      - deleted_line = deleted_lines[line_index1 + 1]
-      - added_line = added_lines[line_index2 + 1]
-      - old_line = old_file.lines[line_index1] if old_file
-      - new_line = file.lines[line_index2]
+  %div.diff-side.diff-side-left
+    %table
+      - old_lines.each do |line|
+
+        %tr.line_holder.parallel
+          - if line.type == :file_created
+            %td.line_content.parallel= "File was created"
+          - elsif line.type == :deleted
+            %td.line_content{class: "parallel noteable_line old #{line.code}", "line_code" => line.code }= line.content
+          - else line.type == :no_change
+            %td.line_content.parallel= line.content
+
+  %div.diff-middle
+    %table
+      - num_lines.times do |index|
+        %tr
+          - if old_lines[index].type == :deleted
+            %td.old_line.old= old_lines[index].num
+          - else
+            %td.old_line= old_lines[index].num
+
+          %td.diff_line=""
 
-      - if deleted_line && added_line
-      - elsif deleted_line
-        - new_line = nil
-        - offset2 += 1
-      - elsif added_line
-        - old_line = nil
-        - offset1 += 1
+          - if new_lines[index].type == :added
+            %td.new_line.new= new_lines[index].num
+          - else
+            %td.new_line= new_lines[index].num
 
-      %tr.line_holder.parallel
-        - if line_index == 0 && diff.new_file
-          %td.line_content.parallel= "File was created"
-          %td.old_line= ""
-        - elsif deleted_line
-          %td.line_content{class: "parallel noteable_line old #{deleted_line[:line_code]}", "line_code" => deleted_line[:line_code] }= old_line
-          %td.old_line.old
-            = line_index1 + 1
-            - if @comments_allowed
-              =# render "projects/notes/diff_note_link", line_code: deleted_line[:line_code]
-        - elsif old_line
-          %td.line_content.parallel= old_line
-          %td.old_line= line_index1 + 1
-        - else
-          %td.line_content.parallel= ""
-          %td.old_line= ""
+  %div.diff-side.diff-side-right
+    %table
+      - new_lines.each do |line|
 
-        %td.diff_line= ""
+        %tr.line_holder.parallel
+          - if line.type == :file_deleted
+            %td.line_content.parallel= "File was deleted"
+          - elsif line.type == :added
+            %td.line_content{class: "parallel noteable_line new #{line.code}", "line_code" => line.code }= line.content
+          - else line.type == :no_change
+            %td.line_content.parallel= line.content
 
-        - if diff.deleted_file && line_index == 0
-          %td.new_line= ""
-          %td.line_content.parallel= "File was deleted"
-        - elsif added_line
-          %td.new_line.new
-            = line_index2 + 1
-            - if @comments_allowed
-              =# render "projects/notes/diff_note_link", line_code: added_line[:line_code]
-          %td.line_content{class: "parallel noteable_line new #{added_line[:line_code]}", "line_code" => added_line[:line_code] }= new_line
-        - elsif new_line
-          %td.new_line= line_index2 + 1
-          %td.line_content.parallel= new_line
-        - else
-          %td.new_line= ""
-          %td.line_content.parallel= ""
+:javascript
+  $('.diff-side-right').on('scroll', function(){
+    $('.diff-side-left, .diff-middle').scrollTop($(this).scrollTop());
+    $('.diff-side-left').scrollLeft($(this).scrollLeft());
+  });
 
-      - if @reply_allowed
-        - comments1 = []
-        - comments2 = []
-        - comments1 = @line_notes.select { |n| n.line_code == deleted_line[:line_code] }.sort_by(&:created_at) if deleted_line
-        - comments2 = @line_notes.select { |n| n.line_code == added_line[:line_code] }.sort_by(&:created_at) if added_line
-        - unless comments1.empty? && comments2.empty?
-          = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2, line1: deleted_line, line2: added_line
\ No newline at end of file
+  $('.diff-side-left').on('scroll', function(){
+    $('.diff-side-right, .diff-middle').scrollTop($(this).scrollTop()); // might never be relevant
+    $('.diff-side-right').scrollLeft($(this).scrollLeft());
+  });
-- 
GitLab


From 2f24641df1e72e579506f1315840daec3bae67c6 Mon Sep 17 00:00:00 2001
From: devblueray <devblueray@gmail.com>
Date: Mon, 28 Apr 2014 01:29:37 -0400
Subject: [PATCH 59/59] Bumped Version

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

diff --git a/VERSION b/VERSION
index a194c18e86e..13673ab4fa3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.5.1
+6.5.1-001
-- 
GitLab