diff --git a/.pkgr.yml b/.pkgr.yml
new file mode 100644
index 0000000000000000000000000000000000000000..09cb83783dcb4a3bacf24944e07d0e65ed676454
--- /dev/null
+++ b/.pkgr.yml
@@ -0,0 +1,19 @@
+user: git
+group: git
+before_precompile: ./bin/pkgr_before_precompile.sh
+targets:
+  debian-7: &wheezy
+    build_dependencies:
+      - libicu-dev
+    dependencies:
+      - libicu48
+      - libpcre3
+      - git
+  ubuntu-12.04: *wheezy
+  ubuntu-14.04:
+    build_dependencies:
+      - libicu-dev
+    dependencies:
+      - libicu52
+      - libpcre3
+      - git
diff --git a/CHANGELOG b/CHANGELOG
index 3ef46f4484e3dcf11efbde4c0939721e29336946..ca0b96b84022325424871b54e3eff7497c0b9ebb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,30 @@
+v 7.0.0
+  - The CPU no longer overheats when you hold down the spacebar
+  - Improve edit file UI
+  - Add ability to upload group avatar when create
+
+v 6.9.0
+  - Store Rails cache data in the Redis `cache:gitlab` namespace
+  - Adjust MySQL limits for existing installations
+  - Add db index on project_id+iid column. This prevents duplicate on iid (During migration duplicates will be removed)
+  - Markdown preview or diff during editing via web editor (Evgeniy Sokovikov)
+  - Give the Rails cache its own Redis namespace
+  - Add ability to set different ssh host, if different from http/https
+  - Fix syntax highlighting for code comments blocks
+  - Improve comments loading logic
+  - Stop refreshing comments when the tab is hidden
+  - Improve issue and merge request mobile UI (Drew Blessing)
+  - Document how to convert a backup to PostgreSQL
+  - Fix locale bug in backup manager
+  - Fix can not automerge when MR description is too long
+  - Fix wiki backup skip bug
+  - Two Step MR creation process
+  - Remove unwanted files from satellite working directory with git clean -fdx
+  - Accept merge request via API (sponsored by O'Reilly Media)
+  - Add more access checks during API calls
+  - Block SSH access for 'disabled' Active Directory users
+  - Labels for merge requests (Drew Blessing)
+
 v 6.8.0
   - Ability to at mention users that are participating in issue and merge req. discussion
   - Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 290804e61873d8f6ea427ed164ae96296775d37a..780db547f829dc0ea6f97bc78618733c5abd94c6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -107,9 +107,10 @@ For examples of feedback on merge requests please look at already [closed merge
 
 ## Style guides
 1. [Ruby](https://github.com/bbatsov/ruby-style-guide)
-2. [Rails](https://github.com/bbatsov/rails-style-guide)
-3. [Formatting](https://github.com/thoughtbot/guides/tree/master/style#formatting)
-4. [Naming](https://github.com/thoughtbot/guides/tree/master/style#naming) 
-8. [Testing](https://github.com/thoughtbot/guides/tree/master/style#testing)
-7. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript)
-9. [Shell commands](doc/development/shell_commands.md)
+1. [Rails](https://github.com/bbatsov/rails-style-guide)
+1. [Formatting](https://github.com/thoughtbot/guides/tree/master/style#formatting)
+1. [Naming](https://github.com/thoughtbot/guides/tree/master/style#naming) 
+1. [Testing](https://github.com/thoughtbot/guides/tree/master/style#testing)
+1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript)
+1. [Shell commands](doc/development/shell_commands.md)
+1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
diff --git a/Gemfile b/Gemfile
index 4ab1ab50eb9c0f4b5fa46a9fd8ab88a5f8c70b75..f7e3fe7b6dd14f98ee33c58d3ee85576bcfffdd1 100644
--- a/Gemfile
+++ b/Gemfile
@@ -71,6 +71,7 @@ gem "carrierwave"
 
 # for aws storage
 gem "fog", "~> 1.14", group: :aws
+gem "unf", group: :aws
 
 # Authorization
 gem "six"
@@ -82,6 +83,9 @@ gem "seed-fu"
 gem "redcarpet",     "~> 2.2.2"
 gem "github-markup"
 
+# Diffs
+gem 'diffy', '~> 3.0.3'
+
 # Asciidoc to HTML
 gem  "asciidoctor"
 
@@ -148,7 +152,7 @@ gem "rack-attack"
 # Ace editor
 gem 'ace-rails-ap'
 
-gem "sass-rails"
+gem "sass-rails", '~> 4.0.2'
 gem "coffee-rails"
 gem "uglifier"
 gem "therubyracer"
@@ -157,8 +161,9 @@ gem 'jquery-turbolinks'
 
 gem 'select2-rails'
 gem 'jquery-atwho-rails', "~> 0.3.3"
-gem "jquery-rails",     "2.1.3"
-gem "jquery-ui-rails",  "2.0.2"
+gem "jquery-rails"
+gem "jquery-ui-rails"
+gem "jquery-scrollto-rails"
 gem "raphael-rails", "~> 2.1.2"
 gem 'bootstrap-sass', '~> 3.0'
 gem "font-awesome-rails", '~> 3.2'
@@ -232,4 +237,4 @@ end
 
 group :production do
   gem "gitlab_meta", '6.0'
-end
\ No newline at end of file
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index 155e03e54567c7f75df28bd17bb34fdbdc000dff..86c752505bdb643339545b191d942b0bf4428cd7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -2,26 +2,26 @@ GEM
   remote: https://rubygems.org/
   specs:
     ace-rails-ap (2.0.1)
-    actionmailer (4.0.3)
-      actionpack (= 4.0.3)
+    actionmailer (4.0.5)
+      actionpack (= 4.0.5)
       mail (~> 2.5.4)
-    actionpack (4.0.3)
-      activesupport (= 4.0.3)
+    actionpack (4.0.5)
+      activesupport (= 4.0.5)
       builder (~> 3.1.0)
       erubis (~> 2.7.0)
       rack (~> 1.5.2)
       rack-test (~> 0.6.2)
-    activemodel (4.0.3)
-      activesupport (= 4.0.3)
+    activemodel (4.0.5)
+      activesupport (= 4.0.5)
       builder (~> 3.1.0)
-    activerecord (4.0.3)
-      activemodel (= 4.0.3)
+    activerecord (4.0.5)
+      activemodel (= 4.0.5)
       activerecord-deprecated_finders (~> 1.0.2)
-      activesupport (= 4.0.3)
+      activesupport (= 4.0.5)
       arel (~> 4.0.0)
     activerecord-deprecated_finders (1.0.3)
-    activesupport (4.0.3)
-      i18n (~> 0.6, >= 0.6.4)
+    activesupport (4.0.5)
+      i18n (~> 0.6, >= 0.6.9)
       minitest (~> 4.2)
       multi_json (~> 1.3)
       thread_safe (~> 0.1)
@@ -34,7 +34,6 @@ GEM
       rake (>= 0.8.7)
     arel (4.0.2)
     asciidoctor (0.1.4)
-    atomic (1.1.16)
     awesome_print (1.2.0)
     axiom-types (0.0.5)
       descendants_tracker (~> 0.0.1)
@@ -101,6 +100,7 @@ GEM
     devise-async (0.8.0)
       devise (>= 2.2, < 3.2)
     diff-lcs (1.2.5)
+    diffy (3.0.3)
     docile (1.1.1)
     dotenv (0.9.0)
     email_spec (1.5.0)
@@ -162,7 +162,7 @@ GEM
       multi_json
     gitlab-grack (2.0.0.pre)
       rack (~> 1.5.1)
-    gitlab-grit (2.6.5)
+    gitlab-grit (2.6.7)
       charlock_holmes (~> 0.6)
       diff-lcs (~> 1.1)
       mime-types (~> 1.15)
@@ -247,15 +247,16 @@ GEM
       rake
     jasmine-core (2.0.0.rc5)
     jquery-atwho-rails (0.3.3)
-    jquery-rails (2.1.3)
-      railties (>= 3.1.0, < 5.0)
-      thor (~> 0.14)
+    jquery-rails (3.1.0)
+      railties (>= 3.0, < 5.0)
+      thor (>= 0.14, < 2.0)
+    jquery-scrollto-rails (1.4.3)
+      railties (> 3.1, < 5.0)
     jquery-turbolinks (2.0.1)
       railties (>= 3.1.0)
       turbolinks
-    jquery-ui-rails (2.0.2)
-      jquery-rails
-      railties (>= 3.1.0)
+    jquery-ui-rails (4.2.1)
+      railties (>= 3.2.16)
     json (1.8.1)
     jwt (0.1.8)
       multi_json (>= 1.5)
@@ -280,7 +281,7 @@ GEM
     mime-types (1.25.1)
     mini_portile (0.5.3)
     minitest (4.7.5)
-    multi_json (1.9.2)
+    multi_json (1.10.0)
     multi_xml (0.5.5)
     multipart-post (1.2.0)
     mysql2 (0.3.11)
@@ -350,13 +351,13 @@ GEM
       rack
     rack-test (0.6.2)
       rack (>= 1.0)
-    rails (4.0.3)
-      actionmailer (= 4.0.3)
-      actionpack (= 4.0.3)
-      activerecord (= 4.0.3)
-      activesupport (= 4.0.3)
+    rails (4.0.5)
+      actionmailer (= 4.0.5)
+      actionpack (= 4.0.5)
+      activerecord (= 4.0.5)
+      activesupport (= 4.0.5)
       bundler (>= 1.3.0, < 2.0)
-      railties (= 4.0.3)
+      railties (= 4.0.5)
       sprockets-rails (~> 2.0.0)
     rails-observers (0.1.2)
       activemodel (~> 4.0)
@@ -369,13 +370,13 @@ GEM
       i18n
       require_all
       ruby-progressbar
-    railties (4.0.3)
-      actionpack (= 4.0.3)
-      activesupport (= 4.0.3)
+    railties (4.0.5)
+      actionpack (= 4.0.5)
+      activesupport (= 4.0.5)
       rake (>= 0.8.7)
       thor (>= 0.18.1, < 2.0)
     raindrops (0.12.0)
-    rake (10.1.1)
+    rake (10.3.1)
     raphael-rails (2.1.2)
     rb-fsevent (0.9.3)
     rb-inotify (0.9.2)
@@ -428,11 +429,12 @@ GEM
     safe_yaml (0.9.7)
     sanitize (2.1.0)
       nokogiri (>= 1.4.4)
-    sass (3.2.12)
-    sass-rails (4.0.1)
+    sass (3.2.19)
+    sass-rails (4.0.3)
       railties (>= 4.0.0, < 5.0)
-      sass (>= 3.1.10)
-      sprockets-rails (~> 2.0.0)
+      sass (~> 3.2.0)
+      sprockets (~> 2.8, <= 2.11.0)
+      sprockets-rails (~> 2.0)
     sdoc (0.3.20)
       json (>= 1.1.3)
       rdoc (~> 3.10)
@@ -479,7 +481,7 @@ GEM
       spring (>= 0.9.1)
     spring-commands-spinach (1.0.0)
       spring (>= 0.9.1)
-    sprockets (2.10.1)
+    sprockets (2.11.0)
       hike (~> 1.2)
       multi_json (~> 1.0)
       rack (~> 1.0)
@@ -502,9 +504,8 @@ GEM
       daemons (>= 1.0.9)
       eventmachine (>= 1.0.0)
       rack (>= 1.0.0)
-    thor (0.18.1)
-    thread_safe (0.3.1)
-      atomic (>= 1.1.7, < 2)
+    thor (0.19.1)
+    thread_safe (0.3.3)
     tilt (1.4.1)
     timers (1.1.0)
     tinder (1.9.3)
@@ -531,6 +532,9 @@ GEM
       execjs (>= 0.3.0)
       json (>= 1.8.0)
     underscore-rails (1.4.4)
+    unf (0.1.4)
+      unf_ext
+    unf_ext (0.0.6)
     unicorn (4.6.3)
       kgio (~> 2.6)
       rack
@@ -574,6 +578,7 @@ DEPENDENCIES
   default_value_for (~> 3.0.0)
   devise (= 3.0.4)
   devise-async (= 0.8.0)
+  diffy (~> 3.0.3)
   email_spec
   email_validator (~> 1.4.0)
   enumerize
@@ -603,9 +608,10 @@ DEPENDENCIES
   httparty
   jasmine (= 2.0.0.rc5)
   jquery-atwho-rails (~> 0.3.3)
-  jquery-rails (= 2.1.3)
+  jquery-rails
+  jquery-scrollto-rails
   jquery-turbolinks
-  jquery-ui-rails (= 2.0.2)
+  jquery-ui-rails
   kaminari (~> 0.15.1)
   launchy
   letter_opener
@@ -634,7 +640,7 @@ DEPENDENCIES
   redis-rails
   rspec-rails
   sanitize (~> 2.0)
-  sass-rails
+  sass-rails (~> 4.0.2)
   sdoc
   seed-fu
   select2-rails
@@ -659,6 +665,7 @@ DEPENDENCIES
   turbolinks
   uglifier
   underscore-rails (~> 1.4.4)
+  unf
   unicorn (~> 4.6.3)
   unicorn-worker-killer
   version_sorter
diff --git a/README.md b/README.md
index 3f3453a267a2337e958b68c80b25790dd3a3d5be..cbbfebc81efb6e0ec1b615da7af8dcefd5030a57 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
 
 ### Canonical source
 
-* The source of GitLab Communinity Edition is [hosted on GitLab Cloud](https://gitlab.com/gitlab-org/gitlab-ce/) and there are mirrors to make [contributing](CONTRIBUTING.md) as easy as possible.
+* The source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/) and there are mirrors to make [contributing](CONTRIBUTING.md) as easy as possible.
 
 ### Code status
 
@@ -25,15 +25,17 @@
 
 * [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
 
+* [![PullReview stats](https://www.pullreview.com/gitlab/gitlab-org/gitlab-ce/badges/master.svg?)](https://www.pullreview.com/gitlab.gitlab.com/gitlab-org/gitlab-ce/reviews/master)
+
 ### Resources
 
 * [GitLab.com](https://www.gitlab.com/) includes information about [subscriptions](https://www.gitlab.com/subscription/), [consultancy](https://www.gitlab.com/consultancy/), the [community](https://www.gitlab.com/community/) and the [hosted GitLab Cloud](https://www.gitlab.com/cloud/).
 
-* [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ce/) offers additional features that are useful for larger organizations (100+ users).
+* [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ee/) offers additional features aimed at larger organizations.
 
 * [GitLab CI](https://www.gitlab.com/gitlab-ci/) is a continuous integration (CI) server that is easy to integrate with GitLab.
 
-* Unofficial third-party [iPhone app](http://gitlabcontrol.com/) and [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en) for GitLab
+* Unofficial third-party [iPhone app](http://gitlabcontrol.com/), [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en) and [command line client](https://github.com/drewblessing/gitlab-cli) and [Ruby API wrapper](https://github.com/NARKOZ/gitlab) for GitLab.
 
 ### Requirements
 
@@ -51,7 +53,7 @@
 
 * [GitLab packages](https://www.gitlab.com/downloads/) **recommended** These packages contain GitLab and all its depencies (Ruby, PostgreSQL, Redis, Nginx, Unicorn, etc.). They are made with [omnibus-gitlab](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md) that also contains the installation instructions.
 
-* [GitLab Chef Cookbook](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/README.md) This cookbook can be used both for development installations and production installations. If you want to [contribute](CONTRIBUTE.md) to GitLab we suggest you follow the [development installation on a virtual machine with Vagrant](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/doc/development.md) instructions to install all testing dependencies.
+* [GitLab Chef Cookbook](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/README.md) This cookbook can be used both for development installations and production installations. If you want to [contribute](CONTRIBUTE.md) to GitLab we suggest you follow the [development installation](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/doc/development.md) instructions to install all testing dependencies.
 
 * [Manual installation guide](doc/install/installation.md) This guide to set up a production server on Ubuntu offers detailed and complete step-by-step instructions.
 
@@ -61,6 +63,8 @@
 
 * [BitNami one-click installers](http://bitnami.com/stack/gitlab) This package contains both GitLab and GitLab CI. It is available as installer, virtual machine or for cloud hosting providers (Amazon Web Services/Azure/etc.).
 
+* [Cloud 66 deployment and management](http://blog.cloud66.com/installing-gitlab-ubuntu/) Use Cloud 66 to deploy GitLab to your own server or any cloud (eg. DigitalOcean, AWS, Rackspace, GCE) and then manage it with database backups, scaling and more.
+
 #### Unofficial installation methods
 
 * [GitLab recipes](https://gitlab.com/gitlab-org/gitlab-recipes/) repository with unofficial guides for using GitLab with different software (operating systems, webservers, etc.) than the official version.
diff --git a/VERSION b/VERSION
index e029aa99b7d8407ab85c00e4122ac115755f8afd..2e45d00c582796b00730346b93af47764bcc5ffd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.8.0
+7.0.0.pre
diff --git a/app/assets/images/ui-icons_222222_256x240.png b/app/assets/images/ui-icons_222222_256x240.png
deleted file mode 100644
index 8bc06cbf03b830a60f29857361df57214e172dfe..0000000000000000000000000000000000000000
Binary files a/app/assets/images/ui-icons_222222_256x240.png and /dev/null differ
diff --git a/app/assets/images/ui-icons_454545_256x240.png b/app/assets/images/ui-icons_454545_256x240.png
deleted file mode 100644
index cfd1eaffaae0f5fe30d8e86d2e54b990d2a1ccd0..0000000000000000000000000000000000000000
Binary files a/app/assets/images/ui-icons_454545_256x240.png and /dev/null differ
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index a22ff6dec3197ddbffc280f690dda822f9c86512..587e51a7a83880c23ab8bb82e4c03e27f31d3bd7 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -13,7 +13,7 @@
 #= require jquery.history
 #= require jquery.waitforimages
 #= require jquery.atwho
-#= require jquery.scrollto
+#= require jquery.scrollTo
 #= require jquery.blockUI
 #= require turbolinks
 #= require jquery.turbolinks
diff --git a/app/assets/javascripts/blob.js.coffee b/app/assets/javascripts/blob.js.coffee
index 584f6faea161c2e980a9a66327652e619b222246..9db919e5a62c9f840f24abf84958eb1870b88b69 100644
--- a/app/assets/javascripts/blob.js.coffee
+++ b/app/assets/javascripts/blob.js.coffee
@@ -26,7 +26,7 @@ class BlobView
       unless isNaN first_line
         $("#tree-content-holder .highlight .line").removeClass("hll")
         $("#LC#{line}").addClass("hll") for line in [first_line..last_line]
-        $("#L#{first_line}").ScrollTo() unless e?
+        $.scrollTo("#L#{first_line}") unless e?
 
     # parse selected lines from hash
     # always return first and last line (initialized to NaN)
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 46d6db0f05cd621d91a315aa10cd84a17357c9f9..b61d9875e03e91c6cac4464cd295e6a493efdfc3 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -59,7 +59,7 @@ class Dispatcher
 
   initHighlight: ->
     $('.highlight pre code').each (i, e) ->
-      hljs.highlightBlock(e)
       $(e).html($.map($(e).html().split("\n"), (line, i) ->
-        "<div class='line' id='LC" + (i + 1) + "'>" + line + "</div>"
+        "<span class='line' id='LC" + (i + 1) + "'>" + line + "</span>"
       ).join("\n"))
+      hljs.highlightBlock(e)
diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index d200d962cae1a9939048954a285cdea817ce2915..4510718c2fd1713bf088cd449ea044359eb70da8 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -1,10 +1,11 @@
 class Notes
   @interval: null
 
-  constructor: (notes_url, note_ids) ->
+  constructor: (notes_url, note_ids, last_fetched_at) ->
     @notes_url = notes_url
     @notes_url = gon.relative_url_root + @notes_url if gon.relative_url_root?
     @note_ids = note_ids
+    @last_fetched_at = last_fetched_at
     @initRefresh()
     @setupMainTargetNoteForm()
     @cleanBinding()
@@ -49,6 +50,15 @@ class Notes
     # hide diff note form
     $(document).on "click", ".js-close-discussion-note-form", @cancelDiscussionForm
 
+    # fetch notes when tab becomes visible
+    $(document).on "visibilitychange", @visibilityChange
+
+    @notes_forms = '.js-main-target-form textarea, .js-discussion-note-form textarea'
+    $(document).on('keypress', @notes_forms, (e)->
+      if e.keyCode == 10 || (e.ctrlKey && e.keyCode == 13)
+        $(@).parents('form').submit()
+    )
+
   cleanBinding: ->
     $(document).off "ajax:success", ".js-main-target-form"
     $(document).off "ajax:success", ".js-discussion-note-form"
@@ -62,6 +72,8 @@ class Notes
     $(document).off "click", ".js-choose-note-attachment-button"
     $(document).off "click", ".js-discussion-reply-button"
     $(document).off "click", ".js-add-diff-note-button"
+    $(document).off "visibilitychange"
+    $(document).off "keypress", @notes_forms
 
 
   initRefresh: ->
@@ -71,14 +83,16 @@ class Notes
     , 15000
 
   refresh: ->
-    @getContent()
+    @getContent() unless document.hidden
 
   getContent: ->
     $.ajax
       url: @notes_url
+      data: "last_fetched_at=" + @last_fetched_at
       dataType: "json"
       success: (data) =>
         notes = data.notes
+        @last_fetched_at = data.last_fetched_at
         $.each notes, (i, note) =>
           @renderNote(note)
 
@@ -450,4 +464,10 @@ class Notes
     filename = $(this).val().replace(/^.*[\\\/]/, "")
     form.find(".js-attachment-filename").text filename
 
+  ###
+  Called when the tab visibility changes
+  ###
+  visibilityChange: =>
+    @refresh()
+
 @Notes = Notes
diff --git a/app/assets/javascripts/project_users_select.js.coffee b/app/assets/javascripts/project_users_select.js.coffee
index 03fad41c490f7fa6b31212e957590e261d3cbd6f..382f9b37992176811e42e7ce4276e33180a7afd0 100644
--- a/app/assets/javascripts/project_users_select.js.coffee
+++ b/app/assets/javascripts/project_users_select.js.coffee
@@ -1,7 +1,7 @@
 @projectUsersSelect =
   init: ->
     $('.ajax-project-users-select').each (i, select) ->
-      project_id = $('body').data('project-id')
+      project_id = $(select).data('project-id') || $('body').data('project-id')
 
       $(select).select2
         placeholder: $(select).data('placeholder') || "Search for a user"
@@ -37,13 +37,13 @@
 
   projectUserFormatResult: (user) ->
     if user.avatar_url
-      avatar = user.avatar_url
+      avatar = gon.relative_url_root + user.avatar_url
     else if gon.gravatar_enabled
       avatar = gon.gravatar_url
       avatar = avatar.replace('%{hash}', md5(user.email))
       avatar = avatar.replace('%{size}', '24')
     else
-      avatar = gon.relative_url_root + "/assets/no_avatar.png"
+      avatar = gon.relative_url_root + "#{image_path('no_avatar.png')}"
 
     if user.id == ''
       avatarMarkup = ''
diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee
index ce9a505b1e3a62b203c81dffe9d7289aa0585a75..da66a4ba7f2971825f81e6524c2ca4cb8640bb64 100644
--- a/app/assets/javascripts/users_select.js.coffee
+++ b/app/assets/javascripts/users_select.js.coffee
@@ -1,13 +1,13 @@
 $ ->
   userFormatResult = (user) ->
     if user.avatar_url
-      avatar = user.avatar_url
+      avatar = gon.relative_url_root + user.avatar_url
     else if gon.gravatar_enabled
       avatar = gon.gravatar_url
       avatar = avatar.replace('%{hash}', md5(user.email))
       avatar = avatar.replace('%{size}', '24')
     else
-      avatar = gon.relative_url_root + "/assets/no_avatar.png"
+      avatar = gon.relative_url_root + "#{image_path('no_avatar.png')}"
 
     "<div class='user-result'>
        <div class='user-image'><img class='avatar s24' src='#{avatar}'></div>
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index ce36c1132eae98b1ad8347eaee55fab8171c2a3b..c53873f95a2afc2914822191a4730107a73bd443 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -12,10 +12,7 @@
  *= require nprogress-bootstrap
 */
 
-@import "main/variables.scss";
-@import "main/mixins.scss";
-@import "main/fonts.scss";
-@import "main/layout.scss";
+@import "main/*";
 
 /**
  * Customized Twitter bootstrap
@@ -31,64 +28,22 @@
 /**
  * Generic css (forms, nav etc):
  */
-@import "generic/avatar.scss";
-@import "generic/common.scss";
-@import "generic/typography.scss";
-@import "generic/buttons.scss";
-@import "generic/blocks.scss";
-@import "generic/ui_box.scss";
-@import "generic/issue_box.scss";
-@import "generic/files.scss";
-@import "generic/lists.scss";
-@import "generic/flash.scss";
-@import "generic/forms.scss";
-@import "generic/selects.scss";
-@import "generic/highlight.scss";
-@import "generic/jquery.scss";
+@import "generic/*";
 
 /**
  * Page specific styles (issues, projects etc):
  */
-@import "sections/header.scss";
-@import "sections/nav.scss";
-@import "sections/commits.scss";
-@import "sections/diff.scss";
-@import "sections/issues.scss";
-@import "sections/projects.scss";
-@import "sections/snippets.scss";
-@import "sections/votes.scss";
-@import "sections/merge_requests.scss";
-@import "sections/graph.scss";
-@import "sections/events.scss";
-@import "sections/themes.scss";
-@import "sections/tree.scss";
-@import "sections/notes.scss";
-@import "sections/profile.scss";
-@import "sections/login.scss";
-@import "sections/editor.scss";
-@import "sections/admin.scss";
-@import "sections/wiki.scss";
-@import "sections/wall.scss";
-@import "sections/dashboard.scss";
-@import "sections/stat_graph.scss";
-@import "sections/groups.scss";
+@import "sections/*";
 
 /**
  * Code highlight
  */
-@import "highlight/white.scss";
-@import "highlight/dark.scss";
-@import "highlight/solarized_dark.scss";
-@import "highlight/monokai.scss";
+@import "highlight/*";
 
 /**
  * UI themes:
  */
-@import "themes/ui_basic.scss";
-@import "themes/ui_mars.scss";
-@import "themes/ui_modern.scss";
-@import "themes/ui_gray.scss";
-@import "themes/ui_color.scss";
+@import "themes/*";
 
 /**
  * Styles for JS behaviors.
diff --git a/app/assets/stylesheets/generic/files.scss b/app/assets/stylesheets/generic/files.scss
index 12559f76051da729808892a6e78fcff706dcdefd..9e4207965f9aa5ea9165cdcece937569f94e3528 100644
--- a/app/assets/stylesheets/generic/files.scss
+++ b/app/assets/stylesheets/generic/files.scss
@@ -11,14 +11,11 @@
   }
 
   .file-title {
-    background: #DDD;
+    background: #EEE;
     border-bottom: 1px solid #CCC;
     text-shadow: 0 1px 1px #fff;
     margin: 0;
-    font-weight: normal;
-    font-weight: bold;
     text-align: left;
-    color: $style_color;
     padding: 9px 10px;
 
     .options {
@@ -26,13 +23,20 @@
       margin-top: -5px;
     }
 
+    .left-options {
+      margin-top: -3px;
+    }
+
     .file_name {
-      color: $style_color;
+      font-weight: bold;
+      padding-left: 3px;
       font-size: 14px;
-      text-shadow: 0 1px 1px #fff;
+
       small {
-        color: #999;
+        color: #888;
         font-size: 13px;
+        font-weight: normal;
+        padding-left: 10px;
       }
     }
   }
diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss
index 56cd4db905ed4bd6897e1b8eca40fa449bb1c221..36551f85b6a4e2c2e5b897bf19db09c29440754c 100644
--- a/app/assets/stylesheets/generic/forms.scss
+++ b/app/assets/stylesheets/generic/forms.scss
@@ -75,3 +75,26 @@ label {
     width: 200px;
   }
 }
+
+.commit-message-container {
+  background-color: $body-bg;
+  position: relative;
+  font-family: $monospace_font;
+  $left: 12px;
+  .max-width-marker {
+    color: rgba(0, 0, 0, 0.0);
+    font-family: inherit;
+    left: $left;
+    height: 100%;
+    border-right: 1px solid mix($input-border, white);
+    position: absolute;
+    z-index: 1;
+  }
+  > textarea {
+    background-color: rgba(0, 0, 0, 0.0);
+    font-family: inherit;
+    padding-left: $left;
+    position: relative;
+    z-index: 2;
+  }
+}
diff --git a/app/assets/stylesheets/generic/issue_box.scss b/app/assets/stylesheets/generic/issue_box.scss
index 3db4d908d9c693dc5eb0097ce01ebc88f937425b..bd692417989709d498e21c6560acae38bf1d0be0 100644
--- a/app/assets/stylesheets/generic/issue_box.scss
+++ b/app/assets/stylesheets/generic/issue_box.scss
@@ -12,41 +12,42 @@
   margin:20px 0;
   background: #FFF;
   border: 1px solid #EEE;
+  @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05));
 
   &.issue-box-closed {
-    border-color: #DA4E49;
+    border-color: $border_danger;
     .state {
-      background-color: #f2dede;
-      border-color: #ebccd1;
-      color: #a94442;
+      background-color: $bg_light_danger;
+      border-color: $border_danger;
+      color: $color_danger;
       .state-label {
-        background: #DA4E49;
+        background-color: $bg_danger;
         color: #FFF;
       }
     }
   }
 
   &.issue-box-merged {
-    border-color: #31708f;
+    border-color: $border_primary;
     .state {
-      background-color: #d9edf7;
-      border-color: #bce8f1;
-      color: #31708f;
+      background-color: $bg_light_primary;
+      border-color: $border_primary;
+      color: $color_primary;
       .state-label {
-        background: #31708f;
+        background-color: $bg_primary;
         color: #FFF;
       }
     }
   }
 
   &.issue-box-open {
-    border-color: #4A4;
+    border-color: $border_success;
     .state {
-      background-color: #dff0d8;
-      border-color: #d6e9c6;
-      color: #3c763d;
+      background-color: $bg_light_success;
+      border-color: $border_success;
+      color: $color_success;
       .state-label {
-        background: #4A4;
+        background-color: $bg_success;
         color: #FFF;
       }
     }
@@ -70,7 +71,6 @@
   }
 
   .state {
-    height: 34px;
     border-bottom: 1px solid #DDD;
     line-height: 32px;
   }
@@ -89,6 +89,18 @@
     border: none;
     border-top: 1px solid #eee;
     padding: 15px 25px;
+
+    // Reset text align for children
+    .text-right > * { text-align: left; }
+
+    @media (max-width: $screen-xs-max) {
+      // Don't right align on mobile
+      .text-right { text-align: left; }
+
+      .row .col-md-6 {
+        padding-top: 5px;
+      }
+    }
   }
 
   .description {
@@ -106,7 +118,11 @@
     padding: 1px 25px;
     text-align: center;
     text-shadow: none;
-    margin-right: 20px;
     display: inline-block;
+    line-height: 34px;
+  }
+
+  .creator {
+    padding: 2px 15px;
   }
 }
diff --git a/app/assets/stylesheets/generic/jquery.scss b/app/assets/stylesheets/generic/jquery.scss
index 4a9341e8f53213914eb18a824f6a1f68dbd1e95d..6b29accb3154a443a58d6dcf9896468d29dc0a4b 100644
--- a/app/assets/stylesheets/generic/jquery.scss
+++ b/app/assets/stylesheets/generic/jquery.scss
@@ -8,7 +8,7 @@
     width: 270px;
 
     .ui-datepicker-header {
-      background: #EEE;
+      background: #FFF;
       border-color: #DDD;
     }
 
@@ -19,20 +19,37 @@
   }
 
   &.ui-autocomplete {
-    @include border-radius(0px);
     border-color: #DDD;
     padding: 0;
+    margin-top: 2px;
+    z-index: 1001;
 
     .ui-menu-item a {
-      color: #777;
-
-      &:hover {
-        background: $hover;
-        border-color: $primary_color;
-        @include border-radius(0px);
-        color: #333;
-      }
+      padding: 4px 10px;
     }
   }
-}
 
+  .ui-state-default {
+    border: 1px solid #FFF;
+    background: #FFF;
+    color: #777;
+  }
+
+  .ui-state-highlight {
+    border: 1px solid #EEE;
+    background: #EEE;
+  }
+
+  .ui-state-active {
+    border: 1px solid $bg_style_color;
+    background: $bg_style_color;
+    color: #FFF;
+  }
+
+  .ui-state-hover,
+  .ui-state-focus {
+    border: 1px solid $hover;
+    background: $hover;
+    color: #333;
+  }
+}
diff --git a/app/assets/stylesheets/generic/typography.scss b/app/assets/stylesheets/generic/typography.scss
index a4419551738755908a050b54ca7a6cdcf7cb986c..8cc72d7f07a49dfa0bd217c3b79b9113425f0abc 100644
--- a/app/assets/stylesheets/generic/typography.scss
+++ b/app/assets/stylesheets/generic/typography.scss
@@ -47,7 +47,7 @@ a {
     text-decoration: underline;
   }
 
-  &.dark {
+  &.darken {
     color: $style_color;
   }
 
diff --git a/app/assets/stylesheets/main/mixins.scss b/app/assets/stylesheets/main/mixins.scss
index fcc7374d0d91ad6f5f021ae2d8dcc68fe2efb64c..8143cfa2c81071321516b6147efd5fe9ef0db194 100644
--- a/app/assets/stylesheets/main/mixins.scss
+++ b/app/assets/stylesheets/main/mixins.scss
@@ -41,31 +41,6 @@
  * Prefilled mixins
  * Mixins with fixed values
  */
-@mixin bg-light-gray-gradient {
-  background: #f1f1f1;
-  background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #f5f5f5), to(#e1e1e1));
-  background-image: -webkit-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
-  background-image: -moz-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
-  background-image: -ms-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
-  background-image: -o-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
-}
-
-@mixin bg-gray-gradient {
-  background: #eee;
-  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);
-}
-
-@mixin bg-dark-gray-gradient {
-  background: #eee;
-  background-image: -webkit-linear-gradient(#e9e9e9, #d7d7d7);
-  background-image: -moz-linear-gradient(#e9e9e9, #d7d7d7);
-  background-image: -ms-linear-gradient(#e9e9e9, #d7d7d7);
-  background-image: -o-linear-gradient(#e9e9e9, #d7d7d7);
-}
 
 @mixin shade {
   @include box-shadow(0 0 3px #ddd);
@@ -77,7 +52,6 @@
 
 @mixin header-font {
   color: $style_color;
-  text-shadow: 0 1px 1px #FFF;
   font-size: 16px;
   line-height: 44px;
   font-weight: normal;
diff --git a/app/assets/stylesheets/main/variables.scss b/app/assets/stylesheets/main/variables.scss
index 4b5fa0979be33bdde91d7db046f0105771bcad00..f133777de56e3bed8fcb2bdceb2a8bb3c293f6dd 100644
--- a/app/assets/stylesheets/main/variables.scss
+++ b/app/assets/stylesheets/main/variables.scss
@@ -8,6 +8,31 @@ $bg_style_color: #2299BB;
 $list-group-active-bg: $bg_style_color;
 $hover: #D9EDF7;
 
+/*
+ * Success colors (green)
+ */
+$border_success: #4cae4c;
+$bg_success: #5cb85c;
+$bg_light_success: #dff0d8;
+$color_success: #3c763d;
+
+/*
+ * Danger colors (red)
+ */
+$border_danger: #d43f3a;
+$bg_danger: #d9534f;
+$bg_light_danger: #f2dede;
+$color_danger: #a94442;
+
+/*
+ * Primary colors (blue)
+ */
+$border_primary: #358ebd;
+$bg_primary: #429bca;
+$bg_light_primary: #d9edf7;
+$color_primary: #31708f;
+
+
 /**
  * Commit Diff Colors
  */
diff --git a/app/assets/stylesheets/sections/diff.scss b/app/assets/stylesheets/sections/diff.scss
index eb272f20f40c23d5b1e473b85bd642c70f5ad27f..24d997c9fcafc6fbeb2fee7c27941507aafc595c 100644
--- a/app/assets/stylesheets/sections/diff.scss
+++ b/app/assets/stylesheets/sections/diff.scss
@@ -4,7 +4,7 @@
 
   .diff-header {
     @extend .clearfix;
-    background: #DDD;
+    background: #EEE;
     border-bottom: 1px solid #CCC;
     padding: 5px 5px 5px 10px;
     color: #555;
@@ -63,33 +63,21 @@
       }
     }
 
-    .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
+    tr.line_holder.parallel{
+      .old_line, .new_line, .diff_line {
+        min-width: 50px;
+      }
+
+      td.line_content.parallel{
+        width: 50%;
+      }
     }
 
     .old_line, .new_line, .diff_line {
       margin: 0px;
       padding: 0px;
       border: none;
-      background: #EEE;
+      background: #F5F5F5;
       color: #666;
       padding: 0px 5px;
       border-right: 1px solid #ccc;
@@ -307,15 +295,9 @@
     } //.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);
+    background: #EEE;
 
     ul, li{
       list-style: none;
@@ -348,3 +330,8 @@
     }
   }
 }
+
+.file-content .diff-file {
+  margin: 0;
+  border: none;
+}
diff --git a/app/assets/stylesheets/sections/graph.scss b/app/assets/stylesheets/sections/graph.scss
index 1e22d161bfc20d15d8725f7de0868314e3de1d98..8a337a5e2067721b59e2c8699f49a6f98151623a 100644
--- a/app/assets/stylesheets/sections/graph.scss
+++ b/app/assets/stylesheets/sections/graph.scss
@@ -1,17 +1,16 @@
 .project-network {
-  border: 1px solid #aaa;
-  padding: 1px;
+  border: 1px solid #CCC;
 
   .tip {
     color: #888;
     font-size: 14px;
     padding: 10px;
     border-bottom: 1px solid #bbb;
-    @include bg-gray-gradient;
+    background: #EEE;
   }
 
   .network-graph {
-    background: #f1f1f1;
+    background: #FFF;
     height: 500px;
     overflow-y: scroll;
     overflow-x: hidden;
diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss
index 06709bd7ef684bfdf3cc5a1d89d07308cba09df9..1adbdfd9790daa61fa9c061f209a784f81b2145a 100644
--- a/app/assets/stylesheets/sections/header.scss
+++ b/app/assets/stylesheets/sections/header.scss
@@ -14,7 +14,6 @@ header {
 
       .nav > li > a {
         color: $style_color;
-        text-shadow: 0 1px 0 #fff;
         font-size: 14px;
         line-height: 32px;
         padding: 6px 10px;
@@ -190,7 +189,6 @@ header {
 
         .nav > li > a {
           color: #AAA;
-          text-shadow: 0 1px 0 #444;
 
           &:hover, &:focus, &:active {
             background: none;
@@ -224,7 +222,6 @@ header {
           background: image-url('logo-white.png') no-repeat center center;
           background-size: 32px;
           color: #fff;
-          text-shadow: 0 1px 1px #444;
         }
       }
     }
@@ -236,7 +233,6 @@ header {
         }
       }
       color: #fff;
-      text-shadow: 0 1px 1px #444;
     }
   }
 
diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss
index d4f8c8108abda6143772f9eece42e0ae7c3e6fe8..02c9123178f1d5335f77204c88369e7b1b481fe8 100644
--- a/app/assets/stylesheets/sections/issues.scss
+++ b/app/assets/stylesheets/sections/issues.scss
@@ -45,14 +45,6 @@
   padding: 6px 10px;
   border: 1px solid #ccc;
   @include border-radius(4px);
-
-
-  input.check_all_issues {
-    padding: 0;
-    margin: 0;
-    position: relative;
-    top: 3px;
-  }
 }
 
 .issues_content {
@@ -143,3 +135,36 @@ form.edit-issue {
     border-color: #E5E5E5;
   }
 }
+
+@media (max-width: $screen-xs-max) {
+  .issue-btn-group {
+    width: 100%;
+    margin-top: 5px;
+
+    .btn-group {
+      width: 100%;
+
+      ul {
+        width: 100%;
+        text-align: center;
+      }
+    }
+
+    .btn {
+      width: 100%;
+      margin-top: -1px;
+
+      &:first-child:not(:last-child) {
+        border-radius: 4px 4px 0 0;
+      }
+
+      &:not(:first-child):not(:last-child) {
+        border-radius: 0;
+      }
+
+      &:last-child:not(:first-child) {
+        border-radius: 0 0 4px 4px;
+      }
+    }
+  }
+}
diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index 790496a1a5a190fd85f389af072da7940600c061..2d9a5e4bbe6b09813b5a1712f5fd0d565d392309 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -31,7 +31,6 @@
 
 .mr_source_commit,
 .mr_target_commit {
-  margin-top: 10px;
   .commit {
     margin: 0;
     padding: 2px 0;
@@ -74,6 +73,10 @@
 
     .merge-request-info {
       color: #999;
+
+      .merge-request-labels {
+        display: inline-block;
+      }
     }
   }
 }
@@ -112,3 +115,7 @@
     }
   }
 }
+
+.merge-request-show-labels .label {
+  padding: 6px 10px;
+}
diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss
index c9c7b6eccedecae4d22f4e231ffbdb9caba5c5ec..7e56781f56a8709edc37b3b665950fba33d69c2d 100644
--- a/app/assets/stylesheets/sections/notes.scss
+++ b/app/assets/stylesheets/sections/notes.scss
@@ -139,6 +139,7 @@ ul.notes {
       background-color: #fff;
       border-width: 1px 0;
       padding-top: 0;
+      vertical-align: top;
 
       li {
         padding: 5px;
diff --git a/app/assets/stylesheets/sections/profile.scss b/app/assets/stylesheets/sections/profile.scss
index 7a696c21e474378dbbefecf185d29802a44ae6e5..67aaa369381613d912ff456236caa4451b435632 100644
--- a/app/assets/stylesheets/sections/profile.scss
+++ b/app/assets/stylesheets/sections/profile.scss
@@ -76,7 +76,7 @@
       }
 
       &.modern {
-        background: #345;
+        background: #009871;
       }
 
       &.gray {
@@ -84,7 +84,7 @@
       }
 
       &.violet {
-        background: #547;
+        background: #548;
       }
     }
   }
diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss
index 55a5819b55a0240d15f4369066509a3a31fc9076..86e2a51641a966d68faf2c012b82d549a5a5b936 100644
--- a/app/assets/stylesheets/sections/tree.scss
+++ b/app/assets/stylesheets/sections/tree.scss
@@ -151,3 +151,5 @@
     }
   }
 }
+
+#modal-remove-blob > .modal-dialog { width: 850px; }
diff --git a/app/assets/stylesheets/sections/votes.scss b/app/assets/stylesheets/sections/votes.scss
index 13f811e01a1680bf901098643bf09b94530b38b1..d683e33e1f05276ac1f9acf7010b7d78b4c1c41b 100644
--- a/app/assets/stylesheets/sections/votes.scss
+++ b/app/assets/stylesheets/sections/votes.scss
@@ -40,4 +40,10 @@
 .votes-holder {
   float: right;
   width: 250px;
+
+  @media (max-width: $screen-xs-max) {
+    width: 100%;
+    margin-top: 5px;
+    margin-bottom: 10px;
+  }
 }
diff --git a/app/assets/stylesheets/themes/ui_color.scss b/app/assets/stylesheets/themes/ui_color.scss
index edac4290e74b45e974f57a1c0be5ea3412c902b7..a08f3ff3d48b1d063e09af73806f8dd70871b8a1 100644
--- a/app/assets/stylesheets/themes/ui_color.scss
+++ b/app/assets/stylesheets/themes/ui_color.scss
@@ -16,28 +16,28 @@
     @extend .header-dark;
     &.navbar-gitlab {
       .navbar-inner {
-        background: #547;
-        border-bottom: 1px solid #435;
+        background: #548;
+        border-bottom: 1px solid #436;
         .app_logo, .navbar-toggle {
           &:hover {
-            background-color: #435;
+            background-color: #436;
           }
         }
         .separator {
-          background: #435;
-          border-left: 1px solid #658;
+          background: #436;
+          border-left: 1px solid #659;
         }
         .nav > li > a {
-          color: #98B;
+          color: #98C;
         }
         .search-input {
-          border-color: #98B;
+          border-color: #98C;
         }
       }
     }
   }
 
   .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
-    background: #769;
+    background: #659;
   }
 }
diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss
index b0827deb1acff5f52073b29567fa48fa404b6111..67616a4a10d9eb7591812c6c3e636e05a8fcad63 100644
--- a/app/assets/stylesheets/themes/ui_modern.scss
+++ b/app/assets/stylesheets/themes/ui_modern.scss
@@ -16,24 +16,28 @@
     @extend .header-dark;
     &.navbar-gitlab {
       .navbar-inner {
-        background: #345;
-        border-bottom: 1px solid #234;
+        background: #00AC7E;
+        border-bottom: 1px solid #00AC7E;
         .app_logo, .navbar-toggle {
           &:hover {
-            background-color: #234;
+            background-color: #009C6E;
           }
         }
         .separator {
-          background: #234;
-          border-left: 1px solid #456;
+          background: #009C6F;
+          border-left: 1px solid #10BC8E;
         }
         .nav > li > a {
-          color: #89A;
+          color: #ADC;
         }
         .search-input {
-          border-color: #89A;
+          border-color: #7fd5be;
         }
       }
     }
   }
+
+  .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
+    background: #00AC7E;
+  }
 }
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 13a7bdcf34a7e8bfb3befb3ef3b0cbe58db15e31..92ef5963373cbe701bd5f222737aaad0ae0ae67b 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -12,6 +12,7 @@ class Admin::ProjectsController < Admin::ApplicationController
     @projects = @projects.with_push if params[:with_push].present?
     @projects = @projects.abandoned if params[:abandoned].present?
     @projects = @projects.search(params[:name]) if params[:name].present?
+    @projects = @projects.sort(@sort = params[:sort])
     @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
   end
 
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index a3f39c23e085e3d9f4da2cb778d1990dc1e46312..2730e9942ecfaf4ff861ede955eb915ee9e2947c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -117,6 +117,11 @@ class ApplicationController < ActionController::Base
     return access_denied! unless can?(current_user, :push_code, project)
   end
 
+  def authorize_labels!
+    # Labels should be accessible for issues and/or merge requests
+    authorize_read_issue! || authorize_read_merge_request!
+  end
+
   def access_denied!
     render "errors/access_denied", layout: "errors", status: 404
   end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index a3019b3ac78f49ec298aed242937a94ee8282507..ddaae6f0e8c5fd4e30a04b6c85134ec00a168204 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -68,7 +68,7 @@ class GroupsController < ApplicationController
     @members = group.users_groups
 
     if params[:search].present?
-      users = group.users.search(params[:search])
+      users = group.users.search(params[:search]).to_a
       @members = @members.where(user_id: users)
     end
 
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 6a6cbe481840530710dcbf85f92a7b3da147ddac..00811f17adb17f858fe5441b316d44c7eb989109 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -4,8 +4,7 @@ class Projects::BranchesController < Projects::ApplicationController
   before_filter :require_non_empty_project
 
   before_filter :authorize_code_access!
-  before_filter :authorize_push!, only: [:create]
-  before_filter :authorize_admin_project!, only: [:destroy]
+  before_filter :authorize_push!, only: [:create, :destroy]
 
   def index
     @branches = Kaminari.paginate_array(@repository.branches).page(params[:page]).per(30)
@@ -22,11 +21,7 @@ class Projects::BranchesController < Projects::ApplicationController
   end
 
   def destroy
-    branch = @repository.find_branch(params[:id])
-
-    if branch && @repository.rm_branch(branch.name)
-      Event.create_ref_event(@project, current_user, branch, 'rm')
-    end
+    DeleteBranchService.new.execute(project, params[:id], current_user)
 
     respond_to do |format|
       format.html { redirect_to project_branches_path(@project) }
diff --git a/app/controllers/projects/edit_tree_controller.rb b/app/controllers/projects/edit_tree_controller.rb
index ff5206b6fa1e56a5edddd03e4a160b4f41489f4d..be611892bb07140abcfb71c44a383961965db09b 100644
--- a/app/controllers/projects/edit_tree_controller.rb
+++ b/app/controllers/projects/edit_tree_controller.rb
@@ -26,6 +26,18 @@ class Projects::EditTreeController < Projects::BaseTreeController
     end
   end
 
+  def preview
+    @content = params[:content]
+    #FIXME workaround https://github.com/gitlabhq/gitlabhq/issues/5936
+    @content += "\n" if @blob.data.end_with?("\n")
+
+    diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
+                            include_diff_info: true)
+    @diff = Gitlab::DiffParser.new(diffy.diff.scan(/.*\n/))
+
+    render layout: false
+  end
+
   private
 
   def blob
diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb
index 0166ca9ff00db5aa474cf17fd8c45771101cabe8..b037cf5650211051a3bc64e7e5ba5892d2108d6e 100644
--- a/app/controllers/projects/labels_controller.rb
+++ b/app/controllers/projects/labels_controller.rb
@@ -1,8 +1,7 @@
 class Projects::LabelsController < Projects::ApplicationController
   before_filter :module_enabled
 
-  # Allow read any issue
-  before_filter :authorize_read_issue!
+  before_filter :authorize_labels!
 
   respond_to :js, :html
 
@@ -13,12 +12,18 @@ class Projects::LabelsController < Projects::ApplicationController
   def generate
     Gitlab::IssuesLabels.generate(@project)
 
-    redirect_to project_issues_path(@project)
+    if params[:redirect] == 'issues'
+      redirect_to project_issues_path(@project)
+    elsif params[:redirect] == 'merge_requests'
+      redirect_to project_merge_requests_path(@project)
+    end
   end
 
   protected
 
   def module_enabled
-    return render_404 unless @project.issues_enabled
+    unless @project.issues_enabled || @project.merge_requests_enabled
+      return render_404
+    end
   end
 end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 745da9c49e47e40a2893185a3d21f7e51a6280b2..d8551db7b012c51275b8663c8a58f0d21c3d2c6e 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -62,11 +62,27 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @merge_request.source_project = @project unless @merge_request.source_project
     @merge_request.target_project ||= (@project.forked_from_project || @project)
     @target_branches = @merge_request.target_project.nil? ? [] : @merge_request.target_project.repository.branch_names
-
     @merge_request.target_branch ||= @merge_request.target_project.default_branch
-
     @source_project = @merge_request.source_project
-    @merge_request
+
+    if @merge_request.target_branch && @merge_request.source_branch
+      compare_action = Gitlab::Satellite::CompareAction.new(
+        current_user,
+        @merge_request.target_project,
+        @merge_request.target_branch,
+        @merge_request.source_project,
+        @merge_request.source_branch
+      )
+
+      @commits = compare_action.commits
+      @commits.map! { |commit| Commit.new(commit) }
+      @commit = @commits.first
+
+      @diffs = compare_action.diffs
+      @merge_request.title = @merge_request.source_branch.titleize.humanize
+      @target_project = @merge_request.target_project
+      @target_repo = @target_project.repository
+    end
   end
 
   def edit
@@ -80,7 +96,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @merge_request = MergeRequests::CreateService.new(project, current_user, params[:merge_request]).execute
 
     if @merge_request.valid?
-      redirect_to [@merge_request.target_project, @merge_request], notice: 'Merge request was successfully created.'
+      redirect_to project_merge_request_path(@merge_request.target_project, @merge_request), notice: 'Merge request was successfully created.'
     else
       @source_project = @merge_request.source_project
       @target_project = @merge_request.target_project
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 85d042a89b5736c5baa051460978cfd0cb06c9f6..b5b0446b43fa12a670cc51fe660e930744012992 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -5,9 +5,10 @@ class Projects::NotesController < Projects::ApplicationController
   before_filter :authorize_admin_note!, only: [:update, :destroy]
 
   def index
+    current_fetched_at = Time.now.to_i
     @notes = NotesFinder.new.execute(project, current_user, params)
 
-    notes_json = { notes: [] }
+    notes_json = { notes: [], last_fetched_at: current_fetched_at }
 
     @notes.each do |note|
       notes_json[:notes] << {
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index bcd9e0d5219fb64a24c7dcdea82d6b09f35d5512..496064c9a6558da73b68b58ab3fb0c6cf3cc84e7 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -12,9 +12,22 @@ class Projects::WikisController < Projects::ApplicationController
 
   def show
     @page = @project_wiki.find_page(params[:id], params[:version_id])
+    gollum_wiki = @project_wiki.wiki
+    file = gollum_wiki.file(params[:id], gollum_wiki.ref, true)
 
     if @page
       render 'show'
+    elsif file
+       if file.on_disk?
+         send_file file.on_disk_path, disposition: 'inline'
+       else
+         send_data(
+           file.raw_data,
+           type: file.mime_type,
+           disposition: 'inline',
+           filename: file.name
+         )
+       end
     else
       return render('empty') unless can?(current_user, :write_wiki, @project)
       @page = WikiPage.new(@project_wiki)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index ebb8a90c630039ace5730de753303406c5ba70e2..e356d09a270e6943987695890d1aef88837adde3 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -190,6 +190,6 @@ class ProjectsController < ApplicationController
   end
 
   def sorted(users)
-    users.uniq.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
+    users.uniq.compact.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
   end
 end
diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb
index 384316e14b7d2308a3edc6fc37527e5925df3adb..ea055694cd7806c787c9525665454a777abcecb9 100644
--- a/app/finders/notes_finder.rb
+++ b/app/finders/notes_finder.rb
@@ -1,9 +1,13 @@
 class NotesFinder
+  FETCH_OVERLAP = 5.seconds
+
   def execute(project, current_user, params)
     target_type = params[:target_type]
     target_id   = params[:target_id]
+    # Default to 0 to remain compatible with old clients
+    last_fetched_at = Time.at(params.fetch(:last_fetched_at, 0).to_i)
 
-    case target_type
+    notes = case target_type
     when "commit"
       project.notes.for_commit_id(target_id).not_inline.fresh
     when "issue"
@@ -12,6 +16,11 @@ class NotesFinder
       project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
     when "snippet"
       project.snippets.find(target_id).notes.fresh
+    else
+      raise 'invalid target_type'
     end
+
+    # Use overlapping intervals to avoid worrying about race conditions
+    notes.where('updated_at > ?', last_fetched_at - FETCH_OVERLAP)
   end
 end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index faecde299c1881f41fc1f0ac6f94785bcff4b13b..e87bf24163a139e10d4a3ada9c76cc051f37510b 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -71,11 +71,11 @@ module ApplicationHelper
     size = 40 if size.nil? || size <= 0
 
     if !Gitlab.config.gravatar.enabled || user_email.blank?
-      '/assets/no_avatar.png'
+      image_path('no_avatar.png')
     else
       gravatar_url = request.ssl? || gitlab_config.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
       user_email.strip!
-      sprintf gravatar_url, hash: Digest::MD5.hexdigest(user_email.downcase), size: size
+      sprintf gravatar_url, hash: Digest::MD5.hexdigest(user_email.downcase), size: size, email: user_email
     end
   end
 
diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e08ffccb94c5e25d92c63454ce70928f52f0c0b0
--- /dev/null
+++ b/app/helpers/branches_helper.rb
@@ -0,0 +1,11 @@
+module BranchesHelper
+  def can_remove_branch?(project, branch_name)
+     if project.protected_branch? branch_name
+       false
+     elsif branch_name == project.repository.root_ref
+       false
+     else
+       can?(current_user, :push_code, project)
+     end
+  end
+end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index c6e4f574b67805c48353ea4544fc132f210d11cd..c4abdbdabc72ae9e90a9cc9dd499f3eb316770eb 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -16,9 +16,10 @@ module CommitsHelper
   end
 
   def each_diff_line(diff, index)
-    Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
-      yield(full_line, type, line_code, line_new, line_old)
-    end
+    Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
+      .each do |full_line, type, line_code, line_new, line_old|
+        yield(full_line, type, line_code, line_new, line_old)
+      end
   end
 
   def each_diff_line_near(diff, index, expected_line_code)
@@ -116,7 +117,7 @@ module CommitsHelper
         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
+    max_length = old_file ? [old_file.loc, file.loc].max : file.loc
 
     offset1 = 0
     offset2 = 0
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 95f0eff58b188bf7f23652293713a55ee358c69a..7c58908165c355fb1794d8211c517124ead28332 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -82,7 +82,7 @@ module IssuesHelper
   end
 
   def milestone_options object
-    options_from_collection_for_select(@project.milestones.active, 'id', 'title', object.milestone_id)
+    options_from_collection_for_select(object.project.milestones.active, 'id', 'title', object.milestone_id)
   end
 
   def issue_box_class(item)
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 9bb3efc41d8ad219ae2e9ce1316bea172a2b3a4c..ef0460f87284a7f5e4f41ffb59b40c3ee1a67b70 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -163,7 +163,7 @@ module ProjectsHelper
   end
 
   def repository_size(project = nil)
-    "#{(project || @project).repository.size} MB"
+    "#{(project || @project).repository_size} MB"
   rescue
     # In order to prevent 500 error
     # when application cannot allocate memory
diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb
index a1fe4488ae9d5e5f0e0706ca65c42163dba179c4..ab24367c45521eccacd14ef5a34b310c277c3d21 100644
--- a/app/helpers/selects_helper.rb
+++ b/app/helpers/selects_helper.rb
@@ -14,7 +14,7 @@ module SelectsHelper
     css_class << (opts[:class] || '')
     value = opts[:selected] || ''
     placeholder = opts[:placeholder] || 'Select user'
-
-    hidden_field_tag(id, value, class: css_class, 'data-placeholder' => placeholder)
+    project_id = opts[:project_id] || @project.id
+    hidden_field_tag(id, value, class: css_class, 'data-placeholder' => placeholder, 'data-project-id' => project_id)
   end
 end
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 50501dffefb54055d5b2ddbe28079f21fce9f051..f39d0081dce4fa1b75f421bb6c1c9f4143ead5ef 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -91,4 +91,12 @@ module TreeHelper
   def leave_edit_message
     "Leave edit mode?\nAll unsaved changes will be lost."
   end
+
+  def editing_preview_title(filename)
+    if gitlab_markdown?(filename) || markup?(filename)
+      'Preview'
+    else
+      'Diff'
+    end
+  end
 end
diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb
index d684e3544529aebb76fbfb870298bf3a11da6299..a096df9dc0de3e9ac5befabfe186e610a568f6f3 100644
--- a/app/mailers/emails/issues.rb
+++ b/app/mailers/emails/issues.rb
@@ -4,6 +4,7 @@ module Emails
       @issue = Issue.find(issue_id)
       @project = @issue.project
       @target_url = project_issue_url(@project, @issue)
+      set_message_id("issue_#{issue_id}")
       mail(from: sender(@issue.author_id),
            to: recipient(recipient_id),
            subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -14,6 +15,7 @@ module Emails
       @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
       @project = @issue.project
       @target_url = project_issue_url(@project, @issue)
+      set_reference("issue_#{issue_id}")
       mail(from: sender(updated_by_user_id),
            to: recipient(recipient_id),
            subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -24,6 +26,7 @@ module Emails
       @project = @issue.project
       @updated_by = User.find updated_by_user_id
       @target_url = project_issue_url(@project, @issue)
+      set_reference("issue_#{issue_id}")
       mail(from: sender(updated_by_user_id),
            to: recipient(recipient_id),
            subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -35,6 +38,7 @@ module Emails
       @project = @issue.project
       @updated_by = User.find updated_by_user_id
       @target_url = project_issue_url(@project, @issue)
+      set_reference("issue_#{issue_id}")
       mail(from: sender(updated_by_user_id),
            to: recipient(recipient_id),
            subject: subject("#{@issue.title} (##{@issue.iid})"))
diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index a97d55f1b505040b84b1fc47fab8ff4e3ee52710..ea5671c45027e7c39e7765b6978eb78bd4508c40 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -4,9 +4,10 @@ module Emails
       @merge_request = MergeRequest.find(merge_request_id)
       @project = @merge_request.project
       @target_url = project_merge_request_url(@project, @merge_request)
+      set_message_id("merge_request_#{merge_request_id}")
       mail(from: sender(@merge_request.author_id),
            to: recipient(recipient_id),
-           subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
+           subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
     end
 
     def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, updated_by_user_id)
@@ -14,9 +15,10 @@ module Emails
       @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
       @project = @merge_request.project
       @target_url = project_merge_request_url(@project, @merge_request)
+      set_reference("merge_request_#{merge_request_id}")
       mail(from: sender(updated_by_user_id),
            to: recipient(recipient_id),
-           subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
+           subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
     end
 
     def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
@@ -24,18 +26,20 @@ module Emails
       @updated_by = User.find updated_by_user_id
       @project = @merge_request.project
       @target_url = project_merge_request_url(@project, @merge_request)
+      set_reference("merge_request_#{merge_request_id}")
       mail(from: sender(updated_by_user_id),
            to: recipient(recipient_id),
-           subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
+           subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
     end
 
     def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
       @merge_request = MergeRequest.find(merge_request_id)
       @project = @merge_request.project
       @target_url = project_merge_request_url(@project, @merge_request)
+      set_reference("merge_request_#{merge_request_id}")
       mail(from: sender(updated_by_user_id),
            to: recipient(recipient_id),
-           subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
+           subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
     end
   end
 
diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb
index ccbdadf010ff6cea082318be92d3c08c7f00caea..8d1f17b0f81755908c591e0436ac82cb7048716c 100644
--- a/app/mailers/emails/notes.rb
+++ b/app/mailers/emails/notes.rb
@@ -15,6 +15,7 @@ module Emails
       @issue = @note.noteable
       @project = @note.project
       @target_url = project_issue_url(@project, @issue, anchor: "note_#{@note.id}")
+      set_reference("issue_#{@issue.id}")
       mail(from: sender(@note.author_id),
            to: recipient(recipient_id),
            subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -25,9 +26,10 @@ module Emails
       @merge_request = @note.noteable
       @project = @note.project
       @target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{@note.id}")
+      set_reference("merge_request_#{@merge_request.id}")
       mail(from: sender(@note.author_id),
            to: recipient(recipient_id),
-           subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
+           subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
     end
 
     def note_wall_email(recipient_id, note_id)
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index 554f53cf1487606c776113895f10a14bc364a2ea..84a0da0129db0c8c49d1db9a31e1eca95d2856dc 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -53,6 +53,22 @@ class Notify < ActionMailer::Base
     end
   end
 
+  # Set the Message-ID header field
+  #
+  # local_part - The local part of the message ID
+  #
+  def set_message_id(local_part)
+    headers["Message-ID"] = "<#{local_part}@#{Gitlab.config.gitlab.host}>"
+  end
+
+  # Set the References header field
+  #
+  # local_part - The local part of the referenced message ID
+  #
+  def set_reference(local_part)
+    headers["References"] = "<#{local_part}@#{Gitlab.config.gitlab.host}>"
+  end
+
   # Formats arguments into a String suitable for use as an email subject
   #
   # extra - Extra Strings to be inserted into the subject
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 8c885b70a4853335843bd578966e02b6d61bc784..061537132b3fb47f09a3fa8b6e81681187655fc2 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -36,7 +36,9 @@ class MergeRequest < ActiveRecord::Base
 
   delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
 
-  attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :state_event, :description
+  attr_accessible :title, :assignee_id, :source_project_id, :source_branch,
+                  :target_project_id, :target_branch, :milestone_id,
+                  :state_event, :description, :label_list
 
   attr_accessor :should_remove_source_branch
 
@@ -44,6 +46,9 @@ class MergeRequest < ActiveRecord::Base
   # It allows us to close or modify broken merge requests
   attr_accessor :allow_broken
 
+  ActsAsTaggableOn.strict_case_match = true
+  acts_as_taggable_on :labels
+
   state_machine :state, initial: :opened do
     event :close do
       transition [:reopened, :opened] => :closed
@@ -253,6 +258,14 @@ class MergeRequest < ActiveRecord::Base
     end
   end
 
+  def target_project_namespace
+    if target_project && target_project.namespace
+      target_project.namespace.path
+    else
+      "(removed)"
+    end
+  end
+
   def source_branch_exists?
     return false unless self.source_project
 
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 0684461add7ee1809e84dab6057f1dc78a76f3eb..7dce71a677bc9e18223ec881812cc0595692d24e 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -86,7 +86,7 @@ class MergeRequestDiff < ActiveRecord::Base
   # between target and source branches
   def unmerged_commits
     commits = if merge_request.for_fork?
-                Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between
+                compare_action.commits
               else
                 repository.commits_between(target_branch, source_branch)
               end
@@ -150,7 +150,7 @@ class MergeRequestDiff < ActiveRecord::Base
   # between target and source branches
   def unmerged_diffs
     diffs = if merge_request.for_fork?
-              Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite
+              compare_action.diffs
             else
               Gitlab::Git::Diff.between(repository, source_branch, target_branch)
             end
@@ -165,4 +165,16 @@ class MergeRequestDiff < ActiveRecord::Base
   def repository
     merge_request.target_project.repository
   end
+
+  private
+
+  def compare_action
+    Gitlab::Satellite::CompareAction.new(
+      merge_request.author,
+      merge_request.target_project,
+      merge_request.target_branch,
+      merge_request.source_project,
+      merge_request.source_branch
+    )
+  end
 end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 6a2ca767030816de4c0a2dad8dc31d67e1ef6077..39ab0b536a39501245e3b0cd259666b26e83564b 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -25,6 +25,7 @@ class Milestone < ActiveRecord::Base
 
   scope :active, -> { with_state(:active) }
   scope :closed, -> { with_state(:closed) }
+  scope :of_projects, ->(ids) { where(project_id: ids) }
 
   validates :title, presence: true
   validates :project, presence: true
diff --git a/app/models/note.rb b/app/models/note.rb
index 6f7afcd1f9f7fe1f5cd47d2432b1a87a3321da23..cee10ec90d2a59843e0294d3b6673dc190322b9a 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -184,9 +184,10 @@ class Note < ActiveRecord::Base
     return @diff_line if @diff_line
 
     if diff
-      Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
-        @diff_line = full_line if line_code == self.line_code
-      end
+      Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
+        .each do |full_line, type, line_code, line_new, line_old|
+          @diff_line = full_line if line_code == self.line_code
+        end
     end
 
     @diff_line
diff --git a/app/models/project.rb b/app/models/project.rb
index 3ae47c181364be4cdf92a487a3af52422230136f..45e950f4807f26ac237be2c8f9acea7c712c1532 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -203,6 +203,7 @@ class Project < ActiveRecord::Base
       when 'oldest' then reorder('projects.created_at ASC')
       when 'recently_updated' then reorder('projects.updated_at DESC')
       when 'last_updated' then reorder('projects.updated_at ASC')
+      when 'largest_repository' then reorder('projects.repository_size DESC')
       else reorder("namespaces.path, projects.name ASC")
       end
     end
@@ -280,8 +281,11 @@ class Project < ActiveRecord::Base
     self.id
   end
 
+  # Tags are shared by issues and merge requests
   def issues_labels
-    @issues_labels ||= (issues_default_labels + issues.tags_on(:labels)).uniq.sort_by(&:name)
+    @issues_labels ||= (issues_default_labels +
+                        merge_requests.tags_on(:labels) +
+                        issues.tags_on(:labels)).uniq.sort_by(&:name)
   end
 
   def issue_exists?(issue_id)
@@ -562,4 +566,8 @@ class Project < ActiveRecord::Base
   def forked_from?(project)
     forked? && project == forked_from_project
   end
+
+  def update_repository_size
+    update_attribute(:repository_size, repository.size)
+  end
 end
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index 163302a18f7f3f9d47cf8a312673bb2278bc264b..08a527824751382707679baaa8bb83937f84d17d 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -64,7 +64,8 @@ class ProjectWiki
   #
   # Returns an initialized WikiPage instance or nil
   def find_page(title, version = nil)
-    if page = wiki.page(title, version)
+    page_title, page_dir = page_title_and_dir(title)
+    if page = wiki.page(page_title, version, page_dir)
       WikiPage.new(self, page, true)
     else
       nil
@@ -90,6 +91,12 @@ class ProjectWiki
     wiki.delete_page(page, commit_details(:deleted, message, page.title))
   end
 
+  def page_title_and_dir(title)
+    title_array =  title.split("/")
+    title = title_array.pop
+    [title.gsub(/\.[^.]*$/, ""), title_array.join("/")]
+  end
+
   private
 
   def create_repo!
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 76f311ed0b4bb258450caa6b3824f2033c305e64..b8a0a9eb58b5b869a18b1f18fde6c0f8bf57c68c 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -175,14 +175,24 @@ class WikiPage
   end
 
   def save(method, *args)
-    if valid? && wiki.send(method, *args)
-      @page = wiki.wiki.paged(title)
+    project_wiki = wiki
+    if valid? && project_wiki.send(method, *args)
+
+      page_details = if method == :update_page
+                       @page.path
+                     else
+                       title
+                     end
+
+      page_title, page_dir = project_wiki.page_title_and_dir(page_details)
+      gollum_wiki = project_wiki.wiki
+      @page = gollum_wiki.paged(page_title, page_dir)
 
       set_attributes
 
       @persisted = true
     else
-      errors.add(:base, wiki.error_message) if wiki.error_message
+      errors.add(:base, project_wiki.error_message) if project_wiki.error_message
       @persisted = false
     end
     @persisted
diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ce2d8093dff90f75b2c90efb5b743b6ed232bbe8
--- /dev/null
+++ b/app/services/delete_branch_service.rb
@@ -0,0 +1,46 @@
+class DeleteBranchService
+  def execute(project, branch_name, current_user)
+    repository = project.repository
+    branch = repository.find_branch(branch_name)
+
+    # No such branch
+    unless branch
+      return error('No such branch')
+    end
+
+    if branch_name == repository.root_ref
+      return error('Cannot remove HEAD branch')
+    end
+
+    # Dont allow remove of protected branch
+    if project.protected_branch?(branch_name)
+      return error('Protected branch cant be removed')
+    end
+
+    # Dont allow user to remove branch if he is not allowed to push
+    unless current_user.can?(:push_code, project)
+      return error('You dont have push access to repo')
+    end
+
+    if repository.rm_branch(branch_name)
+      Event.create_ref_event(project, current_user, branch, 'rm')
+      success('Branch was removed')
+    else
+      return error('Failed to remove branch')
+    end
+  end
+
+  def error(message)
+    {
+      message: message,
+      state: :error
+    }
+  end
+
+  def success(message)
+    {
+      message: message,
+      state: :success
+    }
+  end
+end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 351b446457dfdb2e0e0ec1cce1de31028e5b9bb3..715b5690751d6dea5a376d098615c2f715db7b4a 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -25,6 +25,7 @@ class GitPushService
 
     project.ensure_satellite_exists
     project.repository.expire_cache
+    project.update_repository_size
 
     if push_to_existing_branch?(ref, oldrev)
       project.update_merge_requests(oldrev, newrev, ref, @user)
diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb
index 4969198b8c2b080d5633cf887cc8ea8a16472006..41014f199d5d950c09c1f651d20c08b89d8b5ad4 100644
--- a/app/services/system_hooks_service.rb
+++ b/app/services/system_hooks_service.rb
@@ -31,7 +31,8 @@ class SystemHooksService
         path_with_namespace: model.path_with_namespace,
         project_id: model.id,
         owner_name: owner.name,
-        owner_email: owner.respond_to?(:email) ?  owner.email : nil
+        owner_email: owner.respond_to?(:email) ?  owner.email : nil,
+        project_visibility: Project.visibility_levels.key(model.visibility_level_field).downcase
       })
     when User
       data.merge!({
@@ -46,7 +47,8 @@ class SystemHooksService
         project_id: model.project_id,
         user_name: model.user.name,
         user_email: model.user.email,
-        project_access: model.human_access
+        project_access: model.human_access,
+        project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase
       })
     end
   end
diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml
index f28dadfb65924c9b9c9ca7f95e266a8efe564db4..c58ca2c9a33a0938c9b98bf24900ebb2a5ff624c 100644
--- a/app/views/admin/broadcast_messages/index.html.haml
+++ b/app/views/admin/broadcast_messages/index.html.haml
@@ -22,12 +22,12 @@
     = f.label :color, "Background Color", class: 'control-label'
     .col-sm-10
       = f.text_field :color, placeholder: "#AA33EE", class: "form-control"
-      .light Hex values as 3 double digit numbers, starting with a # sign.
+      .light 6 character hex values starting with a # sign.
   .form-group.js-toggle-colors-container.hide
     = f.label :font, "Font Color", class: 'control-label'
     .col-sm-10
       = f.text_field :font, placeholder: "#224466", class: "form-control"
-      .light Hex values as 3 double digit numbers, starting with a # sign.
+      .light 6 character hex values starting with a # sign.
   .form-group
     = f.label :starts_at, class: 'control-label'
     .col-sm-10.datetime-controls
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 296094ab29c88ff5c92ebf8c3e4b7c630fcbd482..51ad702154fdadcaef36255dbd0e6df15472c92b 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -32,6 +32,7 @@
                     = visibility_level_icon(level)
                     = label
         .form-actions
+          = hidden_field_tag :sort, params[:sort]
           = submit_tag "Search", class: "btn submit btn-primary"
           = link_to "Reset", admin_projects_path, class: "btn"
 
@@ -40,6 +41,28 @@
       .title
         Projects (#{@projects.total_count})
         .pull-right
+          .dropdown.inline
+            %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
+              %span.light sort:
+              - if @sort.present?
+                = @sort.humanize
+              - else
+                Name
+              %b.caret
+            %ul.dropdown-menu
+              %li
+                = link_to admin_projects_path(sort: nil) do
+                  Name
+                = link_to admin_projects_path(sort: 'newest') do
+                  Newest
+                = link_to admin_projects_path(sort: 'oldest') do
+                  Oldest
+                = link_to admin_projects_path(sort: 'recently_updated') do
+                  Recently updated
+                = link_to admin_projects_path(sort: 'last_updated') do
+                  Last updated
+                = link_to admin_projects_path(sort: 'largest_repository') do
+                  Largest repository
           = link_to 'New Project', new_project_path, class: "btn btn-new"
       %ul.well-list
         - @projects.each do |project|
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index 881a043f36f41993b62c69d98b32ccf8113f6b06..b9e6382ea885787103b2090539f590ed2a3e86bb 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -2,9 +2,9 @@
   = form_for [:admin, @user], html: { class: 'form-horizontal' } do |f|
     -if @user.errors.any?
       #error_explanation
-        %ul.unstyled.alert.alert-danger
+        .alert.alert-danger
           - @user.errors.full_messages.each do |msg|
-            %li= msg
+            %p= msg
 
     %fieldset
       %legend Account
diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml
index db5f3ebb00f8af186380418dc11352e798ec381a..ad2afbce14ca41507de0be04365437c2f5ea16dd 100644
--- a/app/views/events/event/_note.html.haml
+++ b/app/views/events/event/_note.html.haml
@@ -14,8 +14,8 @@
     - note = event.target
     - if note.attachment.url
       - if note.attachment.image?
-        = link_to note.attachment.url, target: '_blank' do
-          = image_tag note.attachment.url, class: 'note-image-attach'
+        = link_to note.attachment.secure_url, target: '_blank' do
+          = image_tag note.attachment.secure_url, class: 'note-image-attach'
       - else
         = link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do
           %i.icon-paper-clip
diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml
index bd4e3156af09b18e4f7e11b27f414cd72ff98742..41f8cb9da40bd53c656e3554b3ca74dc95ed9a68 100644
--- a/app/views/groups/_projects.html.haml
+++ b/app/views/groups/_projects.html.haml
@@ -8,7 +8,7 @@
           New project
   %ul.well-list
     - if projects.blank?
-      .nothing-here-block This groups has no projects yet
+      .nothing-here-block This group has no projects yet
     - projects.each do |project|
       %li.project-row
         = link_to project_path(project), class: dom_class(project) do
diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml
index 500c37ab71d41cafd1de8c482c273ad68dddb34f..2a5614cff6c39c2ba089d26af29c4c57c0540160 100644
--- a/app/views/groups/edit.html.haml
+++ b/app/views/groups/edit.html.haml
@@ -45,7 +45,7 @@
                     - if @group.avatar?
                       You can change your group avatar here
                     - else
-                      You can upload an group avatar here
+                      You can upload a group avatar here
                   %a.choose-btn.btn.btn-small.js-choose-group-avatar-button
                     %i.icon-paper-clip
                     %span Choose File ...
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 955a107e542701d4fb2f81cbc8e1fb156628d79e..ebf5e8571aa0b41a8ccc3058e968c390ffa07e83 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -13,6 +13,17 @@
     .col-sm-10
       = f.text_area :description, maxlength: 250, class: "form-control js-gfm-input", rows: 4
 
+  .form-group.group-description-holder
+    = f.label :avatar, "Group avatar", class: 'control-label'
+    .col-sm-10
+      %a.choose-btn.btn.btn-small.js-choose-group-avatar-button
+        %i.icon-paper-clip
+        %span Choose File ...
+      &nbsp;
+      %span.file_name.js-avatar-filename File name...
+      = f.file_field :avatar, class: "js-group-avatar-input hidden"
+      .light The maximum file size allowed is 100KB.
+
   .form-group
     .col-sm-2
     .col-sm-10
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 0343670c203c668b349b1997df9cb89f5e3a38b3..17475288a874c877d46076e2fb4e8b2972606999 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -1,11 +1,14 @@
 .dashboard
-  .activities.col-md-8.hidden-sm
+  .activities.col-md-8.hidden-sm.hidden-xs
     - if current_user
       = render "events/event_last_push", event: @last_push
       = link_to dashboard_path, class: 'btn btn-tiny' do
         &larr; To dashboard
       &nbsp;
-    %span.cgray You will only see events from projects in this group
+    %span.cgray 
+      Currently you are only seeing events from the
+      = @group.name
+      group
     %hr
     = render 'shared/event_filter'
     - if @events.any?
diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index d8001fd76d72f64b0151b95f619b293b882c3005..fba56b5dc3b413abbbb5d0a48658bb165f0737bf 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -19,6 +19,10 @@
           %li.visible-sm.visible-xs
             = link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do
               %i.icon-search
+          %li
+            = link_to help_path, title: 'Help', class: 'has_bottom_tooltip',
+               'data-original-title' => 'Help'  do
+              %i.icon-question-sign
           %li
             = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do
               %i.icon-globe
@@ -39,6 +43,6 @@
           %li
             = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout'  do
               %i.icon-signout
-          %li
+          %li.hidden-xs
             = link_to current_user, class: "profile-pic", id: 'profile-pic' do
               = image_tag avatar_icon(current_user.email, 26), alt: 'User activity'
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index c5041dd71b80e34700414847434af7700aa1ae76..5d93ffa50ad3521bd340db90d07b3dc6d64cfd5d 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -10,7 +10,7 @@
           %p.light
             GitLab is open source software to collaborate on code.
             %br
-            #{link_to "Sign in", new_user_session_path} or browse for #{link_to "public projects", public_projects_path}.
+            Sign in or browse for #{link_to "public projects", public_projects_path}.
     %hr
     .container
       .content
diff --git a/app/views/notify/closed_merge_request_email.html.haml b/app/views/notify/closed_merge_request_email.html.haml
index 809d46f31be0e02a8e0e4f3b891fce027118ce48..574e8bfef245a06fe81d8b1540ce683d5fc128de 100644
--- a/app/views/notify/closed_merge_request_email.html.haml
+++ b/app/views/notify/closed_merge_request_email.html.haml
@@ -1,2 +1,2 @@
 %p
-  = "Merge Request !#{@merge_request.iid} was closed by #{@updated_by.name}"
+  = "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}"
diff --git a/app/views/notify/closed_merge_request_email.text.haml b/app/views/notify/closed_merge_request_email.text.haml
index ee434ec8cb21cec7cebd6ab4d00e21edc947daee..d6b76e906c526184b60beeefc5e0ca23e06a3158 100644
--- a/app/views/notify/closed_merge_request_email.text.haml
+++ b/app/views/notify/closed_merge_request_email.text.haml
@@ -1,4 +1,4 @@
-= "Merge Request #{@merge_request.iid} was closed by #{@updated_by.name}"
+= "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}"
 
 Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
 
diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml
index 0c62d439aed18983fde7d70833b38a16f8cd64b4..6762fae7f64f3c7fd2c3394441341305572c6429 100644
--- a/app/views/notify/merged_merge_request_email.html.haml
+++ b/app/views/notify/merged_merge_request_email.html.haml
@@ -1,2 +1,2 @@
 %p
-  = "Merge Request !#{@merge_request.iid} was merged"
+  = "Merge Request ##{@merge_request.iid} was merged"
diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml
index 550f677fed49c8f3717e7aad6de900217b1205e3..360da60bc3f84028d161746b2dacba14d5b3b89b 100644
--- a/app/views/notify/merged_merge_request_email.text.haml
+++ b/app/views/notify/merged_merge_request_email.text.haml
@@ -1,4 +1,4 @@
-= "Merge Request #{@merge_request.iid} was merged"
+= "Merge Request ##{@merge_request.iid} was merged"
 
 Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
 
diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml
index b8d7fbeb046d660d21a409f2b69ae75cc06fe494..a15b8efe1f7640018e2c7deb69e84c2b5dd34702 100644
--- a/app/views/notify/repository_push_email.text.haml
+++ b/app/views/notify/repository_push_email.text.haml
@@ -17,7 +17,7 @@ Changes:
   - else
     = diff.new_path || diff.old_path
   \=====================================
-  = diff.diff
+  != diff.diff
 \
 - if @compare.timeout
   Huge diff. To prevent performance issues it was hidden
diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml
index e59d970bf46e21e184f310b9bef6f4c669ad3737..863e4e3de53cea66d09125fa4090fbf82af81299 100644
--- a/app/views/projects/blob/_blob.html.haml
+++ b/app/views/projects/blob/_blob.html.haml
@@ -15,18 +15,18 @@
       - else
         = link_to title, '#'
 
-%ul.blob-commit-info.bs-callout.bs-callout-info
+%ul.blob-commit-info.bs-callout.bs-callout-info.hidden-xs
   - blob_commit = @repository.last_commit_for_path(@commit.id, @blob.path)
   = render blob_commit, project: @project
 
 %div#tree-content-holder.tree-content-holder
   .file-holder
-    .file-title
+    .file-title.clearfix
       %i.icon-file
       %span.file_name
         = blob.name
         %small= number_to_human_size blob.size
-      %span.options= render "actions"
+      %span.options.hidden-xs= render "actions"
     - if blob.text?
       = render "text", blob: blob
     - elsif blob.image?
diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml
index 6384703671aee38e3b1ce0758d84b691cb96b2d2..692248dd2333bb0a5fb8acf856f06d1e172c0397 100644
--- a/app/views/projects/blob/_remove.html.haml
+++ b/app/views/projects/blob/_remove.html.haml
@@ -14,7 +14,8 @@
             = label_tag 'commit_message', class: "control-label" do
               Commit message
             .col-sm-10
-              = text_area_tag 'commit_message', params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3, class: 'form-control'
+              = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message',
+                  params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3, class: 'form-control')}
           .form-group
             .col-sm-2
             .col-sm-10
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index f0731977098b52e0433ce9850ba2e967f0424ef2..87f4dd88c27e04dc212f1fadcd1aabcdafa3e4e6 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -16,8 +16,8 @@
           %i.icon-copy
           Compare
 
-      - if can?(current_user, :admin_project, @project) && branch.name != @repository.root_ref
-        = link_to project_branch_path(@project, branch.name), class: 'btn btn-grouped btn-small remove-row', method: :delete, data: { confirm: 'Removed branch cannot be restored. Are you sure?'}, remote: true do
+      - if can_remove_branch?(@project, branch.name)
+        = link_to project_branch_path(@project, branch.name), class: 'btn btn-grouped btn-small btn-remove remove-row', method: :delete, data: { confirm: 'Removed branch cannot be restored. Are you sure?'}, remote: true do
           %i.icon-trash
 
   - if commit
diff --git a/app/views/projects/commits/_parallel_view.html.haml b/app/views/projects/commits/_parallel_view.html.haml
index 5b60ab80ba45dd8111f49b50225ebde0ce0c28f0..80f5be98f2f9a70b748ac5ec173a600608082d56 100644
--- a/app/views/projects/commits/_parallel_view.html.haml
+++ b/app/views/projects/commits/_parallel_view.html.haml
@@ -2,54 +2,37 @@
 - old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file)
 - num_lines = old_lines.length
 
-%div.text-file-parallel
-  %div.diff-side.diff-side-left
-    %table
-      - old_lines.each do |line|
+%div.text-file
+  %table
+    - num_lines.times do |index|
+      - new_line = new_lines[index]
+      - old_line = old_lines[index]
+      %tr.line_holder.parallel
+        -# For old line
+        - if old_line.type == :file_created
+          %td.old_line= old_line.num
+          %td.line_content.parallel= "File was created"
+        - elsif old_line.type == :deleted
+          %td.old_line.old= old_line.num
+          %td.line_content{class: "parallel noteable_line old #{old_line.code}", "line_code" => old_line.code}= old_line.content
+        - else old_line.type == :no_change
+          %td.old_line= old_line.num
+          %td.line_content.parallel= old_line.content
+
+        -# For new line
+        - if new_line.type == :file_deleted
+          %td.new_line= new_line.num
+          %td.line_content.parallel= "File was deleted"
+        - elsif new_line.type == :added
+          %td.new_line.new= new_line.num
+          %td.line_content{class: "parallel noteable_line new #{new_line.code}", "line_code" => new_line.code}= new_line.content
+        - else new_line.type == :no_change
+          %td.new_line= new_line.num
+          %td.line_content.parallel= new_line.content
+
+      - if @reply_allowed
+        - comments1 = @line_notes.select { |n| n.line_code == old_line.code }.sort_by(&:created_at)
+        - comments2 = @line_notes.select { |n| n.line_code == new_line.code }.sort_by(&:created_at)
+        - unless comments1.empty? and comments2.empty?
+          = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2
 
-        %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 new_lines[index].type == :added
-            %td.new_line.new= new_lines[index].num
-          - else
-            %td.new_line= new_lines[index].num
-
-  %div.diff-side.diff-side-right
-    %table
-      - new_lines.each do |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
-
-:javascript
-  $('.diff-side-right').on('scroll', function(){
-    $('.diff-side-left, .diff-middle').scrollTop($(this).scrollTop());
-    $('.diff-side-left').scrollLeft($(this).scrollLeft());
-  });
-
-  $('.diff-side-left').on('scroll', function(){
-    $('.diff-side-right, .diff-middle').scrollTop($(this).scrollTop()); // might never be relevant
-    $('.diff-side-right').scrollLeft($(this).scrollLeft());
-  });
diff --git a/app/views/projects/edit_tree/_diff.html.haml b/app/views/projects/edit_tree/_diff.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..cf044feb9a440b8a010dda01f67d5ea8eb4c705c
--- /dev/null
+++ b/app/views/projects/edit_tree/_diff.html.haml
@@ -0,0 +1,13 @@
+%table.text-file
+  - each_diff_line(diff, 1) do |line, type, line_code, line_new, line_old, raw_line|
+    %tr.line_holder{ id: line_code, class: "#{type}" }
+      - if type == "match"
+        %td.old_line= "..."
+        %td.new_line= "..."
+        %td.line_content.matched= line
+      - else
+        %td.old_line
+          = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
+        %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
+        %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
+
diff --git a/app/views/projects/edit_tree/preview.html.haml b/app/views/projects/edit_tree/preview.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..340f68cc05c4fe229ed4feddd9fb1a86fef324b8
--- /dev/null
+++ b/app/views/projects/edit_tree/preview.html.haml
@@ -0,0 +1,26 @@
+.diff-file
+  .diff-content
+    - if gitlab_markdown?(@blob.name)
+      .file-content.wiki
+        = preserve do
+          = markdown(@content)
+    - elsif markup?(@blob.name)
+      .file-content.wiki
+        = raw GitHub::Markup.render(@blob.name, @content)
+    - else
+      .file-content.code
+        - unless @diff.empty?
+          %table.text-file
+            - @diff.each do |line, type, line_code, line_new, line_old, raw_line|
+              %tr.line_holder{ id: line_code, class: "#{type}" }
+                - if type == "match"
+                  %td.old_line= "..."
+                  %td.new_line= "..."
+                  %td.line_content.matched= line
+                - else
+                  %td.old_line
+                    = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
+                  %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
+                  %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
+        - else
+          .nothing-here-block No changes.
diff --git a/app/views/projects/edit_tree/show.html.haml b/app/views/projects/edit_tree/show.html.haml
index 3f2e98f3a7f634778cc6bd794e0426d0862ed716..32a6d4ef36ed97cf2ac16233bd6c8ad9c26169fb 100644
--- a/app/views/projects/edit_tree/show.html.haml
+++ b/app/views/projects/edit_tree/show.html.haml
@@ -1,25 +1,33 @@
-%h3.page-title Edit mode
 .file-editor
+  %ul.nav.nav-tabs.js-edit-mode
+    %li.active
+      = link_to 'Edit', '#editor'
+    %li
+      = link_to editing_preview_title(@blob.name), '#preview', 'data-preview-url' => preview_project_edit_tree_path(@project, @id)
+
   = form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do
-    .file-holder
+    .file-holder.file
       .file-title
         %i.icon-file
         %span.file_name
+          %span.monospace.light #{@ref}:
           = @path
-          %small
-            on
-            %strong= @ref
         %span.options
           .btn-group.tree-btn-group
             = link_to "Cancel", @after_edit_path, class: "btn btn-tiny btn-cancel", data: { confirm: leave_edit_message }
       .file-content.code
-        %pre#editor= @blob.data
+        %pre.js-edit-mode-pane#editor= @blob.data
+        .js-edit-mode-pane#preview.hide
+          %center
+            %h2
+              %i.icon-spinner.icon-spin
 
     .form-group.commit_message-group
       = label_tag 'commit_message', class: "control-label" do
         Commit message
       .col-sm-10
-        = text_area_tag 'commit_message', '', placeholder: "Update #{@blob.name}", required: true, rows: 3, class: 'form-control'
+        = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message', '',
+            placeholder: "Update #{@blob.name}", required: true, rows: 3, class: 'form-control')}
     .form-actions
       = hidden_field_tag 'last_commit', @last_commit
       = hidden_field_tag 'content', '', id: "file-content"
@@ -45,3 +53,28 @@
     $("#file-content").val(editor.getValue());
     $(".file-editor form").submit();
   });
+
+  var editModePanes = $('.js-edit-mode-pane'),
+      editModeLinks = $('.js-edit-mode a');
+
+  editModeLinks.click(function(event) {
+    event.preventDefault();
+
+    var currentLink = $(this),
+        paneId = currentLink.attr('href'),
+        currentPane = editModePanes.filter(paneId);
+
+    editModeLinks.parent().removeClass('active hover');
+    currentLink.parent().addClass('active hover');
+    editModePanes.hide();
+
+    if (paneId == '#preview') {
+      currentPane.fadeIn(200);
+      $.post(currentLink.data('preview-url'), { content: editor.getValue() }, function(response) {
+        currentPane.empty().append(response);
+      })
+    } else {
+      currentPane.fadeIn(200);
+      editor.focus()
+    }
+  })
diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml
index aae101cf40f6ee78b8895e5b43dd7255db73ed88..425dcb45ddf6dea0b2021f9ec73d7eed20b7cd3d 100644
--- a/app/views/projects/issues/_issue_context.html.haml
+++ b/app/views/projects/issues/_issue_context.html.haml
@@ -1,22 +1,24 @@
 = form_for [@project, @issue], remote: true, html: {class: 'edit-issue inline-update'} do |f|
-  %strong.append-right-10
-    Assignee:
+  .row
+    .col-md-6
+      %strong.append-right-10
+        Assignee:
 
-  - if can?(current_user, :modify_issue, @issue)
-    = project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @issue.assignee_id)
-  - elsif issue.assignee
-    = link_to_member(@project, @issue.assignee)
-  - else
-    None
+      - if can?(current_user, :modify_issue, @issue)
+        = project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @issue.assignee_id)
+      - elsif issue.assignee
+        = link_to_member(@project, @issue.assignee)
+      - else
+        None
 
-  .pull-right
-    %strong.append-right-10
-      Milestone:
-    - if can?(current_user, :modify_issue, @issue)
-      = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone (none):" }, {class: 'select2 select2-compact'})
-      = hidden_field_tag :issue_context
-      = f.submit class: 'btn'
-    - elsif issue.milestone
-      = link_to issue.milestone.title, project_milestone_path
-    - else
-      None
+    .col-md-6.text-right
+      %strong.append-right-10
+        Milestone:
+      - if can?(current_user, :modify_issue, @issue)
+        = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact'})
+        = hidden_field_tag :issue_context
+        = f.submit class: 'btn'
+      - elsif issue.milestone
+        = link_to issue.milestone.title, project_milestone_path
+      - else
+        None
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 5e899d412c6ad6b9a7c64649528036d4cf7614f3..51a8c911af8a457df5b7bad48e1362b730d4763b 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -1,6 +1,7 @@
 = render "head"
 .row
   .col-md-3
-    = render 'shared/project_filter', project_entities_path: project_issues_path(@project), labels: true
+    = render 'shared/project_filter', project_entities_path: project_issues_path(@project),
+             labels: true, redirect: 'issues'
   .col-md-9.issues-holder
     = render "issues"
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 124eb53571d2228be485848a9d6b04deba998cda..b6d3a8edf4da9a22cfb07d8614ac613ea888ddab 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -1,7 +1,7 @@
 %h3.page-title
   Issue ##{@issue.iid}
 
-  %span.pull-right
+  %span.pull-right.issue-btn-group
     - if can?(current_user, :write_issue, @project)
       = link_to new_project_issue_path(@project), class: "btn btn-grouped", title: "New Issue", id: "new_issue_link" do
         %i.icon-plus
@@ -16,28 +16,29 @@
         %i.icon-edit
         Edit
 
-.votes-holder
-  #votes= render 'votes/votes_block', votable: @issue
+.clearfix
+  .votes-holder
+    #votes= render 'votes/votes_block', votable: @issue
 
-.back-link
-  = link_to project_issues_path(@project) do
-    &larr; To issues list
-  %span.milestone-nav-link
-    - if @issue.milestone
-      |
-      %span.light Milestone
-      = link_to project_milestone_path(@project, @issue.milestone) do
-        = @issue.milestone.title
+  .back-link
+    = link_to project_issues_path(@project) do
+      &larr; To issues list
+    %span.milestone-nav-link
+      - if @issue.milestone
+        |
+        %span.light Milestone
+        = link_to project_milestone_path(@project, @issue.milestone) do
+          = @issue.milestone.title
 
 .issue-box{ class: issue_box_class(@issue) }
-  .state
-    %span.state-label
+  .state.clearfix
+    .state-label.col-sm-2.col-xs-12
       - if @issue.closed?
         Closed
       - else
         Open
 
-    %span.creator
+    %span.creator.col-sm-9.col-xs-12
       Created by #{link_to_member(@project, @issue.author)} #{time_ago_with_tooltip(@issue.created_at)}
 
   %h4.title
diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml
index 0fe2d1d98014178096f9b52670b4276536d4ce6b..290a15e2664d5874f2e75a097bfd36d61fa35489 100644
--- a/app/views/projects/merge_requests/_form.html.haml
+++ b/app/views/projects/merge_requests/_form.html.haml
@@ -14,33 +14,6 @@
           - @merge_request.errors.full_messages.each do |msg|
             %div= msg
 
-  .merge-request-branches
-    .form-group
-      = label_tag nil, class: 'control-label' do
-        From
-      .col-sm-10
-        .clearfix
-          .pull-left
-            = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted? })
-          .pull-left
-            &nbsp;
-            = f.select(:source_branch, @merge_request.source_branches, { include_blank: "Select branch" }, {class: 'source_branch select2 span2'})
-        .mr_source_commit
-    %br
-    .form-group
-      = label_tag nil, class: 'control-label' do
-        To
-      .col-sm-10
-        .clearfix
-          .pull-left
-            - projects =  @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project]
-            = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace', f.object.target_project_id), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted? })
-          .pull-left
-            &nbsp;
-            = f.select(:target_branch, @merge_request.target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2'})
-        .mr_target_commit
-
-  %hr
   .merge-request-form-info
     .form-group
       = f.label :title, class: 'control-label' do
@@ -51,6 +24,32 @@
       .col-sm-10
         = f.text_area :description, class: "form-control js-gfm-input", rows: 14
         %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
+    %hr
+    .form-group
+      .issue-assignee
+        = f.label :assignee_id, class: 'control-label' do
+          %i.icon-user
+          Assign to
+        .col-sm-10
+          = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id)
+          &nbsp;
+          = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link'
+    .form-group
+      .issue-milestone
+        = f.label :milestone_id, class: 'control-label' do
+          %i.icon-time
+          Milestone
+        .col-sm-10= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'})
+
+
+    - if @merge_request.persisted? # Only allow labels on edit to avoid fork vs upstream repo labels issue
+      .form-group
+        = f.label :label_list, class: 'control-label' do
+          %i.icon-tag
+          Labels
+        .col-sm-10
+          = f.text_field :label_list, maxlength: 2000, class: "form-control"
+          %p.hint Separate labels with commas.
 
   .form-actions
     - if @merge_request.new_record?
@@ -66,20 +65,36 @@
 
 :javascript
   disableButtonIfEmptyField("#merge_request_title", ".btn-save");
-
-  var source_branch = $("#merge_request_source_branch")
-    , target_branch = $("#merge_request_target_branch")
-    , target_project = $("#merge_request_target_project_id");
-
-  $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: source_branch.val() });
-  $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: target_branch.val() });
-
-  target_project.on("change", function() {
-    $.get("#{update_branches_project_merge_requests_path(@source_project)}", {target_project_id:  $(this).val() });
-  });
-  source_branch.on("change", function() {
-    $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: $(this).val() });
-  });
-  target_branch.on("change", function() {
-    $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() });
+  $('.assign-to-me-link').on('click', function(e){
+    $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
+    e.preventDefault();
   });
+
+  $("#merge_request_label_list")
+    .bind( "keydown", function( event ) {
+      if ( event.keyCode === $.ui.keyCode.TAB &&
+        $( this ).data( "autocomplete" ).menu.active ) {
+        event.preventDefault();
+      }
+    })
+    .bind("click", function(event) {
+      $(this).autocomplete("search", "");
+    })
+    .autocomplete({
+      minLength: 0,
+      source: function( request, response ) {
+        response( $.ui.autocomplete.filter(
+          #{raw labels_autocomplete_source}, extractLast( request.term ) ) );
+      },
+      focus: function() {
+        return false;
+      },
+      select: function(event, ui) {
+        var terms = split( this.value );
+        terms.pop();
+        terms.push( ui.item.value );
+        terms.push( "" );
+        this.value = terms.join( ", " );
+        return false;
+      }
+    });
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 980ac12674237751c670a1bc8f36d761d970a21e..c9a80ec22ef1ff055d03caabd6cd1a92667871aa 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -11,13 +11,9 @@
         - if merge_request.for_fork?
           %span.light
             #{merge_request.source_project_namespace}:
-          = merge_request.source_branch
-          %i.icon-angle-right.light
-          = merge_request.target_branch
-        - else
-          = merge_request.source_branch
-          %i.icon-angle-right.light
-          = merge_request.target_branch
+        = truncate merge_request.source_branch, length: 25
+        %i.icon-angle-right.light
+        = merge_request.target_branch
   .merge-request-info
     - if merge_request.author
       authored by #{link_to_member(merge_request.source_project, merge_request.author)}
@@ -35,3 +31,9 @@
 
     .pull-right
       %small updated #{time_ago_with_tooltip(merge_request.updated_at, 'bottom', 'merge_request_updated_ago')}
+
+    .merge-request-labels
+      - merge_request.labels.each do |label|
+        %span{class: "label #{label_css_class(label.name)}"}
+          %i.icon-tag
+          = label.name
diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..a8b774a3cd1ce58bcc497caaf951cb782ed0182b
--- /dev/null
+++ b/app/views/projects/merge_requests/_new_compare.html.haml
@@ -0,0 +1,84 @@
+%h3.page-title Compare branches for new Merge Request
+%hr
+
+= form_for [@project, @merge_request], url: new_project_merge_request_path(@project), method: :get, html: { class: "merge-request-form form-inline" } do |f|
+  .hide.alert.alert-danger.mr-compare-errors
+  .merge-request-branches.row
+    .col-md-6
+      .panel.panel-default
+        .panel-heading
+          %strong Source branch
+        .panel-body
+          = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted? })
+          &nbsp;
+          = f.select(:source_branch, @merge_request.source_branches, { include_blank: "Select branch" }, {class: 'source_branch select2 span2'})
+        .panel-footer
+          .mr_source_commit
+
+    .col-md-6
+      .panel.panel-default
+        .panel-heading
+          %strong Target branch
+        .panel-body
+          - projects =  @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project]
+          = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace', f.object.target_project_id), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted? })
+          &nbsp;
+          = f.select(:target_branch, @merge_request.target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2'})
+        .panel-footer
+          .mr_target_commit
+
+  -if @merge_request.errors.any?
+    .alert.alert-danger
+      - @merge_request.errors.full_messages.each do |msg|
+        %div= msg
+
+  - if @merge_request.source_branch.present? && @merge_request.target_branch.present?
+    .light-well
+      %center
+        %h4
+          There isn't anything to merge.
+        %p.slead
+          - if @merge_request.source_branch == @merge_request.target_branch
+            You'll need to use different branch names to get a valid comparison.
+          - else
+            %span.label-branch #{@merge_request.source_branch}
+            and
+            %span.label-branch #{@merge_request.target_branch}
+            are the same.
+
+
+  %hr
+  = f.submit 'Compare branches', class: "btn btn-primary mr-compare-btn"
+
+:javascript
+  var source_branch = $("#merge_request_source_branch")
+    , target_branch = $("#merge_request_target_branch")
+    , target_project = $("#merge_request_target_project_id");
+
+  $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: source_branch.val() });
+  $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: target_branch.val() });
+
+  target_project.on("change", function() {
+    $.get("#{update_branches_project_merge_requests_path(@source_project)}", {target_project_id:  $(this).val() });
+  });
+  source_branch.on("change", function() {
+    $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: $(this).val() });
+    $(".mr-compare-errors").fadeOut();
+    $(".mr-compare-btn").enable();
+  });
+  target_branch.on("change", function() {
+    $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() });
+    $(".mr-compare-errors").fadeOut();
+    $(".mr-compare-btn").enable();
+  });
+
+
+:coffeescript
+
+  $(".merge-request-form").on 'submit', ->
+    if $("#merge_request_source_branch").val() is "" or $('#merge_request_target_branch').val() is ""
+      $(".mr-compare-errors").html("You must select source and target branch to proceed")
+      $(".mr-compare-errors").fadeIn()
+      event.preventDefault()
+      return
+
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..b5479be708b4d39ace998377743dd8d9f4e8e97a
--- /dev/null
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -0,0 +1,82 @@
+%h3.page-title
+  New merge request
+%p.slead
+  From
+  %strong.monospace
+    #{@merge_request.source_project_namespace}:#{@merge_request.source_branch}
+  into
+  %strong.monospace
+    #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
+
+  %span.pull-right
+    = link_to 'Change branches', new_project_merge_request_path(@project)
+
+= form_for [@project, @merge_request], html: { class: "merge-request-form" } do |f|
+  .panel.panel-default
+
+    .panel-body
+      .form-group
+        .light
+          = f.label :title do
+            = "Title *"
+        = f.text_field :title, class: "form-control input-lg js-gfm-input", maxlength: 255, rows: 5, required: true
+      .form-group
+        .light
+          = f.label :description, "Description"
+        = f.text_area :description, class: "form-control js-gfm-input", rows: 10
+        %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
+      .form-group
+        .issue-assignee
+          = f.label :assignee_id do
+            %i.icon-user
+            Assign to
+          %div
+            = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id, project_id: @merge_request.target_project_id)
+            &nbsp;
+            = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link'
+      .form-group
+        .issue-milestone
+          = f.label :milestone_id do
+            %i.icon-time
+            Milestone
+          %div= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'})
+    .panel-footer
+      - if @target_repo.contribution_guide
+        - contribution_guide_url = project_blob_path(@target_project, tree_join(@target_repo.root_ref, @target_repo.contribution_guide.name))
+        %p
+          Please review the
+          %strong #{link_to "guidelines for contribution", contribution_guide_url}
+          to this repository.
+      = f.hidden_field :source_project_id
+      = f.hidden_field :target_project_id
+      = f.hidden_field :target_branch
+      = f.hidden_field :source_branch
+      = f.submit 'Submit merge request', class: "btn btn-create"
+
+.mr-compare
+  %div.ui-box
+    .title
+      Commits (#{@commits.count})
+    - if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
+      %ul.well-list
+        - Commit.decorate(@commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE)).each do |commit|
+          = render "projects/commits/inline_commit", commit: commit, project: @project
+        %li.warning-row.unstyled
+          other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden to prevent performance issues.
+    - else
+      %ul.well-list= render Commit.decorate(@commits), project: @project
+
+  %h4 Changes
+  - if @diffs.present?
+    = render "projects/commits/diffs", diffs: @diffs, project: @project
+  - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
+    .bs-callout.bs-callout-danger
+      %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
+      %p To preserve performance the line changes are not shown.
+
+
+:javascript
+  $('.assign-to-me-link').on('click', function(e){
+    $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
+    e.preventDefault();
+  });
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index e36a48f62cf47de480db5612e09fcd9303509907..193c600f7745e015eab353a5c1067d3811aeb8ce 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -4,6 +4,7 @@
   = render "projects/merge_requests/show/mr_box"
   = render "projects/merge_requests/show/state_widget"
   = render "projects/merge_requests/show/commits"
+  = render "projects/merge_requests/show/participants"
 
   - if @commits.present?
     %ul.nav.nav-tabs
diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml
index 693c2057a0f8d1514f74775bd80605b2ca3d07c0..8372afa61b53b4cb5eb1de3615f725ec2b48cf93 100644
--- a/app/views/projects/merge_requests/branch_from.js.haml
+++ b/app/views/projects/merge_requests/branch_from.js.haml
@@ -1,7 +1,2 @@
 :plain
   $(".mr_source_commit").html("#{commit_to_html(@commit, @source_project, false)}");
-  var mrTitle = $('#merge_request_title');
-
-  if(mrTitle.val().length == 0) {
-    mrTitle.val("#{params[:ref].titleize.humanize}");
-  }
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 34faebf619c6faebd57f4e833eeaf07b7e79f9b0..12a72edb2248905bd4619068174c5af3295979ea 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -8,7 +8,8 @@
 %hr
 .row
   .col-md-3
-    = render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project)
+    = render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project),
+             labels: true, redirect: 'merge_requests'
   .col-md-9
     .mr-filters.append-bottom-10
       .dropdown.inline
diff --git a/app/views/projects/merge_requests/new.html.haml b/app/views/projects/merge_requests/new.html.haml
index 8ee0e1a8d46a2d7feddf750889d03a9af9feefdf..c24e591672167850ae20be1f59f739af15ef4710 100644
--- a/app/views/projects/merge_requests/new.html.haml
+++ b/app/views/projects/merge_requests/new.html.haml
@@ -1,3 +1,4 @@
-%h3.page-title New Merge Request
-%hr
-= render 'form'
+- if @commits.present?
+  = render 'new_submit'
+- else
+  = render 'new_compare'
diff --git a/app/views/projects/merge_requests/show/_context.html.haml b/app/views/projects/merge_requests/show/_context.html.haml
index 2bd850426a907fb47b1bc90849be06b79c027c9d..5c6734fd24be3ede39a81eb12bce34410da987db 100644
--- a/app/views/projects/merge_requests/show/_context.html.haml
+++ b/app/views/projects/merge_requests/show/_context.html.haml
@@ -1,22 +1,24 @@
 = form_for [@project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update'} do |f|
-  %strong.append-right-10
-    Assignee:
+  .row
+    .col-md-6
+      %strong.append-right-10
+        Assignee:
 
-  - if can?(current_user, :modify_merge_request, @merge_request)
-    = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @merge_request.assignee_id)
-  - elsif merge_request.assignee
-    = link_to_member(@project, @merge_request.assignee)
-  - else
-    None
+      - if can?(current_user, :modify_merge_request, @merge_request)
+        = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @merge_request.assignee_id)
+      - elsif merge_request.assignee
+        = link_to_member(@project, @merge_request.assignee)
+      - else
+        None
 
-  .pull-right
-    %strong.append-right-10
-      Milestone:
-    - if can?(current_user, :modify_merge_request, @merge_request)
-      = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone (none):" }, {class: 'select2 select2-compact'})
-      = hidden_field_tag :merge_request_context
-      = f.submit class: 'btn'
-    - elsif merge_request.milestone
-      = link_to merge_request.milestone.title, project_milestone_path
-    - else
-      None
+    .col-md-6.text-right
+      %strong.append-right-10
+        Milestone:
+      - if can?(current_user, :modify_merge_request, @merge_request)
+        = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact'})
+        = hidden_field_tag :merge_request_context
+        = f.submit class: 'btn'
+      - elsif merge_request.milestone
+        = link_to merge_request.milestone.title, project_milestone_path
+      - else
+        None
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 6594709f2ae5a1f239b2dd024ac9de78a8d2a879..1276489c2d9e85d113424f357d4a822c3dc9c543 100644
--- a/app/views/projects/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml
@@ -12,7 +12,7 @@
 - if @show_merge_controls
   .automerge_widget.can_be_merged.hide
     .clearfix
-      = form_for [:automerge, @project, @merge_request], remote: true, method: :get do |f|
+      = form_for [:automerge, @project, @merge_request], remote: true, method: :post do |f|
         %h4
           You can accept this request automatically.
         %div
@@ -21,7 +21,6 @@
             = link_to "click here", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
           for instructions.
 
-
         .js-toggle-container
           %p
             If you want to modify merge commit message -
@@ -31,7 +30,8 @@
             .form-group
               = label_tag :merge_commit_message, "Commit message", class: 'control-label'
               .col-sm-10
-                = text_area_tag :merge_commit_message, @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true
+                = render 'shared/commit_message_container', {textarea: text_area_tag(:merge_commit_message,
+                    @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true)}
                 %p.hint
                   The recommended maximum line length is 52 characters for the first line and 72 characters for all following lines.
 
diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml
index 8855982a2e752c7ca80dc0c637d960d01a83ab5a..435e916c6dcafb8aca6df7f136eb057b4e205d44 100644
--- a/app/views/projects/merge_requests/show/_mr_box.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_box.html.haml
@@ -1,6 +1,6 @@
 .issue-box{ class: issue_box_class(@merge_request) }
-  .state
-    %span.state-label
+  .state.clearfix
+    %span.state-label.col-sm-2.col-xs-12
       - if @merge_request.merged?
         Merged
       - elsif @merge_request.closed?
@@ -8,7 +8,7 @@
       - else
         Open
 
-    %span.creator
+    %span.creator.col-sm-9.col-xs-12
       Created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)}
 
   %h4.title
diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml
index c175d2f6b4005f3a81411b483963285bd9c8d986..507a9e507f1d880282b3e301451ff22e0bb6dc45 100644
--- a/app/views/projects/merge_requests/show/_mr_ci.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_ci.html.haml
@@ -26,4 +26,4 @@
 
   .ci_widget.ci-error{style: "display:none"}
     %i.icon-remove
-    %strong Cannot connect to CI server. Please check your setting
+    %strong Cannot connect to the CI server. Please check your settings and try again.
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 7676fc137c7b35e6044a033916ad2409db2f0744..2c905413bc3846b113ec2e222f50a37e7d2f0f80 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_title.html.haml
@@ -1,7 +1,7 @@
 %h3.page-title
   = "Merge Request ##{@merge_request.iid}"
 
-  %span.pull-right
+  %span.pull-right.issue-btn-group
     - if can?(current_user, :modify_merge_request, @merge_request)
       - if @merge_request.open?
         .btn-group.pull-left
@@ -39,4 +39,4 @@
     - else
       %span= @merge_request.source_branch
       &rarr;
-      %spanh= @merge_request.target_branch
+      %span= @merge_request.target_branch
diff --git a/app/views/projects/merge_requests/show/_participants.html.haml b/app/views/projects/merge_requests/show/_participants.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..0dabd965e52379a642308db945a40b7ff5cb0310
--- /dev/null
+++ b/app/views/projects/merge_requests/show/_participants.html.haml
@@ -0,0 +1,11 @@
+.participants
+  %cite.cgray #{@merge_request.participants.count} participants
+  - @merge_request.participants.each do |participant|
+    = link_to_member(@project, participant, name: false, size: 24)
+
+  .merge-request-show-labels.pull-right
+    - @merge_request.labels.each do |label|
+      %span{class: "label #{label_css_class(label.name)}"}
+        %i.icon-tag
+        = label.name
+      &nbsp;
diff --git a/app/views/projects/merge_requests/show/_state_widget.html.haml b/app/views/projects/merge_requests/show/_state_widget.html.haml
index c9ecbceaf5459fc95251bab3ebca1e2b61a97450..80fe540489bbfbe9d13369a99f9e4572a16dc7b9 100644
--- a/app/views/projects/merge_requests/show/_state_widget.html.haml
+++ b/app/views/projects/merge_requests/show/_state_widget.html.haml
@@ -21,14 +21,6 @@
         #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}
       = render "projects/merge_requests/show/remove_source_branch"
 
-    - if !@closes_issues.empty? && @merge_request.open?
-      .alert.alert-info.alert-info
-        %span
-          %i.icon-ok
-          Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'}
-          = succeed '.' do
-            != gfm(@closes_issues.map { |i| "##{i.iid}" }.to_sentence)
-
     - unless @commits.any?
       %h4 Nothing to merge
       %p
@@ -38,3 +30,12 @@
         %span.label-branch #{@merge_request.target_branch}
         %br
         Try to use different branches or push new code.
+
+  - if !@closes_issues.empty? && @merge_request.open?
+    .panel-footer
+      %span
+        %i.icon-ok
+        Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'}
+        = succeed '.' do
+          != gfm(@closes_issues.map { |i| "##{i.iid}" }.to_sentence)
+
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 06cf9946784d5c5a657ecac371c10b70d4d067cb..0fe5ac25b5e01c88c3598218264480e63f1bda69 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -1,8 +1,6 @@
 = render "projects/issues/head"
 %h3.page-title
   Milestone ##{@milestone.iid}
-  %small
-    = @milestone.expires_at
   .pull-right
     - if can?(current_user, :admin_milestone, @project)
       = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped" do
@@ -23,14 +21,16 @@
 
 
 .issue-box{ class: issue_box_class(@milestone) }
-  .state
-    %span.state-label
+  .state.clearfix
+    .state-label.col-sm-2.col-xs-12
       - if @milestone.closed?
         Closed
       - elsif @milestone.expired?
         Expired
       - else
         Open
+    %span.creator.col-sm-9.col-xs-12
+      = @milestone.expires_at
 
   %h4.title
     = gfm escape_once(@milestone.title)
@@ -100,7 +100,7 @@
     %ul.bordered-list
       - @users.each do |user|
         %li
-          = link_to user, title: user.name, class: "dark" do
+          = link_to user, title: user.name, class: "darken" do
             = image_tag avatar_icon(user.email, 32), class: "avatar s32"
             %strong= truncate(user.name, lenght: 40)
             %br
diff --git a/app/views/projects/new_tree/show.html.haml b/app/views/projects/new_tree/show.html.haml
index 9d7c7afbeac2c4cba10624998a3054eb851a4efc..9ecbbe7508e220f0a2ee4a3121b4dc8416542146 100644
--- a/app/views/projects/new_tree/show.html.haml
+++ b/app/views/projects/new_tree/show.html.haml
@@ -24,7 +24,8 @@
       = label_tag 'commit_message', class: "control-label" do
         Commit message
       .col-sm-10
-        = text_area_tag 'commit_message', params[:commit_message], placeholder: "Added new file", required: true, rows: 3, class: 'form-control'
+        = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message',
+            params[:commit_message], placeholder: "Added new file", required: true, rows: 3, class: 'form-control')}
 
     .file-holder
       .file-title
diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
index 2012aa021b9158ef4b6f152a7f54f180d00fefed..399ce30d1a961ab3fadc5103caf490bfdb032530 100644
--- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
+++ b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
@@ -1,34 +1,33 @@
 - note1 = notes1.first # example note
 - note2 = notes2.first # example note
+-# Check if line want not changed since comment was left
+/- if !defined?(line) || line == note.diff_line
 %tr.notes_holder.js-toggle-content
-  -# Check if line want not changed since comment was left
-  /- if !defined?(line1) || line1 == note1.diff_line
   - if note1
+    %td.notes_line
+      %span.btn.disabled
+        %i.icon-comment
+        = notes1.count
     %td.notes_content
       %ul.notes{ rel: note1.discussion_id }
         = render notes1
+
       = render "projects/notes/discussion_reply_button", note: note1
-    %td.notes_line2
-      %span.btn.disabled.parallel-comment
-        %i.icon-comment
-        = notes1.count
   - else
     %td= ""
     %td= ""
 
-  %td= ""
-
-  -# Check if line want not changed since comment was left
-  /- if !defined?(line2) || line2 == note2.diff_line
   - if note2
     %td.notes_line
-      %span.btn.disabled.parallel-comment
+      %span.btn.disabled
         %i.icon-comment
         = notes2.count
     %td.notes_content
       %ul.notes{ rel: note2.discussion_id }
         = render notes2
+
       = render "projects/notes/discussion_reply_button", note: note2
   - else
     %td= ""
     %td= ""
+
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 81bf0611ec679ebc4eac8950a527f4024f0aac52..2fd8cb6d489dd1902cafd2d94e3ccf8544644a19 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -54,8 +54,8 @@
   - if note.attachment.url
     .note-attachment
       - if note.attachment.image?
-        = link_to note.attachment.url, target: '_blank' do
-          = image_tag note.attachment.url, class: 'note-image-attach'
+        = link_to note.attachment.secure_url, target: '_blank' do
+          = image_tag note.attachment.secure_url, class: 'note-image-attach'
       .attachment.pull-right
         = link_to note.attachment.secure_url, target: "_blank" do
           %i.icon-paper-clip
diff --git a/app/views/projects/notes/_notes_with_form.html.haml b/app/views/projects/notes/_notes_with_form.html.haml
index 3bd592e398290ddeabe6ee2a21066f2ddf900e6c..052661962e43bf145742c8ff16d2ca91bde20d7e 100644
--- a/app/views/projects/notes/_notes_with_form.html.haml
+++ b/app/views/projects/notes/_notes_with_form.html.haml
@@ -7,4 +7,4 @@
   = render "projects/notes/form"
 
 :javascript
-  new Notes("#{project_notes_path(target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json})
+  new Notes("#{project_notes_path(target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json}, #{Time.now.to_i})
diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml
index 4a6e8943a9f820049ba9e024970adcc1555c1bc2..e9f67b671bf10e0f8e9ab2b53fdca5681b73d7d0 100644
--- a/app/views/projects/protected_branches/index.html.haml
+++ b/app/views/projects/protected_branches/index.html.haml
@@ -4,12 +4,12 @@
     = render "projects/branches/filter"
   .col-md-9
     .bs-callout.bs-callout-info
-      %p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}.
-      %p This ability allows:
+      %p Protected branches designed to
       %ul
-        %li keep stable branches secured
-        %li forced code review before merge to protected branches
-        %li prevents branch from force push
+        %li prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}.
+        %li prevent branch from force push
+        %li prevent branch from removal
+      %p This ability allows to keep stable branches secured and force code review before merge to protected branches
       %p Read more about project permissions #{link_to "here", help_permissions_path, class: "underlined-link"}
 
     - if can? current_user, :admin_project, @project
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 20879d69091fa1f7ca99c400fc9c7c5cb1a6f627..7e9f1122aa9583692afb79c0936a1535dc7df099 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -6,7 +6,7 @@
     = render 'shared/event_filter'
     .content_list
     = spinner
-  .col-md-3.project-side.hidden-sm
+  .col-md-3.project-side.hidden-sm.hidden-xs
     .clearfix
       - if @project.archived?
         .alert.alert-warning
diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml
index c77ed3433d1c10fead388f16987b4da014308c69..0c2e33f22820c1ded31f13263f12b07f1c6323c5 100644
--- a/app/views/projects/wikis/_form.html.haml
+++ b/app/views/projects/wikis/_form.html.haml
@@ -1,10 +1,9 @@
 = form_for [@project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal' } do |f|
   -if @page.errors.any?
     #error_explanation
-      %h2= "#{pluralize(@page.errors.count, "error")} prohibited this wiki from being saved:"
-      %ul
+      .alert.alert-danger
         - @page.errors.full_messages.each do |msg|
-          %li= msg
+          %p= msg
 
   = f.hidden_field :title, value: @page.title
   .form-group
diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml
index 8cb7fa8aa0b196ff1c39ac928dfc7a483024498b..1ce292a02dfbd0f611cd1c3bf8bc491b05998cc7 100644
--- a/app/views/projects/wikis/_new.html.haml
+++ b/app/views/projects/wikis/_new.html.haml
@@ -9,6 +9,6 @@
           %span Page slug
         = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project)
         %p.hint
-          Please don't use spaces and slashes
+          Please don't use spaces.
       .modal-footer
         = link_to 'Build', '#', class: 'build-new-wiki btn btn-create'
diff --git a/app/views/shared/_commit_message_container.html.haml b/app/views/shared/_commit_message_container.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..cca7a0efc9b7152022c7a118362b4312a06ae267
--- /dev/null
+++ b/app/views/shared/_commit_message_container.html.haml
@@ -0,0 +1,5 @@
+.commit-message-container
+  .max-width-marker
+    -# When the `ch` CSS length unit becomes widely supported `http://www.quirksmode.org/css/units-values` remove this workaround.
+    = 'a' * 72
+  = textarea
diff --git a/app/views/shared/_project_filter.html.haml b/app/views/shared/_project_filter.html.haml
index d82b08eeaa28b8a330e505456cefafae332b53c6..7936a038be390b3859fb4714843a97f9e469068b 100644
--- a/app/views/shared/_project_filter.html.haml
+++ b/app/views/shared/_project_filter.html.haml
@@ -44,7 +44,7 @@
             .light-well
               Add first label to your issues
               %br
-              or #{link_to 'generate', generate_project_labels_path(@project), method: :post} default set of labels
+              or #{link_to 'generate', generate_project_labels_path(@project, redirect: redirect), method: :post} default set of labels
 
     %fieldset
       - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any?
diff --git a/bin/pkgr_before_precompile.sh b/bin/pkgr_before_precompile.sh
new file mode 100755
index 0000000000000000000000000000000000000000..283abb6a0cd28d5c90f152b6f2dc137a034e4fd7
--- /dev/null
+++ b/bin/pkgr_before_precompile.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -e
+
+for file in config/*.yml.example; do
+  cp ${file} config/$(basename ${file} .example)
+done
+
+# Allow to override the Gitlab URL from an environment variable, as this will avoid having to change the configuration file for simple deployments.
+config=$(echo '<% gitlab_url = URI(ENV["GITLAB_URL"] || "http://localhost:80") %>' | cat - config/gitlab.yml)
+echo "$config" > config/gitlab.yml
+sed -i "s/host: localhost/host: <%= gitlab_url.host %>/" config/gitlab.yml
+sed -i "s/port: 80/port: <%= gitlab_url.port %>/" config/gitlab.yml
+sed -i "s/https: false/https: <%= gitlab_url.scheme == 'https' %>/" config/gitlab.yml
+
+# No need for config file. Will be taken care of by REDIS_URL env variable
+rm config/resque.yml
+
+# Set default unicorn.rb file
+echo "" > config/unicorn.rb
+
+# Required for assets precompilation
+sudo service postgresql start
diff --git a/config/application.rb b/config/application.rb
index 76b19eeb52967e7ec2d4b5065133c46a69d70e5d..f087d3507bcc5d240211d4ed7aba4c049242d827 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -66,13 +66,16 @@ module Gitlab
     # Version of your assets, change this if you want to expire all your assets
     config.assets.version = '1.0'
 
+    # Relative url support
     # Uncomment and customize the last line to run in a non-root path
     # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.
-    # Note that four settings need to be changed for this to work.
+    # Note that following settings need to be changed for this to work.
     # 1) In your application.rb file: config.relative_url_root = "/gitlab"
     # 2) In your gitlab.yml file: relative_url_root: /gitlab
     # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
     # 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab"
+    # 5) In lib/support/nginx/gitlab : do not use asset gzipping, remove block starting with "location ~ ^/(assets)/"
+    #
     # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
     #
     # config.relative_url_root = "/gitlab"
diff --git a/config/environments/production.rb b/config/environments/production.rb
index ad3c03d8fc914e3728929fd57ccf8da801e1eccc..47f7e17aeb6e73800bdda9abd6ee75a359c6f60d 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -53,7 +53,7 @@ Gitlab::Application.configure do
                else
                  "redis://localhost:6379"
                end
-  config.cache_store = :redis_store, resque_url
+  config.cache_store = :redis_store, resque_url, {namespace: 'cache:gitlab'}
 
   # Enable serving of images, stylesheets, and JavaScripts from an asset server
   # config.action_controller.asset_host = "http://assets.example.com"
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 64fc02fe8c2aa3f01d00591bfa19785e253c2ffa..7b53a0655336e6493de6985accaf498f673b63ea 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -19,15 +19,13 @@ production: &base
     port: 80
     https: false
 
-    # Uncomment and customize the last line to run in a non-root path
-    # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.
-    # Note that four settings need to be changed for this to work.
-    # 1) In your application.rb file: config.relative_url_root = "/gitlab"
-    # 2) In your gitlab.yml file: relative_url_root: /gitlab
-    # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
-    # 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab"
-    # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
-    #
+    # Uncommment this line below if your ssh host is different from HTTP/HTTPS one
+    # (you'd obviously need to replace ssh.host_example.com with your own host).
+    # Otherwise, ssh host will be set to the `host:` value above
+    # ssh_host: ssh.host_example.com
+
+    # WARNING: See config/application.rb under "Relative url support" for the list of
+    # other files that need to be changed for relative url support
     # relative_url_root: /gitlab
 
     # Uncomment and customize if you can't use the default user to run GitLab (default: 'git')
@@ -35,10 +33,10 @@ production: &base
 
     ## Email settings
     # Email address used in the "From" field in mails sent by GitLab
-    email_from: gitlab@localhost
+    email_from: example@example.com
 
     # Email address of your support contact (default: same as email_from)
-    support_email: support@localhost
+    support_email: support@example.com
 
     ## User settings
     default_projects_limit: 10
@@ -102,7 +100,7 @@ production: &base
     #   ##  :id                - Issue id (from commit messages)
     #   issues_url: "http://redmine.sample/issues/:id"
     #
-    #   ## If not nil, linkis to creating new issues will be replaced with this
+    #   ## If not nil, links to creating new issues will be replaced with this
     #   ## Use placeholders:
     #   ##  :project_id        - GitLab project identifier
     #   ##  :issues_tracker_id - Project Name or Id in external issue tracker
@@ -117,6 +115,7 @@ production: &base
   ## Gravatar
   gravatar:
     enabled: true                 # Use user avatar image from Gravatar.com (default: true)
+    # gravatar urls: possible placeholders: %{hash} %{size} %{email}
     # plain_url: "http://..."     # default: http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm
     # ssl_url:   "https://..."    # default: https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm
 
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 4e8b3f304d0a5733e91da414cb106e1841e03e91..97f295464040938f721f89d04568d469f8529a21 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -73,6 +73,7 @@ Settings.gitlab['default_projects_limit'] ||= 10
 Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_can_create_group'].nil?
 Settings.gitlab['default_theme'] = Gitlab::Theme::MARS if Settings.gitlab['default_theme'].nil?
 Settings.gitlab['host']       ||= 'localhost'
+Settings.gitlab['ssh_host']   ||= Settings.gitlab.host
 Settings.gitlab['https']        = false if Settings.gitlab['https'].nil?
 Settings.gitlab['port']       ||= Settings.gitlab.https ? 443 : 80
 Settings.gitlab['relative_url_root'] ||= ENV['RAILS_RELATIVE_URL_ROOT'] || ''
@@ -117,7 +118,7 @@ Settings.gitlab_shell['hooks_path']   ||= Settings.gitlab['user_home'] + '/gitla
 Settings.gitlab_shell['receive_pack']   = true if Settings.gitlab_shell['receive_pack'].nil?
 Settings.gitlab_shell['upload_pack']    = true if Settings.gitlab_shell['upload_pack'].nil?
 Settings.gitlab_shell['repos_path']   ||= Settings.gitlab['user_home'] + '/repositories/'
-Settings.gitlab_shell['ssh_host']     ||= (Settings.gitlab.host || 'localhost')
+Settings.gitlab_shell['ssh_host']     ||= Settings.gitlab.ssh_host
 Settings.gitlab_shell['ssh_port']     ||= 22
 Settings.gitlab_shell['ssh_user']     ||= Settings.gitlab.user
 Settings.gitlab_shell['owner_group']  ||= Settings.gitlab.user
diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb
index 6875fa74eddeb3afe53c8cd29b6cb0129994605c..d0065b63e545ead2c3cf7d762b673f5ce495471a 100644
--- a/config/initializers/carrierwave.rb
+++ b/config/initializers/carrierwave.rb
@@ -18,4 +18,16 @@ if File.exists?(aws_file)
     config.fog_authenticated_url_expiration = 1 << 29               # optional time (in seconds) that authenticated urls will be valid.
                                                                     # when fog_public is false and provider is AWS or Google, defaults to 600
   end
+
+  # Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders
+  if Rails.env.test?
+    Fog.mock!
+    connection = ::Fog::Storage.new(
+        :aws_access_key_id      => AWS_CONFIG['access_key_id'],
+        :aws_secret_access_key  => AWS_CONFIG['secret_access_key'],
+        :provider               => 'AWS',
+        :region                 => AWS_CONFIG['region']
+      )
+    connection.directories.create(:key => AWS_CONFIG['bucket'])
+  end
 end
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index 50669ece7a81af1c42fd3786930a33bd93d803c9..d5cb110e8814fe96cf5c2ca000df4de1c1b7e67b 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -223,6 +223,7 @@ Devise.setup do |config|
       method:   Gitlab.config.ldap['method'],
       bind_dn:  Gitlab.config.ldap['bind_dn'],
       password: Gitlab.config.ldap['password'],
+      filter:   Gitlab.config.ldap['user_filter'],
       name_proc: email_stripping_proc
   end
 
@@ -244,4 +245,4 @@ Devise.setup do |config|
 
     config.omniauth provider['name'].to_sym, *provider_arguments
   end
-end
+end
\ No newline at end of file
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index f80b67a554bdc65730a47d88c7cfda89ca05a9ff..5fe5270236b6ec4a488d6e6c86e74ec10daa113b 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -2,7 +2,7 @@
 
 Gitlab::Application.config.session_store(
   :redis_store, # Using the cookie_store would enable session replay attacks.
-  servers: Gitlab::Application.config.cache_store.last, # re-use the Redis config from the Rails cache store
+  servers: Gitlab::Application.config.cache_store[1], # re-use the Redis config from the Rails cache store
   key: '_gitlab_session',
   secure: Gitlab.config.gitlab.https,
   httponly: true,
diff --git a/config/routes.rb b/config/routes.rb
index f23542cc8931aa5bab6780f75bd4afe6f856b9be..7641fe430889bbe469856c4d9926e033c023c431 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -187,7 +187,9 @@ Gitlab::Application.routes.draw do
       resources :blob,      only: [:show, :destroy], constraints: {id: /.+/}
       resources :raw,       only: [:show], constraints: {id: /.+/}
       resources :tree,      only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
-      resources :edit_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'edit'
+      resources :edit_tree, only: [:show, :update], constraints: { id: /.+/ }, path: 'edit' do
+        post :preview, on: :member
+      end
       resources :new_tree,  only: [:show, :update], constraints: {id: /.+/}, path: 'new'
       resources :commit,    only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
       resources :commits,   only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
@@ -204,7 +206,7 @@ Gitlab::Application.routes.draw do
           end
         end
 
-      resources :wikis, only: [:show, :edit, :destroy, :create], constraints: {id: /[a-zA-Z.0-9_\-]+/} do
+      resources :wikis, only: [:show, :edit, :destroy, :create], constraints: {id: /[a-zA-Z.0-9_\-\/]+/} do
         collection do
           get :pages
           put ':id' => 'wikis#update'
@@ -271,7 +273,7 @@ Gitlab::Application.routes.draw do
       resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do
         member do
           get :diffs
-          get :automerge
+          post :automerge
           get :automerge_check
           get :ci_status
         end
diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example
index ba5e5cdde0b14776b080ff7c3ceb3f129faf07be..f6c0f09b51d025e036bd0cdefe2816c0513d67d2 100644
--- a/config/unicorn.rb.example
+++ b/config/unicorn.rb.example
@@ -8,14 +8,8 @@
 # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
 # documentation.
 
-# Uncomment and customize the last line to run in a non-root path
-# WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.
-# Note that four settings need to be changed for this to work.
-# 1) In your application.rb file: config.relative_url_root = "/gitlab"
-# 2) In your gitlab.yml file: relative_url_root: /gitlab
-# 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
-# 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab"
-# To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
+# WARNING: See config/application.rb under "Relative url support" for the list of
+# other files that need to be changed for relative url support
 #
 # ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
 
diff --git a/db/fixtures/development/04_project.rb b/db/fixtures/development/04_project.rb
index 9303ab93300f4d79bbde3a5f68c1700aec4a4342..164bb637809488af634460959f29a60641ac5d40 100644
--- a/db/fixtures/development/04_project.rb
+++ b/db/fixtures/development/04_project.rb
@@ -40,7 +40,8 @@ Gitlab::Seeder.quiet do
       import_url: url,
       namespace_id: group.id,
       name: project_path.titleize,
-      description: Faker::Lorem.sentence
+      description: Faker::Lorem.sentence,
+      visibility_level: Gitlab::VisibilityLevel.values.sample
     }
 
     project = Projects::CreateService.new(User.first, params).execute
diff --git a/db/fixtures/development/10_merge_requests.rb b/db/fixtures/development/10_merge_requests.rb
index cb08a7c253717d61e07366cd21d609e19bfb07bb..62fd0d84ea323312ec5e4bece5445c703176d4de 100644
--- a/db/fixtures/development/10_merge_requests.rb
+++ b/db/fixtures/development/10_merge_requests.rb
@@ -1,45 +1,33 @@
 Gitlab::Seeder.quiet do
-  (1..100).each  do |i|
-    # Random Project
-    project = Project.all.sample
-
-    # Random user
-    user = project.team.users.sample
-
-    next unless user
-
-    next if project.empty_repo?
-
-    branches = project.repository.branch_names.sample(2)
-
-    next if branches.uniq.size < 2
-
-    user_id = user.id
-
-    Gitlab::Seeder.by_user(user) do
-      MergeRequest.seed(:id, [{
-        id: i,
-        source_branch: branches.first,
-        target_branch: branches.last,
-        source_project_id: project.id,
-        target_project_id: project.id,
-        author_id: user_id,
-        assignee_id: user_id,
-        milestone: project.milestones.sample,
-        title: Faker::Lorem.sentence(6)
-      }])
+  Project.all.reject(&:empty_repo?).each do |project|
+    branches = project.repository.branch_names
+
+    branches.each do |branch_name|
+      break if branches.size < 2
+      source_branch = branches.pop
+      target_branch = branches.pop
+
+      # Random user
+      user = project.team.users.sample
+      next unless user
+
+      params = {
+        source_branch: source_branch,
+        target_branch: target_branch,
+        title: Faker::Lorem.sentence(6),
+        description: Faker::Lorem.sentences(3).join(" ")
+      }
+
+      merge_request = MergeRequests::CreateService.new(project, user, params).execute
+
+      if merge_request.valid?
+        merge_request.assignee = user
+        merge_request.milestone = project.milestones.sample
+        merge_request.save
+        print '.'
+      else
+        print 'F'
+      end
     end
-    print('.')
   end
 end
-
-MergeRequest.all.map do |mr|
-  mr.set_iid
-  mr.save
-end
-
-puts 'Load diffs for Merge Requests (it will take some time)...'
-MergeRequest.all.each do |mr|
-  mr.reload_code
-  print '.'
-end
diff --git a/db/migrate/20140415124820_limits_to_mysql.rb b/db/migrate/20140415124820_limits_to_mysql.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3f6e62617c57ab82367fafd407c89815c504c34d
--- /dev/null
+++ b/db/migrate/20140415124820_limits_to_mysql.rb
@@ -0,0 +1 @@
+require_relative 'limits_to_mysql'
diff --git a/db/migrate/20140416074002_add_index_on_iid.rb b/db/migrate/20140416074002_add_index_on_iid.rb
new file mode 100644
index 0000000000000000000000000000000000000000..85269e2a03b3be385cdca8d69d0b0635b06ca73e
--- /dev/null
+++ b/db/migrate/20140416074002_add_index_on_iid.rb
@@ -0,0 +1,32 @@
+class AddIndexOnIid < ActiveRecord::Migration
+  def change
+    RemoveDuplicateIid.clean(Issue)
+    RemoveDuplicateIid.clean(MergeRequest, 'target_project_id')
+    RemoveDuplicateIid.clean(Milestone)
+
+    add_index :issues, [:project_id, :iid], unique: true
+    add_index :merge_requests, [:target_project_id, :iid], unique: true
+    add_index :milestones, [:project_id, :iid], unique: true
+  end
+end
+
+class RemoveDuplicateIid
+  def self.clean(klass, project_field = 'project_id')
+    duplicates = klass.find_by_sql("SELECT iid, #{project_field} FROM #{klass.table_name} GROUP BY #{project_field}, iid HAVING COUNT(*) > 1")
+
+    duplicates.each do |duplicate|
+      project_id = duplicate.send(project_field)
+      iid = duplicate.iid
+      items = klass.of_projects(project_id).where(iid: iid)
+
+      if items.size > 1
+        puts "Remove #{klass.name} duplicates for iid: #{iid} and project_id: #{project_id}"
+        items.shift
+        items.each do |item|
+          item.destroy
+          puts '.'
+        end
+      end
+    end
+  end
+end
diff --git a/db/migrate/20140416185734_index_on_current_sign_in_at.rb b/db/migrate/20140416185734_index_on_current_sign_in_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0bf80ce154a151366967d45921bcebef5bcbe143
--- /dev/null
+++ b/db/migrate/20140416185734_index_on_current_sign_in_at.rb
@@ -0,0 +1,5 @@
+class IndexOnCurrentSignInAt < ActiveRecord::Migration
+  def change
+    add_index :users, :current_sign_in_at
+  end
+end
diff --git a/db/migrate/20140428105831_add_notes_index_updated_at.rb b/db/migrate/20140428105831_add_notes_index_updated_at.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6c25570f128141919bee9e459d9690a4b63cb445
--- /dev/null
+++ b/db/migrate/20140428105831_add_notes_index_updated_at.rb
@@ -0,0 +1,5 @@
+class AddNotesIndexUpdatedAt < ActiveRecord::Migration
+  def change
+    add_index :notes, :updated_at
+  end
+end
diff --git a/db/migrate/20140502115131_add_repo_size_to_db.rb b/db/migrate/20140502115131_add_repo_size_to_db.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7361d1a9440f3592bdff0d3235df55a365ebd115
--- /dev/null
+++ b/db/migrate/20140502115131_add_repo_size_to_db.rb
@@ -0,0 +1,5 @@
+class AddRepoSizeToDb < ActiveRecord::Migration
+  def change
+    add_column :projects, :repository_size, :float, default: 0
+  end
+end
diff --git a/db/migrate/20140502125220_migrate_repo_size.rb b/db/migrate/20140502125220_migrate_repo_size.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eed6d366814c5e956a0ee7fe7d5bd8bc974ff6d3
--- /dev/null
+++ b/db/migrate/20140502125220_migrate_repo_size.rb
@@ -0,0 +1,21 @@
+class MigrateRepoSize < ActiveRecord::Migration
+  def up
+    Project.reset_column_information
+    Project.find_each(batch_size: 500) do |project|
+      begin
+        if project.empty_repo?
+          print '-'
+        else
+          project.update_repository_size
+          print '.'
+        end
+      rescue
+        print 'F'
+      end
+    end
+    puts 'Done'
+  end
+
+  def down
+  end
+end
diff --git a/db/migrate/limits_to_mysql.rb b/db/migrate/limits_to_mysql.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2b7afae6d7cb3f73197f2c6d9549ba216429af82
--- /dev/null
+++ b/db/migrate/limits_to_mysql.rb
@@ -0,0 +1,10 @@
+class LimitsToMysql < ActiveRecord::Migration
+  def up
+    return unless ActiveRecord::Base.configurations[Rails.env]['adapter'] =~ /^mysql/
+
+    change_column :merge_request_diffs, :st_commits, :text, limit: 2147483647
+    change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647
+    change_column :snippets, :content, :text, limit: 2147483647
+    change_column :notes, :st_diff, :text, limit: 2147483647
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 265d556bd277a7a1f3fc916061b3666603589a88..93837337afc311c848a8e0a4bbe5ad03ba4c3fc6 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20140414131055) do
+ActiveRecord::Schema.define(version: 20140502125220) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -93,6 +93,7 @@ ActiveRecord::Schema.define(version: 20140414131055) do
   add_index "issues", ["author_id"], name: "index_issues_on_author_id", using: :btree
   add_index "issues", ["created_at"], name: "index_issues_on_created_at", using: :btree
   add_index "issues", ["milestone_id"], name: "index_issues_on_milestone_id", using: :btree
+  add_index "issues", ["project_id", "iid"], name: "index_issues_on_project_id_and_iid", unique: true, using: :btree
   add_index "issues", ["project_id"], name: "index_issues_on_project_id", using: :btree
   add_index "issues", ["title"], name: "index_issues_on_title", using: :btree
 
@@ -143,6 +144,7 @@ ActiveRecord::Schema.define(version: 20140414131055) do
   add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree
   add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_source_project_id", using: :btree
   add_index "merge_requests", ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree
+  add_index "merge_requests", ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid", unique: true, using: :btree
   add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree
 
   create_table "milestones", force: true do |t|
@@ -157,6 +159,7 @@ ActiveRecord::Schema.define(version: 20140414131055) do
   end
 
   add_index "milestones", ["due_date"], name: "index_milestones_on_due_date", using: :btree
+  add_index "milestones", ["project_id", "iid"], name: "index_milestones_on_project_id_and_iid", unique: true, using: :btree
   add_index "milestones", ["project_id"], name: "index_milestones_on_project_id", using: :btree
 
   create_table "namespaces", force: true do |t|
@@ -197,6 +200,7 @@ ActiveRecord::Schema.define(version: 20140414131055) do
   add_index "notes", ["noteable_type"], name: "index_notes_on_noteable_type", using: :btree
   add_index "notes", ["project_id", "noteable_type"], name: "index_notes_on_project_id_and_noteable_type", using: :btree
   add_index "notes", ["project_id"], name: "index_notes_on_project_id", using: :btree
+  add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree
 
   create_table "projects", force: true do |t|
     t.string   "name"
@@ -218,6 +222,7 @@ ActiveRecord::Schema.define(version: 20140414131055) do
     t.integer  "visibility_level",       default: 0,        null: false
     t.boolean  "archived",               default: false,    null: false
     t.string   "import_status"
+    t.float    "repository_size",        default: 0.0
   end
 
   add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree
@@ -319,7 +324,6 @@ ActiveRecord::Schema.define(version: 20140414131055) do
     t.integer  "notification_level",       default: 1,     null: false
     t.datetime "password_expires_at"
     t.integer  "created_by_id"
-    t.datetime "last_credential_check_at"
     t.string   "avatar"
     t.string   "confirmation_token"
     t.datetime "confirmed_at"
@@ -327,11 +331,13 @@ ActiveRecord::Schema.define(version: 20140414131055) do
     t.string   "unconfirmed_email"
     t.boolean  "hide_no_ssh_key",          default: false
     t.string   "website_url",              default: "",    null: false
+    t.datetime "last_credential_check_at"
   end
 
   add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
   add_index "users", ["authentication_token"], name: "index_users_on_authentication_token", unique: true, using: :btree
   add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
+  add_index "users", ["current_sign_in_at"], name: "index_users_on_current_sign_in_at", using: :btree
   add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
   add_index "users", ["extern_uid", "provider"], name: "index_users_on_extern_uid_and_provider", unique: true, using: :btree
   add_index "users", ["name"], name: "index_users_on_name", using: :btree
diff --git a/doc/api/README.md b/doc/api/README.md
index b1740f357925798ed35c46cecfda4bb2fbad24b0..acd2f524beb350e32e0facc93f1a4aaebc3826a3 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -13,7 +13,7 @@
 + [Merge Requests](merge_requests.md)
 + [Issues](issues.md)
 + [Milestones](milestones.md)
-+ [Notes](notes.md)
++ [Notes](notes.md) (comments)
 + [Deploy Keys](deploy_keys.md)
 + [System Hooks](system_hooks.md)
 + [Groups](groups.md)
@@ -21,9 +21,12 @@
 ## Clients
 
 + [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP
++ [Laravel API Wrapper for GitLab CE](https://github.com/adamgoose/gitlab) - PHP / [Laravel](http://laravel.com)
 + [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby
 + [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python
 + [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java
++ [node-gitlab](https://github.com/moul/node-gitlab) - Node.js
++ [NGitLab](https://github.com/Scooletz/NGitLab) - .NET
 
 ## Introduction
 
diff --git a/doc/api/deploy_key_multiple_projects.md b/doc/api/deploy_key_multiple_projects.md
new file mode 100644
index 0000000000000000000000000000000000000000..1a5a458905e061112acd95d20f0b1876ad88ecb3
--- /dev/null
+++ b/doc/api/deploy_key_multiple_projects.md
@@ -0,0 +1,25 @@
+# Adding deploy keys to multiple projects
+
+If you want to easily add the same deploy key to multiple projects in the same group, this can be achieved quite easily with the API.
+
+First, find the ID of the projects you're interested in, by either listing all projects:
+
+```
+curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects
+```
+
+Or finding the id of a group and then listing all projects in that group:
+
+```
+curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups
+
+# For group 1234:
+curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups/1234
+```
+
+With those IDs, add the same deploy key to all:
+```
+for project_id in 321 456 987; do
+    curl -X POST --data '{"title": "my key", "key": "ssh-rsa AAAA..."}' --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects/${project_id}/keys
+done
+```
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 823b72f5b0c34d00c7beec2eadd8c9b70414dfe4..d18506f9ce6a6c4836a4305087f0a8f16913393e 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -193,3 +193,7 @@ Parameters:
 
 + `id` (required) - The project ID
 + `issue_id` (required) - The ID of the issue
+
+## Comments on issues
+
+Comments are done via the notes resource.
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 4e864ae1078704dd733d50b736e4615bb3d7d6dd..d68f34971f1be9bb948bd44e55e75b6acdaa1060 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -105,10 +105,11 @@ POST /projects/:id/merge_requests
 Parameters:
 
 + `id` (required) - The ID of a project
-+ `source_branch` (required) - The source branch
-+ `target_branch` (required) - The target branch
-+ `assignee_id` (optional)   - Assignee user ID
-+ `title` (required)         - Title of MR
++ `source_branch` (required)     - The source branch
++ `target_branch` (required)     - The target branch
++ `assignee_id` (optional)       - Assignee user ID
++ `title` (required)             - Title of MR
++ `target_project_id` (optional) - The target project (numeric id)
 
 ```json
 {
@@ -188,6 +189,54 @@ Parameters:
 ```
 
 
+## Accept MR
+
+Merge changes submitted with MR usign this API.
+If merge success you get 200 OK.
+If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged'
+If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed' 
+If you dont have permissions to accept this merge request - you get 401
+
+```
+PUT /projects/:id/merge_request/:merge_request_id/merge
+```
+
+Parameters:
+
++ `id` (required)               - The ID of a project
++ `merge_request_id` (required) - ID of MR
++ `merge_commit_message` (optional) - Custom merge commit message
+
+```json
+{
+  "id": 1,
+  "target_branch": "master",
+  "source_branch": "test1",
+  "project_id": 3,
+  "title": "test1",
+  "state": "merged",
+  "upvotes": 0,
+  "downvotes": 0,
+  "author": {
+    "id": 1,
+    "username": "admin",
+    "email": "admin@local.host",
+    "name": "Administrator",
+    "state": "active",
+    "created_at": "2012-04-29T08:46:00Z"
+  },
+  "assignee": {
+    "id": 1,
+    "username": "admin",
+    "email": "admin@local.host",
+    "name": "Administrator",
+    "state": "active",
+    "created_at": "2012-04-29T08:46:00Z"
+  }
+}
+```
+
+
 ## Post comment to MR
 
 Adds a comment to a merge request.
@@ -257,3 +306,7 @@ Parameters:
   }
 ]
 ```
+
+## Comments on issues
+
+Comments are done via the notes resource.
diff --git a/doc/api/notes.md b/doc/api/notes.md
index b15ebdd2bac0edae36ef7b120d7cc2e1a6140c89..e9ad6e00c73164c1c009e0afa8e43045f396ba4e 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -1,3 +1,5 @@
+Notes can be wall notes or comments on snippets, issues or merge requests.
+
 ## Wall
 
 ### List project wall notes
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 40bcc6e2cd49109a809777c913fdb69817463070..ffaba0af7fe40ed9d113c1fac61ecb56ac161247 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -43,7 +43,8 @@ GET /projects
       "owner_id": 1,
       "path": "diaspora",
       "updated_at": "2013-09-30T13: 46: 02Z"
-    }
+    },
+    "archived": false
   },
   {
     "id": 6,
@@ -78,7 +79,8 @@ GET /projects
       "owner_id": 1,
       "path": "brightbox",
       "updated_at": "2013-09-30T13:46:02Z"
-    }
+    },
+    "archived": false
   }
 ]
 ```
@@ -157,7 +159,8 @@ Parameters:
       "access_level": 50,
       "notification_level": 3
     }
-  }
+  },
+  "archived": false
 }
 ```
 
diff --git a/doc/api/users.md b/doc/api/users.md
index 2d5dedb3a3904595f07c3e82353c0d536b37540a..2b927c30777349fcf78f68319058c17d08cf4bfc 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -220,6 +220,18 @@ Parameters:
 
 + **none**
 
+## List SSH keys for user
+
+Get a list of a specified user's SSH keys. Available only for admin
+
+```
+GET /users/:uid/keys
+```
+
+Parameters:
+
++ `uid` (required) - id of specified user
+
 
 ## Single SSH key
 
@@ -286,3 +298,18 @@ Parameters:
 
 + `id` (required) - SSH key ID
 
+## Delete SSH key
+
+Deletes key owned by a specified user. Available only for admin.
+
+```
+DELETE /users/:uid/keys/:id
+```
+
+Parameters:
+
++ `uid` (required) - id of specified user
++ `id` (required) - SSH key ID
+
+Will return `200 Ok` on success, or `404 Not found` if either user or key cannot be found.
+
diff --git a/doc/development/README.md b/doc/development/README.md
index aa59eb2c3e1fa1f86b3432972b086cfec79a0de6..eb88b6c860ff7c1ce71ec39231aa4b8ccc602be2 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -1,2 +1,5 @@
-+ [Architecture](architecture.md)
-+ [Shell commands](shell_commands.md)
+## Development 
+
++ [Architecture](architecture.md) of GitLab
++ [Shell commands](shell_commands.md) in the GitLab codebase
++ [Rake tasks](rake_tasks.md) for development
diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md
new file mode 100644
index 0000000000000000000000000000000000000000..9e75b3a62754d9c93679a3aa8fd561d78ebf371c
--- /dev/null
+++ b/doc/development/rake_tasks.md
@@ -0,0 +1,25 @@
+# Rake tasks for developers
+
+## Setup db with developer seeds:
+
+Note that if your db user does not have advanced privilegies you must create db manually before run this command 
+
+```
+bundle exec rake setup
+```
+
+## Run tests
+
+This runs all test suite present in GitLab 
+
+```
+bundle exec rake test
+```
+
+## Generate searchable docs for source code
+
+You can find results under `doc/code` directory
+
+```
+bundle exec rake gitlab:generate_docs
+```
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 579656eda2f4b1fa5074fe4d907c0a53a8013552..44f5a28fde5e1309e62def117221360532622cfc 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -1,10 +1,10 @@
 # Select Version to Install
-Make sure you view this installation guide from the branch (version) of GitLab you would like to install. In most cases
+Make sure you view [this installation guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md) from the branch (version) of GitLab you would like to install. In most cases
 this should be the highest numbered stable branch (example shown below).
 
 ![capture](http://i.imgur.com/d2AlIVj.png)
 
-If this is unclear check the [GitLab Blog](https://www.gitlab.com/blog/) for installation guide links by version.
+If the highest number stable branch is unclear please check the [GitLab Blog](https://www.gitlab.com/blog/) for installation guide links by version.
 
 # Important notes
 
@@ -27,10 +27,9 @@ The GitLab installation consists of setting up the following components:
 1. Packages / Dependencies
 2. Ruby
 3. System Users
-4. GitLab shell
-5. Database
-6. GitLab
-7. Nginx
+4. Database
+5. GitLab
+6. Nginx
 
 
 # 1. Packages / Dependencies
@@ -87,7 +86,7 @@ Is the system packaged Git too old? Remove it and compile from source.
 mail server. By default, Debian is shipped with exim4 whereas Ubuntu
 does not ship with one. The recommended mail server is postfix and you can install it with:
 
-	sudo apt-get install -y postfix
+    sudo apt-get install -y postfix
 
 Then select 'Internet Site' and press enter to confirm the hostname.
 
@@ -102,8 +101,8 @@ Remove the old Ruby 1.8 if present
 Download Ruby and compile it:
 
     mkdir /tmp/ruby && cd /tmp/ruby
-    curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p353.tar.gz | tar xz
-    cd ruby-2.0.0-p353
+    curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p481.tar.gz | tar xz
+    cd ruby-2.0.0-p481
     ./configure --disable-install-rdoc
     make
     sudo make install
@@ -119,32 +118,10 @@ Create a `git` user for Gitlab:
 
     sudo adduser --disabled-login --gecos 'GitLab' git
 
-
-# 4. GitLab shell
-
-GitLab Shell is an ssh access and repository management software developed specially for GitLab.
-
-    # Go to home directory
-    cd /home/git
-
-    # Clone gitlab shell
-    sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.9.3
-
-    cd gitlab-shell
-
-    sudo -u git -H cp config.yml.example config.yml
-
-    # Edit config and replace gitlab_url
-    # with something like 'http://domain.com/'
-    sudo -u git -H editor config.yml
-
-    # Do setup
-    sudo -u git -H ./bin/install
-
-
-# 5. Database
+# 4. Database
 
 We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](database_mysql.md).
+NOTE: because we need to make use of extensions you need at least pgsql 9.1.
 
     # Install the database packages
     sudo apt-get install -y postgresql-9.1 postgresql-client libpq-dev
@@ -153,7 +130,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
     sudo -u postgres psql -d template1
 
     # Create a user for GitLab.
-    template1=# CREATE USER git;
+    template1=# CREATE USER git CREATEDB;
 
     # Create the GitLab production database & grant all privileges on database
     template1=# CREATE DATABASE gitlabhq_production OWNER git;
@@ -165,7 +142,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
     sudo -u git -H psql -d gitlabhq_production
 
 
-# 6. GitLab
+# 5. GitLab
 
     # We'll install GitLab into home directory of the user "git"
     cd /home/git
@@ -173,13 +150,13 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
 ## Clone the Source
 
     # Clone GitLab repository
-    sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-8-stable gitlab
+    sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-9-stable gitlab
 
     # Go to gitlab dir
     cd /home/git/gitlab
 
 **Note:**
-You can change `6-8-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
+You can change `6-9-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
 
 ## Configure it
 
@@ -224,7 +201,7 @@ You can change `6-8-stable` to `master` if you want the *bleeding edge* version,
     # Configure Git global settings for git user, useful when editing via web
     # Edit user.email according to what is set in gitlab.yml
     sudo -u git -H git config --global user.name "GitLab"
-    sudo -u git -H git config --global user.email "gitlab@localhost"
+    sudo -u git -H git config --global user.email "example@example.com"
     sudo -u git -H git config --global core.autocrlf input
 
 **Important Note:**
@@ -267,6 +244,19 @@ that were [fixed](https://github.com/bundler/bundler/pull/2817) in 1.5.2.
     # Or if you use MySQL (note, the option says "without ... postgres")
     sudo -u git -H bundle install --deployment --without development test postgres aws
 
+## Install GitLab shell
+
+GitLab Shell is an ssh access and repository management software developed specially for GitLab.
+
+    # Go to the Gitlab installation folder:
+    cd /home/git/gitlab
+
+    # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
+    sudo -u git -H bundle exec rake gitlab:shell:install[v1.9.4] REDIS_URL=redis://localhost:6379 RAILS_ENV=production
+
+    # By default, the gitlab-shell config is generated from your main gitlab config. You can review (and modify) it as follows:
+    sudo -u git -H editor /home/git/gitlab-shell/config.yml
+
 
 ## Initialize Database and Activate Advanced Features
 
@@ -276,7 +266,6 @@ that were [fixed](https://github.com/bundler/bundler/pull/2817) in 1.5.2.
 
     # When done you see 'Administrator account created:'
 
-
 ## Install Init Script
 
 Download the init script (will be /etc/init.d/gitlab):
@@ -313,7 +302,8 @@ Check if GitLab and its environment are configured correctly:
     # or
     sudo /etc/init.d/gitlab restart
 
-# 7. Nginx
+
+# 6. Nginx
 
 **Note:**
 Nginx is the officially supported web server for GitLab. If you cannot or do not want to use Nginx as your web server, have a look at the
@@ -419,22 +409,22 @@ GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already
 These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation.
 
 * Stop GitLab
-		`sudo service gitlab stop`
+    `sudo service gitlab stop`
 
 * Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/gitlab.yml.example) as a reference)
 
 * Add the gem to your [Gemfile](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/Gemfile)
                 `gem "omniauth-your-auth-provider"`
 * If you're using MySQL, install the new Omniauth provider gem by running the following command:
-		`sudo -u git -H bundle install --without development test postgres --path vendor/bundle --no-deployment`
+    `sudo -u git -H bundle install --without development test postgres --path vendor/bundle --no-deployment`
 
 * If you're using PostgreSQL, install the new Omniauth provider gem by running the following command:
-		`sudo -u git -H bundle install --without development test mysql --path vendor/bundle --no-deployment`
+    `sudo -u git -H bundle install --without development test mysql --path vendor/bundle --no-deployment`
 
 > These are the same commands you used in the [Install Gems section](#install-gems) with `--path vendor/bundle --no-deployment` instead of `--deployment`.
 
 * Start GitLab
-		`sudo service gitlab start`
+    `sudo service gitlab start`
 
 
 ### Examples
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 62e21dc72bb683bd562c15f36f05b5e3b661d992..fd2dd16cd8eb4cad399e0638b0655d8428c06c50 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -53,7 +53,7 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) but GitLab
 
 ## Memory
 
-- 512MB is the abolute minimum, you need 256MB of swap, you can configure only one slow unicorn worker, only ssh access will work, we do not recommend this
+- 512MB is the absolute minimum, you need 256MB of swap, you can configure only one slow unicorn worker, only ssh access will work, we do not recommend this
 - 1GB supports up to 100 users (with individual repositories under 250MB, otherwise git memory usage necessitates using swap space)
 - **2GB** is the **recommended** memory size and supports up to 500 users
 - 4GB supports up to 2,000 users
@@ -74,11 +74,14 @@ Apart from a local hard drive you can also mount a volume that supports the netw
 
 If you have enough RAM memory and a recent CPU the speed of GitLab is mainly limited by hard drive seek times. Having a fast drive (7200 RPM and up) or a solid state drive (SSD) will improve the responsiveness of GitLab.
 
+## Database
+
+If you want to run the database separately, the **recommended** database size is **1 MB per user**
 
 # Supported webbrowsers
 
 - Chrome (Latest stable version)
 - Firefox (Latest released version) 
-- Safari 7+ (Know problem: required fields in html5 do not work)
+- Safari 7+ (known problem: required fields in html5 do not work)
 - Opera (Latest released version)
 - IE 10+
diff --git a/doc/integration/README.md b/doc/integration/README.md
index 3e8d329d55821d763d548fdf62f81d8dc5734b3a..4773dd8fffb93d8e3bfff44371f46bc87c200eae 100644
--- a/doc/integration/README.md
+++ b/doc/integration/README.md
@@ -6,3 +6,6 @@ See the documentation below for details on how to configure these services.
 + [External issue tracker](external-issue-tracker.md) Redmine, JIRA, etc.
 + [LDAP](ldap.md) Set up sign in via LDAP
 + [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, and Google via OAuth.
++ [Slack](slack.md) Integrate with the Slack chat service
+
+Jenkins support is [available in GitLab EE](http://doc.gitlab.com/ee/integration/jenkins.html).
diff --git a/doc/integration/external-issue-tracker.md b/doc/integration/external-issue-tracker.md
index 7d8312075aceae192b4a655cb133b30b516ce4ef..1b531aeeda750f322cc394200355d3a307fe9862 100644
--- a/doc/integration/external-issue-tracker.md
+++ b/doc/integration/external-issue-tracker.md
@@ -2,8 +2,10 @@ GitLab has a great issue tracker but you can also use an external issue tracker
 
 - the 'Issues' link on the GitLab project pages takes you to the appropriate JIRA issue index;
 - clicking 'New issue' on the project dashboard creates a new JIRA issue;
-- To reference JIRA issue PROJECT-1234 in comments, use syntax #PROJECT-1234. Commit messages get turned into HTML links to the corresponding JIRA issue.
+- To reference JIRA issue PROJECT-1234 in comments, use syntax PROJECT-1234. Commit messages get turned into HTML links to the corresponding JIRA issue.
 
 ![jira screenshot](jira-integration-points.png)
 
-You can configure the integration in the gitlab.yml configuration file.
\ No newline at end of file
+You can configure the integration in the gitlab.yml configuration file.
+
+Support to add your commits to the Jira ticket automatically is [available in GitLab EE](http://doc.gitlab.com/ee/integration/jira.html).
diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md
index a4491432caf0f7c7901a3f7a342d3ae0d79bda87..84a5a8e8c28d25859b290d94ea2d0f4c53dd23df 100644
--- a/doc/integration/omniauth.md
+++ b/doc/integration/omniauth.md
@@ -21,6 +21,7 @@ Before configuring individual OmniAuth providers there are a few global settings
     ```
 
 2. Find the section dealing with OmniAuth. The section will look similar to the following.<br />
+
     ```
       ## OmniAuth settings
       omniauth:
@@ -50,6 +51,7 @@ Before configuring individual OmniAuth providers there are a few global settings
         #     app_secret: 'YOUR APP SECRET',
         #     args: { scope: 'user:email' } }
     ```
+
 3. Change `enabled` to `true`.
 4. Consider the next two configuration options: `allow_single_sign_on` and `block_auto_created_users`.
     * `allow_single_sign_on` defaults to `false`. If `false` users must be created manually or they will not be able to
diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md
index ac4bdefddd502a043f40603dfd39b2e2a8bbfb91..9be6423f66761a54456a0a2534c00379a02db37d 100644
--- a/doc/permissions/permissions.md
+++ b/doc/permissions/permissions.md
@@ -27,7 +27,7 @@ If a user is a GitLab administrator they receive all permissions.
 |Remove protected branches| |||✓|✓|
 |Edit project| |||✓|✓|
 |Add Deploy Keys to project| |||✓|✓|
-|Confiure Project Hooks| |||✓|✓|
+|Configure Project Hooks| |||✓|✓|
 |Switch visibility level| ||||✓|
 |Transfer project to another namespace| ||||✓|
 |Remove project| ||||✓|
diff --git a/doc/public_access/public_access.md b/doc/public_access/public_access.md
index bf9d2784affbf38f50a39e2253c5f376bda5dc3d..76d83e6f3b69f0c9d318336ecb644aa27f6323d3 100644
--- a/doc/public_access/public_access.md
+++ b/doc/public_access/public_access.md
@@ -4,7 +4,7 @@ Internal projects will only be available to authenticated users.
 
 #### Public projects
 Public projects can be cloned **without any** authentication.
-It will also be listen on the [public access directory](/public).
+It will also be listed on the [public access directory](/public).
 **Any logged in user** will have [Guest](/help/permissions) permissions on the repository.
 
 #### Internal projects
diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md
index 9aa80af12cc6a69644e2f086989a5dbb3ff78bf5..6be24f0102aeb218789ca0038fdd2ca24ca5833d 100644
--- a/doc/raketasks/README.md
+++ b/doc/raketasks/README.md
@@ -1,6 +1,7 @@
 + [Backup restore](backup_restore.md)
 + [Cleanup](cleanup.md)
 + [Features](features.md)
-+ [Maintenance](maintenance.md)
++ [Maintenance](maintenance.md) and self-checks
 + [User management](user_management.md)
 + [Web hooks](web_hooks.md)
++ [Import](import.md) of git repositories in bulk
diff --git a/doc/raketasks/import.md b/doc/raketasks/import.md
new file mode 100644
index 0000000000000000000000000000000000000000..e11328dc5ce7d15e257d9391f748c35f06e46ab4
--- /dev/null
+++ b/doc/raketasks/import.md
@@ -0,0 +1,28 @@
+### Import bare repositories into GitLab project instance
+
+Notes:
+
+* project owner will be a first admin
+* groups will be created as needed
+* group owner will be the first admin
+* existing projects will be skipped
+
+How to use:
+
+1. copy your bare repos under git repos_path (see `config/gitlab.yml` gitlab_shell -> repos_path)
+2. run the command below
+
+```
+bundle exec rake gitlab:import:repos RAILS_ENV=production
+```
+
+Example output:
+
+```
+Processing abcd.git
+ * Created abcd (abcd.git)
+Processing group/xyz.git
+ * Created Group group (2)
+ * Created xyz (group/xyz.git)
+[...]
+```
diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md
index 3033d8c46b4e4c2b9015a4c9fa7fb508ee6e88db..907c9352c59763aea7d1670b2e4afacd3375dfc3 100644
--- a/doc/raketasks/maintenance.md
+++ b/doc/raketasks/maintenance.md
@@ -24,9 +24,9 @@ Version:	5.1.0.beta2
 Revision:	4da8b37
 Directory:	/home/git/gitlab
 DB Adapter:	mysql2
-URL:		http://localhost
-HTTP Clone URL:	http://localhost/some-project.git
-SSH Clone URL:	git@localhost:some-project.git
+URL:		http://example.com
+HTTP Clone URL:	http://example.com/some-project.git
+SSH Clone URL:	git@example.com:some-project.git
 Using LDAP:	no
 Using Omniauth:	no
 
@@ -110,32 +110,3 @@ If necessary, remove the `tmp/repo_satellites` directory and rerun the command b
 ```
 bundle exec rake gitlab:satellites:create RAILS_ENV=production
 ```
-
-### Import bare repositories into GitLab project instance
-
-Notes:
-
-* project owner will be a first admin
-* groups will be created as needed
-* group owner will be the first admin
-* existing projects will be skipped
-
-How to use:
-
-1. copy your bare repos under git repos_path (see `config/gitlab.yml` gitlab_shell -> repos_path)
-2. run the command below
-
-```
-bundle exec rake gitlab:import:repos RAILS_ENV=production
-```
-
-Example output:
-
-```
-Processing abcd.git
- * Created abcd (abcd.git)
-Processing group/xyz.git
- * Created Group group (2)
- * Created xyz (group/xyz.git)
-[...]
-```
diff --git a/doc/release/monthly.md b/doc/release/monthly.md
index 284e4e165956443a930d200b0084b68fc323206b..514d73517b2ad580bef02083336d4df1fc372bfe 100644
--- a/doc/release/monthly.md
+++ b/doc/release/monthly.md
@@ -1,15 +1,36 @@
-# Things to do when creating new monthly minor or major release
-NOTE: This is a guide for GitLab developers. If you are trying to install GitLab see the latest stable [installation guide](install/installation.md) and if you are trying to upgrade, see the [upgrade guides](update).
+# Monthly Release
+NOTE: This is a guide for GitLab developers.
 
-## Install guide up to date?
+# **15th - Code Freeze & Release Manager**
 
-* References correct GitLab branch `x-x-stable` and correct GitLab shell tag?
+### **1. Stop merging in code, except for important bugfixes**
 
-## Make upgrade guide
+### **2. Release Manager**
 
-### From x.x to x.x
+A release manager is selected that coordinates the entire release of this version. The release manager has to make sure all the steps below are done and delegated where necessary. This person should also make sure this document is kept up to date and issues are created and updated.
 
-#### 0. Any major changes? Database updates? Web server change? File structure changes?
+# **18th - Releasing RC1**
+
+The RC1 release comes with the task to update the installation and upgrade docs. Be mindful that there might already be merge requests for this on GitLab or GitHub.
+
+### **1. Create an issue for RC1 release**
+
+### **2. Update the installation guide**
+
+1. Check if it references the correct branch `x-x-stable` (doesn't exist yet, but that is okay)
+2. Check the [GitLab Shell version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L782)
+3. Check the [Git version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L794)
+4. There might be other changes. Ask around.
+
+### **3. Create an update guide**
+
+It's best to copy paste the previous guide and make changes where necessary. The typical steps are listed below with any points you should specifically look at.
+
+#### 0. Any major changes?
+List any major changes here, so the user is aware of them before starting to upgrade. For instance: 
+- Database updates
+- Web server changes
+- File structure changes
 
 #### 1. Make backup
 
@@ -17,9 +38,9 @@ NOTE: This is a guide for GitLab developers. If you are trying to install GitLab
 
 #### 3. Do users need to update dependencies like `git`?
 
-- Check the [GitLab Shell version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L782)
+- Check if the [GitLab Shell version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L782) changed since the last release.
 
-- Check the [Git version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L794)
+- Check if the [Git version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L794) changed since the last release.
 
 #### 4. Get latest code
 
@@ -29,7 +50,7 @@ NOTE: This is a guide for GitLab developers. If you are trying to install GitLab
 
 #### 7. Any config files updated since last release?
 
-Check if any of these changed since last release (~22nd of last month depending on when last release branch was created):
+Check if any of these changed since last release:
 
 * https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/nginx/gitlab
 * https://gitlab.com/gitlab-org/gitlab-shell/commits/master/config.yml.example
@@ -40,13 +61,14 @@ Check if any of these changed since last release (~22nd of last month depending
 
 #### 8. Need to update init script?
 
-Check if changed since last release (~22nd of last month depending on when last release branch was created): https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/init.d/gitlab
+Check if the init.d/gitlab script changed since last release: https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/init.d/gitlab
 
 #### 9. Start application
 
 #### 10. Check application status
 
-## Make sure the code quality indicatiors are good
+### **4. Code quality indicatiors**
+Make sure the code quality indicators are green / good.
 
 * [![build status](http://ci.gitlab.org/projects/1/status.png?ref=master)](http://ci.gitlab.org/projects/1?ref=master) on ci.gitlab.org (master branch)
 
@@ -58,48 +80,88 @@ Check if changed since last release (~22nd of last month depending on when last
 
 * [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
 
-## Release Schedule
-
-After making the release branch new commits are cherry-picked from master. When the release gets closer we get more selective what is cherry-picked. The days of the month are approximately as follows:
-
-* 1-7th: Official merge window (see contributing guide).
-* 8-14th: Work on bugfixes, sponsored features and GitLab EE.
-* 15th: Code freeze
-    - Stop merging into master, except essential bugfixes
-    - Select a Release Manager
-* 18th: Release Candidate 1
-    - Set VERSION to x.x.0.rc1
-    - Create annotated tag x.x.0.rc1
-    - Push the changes to GitLab.com, dev.gitlab.com, GitHub
-    - Tweet about the release
-    - Create a new branch on cloud for rc1
-    - Deploy the new branch on Cloud after tests pass
-* 20st: Optional release candidate 2 (x.x.0.rc2, only if rc1 had problems)
-* 22nd: Release
-    - Create x-x-stable branch and push to the repositories
-    - QA
-    - Fix anything coming out of the QA
-    - Set VERSION to x.x.0
-    - Create annotated tag x.x.0
-    - Push VERSION + Tag to master, merge into x-x-stable
-    - Publish blog for new release
-    - Tweet to blog (see below)
-* 23nd: optional patch releases (x.x.1, x.x.2, etc., only if there are serious problems)
-* 24-end of month: release GitLab EE and GitLab CI
-
-# Write a blog post
+### **5. Set VERSION**
+
+Set VERSION tot x.x.0.rc1
+
+
+### **6. Tag**
+
+Create an annotated tag that points to the version change commit.
+```
+git tag -a vx.x.0.rc1 -m 'Version x.x.0.rc1'
+```
+
+### **7. Tweet**
+
+Tweet about the RC release:
+
+> GitLab x.x.x.rc1 is out. This is a release candidate intended for testing only. Please let us know if you find regressions.
+
+### **8. Update Cloud**
+
+Merge the RC1 code into Cloud. Once the build is green, deploy in the morning.
+
+It is important to do this as soon as possible, so we can catch any errors before we release the full version.
 
-* Mention what GitLab is on the second line: GitLab is open source software to collaborate on code.
-* Select and thank the the Most Valuable Person (MVP) of this release.
-* Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible.
 
-# Tweet
+# **22nd - Release CE and EE**
 
-Send out a tweet to share the good news with the world. For a major/minor release, list the features in short and link to the blog post.
+For GitLab EE, append -ee to the branches and tags.
 
-For a RC, make sure to explain what a RC is.
+`x-x-stable-ee`
+
+`v.x.x.0-ee`
+
+### **1. Create x-x-stable branch and push to the repositories**
+
+```
+git checkout master
+git pull
+git checkout -b x-x-stable
+git push <remote> x-x-stable
+```
+
+### **2. Build the Omnibus packages**
+[Follow this guide](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md)
+
+### **3. QA**
+Use the omnibus packages to test using [this guide](https://dev.gitlab.org/gitlab/gitlab-ee/blob/master/doc/release/manual_testing.md)
+
+
+### **4. Fix anything coming out of the QA**
+
+### **5. Set VERSION to x.x.0**
+
+### **6. Create annotated tag vx.x.0**
+```
+git tag -a vx.x.0 -m 'Version x.x.0'
+```
+
+### **7. Push VERSION + Tag to master, merge into x-x-stable**
+```
+git push origin master
+```
+
+Next, merge the VERSION into the x-x-stable branch.
+
+### **8. Push to remotes**
+
+For GitLab CE, push to dev, GitLab.com and GitHub.
+
+For GitLab EE, push to the subscribers repo.
+
+NOTE: You might not have the rights to push to master on dev. Ask Dmitriy.
+
+### **9. Publish blog for new release**
+* Mention what GitLab is on the second line: GitLab is open source software to collaborate on code.
+* Select and thank the the Most Valuable Person (MVP) of this release.
+* Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible.
 
-A patch release tweet should specify the fixes it brings and link to the corresponding blog post.
+### **10. Tweet to blog**
 
+Send out a tweet to share the good news with the world. List the features in short and link to the blog post.
 
+# **23rd - Optional Patch Release**
 
+# **25th - Release GitLab CI**
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index 76ca2a59911a8c8c89e412fc18c70b1b7953f7dd..5c8daf466ab4382cfae0cc64b430e10482bd97cb 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -16,6 +16,7 @@ System hooks can be used, e.g. for logging or changing information in a LDAP ser
                 "path": "stormcloud",
  "path_with_namespace": "jsmith/stormcloud",
           "project_id": 74,
+  "project_visibility": "private",
 }
 ```
 
@@ -31,6 +32,7 @@ System hooks can be used, e.g. for logging or changing information in a LDAP ser
                 "path": "underscore",
  "path_with_namespace": "jsmith/underscore",
           "project_id": 73,
+  "project_visibility": "internal",
 }
 ```
 
@@ -38,14 +40,15 @@ System hooks can be used, e.g. for logging or changing information in a LDAP ser
 
 ```json
 {
-     "created_at": "2012-07-21T07:30:56Z",
-     "event_name": "user_add_to_team",
- "project_access": "Master",
-     "project_id": 74, 
-   "project_name": "StoreCloud",
-   "project_path": "storecloud", 
-    "user_email": "johnsmith@gmail.com",
-     "user_name": "John Smith",
+         "created_at": "2012-07-21T07:30:56Z",
+         "event_name": "user_add_to_team",
+     "project_access": "Master",
+         "project_id": 74,
+       "project_name": "StoreCloud",
+       "project_path": "storecloud",
+         "user_email": "johnsmith@gmail.com",
+          "user_name": "John Smith",
+ "project_visibility": "private",
 }
 ```
 
@@ -53,14 +56,15 @@ System hooks can be used, e.g. for logging or changing information in a LDAP ser
 
 ```json
 {
-     "created_at": "2012-07-21T07:30:56Z",
-     "event_name": "user_remove_from_team",
- "project_access": "Master",
-     "project_id": 74, 
-   "project_name": "StoreCloud",
-   "project_path": "storecloud", 
-    "user_email": "johnsmith@gmail.com",
-     "user_name": "John Smith",
+         "created_at": "2012-07-21T07:30:56Z",
+         "event_name": "user_remove_from_team",
+     "project_access": "Master",
+         "project_id": 74,
+       "project_name": "StoreCloud",
+       "project_path": "storecloud",
+         "user_email": "johnsmith@gmail.com",
+          "user_name": "John Smith",
+ "project_visibility": "private",
 }
 ```
 
diff --git a/doc/update/6.0-to-6.7.md b/doc/update/6.0-to-6.8.md
similarity index 84%
rename from doc/update/6.0-to-6.7.md
rename to doc/update/6.0-to-6.8.md
index aa1b388fa9a533209a6094fa5834b237e8d779d2..5c71e99aa527653cd03983c5491c20056a3b1351 100644
--- a/doc/update/6.0-to-6.7.md
+++ b/doc/update/6.0-to-6.8.md
@@ -1,4 +1,4 @@
-# From 6.0 to 6.7
+# From 6.0 to 6.8
 
 # In 6.1 we remove a lot of deprecated code.
 # You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run.
@@ -33,7 +33,7 @@ sudo -u git -H git fetch --all
 For Gitlab Community Edition:
 
 ```bash
-sudo -u git -H git checkout 6-7-stable
+sudo -u git -H git checkout 6-8-stable
 ```
 
 OR
@@ -41,7 +41,7 @@ OR
 For GitLab Enterprise Edition:
 
 ```bash
-sudo -u git -H git checkout 6-7-stable-ee
+sudo -u git -H git checkout 6-8-stable-ee
 ```
 
 
@@ -57,7 +57,7 @@ sudo apt-get install logrotate
 ```bash
 cd /home/git/gitlab-shell
 sudo -u git -H git fetch
-sudo -u git -H git checkout v1.9.1 # Addresses multiple critical security vulnerabilities
+sudo -u git -H git checkout v1.9.3 # Addresses multiple critical security vulnerabilities
 ```
 
 ### 5. Install libs, migrations, etc.
@@ -90,11 +90,12 @@ sudo chmod u+rwx,g+rx,o-rwx /home/git/gitlab-satellites
 TIP: to see what changed in gitlab.yml.example in this release use next command: 
 
 ```
-git diff 6-0-stable:config/gitlab.yml.example 6-7-stable:config/gitlab.yml.example
+git diff 6-0-stable:config/gitlab.yml.example 6-8-stable:config/gitlab.yml.example
 ```
 
-* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/gitlab.yml.example but with your settings.
-* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/unicorn.rb.example but with your settings.
+* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-8-stable/config/gitlab.yml.example but with your settings.
+* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-8-stable/config/unicorn.rb.example but with your settings.
+* Make `/etc/nginx/sites-available/nginx` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-8-stable/lib/support/nginx/gitlab but with your settings.
 * Copy rack attack middleware config
 
 ```bash
diff --git a/doc/update/6.6-to-6.7.md b/doc/update/6.6-to-6.7.md
index 0f39c037c9fabc1ca00aa12382d3d802d0eeff35..61a63057d0856c5f447a74a4a1f507f502e10ae0 100644
--- a/doc/update/6.6-to-6.7.md
+++ b/doc/update/6.6-to-6.7.md
@@ -64,6 +64,10 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
 # Update the logrotate configuration (keep logs for 90 days instead of 52 weeks)
 sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
 
+# Compress existing .log.1 files because we turned off delaycompress in logrotate
+sudo -u git -H gzip /home/git/gitlab/log/*.log.1
+sudo -u git -H gzip /home/git/gitlab-shell/gitlab-shell.log.1
+
 # Close access to gitlab-satellites for others
 sudo chmod u+rwx,g+rx,o-rwx /home/git/gitlab-satellites
 ```
diff --git a/doc/update/6.7-to-6.8.md b/doc/update/6.7-to-6.8.md
index 63023fd384baa3b70ba6db5bbbe0f091b2565f22..cb19d235819b395827527cafeea28a3e7fdb453f 100644
--- a/doc/update/6.7-to-6.8.md
+++ b/doc/update/6.7-to-6.8.md
@@ -62,9 +62,7 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS
 
 # Update init.d script
 sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
-
-# Update the logrotate configuration (keep logs for 90 days instead of 52 weeks)
-sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
 
 # Close access to gitlab-satellites for others
 sudo chmod u+rwx,g+rx,o-rwx /home/git/gitlab-satellites
@@ -92,19 +90,12 @@ If you are using HTTPS, disable gzip as in [this commit](https://gitlab.com/gitl
 
 To improve performance, enable gzip asset compression as seen [in this commit](https://gitlab.com/gitlab-org/gitlab-ce/commit/8af94ed75505f0253823b9b2d44320fecea5b5fb).
 
-### 6. Update Init script
-
-```bash
-sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
-sudo chmod +x /etc/init.d/gitlab
-```
-
-### 7. Start application
+### 6. Start application
 
     sudo service gitlab start
     sudo service nginx restart
 
-### 8. Check application status
+### 7. Check application status
 
 Check if GitLab and its environment are configured correctly:
 
diff --git a/doc/update/6.8-to-6.9.md b/doc/update/6.8-to-6.9.md
new file mode 100644
index 0000000000000000000000000000000000000000..4a3e45ae5eeb65415e90b089bd62d4511d72edfd
--- /dev/null
+++ b/doc/update/6.8-to-6.9.md
@@ -0,0 +1,102 @@
+# From 6.8 to 6.9
+
+### 0. Backup
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
+```
+
+### 1. Stop server
+
+```bash
+sudo service gitlab stop
+```
+
+### 2. Get latest code
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H git fetch --all
+```
+
+For Gitlab Community Edition:
+
+```bash
+sudo -u git -H git checkout 6-9-stable
+```
+
+OR
+
+For GitLab Enterprise Edition:
+
+```bash
+sudo -u git -H git checkout 6-9-stable-ee
+```
+
+### 3. Update gitlab-shell (and its config)
+
+```bash
+cd /home/git/gitlab-shell
+sudo -u git -H git fetch
+sudo -u git -H git checkout v1.9.4
+```
+
+### 4. Install libs, migrations, etc.
+
+```bash
+cd /home/git/gitlab
+
+# MySQL installations (note: the line below states '--without ... postgres')
+sudo -u git -H bundle install --without development test postgres --deployment
+
+# PostgreSQL installations (note: the line below states '--without ... mysql')
+sudo -u git -H bundle install --without development test mysql --deployment
+
+# Run database migrations
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+
+# Clean up assets and cache
+sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
+```
+
+### 5. Update config files
+
+#### New configuration options for gitlab.yml
+
+There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml if desired.
+
+```
+git diff 6-8-stable:config/gitlab.yml.example 6-9-stable:config/gitlab.yml.example
+```
+
+### 6. Start application
+
+    sudo service gitlab start
+    sudo service nginx restart
+
+### 7. Check application status
+
+Check if GitLab and its environment are configured correctly:
+
+    sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
+
+To make sure you didn't miss anything run a more thorough check with:
+
+    sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+
+If all items are green, then congratulations upgrade is complete!
+
+## Things went south? Revert to previous version (6.8)
+
+### 1. Revert the code to the previous version
+Follow the [`upgrade guide from 6.7 to 6.8`](6.7-to-6.8.md), except for the database migration 
+(The backup is already migrated to the previous version)
+
+### 2. Restore from the backup:
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
+```
+If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above.
diff --git a/doc/update/mysql_to_postgresql.md b/doc/update/mysql_to_postgresql.md
index 9a324545eb0ae373fe26a04e329206f033a55813..acd1e33f5990e392bd5f964fb76d60fad483da69 100644
--- a/doc/update/mysql_to_postgresql.md
+++ b/doc/update/mysql_to_postgresql.md
@@ -1,9 +1,96 @@
-# Use the shell commands below to convert a MySQL GitLab database to a PostgreSQL one.
+# Migrating GitLab from MySQL to Postgres
+
+If you are replacing MySQL with Postgres while keeping GitLab on the same
+server all you need to do is to export from MySQL, import into Postgres and
+rebuild the indexes as described below. If you are also moving GitLab to
+another server, or if you are switching to omnibus-gitlab, you may want to use
+a GitLab backup file. The second part of this documents explains the procedure
+to do this.
+
+## Export from MySQL and import into Postgres
+
+Use this if you are keeping GitLab on the same server.
 
 ```
-git clone https://github.com/lanyrd/mysql-postgresql-converter.git
+sudo service gitlab stop
+
+# Update /home/git/gitlab/config/database.yml
+
+git clone https://github.com/gitlabhq/mysql-postgresql-converter.git
 cd mysql-postgresql-converter
 mysqldump --compatible=postgresql --default-character-set=utf8 -r databasename.mysql -u root gitlabhq_production
 python db_converter.py databasename.mysql databasename.psql
 psql -f databasename.psql -d gitlabhq_production
+
+# Rebuild indexes (see below)
+
+sudo service gitlab start
+```
+
+
+## Rebuild indexes
+
+The lanyrd database converter script does not preserve all indexes, so we have
+to recreate them ourselves after migrating from MySQL. It is not necessary to
+shut down GitLab for this process.
+
+```
+# Clone the database converter on your Postgres-backed GitLab server
+cd /tmp
+git clone https://github.com/gitlabhq/mysql-postgresql-converter.git
+
+# Stash changes to db/schema.rb to make sure we can find the right index statements
+cd /home/git/gitlab
+sudo -u git -H git stash
+
+# Generate the `CREATE INDEX CONCURRENTLY` statements based on schema.rb
+cd /tmp/mysql-to-postgresql-converter
+ruby index_create_statements.rb /home/git/gitlab/db/schema.rb > index_create_statements.psql
+
+# Execute the SQL statements against the GitLab database
+sudo -u git psql -f index_create_statements.psql -d gitlabhq_production
+```
+
+## Converting a GitLab backup file from MySQL to Postgres
+
+GitLab backup files (<timestamp>_gitlab_backup.tar) contain a SQL dump.  Using
+the lanyrd database converter we can replace a MySQL database dump inside the
+tar file with a Postgres database dump. This can be useful if you are moving to
+another server.
+
+```
+# Stop GitLab
+sudo service gitlab stop
+
+# Create the backup
+cd /home/git/gitlab
+sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
+
+# Note the filename of the backup that was created. We will call it
+# TIMESTAMP_gitlab_backup.tar below.
+
+# Move the backup file we will convert to its own directory
+sudo -u git -H mkdir -p tmp/backups/postgresql
+sudo -u git -H mv tmp/backups/TIMESTAMP_gitlab_backup.tar tmp/backups/postgresql/
+
+# Create a separate database dump with PostgreSQL compatibility
+cd tmp/backups/postgresql
+sudo -u git -H mysqldump --compatible=postgresql --default-character-set=utf8 -r gitlabhq_production.mysql -u root gitlabhq_production
+
+# Clone the database converter
+sudo -u git -H git clone https://github.com/lanyrd/mysql-postgresql-converter.git
+
+# Convert gitlabhq_production.mysql
+sudo -u git -H mkdir db
+sudo -u git -H python mysql-postgresql-converter/db_converter.py gitlabhq_production.mysql db/database.sql
+
+# Replace the MySQL dump in TIMESTAMP_gitlab_backup.tar.
+
+# Warning: if you forget to replace TIMESTAMP below, tar will create a new file
+# 'TIMESTAMP_gitlab_backup.tar' without giving an error.
+
+sudo -u git -H tar rf TIMESTAMP_gitlab_backup.tar db/database.sql
+
+# Done! TIMESTAMP_gitlab_backup.tar can now be restored into a Postgres GitLab
+# installation. Remember to recreate the indexes after the import.
 ```
diff --git a/doc/update/ruby.md b/doc/update/ruby.md
index 9d0cafb3f05ef92321d256275a3e809f1d0307d9..e98167f6b6640769f619bdbc04fb06a24016312e 100644
--- a/doc/update/ruby.md
+++ b/doc/update/ruby.md
@@ -1,6 +1,6 @@
 # Updating Ruby from source
 
-This guide explains how to update Ruby in case you installed it from source according to the instructions in https://gitlab.com/gitlab-org/gitlab-ce/blob/masterdoc/install/installation.md#2-ruby .
+This guide explains how to update Ruby in case you installed it from source according to the [instructions](../install/installation.md#2-ruby).
 
 ### 1. Look for Ruby versions
 This guide will only update `/usr/local/bin/ruby`. You can see which Ruby binaries are installed on your system by running:
@@ -36,7 +36,7 @@ sudo gem install bundler
 ```
 
 ### 5. Reinstall GitLab gem bundle
-Just to be sure we will reinstall the gems used by GitLab. Note that the `bundle install` command [depends on your choice of database](https://gitlab.com/gitlab-org/gitlab-ce/blob/masterdoc/install/installation.md#install-gems).
+Just to be sure we will reinstall the gems used by GitLab. Note that the `bundle install` command [depends on your choice of database](../install/installation.md#install-gems).
 
 ```bash
 cd /home/git/gitlab
diff --git a/doc/update/upgrader.md b/doc/update/upgrader.md
index fd45154ac82909f7dd832260902915c3ea9a640b..72a94f67b3c5b4d3ac7ec1b03ebd4086bbc3a691 100644
--- a/doc/update/upgrader.md
+++ b/doc/update/upgrader.md
@@ -46,4 +46,8 @@ If all items are green, then congratulations upgrade is complete!
 
 You've read through the entire guide, and probably did all the steps manually. Here is a one liner for convenience, the next time you upgrade:
 
-    cd /home/git/gitlab; sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; sudo service gitlab stop; sudo -u git -H ruby script/upgrade.rb -y; sudo service gitlab start; sudo service nginx restart; sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+```bash
+cd /home/git/gitlab; sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; \
+  sudo service gitlab stop; sudo -u git -H ruby script/upgrade.rb -y; sudo service gitlab start; \
+  sudo service nginx restart; sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+```
diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md
index f80891e264d0ff54d515906e67db2b13410fcd03..4c06bc4d44401718e15b0b6b7f199c165241a247 100644
--- a/doc/web_hooks/web_hooks.md
+++ b/doc/web_hooks/web_hooks.md
@@ -2,16 +2,16 @@ Project web hooks allow you to trigger an URL if new code is pushed or a new iss
 
 ---
 
-You can configure web hook to listen for specific events like pushes, issues, merge requests.
-GitLab will send POST request with data to web hook URL.
-Web Hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.
+You can configure web hooks to listen for specific events like pushes, issues or merge requests.
+GitLab will send a POST request with data to the web hook URL.
+Web hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.
 If you send a web hook to an SSL endpoint [the certificate will not be verified](https://gitlab.com/gitlab-org/gitlab-ce/blob/ccd617e58ea71c42b6b073e692447d0fe3c00be6/app/models/web_hook.rb#L35) since many people use self-signed certificates.
 
 ---
 
 #### Push events
 
-Triggered when you push to the repository except pushing tags.
+Triggered when you push to the repository except when pushing tags.
 
 **Request body:**
 
@@ -25,16 +25,16 @@ Triggered when you push to the repository except pushing tags.
   "project_id": 15,
   "repository": {
     "name": "Diaspora",
-    "url": "git@localhost:diaspora.git",
+    "url": "git@example.com:diaspora.git",
     "description": "",
-    "homepage": "http://localhost/diaspora"
+    "homepage": "http://example.com/diaspora"
   },
   "commits": [
     {
       "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
       "message": "Update Catalan translation to e38cb41.",
       "timestamp": "2011-12-12T14:27:31+02:00",
-      "url": "http://localhost/diaspora/commits/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
+      "url": "http://example.com/diaspora/commits/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
       "author": {
         "name": "Jordi Mallach",
         "email": "jordi@softcatala.org"
@@ -44,7 +44,7 @@ Triggered when you push to the repository except pushing tags.
       "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
       "message": "fixed readme",
       "timestamp": "2012-01-03T23:36:29+02:00",
-      "url": "http://localhost/diaspora/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
+      "url": "http://example.com/diaspora/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
       "author": {
         "name": "GitLab dev user",
         "email": "gitlabdev@dv6700.(none)"
@@ -84,7 +84,7 @@ Triggered when a new issue is created or an existing issue was updated/closed/re
 
 #### Merge request events
 
-Triggered when a new merge request is created or an existing merge request was updated/merges/closed.
+Triggered when a new merge request is created or an existing merge request was updated/merged/closed.
 
 **Request body:**
 
@@ -112,3 +112,34 @@ Triggered when a new merge request is created or an existing merge request was u
   }
 }
 ```
+
+#### Example webhook receiver
+
+If you want to see GitLab's webhooks in action for testing purposes you can use
+a simple echo script running in a console session.
+
+Save the following file as `print_http_body.rb`.
+
+```ruby
+require 'webrick'
+
+server = WEBrick::HTTPServer.new(Port: ARGV.first)
+server.mount_proc '/' do |req, res|
+  puts req.body
+end
+
+trap 'INT' do server.shutdown end
+server.start
+```
+
+Pick an unused port (e.g. 8000) and start the script: `ruby print_http_body.rb
+8000`.  Then add your server as a webhook receiver in GitLab as
+`http://my.host:8000/`.
+
+When you press 'Test Hook' in GitLab, you should see something like this in the console.
+
+```
+{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",<SNIP>}
+example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0
+- -> /
+```
diff --git a/features/group.feature b/features/group.feature
index 4e11bcba9390c72c349d9ff9d51f35e9f1c1119b..71c28c07a3c2b8dd4bd9780a528a67d4278773ad 100644
--- a/features/group.feature
+++ b/features/group.feature
@@ -113,3 +113,10 @@ Feature: Groups
     Then I should see user "John Doe" in team list
     Then I should see user "Mary Jane" in team list
     Then I should not see the "Remove User From Group" button for "Mary Jane"
+
+  Scenario: Search member by name
+    Given "Mary Jane" is guest of group "Guest"
+    And I visit group "Guest" members page
+    When I search for 'Mary' member
+    Then I should see user "Mary Jane" in team list
+    Then I should not see user "John Doe" in team list
diff --git a/features/project/forked_merge_requests.feature b/features/project/forked_merge_requests.feature
index 2d94b98c90b32d46a708654063f2cfc165f47f81..5832b729deb10af76680f873d56807994f18d76e 100644
--- a/features/project/forked_merge_requests.feature
+++ b/features/project/forked_merge_requests.feature
@@ -30,11 +30,10 @@ Feature: Project Forked Merge Requests
     Given I visit project "Forked Shop" merge requests page
     And I click link "New Merge Request"
     And I fill out an invalid "Merge Request On Forked Project" merge request
-    And I submit the merge request
     Then I should see validation errors
 
   @javascript
   Scenario: Merge request should target fork repository by default
     Given I visit project "Forked Shop" merge requests page
     And I click link "New Merge Request"
-    Then the target repository should be the original repository
\ No newline at end of file
+    Then the target repository should be the original repository
diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature
index fd9a2f01a28c619ce85b4865003e5f547eaf24c4..a204c3e10c7d08105c7c833b6c273a57e2cf9b14 100644
--- a/features/project/source/browse_files.feature
+++ b/features/project/source/browse_files.feature
@@ -29,3 +29,13 @@ Feature: Project Browse files
     Given I click on "Gemfile.lock" file in repo
     And I click button "edit"
     Then I can edit code
+
+  @javascript
+  Scenario: I can see editing preview
+    Given I click on "Gemfile.lock" file in repo
+    And I click button "edit"
+    And I edit code
+    And I click link "Diff"
+    Then I see diff
+
+
diff --git a/features/project/wiki.feature b/features/project/wiki.feature
index 90eb2b79c6680cb976c0b177e5741ca1d1d11a7e..4a8c771ddac2207ac8301ce569419e54f346794f 100644
--- a/features/project/wiki.feature
+++ b/features/project/wiki.feature
@@ -45,3 +45,20 @@ Feature: Project Wiki
     And I browse to that Wiki page
     And I click on the "Pages" button
     Then I should see the existing page in the pages list
+
+  Scenario: File exists in wiki repo
+    Given I have an existing Wiki page with images linked on page
+    And I browse to wiki page with images
+    And I click on existing image link
+    Then I should see the image from wiki repo
+
+  Scenario: Image in wiki repo shown on the page
+    Given I have an existing Wiki page with images linked on page
+    And I browse to wiki page with images
+    Then Image should be shown on the page
+
+  Scenario: File does not exist in wiki repo
+    Given I have an existing Wiki page with images linked on page
+    And I browse to wiki page with images
+    And I click on image link
+    Then I should see the new wiki page form
diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb
index 394acd3fe8f14d3632db666501501a664b5146f8..706c9babcee55b96fb53d8ec8ea76efc9633e96a 100644
--- a/features/steps/dashboard/dashboard.rb
+++ b/features/steps/dashboard/dashboard.rb
@@ -25,7 +25,6 @@ class Dashboard < Spinach::FeatureSteps
     find("#merge_request_target_project_id").value.should == @project.id.to_s
     find("#merge_request_source_branch").value.should == "new_design"
     find("#merge_request_target_branch").value.should == "master"
-    find("#merge_request_title").value.should == "New design"
   end
 
   Given 'user with name "John Doe" joined project "Shop"' do
diff --git a/features/steps/group/group.rb b/features/steps/group/group.rb
index 81472d1ca3531d6c95f7bb43910830b46424f23a..5e0c71581f1ccdf8d5b8881557a55317b2f3d4d0 100644
--- a/features/steps/group/group.rb
+++ b/features/steps/group/group.rb
@@ -89,7 +89,7 @@ class Groups < Spinach::FeatureSteps
   Then 'I should see newly created group "Samurai"' do
     page.should have_content "Samurai"
     page.should have_content "Tokugawa Shogunate"
-    page.should have_content "You will only see events from projects in this group"
+    page.should have_content "Currently you are only seeing events from the"
   end
 
   And 'I change group "Owned" name to "new-name"' do
@@ -157,6 +157,13 @@ class Groups < Spinach::FeatureSteps
     # poltergeist always confirms popups.
   end
 
+  step 'I search for \'Mary\' member' do
+    within '.member-search-form' do
+      fill_in 'search', with: 'Mary'
+      click_button 'Search'
+    end
+  end
+
   protected
 
   def assigned_to_me key
diff --git a/features/steps/project/browse_files.rb b/features/steps/project/browse_files.rb
index 069086d5eac996d3c591d698ee0e2b8af101f985..7cdd1101ac5e7d6e3d51c7097876941cbba510d3 100644
--- a/features/steps/project/browse_files.rb
+++ b/features/steps/project/browse_files.rb
@@ -41,6 +41,18 @@ class ProjectBrowseFiles < Spinach::FeatureSteps
     page.evaluate_script('editor.getValue()').should == "GitlabFileEditor"
   end
 
+  step 'I edit code' do
+    page.execute_script('editor.setValue("GitlabFileEditor")')
+  end
+
+  step 'I click link "Diff"' do
+    click_link 'Diff'
+  end
+
+  step 'I see diff' do
+    page.should have_css '.line_holder.new'
+  end
+
   step 'I click on "new file" link in repo' do
     click_link 'new-file-link'
   end
diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb
index df69cb7543768f4bd5c2c8aafd7b9018bc3d9d9c..3c497638d9cd3c6b339d695501739fce013738c9 100644
--- a/features/steps/project/forked_merge_requests.rb
+++ b/features/steps/project/forked_merge_requests.rb
@@ -53,6 +53,7 @@ class ProjectForkedMergeRequests < Spinach::FeatureSteps
 
     find(:select, "merge_request_source_branch", {}).value.should == 'master'
     find(:select, "merge_request_target_branch", {}).value.should == 'stable'
+    click_button "Compare branches"
 
     fill_in "merge_request_title", with: "Merge Request On Forked Project"
   end
@@ -148,29 +149,19 @@ class ProjectForkedMergeRequests < Spinach::FeatureSteps
     current_path.should == edit_project_merge_request_path(@project, @merge_request)
     page.should have_content "Edit merge request ##{@merge_request.id}"
     find("#merge_request_title").value.should == "Merge Request On Forked Project"
-    find("#merge_request_source_project_id").value.should == @forked_project.id.to_s
-    find("#merge_request_target_project_id").value.should == @project.id.to_s
-    find("#merge_request_source_branch").value.should have_content "master"
-    verify_commit_link(".mr_source_commit",@forked_project)
-    find("#merge_request_target_branch").value.should have_content "stable"
-    verify_commit_link(".mr_target_commit",@project)
   end
 
   step 'I fill out an invalid "Merge Request On Forked Project" merge request' do
-    #If this isn't filled in the rest of the validations won't be triggered
-    fill_in "merge_request_title", with: "Merge Request On Forked Project"
-
     select "Select branch", from: "merge_request_target_branch"
-
     find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s
     find(:select, "merge_request_target_project_id", {}).value.should == project.id.to_s
     find(:select, "merge_request_source_branch", {}).value.should == ""
     find(:select, "merge_request_target_branch", {}).value.should == ""
+    click_button "Compare branches"
   end
 
   step 'I should see validation errors' do
-    page.should have_content "Source branch can't be blank"
-    page.should have_content "Target branch can't be blank"
+    page.should have_content "You must select source and target branch"
   end
 
   step 'the target repository should be the original repository' do
diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb
index f42eb6377ce1f741980c17aee1c85be80a7af298..e0aec699a56e9ae17cffaf972cf440fe233d9657 100644
--- a/features/steps/project/merge_requests.rb
+++ b/features/steps/project/merge_requests.rb
@@ -61,9 +61,10 @@ class ProjectMergeRequests < Spinach::FeatureSteps
   end
 
   step 'I submit new merge request "Wiki Feature"' do
-    fill_in "merge_request_title", with: "Wiki Feature"
     select "master", from: "merge_request_source_branch"
     select "notes_refactoring", from: "merge_request_target_branch"
+    click_button "Compare branches"
+    fill_in "merge_request_title", with: "Wiki Feature"
     click_button "Submit merge request"
   end
 
diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb
index a819ee37d7f7cb012e10e220b9f202cd4f08e40f..96f2505d24c1f06a9929455401999bdf70e3d190 100644
--- a/features/steps/project/wiki.rb
+++ b/features/steps/project/wiki.rb
@@ -86,6 +86,47 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps
     page.should have_content @page.title
   end
 
+  Given 'I have an existing Wiki page with images linked on page' do
+    wiki.create_page("pictures", "Look at this [image](image.jpg)\n\n ![image](image.jpg)", :markdown, "first commit")
+    @wiki_page = wiki.find_page("pictures")
+  end
+
+  And 'I browse to wiki page with images' do
+    visit project_wiki_path(project, @wiki_page)
+  end
+
+  And 'I click on existing image link' do
+    file = Gollum::File.new(wiki.wiki)
+    Gollum::Wiki.any_instance.stub(:file).with("image.jpg", "master", true).and_return(file)
+    Gollum::File.any_instance.stub(:mime_type).and_return("image/jpeg")
+    page.should have_link('image', href: "image.jpg")
+    click_on "image"
+  end
+
+  Then 'I should see the image from wiki repo' do
+    url = URI.parse(current_url)
+    url.path.should match("wikis/image.jpg")
+    page.should_not have_xpath('/html') # Page should render the image which means there is no html involved
+    Gollum::Wiki.any_instance.unstub(:file)
+    Gollum::File.any_instance.unstub(:mime_type)
+  end
+
+  Then 'Image should be shown on the page' do
+    page.should have_xpath("//img[@src=\"image.jpg\"]")
+  end
+
+  And 'I click on image link' do
+    page.should have_link('image', href: "image.jpg")
+    click_on "image"
+  end
+
+  Then 'I should see the new wiki page form' do
+    url = URI.parse(current_url)
+    url.path.should match("wikis/image.jpg")
+    page.should have_content('New Wiki Page')
+    page.should have_content('Editing - image.jpg')
+  end
+
   def wiki
     @project_wiki = ProjectWiki.new(project, current_user)
   end
diff --git a/lib/api/branches.rb b/lib/api/branches.rb
index 953c6100f8b914f92d42bd638b10d7e0610284f0..32597eb94c478848966db72a30d9e068be8ef4b8 100644
--- a/lib/api/branches.rb
+++ b/lib/api/branches.rb
@@ -24,7 +24,7 @@ module API
       #   branch (required) - The name of the branch
       # Example Request:
       #   GET /projects/:id/repository/branches/:branch
-      get ":id/repository/branches/:branch" do
+      get ':id/repository/branches/:branch', requirements: { branch: /.*/ } do
         @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
         not_found!("Branch does not exist") if @branch.nil?
         present @branch, with: Entities::RepoObject, project: user_project
@@ -37,7 +37,9 @@ module API
       #   branch (required) - The name of the branch
       # Example Request:
       #   PUT /projects/:id/repository/branches/:branch/protect
-      put ":id/repository/branches/:branch/protect" do
+      put ':id/repository/branches/:branch/protect',
+          requirements: { branch: /.*/ } do
+
         authorize_admin_project
 
         @branch = user_project.repository.find_branch(params[:branch])
@@ -55,7 +57,9 @@ module API
       #   branch (required) - The name of the branch
       # Example Request:
       #   PUT /projects/:id/repository/branches/:branch/unprotect
-      put ":id/repository/branches/:branch/unprotect" do
+      put ':id/repository/branches/:branch/unprotect',
+          requirements: { branch: /.*/ } do
+
         authorize_admin_project
 
         @branch = user_project.repository.find_branch(params[:branch])
@@ -80,6 +84,18 @@ module API
 
         present @branch, with: Entities::RepoObject, project: user_project
       end
+
+      # Delete branch
+      #
+      # Parameters:
+      #   id (required) - The ID of a project
+      #   branch (required) - The name of the branch
+      # Example Request:
+      #   DELETE /projects/:id/repository/branches/:branch
+      delete ":id/repository/branches/:branch" do
+        authorize_push_project
+        DeleteBranchService.new.execute(user_project, params[:branch], current_user)
+      end
     end
   end
 end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index abe6fceff14637f928084ca00ba6885c38effcdb..457af52fe9dad757aeabfceafc8029260c5ea60c 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -43,6 +43,7 @@ module API
     class Project < Grape::Entity
       expose :id, :description, :default_branch
       expose :public?, as: :public
+      expose :archived?, as: :archived
       expose :visibility_level, :ssh_url_to_repo, :http_url_to_repo, :web_url
       expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group }
       expose :name, :name_with_namespace
@@ -135,6 +136,7 @@ module API
       expose :target_branch, :source_branch, :upvotes, :downvotes
       expose :author, :assignee, using: Entities::UserBasic
       expose :source_project_id, :target_project_id
+      expose :label_list, as: :labels
     end
 
     class SSHKey < Grape::Entity
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 7ee4b9d13819c160ac65bd52cb4fbe88790bf15f..654c1f62c6c0f53d862f7f1e3f6a37ebfb171506 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -8,6 +8,11 @@ module API
     def current_user
       private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s
       @current_user ||= User.find_by(authentication_token: private_token)
+
+      unless @current_user && Gitlab::UserAccess.allowed?(@current_user)
+        return nil
+      end
+
       identifier = sudo_identifier()
 
       # If the sudo is the current user do nothing
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 4b88b0f84c124b4bd0d4030bcf4a8f5286ab5778..017cb1f562e82b93a695ae0d027a17b0a0470be2 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -34,7 +34,7 @@ module API
               when "closed" then user_project.merge_requests.closed
               when "merged" then user_project.merge_requests.merged
               else user_project.merge_requests
-        end
+              end
 
         present paginate(mrs), with: Entities::MergeRequest
       end
@@ -67,6 +67,7 @@ module API
       #   assignee_id              - Assignee user ID
       #   title (required)         - Title of MR
       #   description              - Description of MR
+      #   labels (optional)        - Labels for MR as a comma-separated list
       #
       # Example:
       #   POST /projects/:id/merge_requests
@@ -75,6 +76,7 @@ module API
         authorize! :write_merge_request, user_project
         required_attributes! [:source_branch, :target_branch, :title]
         attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description]
+        attrs[:label_list] = params[:labels] if params[:labels].present?
         merge_request = ::MergeRequests::CreateService.new(user_project, current_user, attrs).execute
 
         if merge_request.valid?
@@ -95,11 +97,13 @@ module API
       #   title                       - Title of MR
       #   state_event                 - Status of MR. (close|reopen|merge)
       #   description                 - Description of MR
+      #   labels (optional)           - Labels for a MR as a comma-separated list
       # Example:
       #   PUT /projects/:id/merge_request/:merge_request_id
       #
       put ":id/merge_request/:merge_request_id" do
         attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event, :description]
+        attrs[:label_list] = params[:labels] if params[:labels].present?
         merge_request = user_project.merge_requests.find(params[:merge_request_id])
         authorize! :modify_merge_request, merge_request
         merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, attrs).execute(merge_request)
@@ -111,6 +115,49 @@ module API
         end
       end
 
+      # Merge MR
+      #
+      # Parameters:
+      #   id (required)               - The ID of a project
+      #   merge_request_id (required) - ID of MR
+      #   merge_commit_message (optional) - Custom merge commit message
+      # Example:
+      #   PUT /projects/:id/merge_request/:merge_request_id/merge
+      #
+      put ":id/merge_request/:merge_request_id/merge" do
+        merge_request = user_project.merge_requests.find(params[:merge_request_id])
+
+        action = if user_project.protected_branch?(merge_request.target_branch)
+                   :push_code_to_protected_branches
+                 else
+                   :push_code
+                 end
+
+        if can?(current_user, action, user_project)
+          if merge_request.unchecked?
+            merge_request.check_if_can_be_merged
+          end
+
+          if merge_request.open?
+            if merge_request.can_be_merged?
+              merge_request.automerge!(current_user, params[:merge_commit_message] || merge_request.merge_commit_message)
+              present merge_request, with: Entities::MergeRequest
+            else
+              render_api_error!('Branch cannot be merged', 405)
+            end
+          else
+            # Merge request can not be merged
+            # because it is already closed/merged
+            not_allowed!
+          end
+        else
+          # Merge request can not be merged
+          # because user dont have permissions to push into target branch
+          unauthorized!
+        end
+      end
+
+
       # Get a merge request's comments
       #
       # Parameters:
diff --git a/lib/api/users.rb b/lib/api/users.rb
index ae808b6272bad4e1c0642b53227460615d26b264..6ed2740c3330281e75071333b15dfec5a17ee5c7 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -113,6 +113,45 @@ module API
         end
       end
 
+      # Get ssh keys of a specified user. Only available to admin users.
+      #
+      # Parameters:
+      # uid (required) - The ID of a user
+      # Example Request:
+      # GET /users/:uid/keys
+      get ':uid/keys' do
+        authenticated_as_admin!
+        user = User.find_by(id: params[:uid])
+        if user
+          present user.keys, with: Entities::SSHKey
+        else
+          not_found!
+        end
+      end
+
+      # Delete existing ssh key of a specified user. Only available to admin
+      # users.
+      #
+      # Parameters:
+      #   uid (required) - The ID of a user
+      #   id (required) - SSH Key ID
+      # Example Request:
+      #   DELETE /users/:uid/keys/:id
+      delete ':uid/keys/:id' do
+        authenticated_as_admin!
+        user = User.find_by(id: params[:uid])
+        if user
+          begin
+            key = user.keys.find params[:id]
+            key.destroy
+          rescue ActiveRecord::RecordNotFound
+            not_found!
+          end
+        else
+          not_found!
+        end
+      end
+
       # Delete user. Available only for admin
       #
       # Example Request:
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 05814fc78f6b8393ed1c4ed11cb2b23ccf8ba1cc..28e323fe30d148f04b70a9ac7f6a0e68aa1818f3 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -101,7 +101,7 @@ module Backup
 
     def tar_version
       tar_version, _ = Gitlab::Popen.popen(%W(tar --version))
-      tar_version.split("\n").first
+      tar_version.force_encoding('locale').split("\n").first
     end
   end
 end
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index 214d9824ee125cf118bbb0de835169d97f3e3fa8..6f7c4f7c9091ac2c010e317c59764df8315297c8 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -10,15 +10,12 @@ module Backup
       Project.find_each(batch_size: 1000) do |project|
         print " * #{project.path_with_namespace} ... "
 
-        if project.empty_repo?
-          puts "[SKIPPED]".cyan
-          next
-        end
-
         # Create namespace dir if missing
         FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.path)) if project.namespace
 
-        if system(*%W(git --git-dir=#{path_to_repo(project)} bundle create #{path_to_bundle(project)} --all), silent)
+        if project.empty_repo?
+          puts "[SKIPPED]".cyan
+        elsif system(*%W(git --git-dir=#{path_to_repo(project)} bundle create #{path_to_bundle(project)} --all), silent)
           puts "[DONE]".green
         else
           puts "[FAILED]".red
diff --git a/lib/gitlab/diff_parser.rb b/lib/gitlab/diff_parser.rb
index fb27280c4a4d403b7183c7c5c370586ac536c0cf..14bbb328637bc5acdb8051f52be7ec521587ef19 100644
--- a/lib/gitlab/diff_parser.rb
+++ b/lib/gitlab/diff_parser.rb
@@ -4,9 +4,9 @@ module Gitlab
 
     attr_reader :lines, :new_path
 
-    def initialize(diff)
-      @lines = diff.diff.lines.to_a
-      @new_path = diff.new_path
+    def initialize(lines, new_path = '')
+      @lines = lines
+      @new_path = new_path
     end
 
     def each
@@ -18,10 +18,7 @@ module Gitlab
       lines_arr.each do |line|
         raw_line = line.dup
 
-        next if line.match(/^\-\-\- \/dev\/null/)
-        next if line.match(/^\+\+\+ \/dev\/null/)
-        next if line.match(/^\-\-\- a/)
-        next if line.match(/^\+\+\+ b/)
+        next if filename?(line)
 
         full_line = html_escape(line.gsub(/\n/, ''))
         full_line = ::Gitlab::InlineDiff.replace_markers full_line
@@ -53,8 +50,17 @@ module Gitlab
       end
     end
 
+    def empty?
+      @lines.empty?
+    end
+
     private
 
+    def filename?(line)
+      line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b',
+                       '--- /tmp/diffy', '+++ /tmp/diffy')
+    end
+
     def identification_type(line)
       if line[0] == "+"
         "new"
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index eefdb1833fc1f3dec3aad83a2668803c7cef6e48..2f8b55aaca0164b3acfc725eb180826df078fa15 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -44,14 +44,18 @@ module Gitlab
     def push_allowed?(user, project, ref, oldrev, newrev, forced_push)
       if user && user_allowed?(user)
         action = if project.protected_branch?(ref)
-                    if forced_push.to_s == 'true'
-                      :force_push_code_to_protected_branches
-                    else
-                      :push_code_to_protected_branches
-                    end
-                  else
-                    :push_code
-                  end
+                   # we dont allow force push to protected branch
+                   if forced_push.to_s == 'true'
+                     :force_push_code_to_protected_branches
+                   # and we dont allow remove of protected branch
+                   elsif newrev =~ /0000000/
+                     :remove_protected_branches
+                   else
+                     :push_code_to_protected_branches
+                   end
+                 else
+                   :push_code
+                 end
         user.can?(action, project)
       else
         false
@@ -61,18 +65,7 @@ module Gitlab
     private
 
     def user_allowed?(user)
-      return false if user.blocked?
-
-      if Gitlab.config.ldap.enabled
-        if user.ldap_user?
-          # Check if LDAP user exists and match LDAP user_filter
-          unless Gitlab::LDAP::Access.new.allowed?(user)
-            return false
-          end
-        end
-      end
-
-      true
+      Gitlab::UserAccess.allowed?(user)
     end
   end
 end
diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb
index 8f492e5c012791031f2f0f03f180ba20561f5487..4e48ff11871dadf2c2e226de3004d8150653ca29 100644
--- a/lib/gitlab/ldap/access.rb
+++ b/lib/gitlab/ldap/access.rb
@@ -14,7 +14,11 @@ module Gitlab
       end
 
       def allowed?(user)
-        !!Gitlab::LDAP::Person.find_by_dn(user.extern_uid, adapter)
+        if Gitlab::LDAP::Person.find_by_dn(user.extern_uid, adapter)
+          !Gitlab::LDAP::Person.active_directory_disabled?(user.extern_uid, adapter)
+        else
+          false
+        end
       rescue
         false
       end
diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb
index 983a2956a35dfef0c115f55e951fe76fc81f1389..e36616f0e666833ef64c54a21a26b7d1d8d35e70 100644
--- a/lib/gitlab/ldap/adapter.rb
+++ b/lib/gitlab/ldap/adapter.rb
@@ -44,7 +44,8 @@ module Gitlab
       def users(field, value)
         if field.to_sym == :dn
           options = {
-            base: value
+            base: value,
+            scope: Net::LDAP::SearchScope_BaseObject
           }
         else
           options = {
@@ -63,7 +64,7 @@ module Gitlab
                              end
         end
 
-        entries = ldap.search(options).select do |entry|
+        entries = ldap_search(options).select do |entry|
           entry.respond_to? config.uid
         end
 
@@ -76,6 +77,26 @@ module Gitlab
         users(*args).first
       end
 
+      def dn_matches_filter?(dn, filter)
+        ldap_search(base: dn, filter: filter, scope: Net::LDAP::SearchScope_BaseObject, attributes: %w{dn}).any?
+      end
+
+      def ldap_search(*args)
+        results = ldap.search(*args)
+
+        if results.nil?
+          response = ldap.get_operation_result
+
+          unless response.code.zero?
+            Rails.logger.warn("LDAP search error: #{response.message}")
+          end
+
+          []
+        else
+          results
+        end
+      end
+
       private
 
       def config
diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb
index 06b17c58f8c417898353253555d8014b57a6e9b5..9ad6618bd46448e8dc4613a1b904fb92859c2435 100644
--- a/lib/gitlab/ldap/person.rb
+++ b/lib/gitlab/ldap/person.rb
@@ -1,6 +1,11 @@
 module Gitlab
   module LDAP
     class Person
+      # Active Directory-specific LDAP filter that checks if bit 2 of the
+      # userAccountControl attribute is set.
+      # Source: http://ctogonewild.com/2009/09/03/bitmask-searches-in-ldap/
+      AD_USER_DISABLED = Net::LDAP::Filter.ex("userAccountControl:1.2.840.113556.1.4.803", "2")
+
       def self.find_by_uid(uid, adapter=nil)
         adapter ||= Gitlab::LDAP::Adapter.new
         adapter.user(config.uid, uid)
@@ -11,6 +16,11 @@ module Gitlab
         adapter.user('dn', dn)
       end
 
+      def self.active_directory_disabled?(dn, adapter=nil)
+        adapter ||= Gitlab::LDAP::Adapter.new
+        adapter.dn_matches_filter?(dn, AD_USER_DISABLED)
+      end
+
       def initialize(entry)
         Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" }
         @entry = entry
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index de14a3eca275611cf7ada45224116049f31bf8e7..dca3d7a7bed14ebaf1c930d6dc0ab0cbda49b9f1 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -98,6 +98,7 @@ module Gitlab
       (?<prefix>\W)?                         # Prefix
       (                                      # Reference
          @(?<user>[a-zA-Z][a-zA-Z0-9_\-\.]*) # User name
+        |(?<issue>([A-Z\-]+-)\d+)            # JIRA Issue ID
         |\#(?<issue>([a-zA-Z\-]+-)?\d+)      # Issue ID
         |!(?<merge_request>\d+)              # MR ID
         |\$(?<snippet>\d+)                   # Snippet ID
@@ -172,11 +173,15 @@ module Gitlab
     end
 
     def reference_issue(identifier)
-      if @project.issue_exists? identifier
-        url = url_for_issue(identifier)
-        title = title_for_issue(identifier)
+      if @project.used_default_issues_tracker? || !external_issues_tracker_enabled?
+        if @project.issue_exists? identifier
+          url = url_for_issue(identifier)
+          title = title_for_issue(identifier)
 
-        link_to("##{identifier}", url, html_options.merge(title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
+          link_to("##{identifier}", url, html_options.merge(title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
+        end
+      else
+        reference_jira_issue(identifier) if @project.issues_tracker == "jira"
       end
     end
 
@@ -197,5 +202,12 @@ module Gitlab
         link_to(identifier, project_commit_url(@project, commit), html_options.merge(title: commit.link_title, class: "gfm gfm-commit #{html_options[:class]}"))
       end
     end
+
+    def reference_jira_issue(identifier)
+      url = url_for_issue(identifier)
+      title = Gitlab.config.issues_tracker[@project.issues_tracker]["title"]
+
+      link_to("#{identifier}", url, html_options.merge(title: "Issue in #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
+    end
   end
 end
diff --git a/lib/gitlab/oauth/user.rb b/lib/gitlab/oauth/user.rb
index 1bac93378ef9c9d8f7ef2810de48570b8735801d..d154bd8600bbe34f569b88d1438300dcee20ed16 100644
--- a/lib/gitlab/oauth/user.rb
+++ b/lib/gitlab/oauth/user.rb
@@ -34,9 +34,11 @@ module Gitlab
           # In this case we generate temporary email and force user to fill it later
           if user.email.blank?
             user.generate_tmp_oauth_email
-          else
+          elsif provider != "ldap"
             # Google oauth returns email but dont return nickname
             # So we use part of email as username for new user
+            # For LDAP, username is already set to the user's
+            # uid/userid/sAMAccountName.
             user.username = email.match(/^[^@]*/)[0]
           end
 
@@ -65,7 +67,11 @@ module Gitlab
         end
 
         def name
-          auth.info.name.to_s.force_encoding("utf-8")
+          if auth.info.name.nil?
+            "#{auth.info.first_name} #{auth.info.last_name}".force_encoding('utf-8')
+          else
+            auth.info.name.to_s.force_encoding('utf-8')
+          end
         end
 
         def username
diff --git a/lib/gitlab/satellite/compare_action.rb b/lib/gitlab/satellite/compare_action.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c923bb9c0f00d8f6def33e7ad6d15c96ab4989cc
--- /dev/null
+++ b/lib/gitlab/satellite/compare_action.rb
@@ -0,0 +1,53 @@
+module Gitlab
+  module Satellite
+    class CompareAction < Action
+      def initialize(user, target_project, target_branch, source_project, source_branch)
+        super user, target_project
+
+        @target_project, @target_branch = target_project, target_branch
+        @source_project, @source_branch = source_project, source_branch
+      end
+
+      # Only show what is new in the source branch compared to the target branch, not the other way around.
+      # The line below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
+      # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
+      def diffs
+        in_locked_and_timed_satellite do |target_repo|
+          prepare_satellite!(target_repo)
+          update_satellite_source_and_target!(target_repo)
+          common_commit = target_repo.git.native(:merge_base, default_options, ["origin/#{@target_branch}", "source/#{@source_branch}"]).strip
+          #this method doesn't take default options
+          diffs = target_repo.diff(common_commit, "source/#{@source_branch}")
+          diffs = diffs.map { |diff| Gitlab::Git::Diff.new(diff) }
+          diffs
+        end
+      rescue Grit::Git::CommandFailed => ex
+        handle_exception(ex)
+      end
+
+      # Retrieve an array of commits between the source and the target
+      def commits
+        in_locked_and_timed_satellite do |target_repo|
+          prepare_satellite!(target_repo)
+          update_satellite_source_and_target!(target_repo)
+          commits = target_repo.commits_between("origin/#{@target_branch}", "source/#{@source_branch}")
+          commits = commits.map { |commit| Gitlab::Git::Commit.new(commit, nil) }
+          commits
+        end
+      rescue Grit::Git::CommandFailed => ex
+        handle_exception(ex)
+      end
+
+      private
+
+      # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for diffs
+      def update_satellite_source_and_target!(target_repo)
+        target_repo.remote_add('source', @source_project.repository.path_to_repo)
+        target_repo.remote_fetch('source')
+        target_repo.git.checkout(default_options({b: true}), @target_branch, "origin/#{@target_branch}")
+      rescue Grit::Git::CommandFailed => ex
+        handle_exception(ex)
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb
index c6e4d3351cf51cdb84a6511f798209cc55dfa2ea..05123ad9c4181edbaac966b9d3a684101b0c85cf 100644
--- a/lib/gitlab/satellite/satellite.rb
+++ b/lib/gitlab/satellite/satellite.rb
@@ -84,6 +84,7 @@ module Gitlab
       # Clear the working directory
       def clear_working_dir!
         repo.git.reset(hard: true)
+        repo.git.clean(f: true, d: true, x: true)
       end
 
       # Deletes all branches except the parking branch
diff --git a/lib/gitlab/user_access.rb b/lib/gitlab/user_access.rb
new file mode 100644
index 0000000000000000000000000000000000000000..16df21b49baaf2ccf56f5f72fabf50964ce83631
--- /dev/null
+++ b/lib/gitlab/user_access.rb
@@ -0,0 +1,18 @@
+module Gitlab
+  module UserAccess
+    def self.allowed?(user)
+      return false if user.blocked?
+
+      if Gitlab.config.ldap.enabled
+        if user.ldap_user?
+          # Check if LDAP user exists and match LDAP user_filter
+          Gitlab::LDAP::Access.open do |adapter|
+            return false unless adapter.allowed?(user)
+          end
+        end
+      end
+
+      true
+    end
+  end
+end
diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
index f64c8d5883c53d4046825a23d3b05af6e79a3823..98c916373909fceed6aac97d961706f7b8404da9 100644
--- a/lib/support/nginx/gitlab
+++ b/lib/support/nginx/gitlab
@@ -59,6 +59,9 @@ server {
   }
 
   # Enable gzip compression as per rails guide: http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression
+  # WARNING: If you are using relative urls do remove the block below
+  # See config/application.rb under "Relative url support" for the list of
+  # other files that need to be changed for relative url support
   location ~ ^/(assets)/  {
     root /home/git/gitlab/public;
     gzip_static on; # to serve pre-gzipped version
@@ -67,4 +70,4 @@ server {
   }
 
   error_page 502 /502.html;
-}
\ No newline at end of file
+}
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index e9258cc626b2046a8f385df08b254ac6015515f2..0387795fa4846b1db9093782eeceec1ed8e85db4 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -779,7 +779,7 @@ namespace :gitlab do
   end
 
   def check_gitlab_shell
-    required_version = Gitlab::VersionInfo.new(1, 9, 1)
+    required_version = Gitlab::VersionInfo.new(1, 9, 4)
     current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
 
     print "GitLab Shell version >= #{required_version} ? ... "
diff --git a/lib/tasks/gitlab/setup.rake b/lib/tasks/gitlab/setup.rake
index 853994dd67db0dc2a2f7b636aafc3c4e1212c045..8b4ccdfc3fe01eb0b7ad8308746024c02bec7875 100644
--- a/lib/tasks/gitlab/setup.rake
+++ b/lib/tasks/gitlab/setup.rake
@@ -15,14 +15,7 @@ namespace :gitlab do
     end
 
     Rake::Task["db:setup"].invoke
-
-    config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
-    success = case config["adapter"]
-              when /^mysql/ then
-                Rake::Task["add_limits_mysql"].invoke
-              when "postgresql" then
-              end
-
+    Rake::Task["add_limits_mysql"].invoke
     Rake::Task["db:seed_fu"].invoke
   rescue Gitlab::TaskAbortedByUserError
     puts "Quitting...".red
diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake
index 08de0f2dd5d259117a26a48dc8f4e7e4f31da19e..dfc90bb3339ba86d8c6aa2f2af2043bf8b8d91f0 100644
--- a/lib/tasks/gitlab/shell.rake
+++ b/lib/tasks/gitlab/shell.rake
@@ -1,5 +1,64 @@
 namespace :gitlab do
   namespace :shell do
+    desc "GITLAB | Install or upgrade gitlab-shell"
+    task :install, [:tag, :repo] => :environment do |t, args|
+      warn_user_is_not_gitlab
+
+      args.with_defaults(tag: "v1.9.3", repo: "https://gitlab.com/gitlab-org/gitlab-shell.git")
+
+      user = Settings.gitlab.user
+      home_dir = Settings.gitlab.user_home
+      gitlab_url = Settings.gitlab.url
+      # gitlab-shell requires a / at the end of the url
+      gitlab_url += "/" unless gitlab_url.match(/\/$/)
+      repos_path = Gitlab.config.gitlab_shell.repos_path
+      target_dir = Gitlab.config.gitlab_shell.path
+
+      # Clone if needed
+      unless File.directory?(target_dir)
+        sh "git clone '#{args.repo}' '#{target_dir}'"
+      end
+
+      # Make sure we're on the right tag
+      Dir.chdir(target_dir) do
+        sh "git fetch origin && git reset --hard $(git describe #{args.tag} || git describe origin/#{args.tag})"
+
+        redis_url = URI.parse(ENV['REDIS_URL'] || "redis://localhost:6379")
+
+        config = {
+          user: user,
+          gitlab_url: gitlab_url,
+          http_settings: {self_signed_cert: false}.stringify_keys,
+          repos_path: repos_path,
+          auth_file: File.join(home_dir, ".ssh", "authorized_keys"),
+          redis: {
+            bin: %x{which redis-cli}.chomp,
+            host: redis_url.host,
+            port: redis_url.port,
+            namespace: "resque:gitlab"
+          }.stringify_keys,
+          log_level: "INFO",
+          audit_usernames: false
+        }.stringify_keys
+
+        # Generate config.yml based on existing gitlab settings
+        File.open("config.yml", "w+") {|f| f.puts config.to_yaml}
+
+        # Launch installation process
+        sh "bin/install"
+      end
+
+      # Required for debian packaging with PKGR: Setup .ssh/environment with
+      # the current PATH, so that the correct ruby version gets loaded
+      # Requires to set "PermitUserEnvironment yes" in sshd config (should not
+      # be an issue since it is more than likely that there are no "normal"
+      # user accounts on a gitlab server). The alternative is for the admin to
+      # install a ruby (1.9.3+) in the global path.
+      File.open(File.join(home_dir, ".ssh", "environment"), "w+") do |f|
+        f.puts "PATH=#{ENV['PATH']}"
+      end
+    end
+
     desc "GITLAB | Setup gitlab-shell"
     task setup: :environment do
       setup
diff --git a/lib/tasks/gitlab/test.rake b/lib/tasks/gitlab/test.rake
index 2c9b997893307463d5b4e08dba79fb427b7163a5..9516210e205ffde18906a76a76a905906aaaaaec 100644
--- a/lib/tasks/gitlab/test.rake
+++ b/lib/tasks/gitlab/test.rake
@@ -8,9 +8,9 @@ namespace :gitlab do
     ]
 
     cmds.each do |cmd|
-      system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd)
+      result = system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd)
 
-      raise "#{cmd} failed!" unless $?.exitstatus.zero?
+      raise "#{cmd} failed!" unless result
     end
   end
 end
diff --git a/lib/tasks/migrate/add_limits_mysql.rake b/lib/tasks/migrate/add_limits_mysql.rake
index 46b6451752b5bca5de8a756094e05d796434cf23..a1972a682d8512766e8dd6b6c6d24ab44c812461 100644
--- a/lib/tasks/migrate/add_limits_mysql.rake
+++ b/lib/tasks/migrate/add_limits_mysql.rake
@@ -1,14 +1,7 @@
+require Rails.root.join('db/migrate/limits_to_mysql')
+
 desc "GITLAB | Add limits to strings in mysql database"
 task add_limits_mysql: :environment do
   puts "Adding limits to schema.rb for mysql"
   LimitsToMysql.new.up
 end
-
-class LimitsToMysql < ActiveRecord::Migration
-  def up
-    change_column :merge_request_diffs, :st_commits, :text, limit: 2147483647
-    change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647
-    change_column :snippets, :content, :text, limit: 2147483647
-    change_column :notes, :st_diff, :text, limit: 2147483647
-  end
-end
diff --git a/lib/tasks/setup.rake b/lib/tasks/setup.rake
new file mode 100644
index 0000000000000000000000000000000000000000..93701de8f6309ff9643fcdde9bfa9c653c113b6b
--- /dev/null
+++ b/lib/tasks/setup.rake
@@ -0,0 +1,4 @@
+desc "GITLAB | Setup gitlab db"
+task :setup do
+  Rake::Task["gitlab:setup"].invoke
+end
diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f2e0dd090ff597a7261de7b8b7d403a92691a51
Binary files /dev/null and b/public/apple-touch-icon-precomposed.png differ
diff --git a/public/static.css b/public/static.css
index aa834553a1ca64ab8fdde45835f04947f259a334..c6f92ac01d90897ad9fd97c41ae715137d92d38d 100644
--- a/public/static.css
+++ b/public/static.css
@@ -2,7 +2,6 @@ body {
   color: #666;
   text-align: center;
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  sans-serif;
   margin:0;
   width: 800px;
   margin: auto;
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index cfb6deb1834eb931a61ce73960002323a65b0f9d..45aebf128c299fac579108463df3a962df8b4eb6 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -132,7 +132,7 @@ describe "On a merge request", js: true, feature: true do
   end
 end
 
-describe "On a merge request diff", js: true do
+describe "On a merge request diff", js: true, feature: true do
   let(:merge_request) { create(:merge_request, :with_diffs, :simple) }
   let(:project) { merge_request.source_project }
 
@@ -210,9 +210,3 @@ describe "On a merge request diff", js: true do
     end
   end
 end
-
-describe "On merge request discussion", js: true do
-  describe "with merge request diff note"
-  describe "with commit note"
-  describe "with commit diff note"
-end
diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4f8a5f909df1207545e28be2e1296b77b0e54a85
--- /dev/null
+++ b/spec/finders/notes_finder_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+describe NotesFinder do
+  let(:user) { create :user }
+  let(:project) { create :project }
+  let(:note1) { create :note_on_commit, project: project }
+  let(:note2) { create :note_on_commit, project: project }
+  let(:commit) { note1.noteable }
+
+  before do
+    project.team << [user, :master]
+  end
+
+  describe :execute do
+    let(:params)  { { target_id: commit.id, target_type: 'commit', last_fetched_at: 1.hour.ago.to_i } }
+
+    before do
+      note1
+      note2
+    end
+
+    it 'should find all notes' do
+      notes = NotesFinder.new.execute(project, user, params)
+      notes.size.should eq(2)
+    end
+
+    it 'should raise an exception for an invalid target_type' do
+      params.merge!(target_type: 'invalid')
+      expect { NotesFinder.new.execute(project, user, params) }.to raise_error('invalid target_type')
+    end
+
+    it 'filters out old notes' do
+      note2.update_attribute(:updated_at, 2.hours.ago)
+      notes = NotesFinder.new.execute(project, user, params)
+      notes.should eq([note1])
+    end
+  end
+end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 61c561335e53d8333e4841d23c97bbba1dfeca91..0376e0aadf0771f2de1e76aab02cc4a3704907f9 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -46,7 +46,7 @@ describe ApplicationHelper do
       group = create(:group)
       group.avatar = File.open(avatar_file_path)
       group.save!
-      group_icon(group.path).to_s.should == "/uploads/group/avatar/#{ group.id }/gitlab_logo.png"
+      group_icon(group.path).to_s.should match("/uploads/group/avatar/#{ group.id }/gitlab_logo.png")
     end
 
     it "should give default avatar_icon when no avatar is present" do
@@ -63,7 +63,7 @@ describe ApplicationHelper do
       user = create(:user)
       user.avatar = File.open(avatar_file_path)
       user.save!
-      avatar_icon(user.email).to_s.should == "/uploads/user/avatar/#{ user.id }/gitlab_logo.png"
+      avatar_icon(user.email).to_s.should match("/uploads/user/avatar/#{ user.id }/gitlab_logo.png")
     end
 
     it "should call gravatar_icon when no avatar is present" do
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index 5bd16d1c16ccf473176a196abdf404eb81e4705c..49b48d26e2b4903b978a3d547a9391b4053940c8 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -181,6 +181,52 @@ describe GitlabMarkdownHelper do
       include_examples 'referenced object'
     end
 
+    describe "referencing a Jira issue" do
+      let(:actual)   { "Reference to JIRA-#{issue.iid}" }
+      let(:expected) { "http://jira.example/browse/JIRA-#{issue.iid}" }
+      let(:reference) { "JIRA-#{issue.iid}" }
+
+      before do
+        issue_tracker_config = { "jira" => { "title" => "JIRA tracker", "issues_url" => "http://jira.example/browse/:id" } }
+        Gitlab.config.stub(:issues_tracker).and_return(issue_tracker_config)
+        @project.stub(:issues_tracker).and_return("jira")
+        @project.stub(:issues_tracker_id).and_return("JIRA")
+      end
+
+      it "should link using a valid id" do
+        gfm(actual).should match(expected)
+      end
+
+      it "should link with adjacent text" do
+        # Wrap the reference in parenthesis
+        gfm(actual.gsub(reference, "(#{reference})")).should match(expected)
+
+        # Append some text to the end of the reference
+        gfm(actual.gsub(reference, "#{reference}, right?")).should match(expected)
+      end
+
+      it "should keep whitespace intact" do
+        actual   = "Referenced #{reference} already."
+        expected = /Referenced <a.+>[^\s]+<\/a> already/
+        gfm(actual).should match(expected)
+      end
+
+      it "should not link with an invalid id" do
+        # Modify the reference string so it's still parsed, but is invalid
+        invalid_reference = actual.gsub(/(\d+)$/, "r45")
+        gfm(invalid_reference).should == invalid_reference
+      end
+
+      it "should include a title attribute" do
+        title = "Issue in JIRA tracker"
+        gfm(actual).should match(/title="#{title}"/)
+      end
+
+      it "should include standard gfm classes" do
+        gfm(actual).should match(/class="\s?gfm gfm-issue\s?"/)
+      end
+    end
+
     describe "referencing a merge request" do
       let(:object)    { merge_request }
       let(:reference) { "!#{merge_request.iid}" }
diff --git a/spec/lib/gitlab/ldap/ldap_access_spec.rb b/spec/lib/gitlab/ldap/ldap_access_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d8c107502ba49ceca3e29514253afc2b5249568f
--- /dev/null
+++ b/spec/lib/gitlab/ldap/ldap_access_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe Gitlab::LDAP::Access do
+  let(:access) { Gitlab::LDAP::Access.new }
+  let(:user) { create(:user) }
+
+  describe :allowed? do
+    subject { access.allowed?(user) }
+
+    context 'when the user cannot be found' do
+      before { Gitlab::LDAP::Person.stub(find_by_dn: nil) }
+
+      it { should be_false }
+    end
+
+    context 'when the user is found' do
+      before { Gitlab::LDAP::Person.stub(find_by_dn: :ldap_user) }
+
+      context 'and the Active Directory disabled flag is set' do
+        before { Gitlab::LDAP::Person.stub(active_directory_disabled?: true) }
+
+        it { should be_false }
+      end
+
+      context 'and the Active Directory disabled flag is not set' do
+        before { Gitlab::LDAP::Person.stub(active_directory_disabled?: false) }
+
+        it { should be_true }
+      end
+    end
+  end
+end
diff --git a/spec/lib/gitlab/ldap/ldap_adapter_spec.rb b/spec/lib/gitlab/ldap/ldap_adapter_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c3f07334431721028c5d5789290ef1ea38d5b6d5
--- /dev/null
+++ b/spec/lib/gitlab/ldap/ldap_adapter_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+describe Gitlab::LDAP::Adapter do
+  let(:adapter) { Gitlab::LDAP::Adapter.new }
+
+  describe :dn_matches_filter? do
+    let(:ldap) { double(:ldap) }
+    subject { adapter.dn_matches_filter?(:dn, :filter) }
+    before { adapter.stub(ldap: ldap) }
+
+    context "when the search is successful" do
+      context "and the result is non-empty" do
+        before { ldap.stub(search: [:foo]) }
+
+        it { should be_true }
+      end
+
+      context "and the result is empty" do
+        before { ldap.stub(search: []) }
+
+        it { should be_false }
+      end
+    end
+
+    context "when the search encounters an error" do
+      before { ldap.stub(search: nil, get_operation_result: double(code: 1, message: 'some error')) }
+
+      it { should be_false }
+    end
+  end
+end
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 19259a8b79c712c7927063d0cef0f43b3de985e6..99fed27c796fa876180f0c5781ace5cbd8f9b12b 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -11,6 +11,12 @@ describe Gitlab::ReferenceExtractor do
     subject.issues.should == ["1234"]
   end
 
+  it 'extracts JIRA issue references' do
+    Gitlab.config.gitlab.stub(:issues_tracker).and_return("jira")
+    subject.analyze "this one talks about issue JIRA-1234"
+    subject.issues.should == ["JIRA-1234"]
+  end
+
   it 'extracts merge request references' do
     subject.analyze "and here's !43, a merge request"
     subject.merge_requests.should == ["43"]
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index e86a60a42b517b8c3dec7b51a3be15232267b49a..547268d44f0ca933eef328e178639d9b94760db1 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -161,6 +161,10 @@ describe Notify do
           it 'contains a link to the new issue' do
             should have_body_text /#{project_issue_path project, issue}/
           end
+
+          it 'has the correct message-id set' do
+            should have_header 'Message-ID', "<issue_#{issue.id}@#{Gitlab.config.gitlab.host}>"
+          end
         end
 
         describe 'that are new with a description' do
@@ -197,6 +201,10 @@ describe Notify do
           it 'contains a link to the issue' do
             should have_body_text /#{project_issue_path project, issue}/
           end
+
+          it 'has the correct reference set' do
+            should have_header 'References', "<issue_#{issue.id}@#{Gitlab.config.gitlab.host}>"
+          end
         end
 
         describe 'status changed' do
@@ -224,6 +232,10 @@ describe Notify do
           it 'contains a link to the issue' do
             should have_body_text /#{project_issue_path project, issue}/
           end
+
+          it 'has the correct reference set' do
+            should have_header 'References', "<issue_#{issue.id}@#{Gitlab.config.gitlab.host}>"
+          end
         end
 
       end
@@ -239,7 +251,7 @@ describe Notify do
           it_behaves_like 'an assignee email'
 
           it 'has the correct subject' do
-            should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
+            should have_subject /#{merge_request.title} \(##{merge_request.iid}\)/
           end
 
           it 'contains a link to the new merge request' do
@@ -253,6 +265,10 @@ describe Notify do
           it 'contains the target branch for the merge request' do
             should have_body_text /#{merge_request.target_branch}/
           end
+
+          it 'has the correct message-id set' do
+            should have_header 'Message-ID', "<merge_request_#{merge_request.id}@#{Gitlab.config.gitlab.host}>"
+          end
         end
 
         describe 'that are new with a description' do
@@ -275,7 +291,7 @@ describe Notify do
           end
 
           it 'has the correct subject' do
-            should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
+            should have_subject /#{merge_request.title} \(##{merge_request.iid}\)/
           end
 
           it 'contains the name of the previous assignee' do
@@ -303,7 +319,7 @@ describe Notify do
           end
 
           it 'has the correct subject' do
-            should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
+            should have_subject /#{merge_request.title} \(##{merge_request.iid}\)/
           end
 
           it 'contains the new status' do
@@ -313,6 +329,10 @@ describe Notify do
           it 'contains a link to the merge request' do
             should have_body_text /#{project_merge_request_path project, merge_request}/
           end
+
+          it 'has the correct reference set' do
+            should have_header 'References', "<merge_request_#{merge_request.id}@#{Gitlab.config.gitlab.host}>"
+          end
         end
       end
     end
@@ -426,7 +446,7 @@ describe Notify do
         it_behaves_like 'a note email'
 
         it 'has the correct subject' do
-          should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
+          should have_subject /#{merge_request.title} \(##{merge_request.iid}\)/
         end
 
         it 'contains a link to the merge request note' do
diff --git a/spec/requests/api/api_helpers_spec.rb b/spec/requests/api/api_helpers_spec.rb
index 6f961d321bdb1f1088aa1a5e0c02d14c8dfba196..e2f222c0d341266ae63391ecc0a68277cce4d7ab 100644
--- a/spec/requests/api/api_helpers_spec.rb
+++ b/spec/requests/api/api_helpers_spec.rb
@@ -39,6 +39,17 @@ describe API, api: true do
   end
 
   describe ".current_user" do
+    it "should return nil for an invalid token" do
+      env[API::APIHelpers::PRIVATE_TOKEN_HEADER] = 'invalid token'
+      current_user.should be_nil
+    end
+
+    it "should return nil for a user without access" do
+      env[API::APIHelpers::PRIVATE_TOKEN_HEADER] = user.private_token
+      Gitlab::UserAccess.stub(allowed?: false)
+      current_user.should be_nil
+    end
+
     it "should leave user as is when sudo not specified" do
       env[API::APIHelpers::PRIVATE_TOKEN_HEADER] = user.private_token
       current_user.should == user
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index db7c30e1ab8e3411a0a2e436c7a4ce805a1c5f86..2fb3684fdf0b11fcdb5e8f0330a58f2dfc86d3e3 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -183,11 +183,33 @@ describe API::API, api: true  do
     end
   end
 
-  describe "PUT /projects/:id/merge_request/:merge_request_id to merge MR" do
-    it "should return merge_request" do
-      put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), state_event: "merge"
+  describe "PUT /projects/:id/merge_request/:merge_request_id/merge" do
+    it "should return merge_request in case of success" do
+      MergeRequest.any_instance.stub(can_be_merged?: true, automerge!: true)
+      put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
       response.status.should == 200
-      json_response['state'].should == 'merged'
+    end
+
+    it "should return 405 if branch can't be merged" do
+      MergeRequest.any_instance.stub(can_be_merged?: false)
+      put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
+      response.status.should == 405
+      json_response['message'].should == 'Branch cannot be merged'
+    end
+
+    it "should return 405 if merge_request is not open" do
+      merge_request.close
+      put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
+      response.status.should == 405
+      json_response['message'].should == 'Method Not Allowed'
+    end
+
+    it "should return 401 if user has no permissions to merge" do
+      user2 = create(:user)
+      project.team << [user2, :reporter]
+      put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user2)
+      response.status.should == 401
+      json_response['message'].should == '401 Unauthorized'
     end
   end
 
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 4b8f41a46830ce1da0f26a4c0a913c980439c653..81e6abbb0d7c5f7af3629e09eb191a3da9a989d9 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -14,6 +14,12 @@ describe API::API, api: true  do
   let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
   let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
   let(:issue_with_labels) { create(:issue, author: user, assignee: user, project: project, :label_list => "label1, label2") }
+  let(:merge_request_with_labels) do
+    create(:merge_request, :simple, author: user, assignee: user,
+           source_project: project, target_project: project, title: 'Test',
+           label_list: 'label3, label4')
+  end
+
 
   describe "GET /projects" do
     before { project }
@@ -634,15 +640,45 @@ describe API::API, api: true  do
     end
   end
 
-   describe "GET /projects/:id/labels" do
-    before { issue_with_labels }
+  describe 'GET /projects/:id/labels' do
+    context 'with an issue' do
+      before { issue_with_labels }
 
-    it "should return project labels" do
-      get api("/projects/#{project.id}/labels", user)
-      response.status.should == 200
-      json_response.should be_an Array
-      json_response.first['name'].should == issue_with_labels.labels.first.name
-      json_response.last['name'].should == issue_with_labels.labels.last.name
+      it 'should return project labels' do
+        get api("/projects/#{project.id}/labels", user)
+        response.status.should == 200
+        json_response.should be_an Array
+        json_response.first['name'].should == issue_with_labels.labels.first.name
+        json_response.last['name'].should == issue_with_labels.labels.last.name
+      end
+    end
+
+    context 'with a merge request' do
+      before { merge_request_with_labels }
+
+      it 'should return project labels' do
+        get api("/projects/#{project.id}/labels", user)
+        response.status.should == 200
+        json_response.should be_an Array
+        json_response.first['name'].should == merge_request_with_labels.labels.first.name
+        json_response.last['name'].should == merge_request_with_labels.labels.last.name
+      end
+    end
+
+    context 'with an issue and a merge request' do
+      before do
+        issue_with_labels
+        merge_request_with_labels
+      end
+
+      it 'should return project labels from both' do
+        get api("/projects/#{project.id}/labels", user)
+        response.status.should == 200
+        json_response.should be_an Array
+        all_labels = issue_with_labels.labels.map(&:name).to_a
+                       .concat(merge_request_with_labels.labels.map(&:name).to_a)
+        json_response.map { |e| e['name'] }.should =~ all_labels
+      end
     end
   end
 end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 86610c47513782f98b94fc3bfa589fc33405ac4e..a6d300b099b21e2a6626fe6d746a2d89ca87b11e 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -242,6 +242,67 @@ describe API::API, api: true  do
     end
   end
 
+  describe 'GET /user/:uid/keys' do
+    before { admin }
+
+    context 'when unauthenticated' do
+      it 'should return authentication error' do
+        get api("/users/#{user.id}/keys")
+        response.status.should == 401
+      end
+    end
+
+    context 'when authenticated' do
+      it 'should return 404 for non-existing user' do
+        get api('/users/999999/keys', admin)
+        response.status.should == 404
+      end
+
+      it 'should return array of ssh keys' do
+        user.keys << key
+        user.save
+        get api("/users/#{user.id}/keys", admin)
+        response.status.should == 200
+        json_response.should be_an Array
+        json_response.first['title'].should == key.title
+      end
+    end
+  end
+
+  describe 'DELETE /user/:uid/keys/:id' do
+    before { admin }
+
+    context 'when unauthenticated' do
+      it 'should return authentication error' do
+        delete api("/users/#{user.id}/keys/42")
+        response.status.should == 401
+      end
+    end
+
+    context 'when authenticated' do
+      it 'should delete existing key' do
+        user.keys << key
+        user.save
+        expect {
+          delete api("/users/#{user.id}/keys/#{key.id}", admin)
+        }.to change { user.keys.count }.by(-1)
+        response.status.should == 200
+      end
+
+      it 'should return 404 error if user not found' do
+        user.keys << key
+        user.save
+        delete api("/users/999999/keys/#{key.id}", admin)
+        response.status.should == 404
+      end
+
+      it 'should return 404 error if key not foud' do
+        delete api("/users/#{user.id}/keys/42", admin)
+        response.status.should == 404
+      end
+    end
+  end
+
   describe "DELETE /users/:id" do
     before { admin }
 
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 97f7392e50aae6a9fa973d06abc3a4ce5335a0cb..fa9762625d72316065f1b73b061ddfffe955720e 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -213,7 +213,7 @@ describe Projects::RefsController, "routing" do
 end
 
 #           diffs_project_merge_request GET    /:project_id/merge_requests/:id/diffs(.:format)           projects/merge_requests#diffs
-#       automerge_project_merge_request GET    /:project_id/merge_requests/:id/automerge(.:format)       projects/merge_requests#automerge
+#       automerge_project_merge_request POST   /:project_id/merge_requests/:id/automerge(.:format)       projects/merge_requests#automerge
 # automerge_check_project_merge_request GET    /:project_id/merge_requests/:id/automerge_check(.:format) projects/merge_requests#automerge_check
 #    branch_from_project_merge_requests GET    /:project_id/merge_requests/branch_from(.:format)         projects/merge_requests#branch_from
 #      branch_to_project_merge_requests GET    /:project_id/merge_requests/branch_to(.:format)           projects/merge_requests#branch_to
@@ -230,7 +230,10 @@ describe Projects::MergeRequestsController, "routing" do
   end
 
   it "to #automerge" do
-    get("/gitlab/gitlabhq/merge_requests/1/automerge").should route_to('projects/merge_requests#automerge', project_id: 'gitlab/gitlabhq', id: '1')
+    post('/gitlab/gitlabhq/merge_requests/1/automerge').should route_to(
+      'projects/merge_requests#automerge',
+      project_id: 'gitlab/gitlabhq', id: '1'
+    )
   end
 
   it "to #automerge_check" do
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index f1df7e55dd0a5f13bb8d9962ec05c8a68fe7f043..3c2eec6cfd917712add9d9b7f166cca351b7f1c2 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -8,10 +8,10 @@ describe SystemHooksService do
   context 'event data' do
     it { event_data(user, :create).should include(:event_name, :name, :created_at, :email, :user_id) }
     it { event_data(user, :destroy).should include(:event_name, :name, :created_at, :email, :user_id) }
-    it { event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email) }
-    it { event_data(project, :destroy).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email) }
-    it { event_data(users_project, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access) }
-    it { event_data(users_project, :destroy).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access) }
+    it { event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
+    it { event_data(project, :destroy).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
+    it { event_data(users_project, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access, :project_visibility) }
+    it { event_data(users_project, :destroy).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access, :project_visibility) }
   end
 
   context 'event names' do
diff --git a/vendor/assets/javascripts/jquery.scrollto.js b/vendor/assets/javascripts/jquery.scrollto.js
deleted file mode 100644
index 7f10b7f108254762bf990c4c24393054fb74d31a..0000000000000000000000000000000000000000
--- a/vendor/assets/javascripts/jquery.scrollto.js
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
- * @depends jquery
- * @name jquery.scrollto
- * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto}
- */
-
-/**
- * jQuery Aliaser
- */
-(function(window,undefined){
-	// Prepare
-	var jQuery, $, ScrollTo;
-	jQuery = $ = window.jQuery;
-
-	/**
-	 * jQuery ScrollTo (balupton edition)
-	 * @version 1.2.0
-	 * @date July 9, 2012
-	 * @since 0.1.0, August 27, 2010
-	 * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto}
-	 * @author Benjamin "balupton" Lupton {@link http://balupton.com}
-	 * @copyright (c) 2010 Benjamin Arthur Lupton {@link http://balupton.com}
-	 * @license MIT License {@link http://creativecommons.org/licenses/MIT/}
-	 */
-	ScrollTo = $.ScrollTo = $.ScrollTo || {
-		/**
-		 * The Default Configuration
-		 */
-		config: {
-			duration: 400,
-			easing: 'swing',
-			callback: undefined,
-			durationMode: 'each',
-			offsetTop: 0,
-			offsetLeft: 0
-		},
-
-		/**
-		 * Configure ScrollTo
-		 */
-		configure: function(options){
-			// Apply Options to Config
-			$.extend(ScrollTo.config, options||{});
-
-			// Chain
-			return this;
-		},
-
-		/**
-		 * Perform the Scroll Animation for the Collections
-		 * We use $inline here, so we can determine the actual offset start for each overflow:scroll item
-		 * Each collection is for each overflow:scroll item
-		 */
-		scroll: function(collections, config){
-			// Prepare
-			var collection, $container, container, $target, $inline, position,
-				containerScrollTop, containerScrollLeft,
-				containerScrollTopEnd, containerScrollLeftEnd,
-				startOffsetTop, targetOffsetTop, targetOffsetTopAdjusted,
-				startOffsetLeft, targetOffsetLeft, targetOffsetLeftAdjusted,
-				scrollOptions,
-				callback;
-
-			// Determine the Scroll
-			collection = collections.pop();
-			$container = collection.$container;
-			container = $container.get(0);
-			$target = collection.$target;
-
-			// Prepare the Inline Element of the Container
-			$inline = $('<span/>').css({
-				'position': 'absolute',
-				'top': '0px',
-				'left': '0px'
-			});
-			position = $container.css('position');
-
-			// Insert the Inline Element of the Container
-			$container.css('position','relative');
-			$inline.appendTo($container);
-
-			// Determine the top offset
-			startOffsetTop = $inline.offset().top;
-			targetOffsetTop = $target.offset().top;
-			targetOffsetTopAdjusted = targetOffsetTop - startOffsetTop - parseInt(config.offsetTop,10);
-
-			// Determine the left offset
-			startOffsetLeft = $inline.offset().left;
-			targetOffsetLeft = $target.offset().left;
-			targetOffsetLeftAdjusted = targetOffsetLeft - startOffsetLeft - parseInt(config.offsetLeft,10);
-
-			// Determine current scroll positions
-			containerScrollTop = container.scrollTop;
-			containerScrollLeft = container.scrollLeft;
-
-			// Reset the Inline Element of the Container
-			$inline.remove();
-			$container.css('position',position);
-
-			// Prepare the scroll options
-			scrollOptions = {};
-
-			// Prepare the callback
-			callback = function(event){
-				// Check
-				if ( collections.length === 0 ) {
-					// Callback
-					if ( typeof config.callback === 'function' ) {
-						config.callback.apply(this,[event]);
-					}
-				}
-				else {
-					// Recurse
-					ScrollTo.scroll(collections,config);
-				}
-				// Return true
-				return true;
-			};
-
-			// Handle if we only want to scroll if we are outside the viewport
-			if ( config.onlyIfOutside ) {
-				// Determine current scroll positions
-				containerScrollTopEnd = containerScrollTop + $container.height();
-				containerScrollLeftEnd = containerScrollLeft + $container.width();
-
-				// Check if we are in the range of the visible area of the container
-				if ( containerScrollTop < targetOffsetTopAdjusted && targetOffsetTopAdjusted < containerScrollTopEnd ) {
-					targetOffsetTopAdjusted = containerScrollTop;
-				}
-				if ( containerScrollLeft < targetOffsetLeftAdjusted && targetOffsetLeftAdjusted < containerScrollLeftEnd ) {
-					targetOffsetLeftAdjusted = containerScrollLeft;
-				}
-			}
-
-			// Determine the scroll options
-			if ( targetOffsetTopAdjusted !== containerScrollTop ) {
-				scrollOptions.scrollTop = targetOffsetTopAdjusted;
-			}
-			if ( targetOffsetLeftAdjusted !== containerScrollLeft ) {
-				scrollOptions.scrollLeft = targetOffsetLeftAdjusted;
-			}
-
-			// Perform the scroll
-			if ( $.browser.safari && container === document.body ) {
-				window.scrollTo(scrollOptions.scrollLeft, scrollOptions.scrollTop);
-				callback();
-			}
-			else if ( scrollOptions.scrollTop || scrollOptions.scrollLeft ) {
-				$container.animate(scrollOptions, config.duration, config.easing, callback);
-			}
-			else {
-				callback();
-			}
-
-			// Return true
-			return true;
-		},
-
-		/**
-		 * ScrollTo the Element using the Options
-		 */
-		fn: function(options){
-			// Prepare
-			var collections, config, $container, container;
-			collections = [];
-
-			// Prepare
-			var	$target = $(this);
-			if ( $target.length === 0 ) {
-				// Chain
-				return this;
-			}
-
-			// Handle Options
-			config = $.extend({},ScrollTo.config,options);
-
-			// Fetch
-			$container = $target.parent();
-			container = $container.get(0);
-
-			// Cycle through the containers
-			while ( ($container.length === 1) && (container !== document.body) && (container !== document) ) {
-				// Check Container for scroll differences
-				var scrollTop, scrollLeft;
-				scrollTop = $container.css('overflow-y') !== 'visible' && container.scrollHeight !== container.clientHeight;
-				scrollLeft =  $container.css('overflow-x') !== 'visible' && container.scrollWidth !== container.clientWidth;
-				if ( scrollTop || scrollLeft ) {
-					// Push the Collection
-					collections.push({
-						'$container': $container,
-						'$target': $target
-					});
-					// Update the Target
-					$target = $container;
-				}
-				// Update the Container
-				$container = $container.parent();
-				container = $container.get(0);
-			}
-
-			// Add the final collection
-			collections.push({
-				'$container': $(
-					($.browser.msie || $.browser.mozilla) ? 'html' : 'body'
-				),
-				'$target': $target
-			});
-
-			// Adjust the Config
-			if ( config.durationMode === 'all' ) {
-				config.duration /= collections.length;
-			}
-
-			// Handle
-			ScrollTo.scroll(collections,config);
-
-			// Chain
-			return this;
-		}
-	};
-
-	// Apply our jQuery Prototype Function
-	$.fn.ScrollTo = $.ScrollTo.fn;
-
-})(window);