Commit f5147780ff2290332d8979d399cfd55bf4a5fd37

Authored by Marc Radulescu
2 parents d1980adf 9f80ab8e

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq into grammar_fixes

Showing 142 changed files with 1879 additions and 655 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 142 files displayed.

.pkgr.yml 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +user: git
  2 +group: git
  3 +before_precompile: ./bin/pkgr_before_precompile.sh
  4 +targets:
  5 + debian-7: &wheezy
  6 + build_dependencies:
  7 + - libicu-dev
  8 + dependencies:
  9 + - libicu48
  10 + - libpcre3
  11 + - git
  12 + ubuntu-12.04: *wheezy
  13 + ubuntu-14.04:
  14 + build_dependencies:
  15 + - libicu-dev
  16 + dependencies:
  17 + - libicu52
  18 + - libpcre3
  19 + - git
@@ -8,6 +8,16 @@ v 6.9.0 @@ -8,6 +8,16 @@ v 6.9.0
8 - Fix syntax highlighting for code comments blocks 8 - Fix syntax highlighting for code comments blocks
9 - Improve comments loading logic 9 - Improve comments loading logic
10 - Stop refreshing comments when the tab is hidden 10 - Stop refreshing comments when the tab is hidden
  11 + - Improve issue and merge request mobile UI (Drew Blessing)
  12 + - Document how to convert a backup to PostgreSQL
  13 + - Fix locale bug in backup manager
  14 + - Fix can not automerge when MR description is too long
  15 + - Fix wiki backup skip bug
  16 + - Two Step MR creation process
  17 + - Remove unwanted files from satellite working directory with git clean -fdx
  18 + - Accept merge request via API (sponsored by O'Reilly Media)
  19 + - Add more access checks during API calls
  20 + - Block SSH access for 'disabled' Active Directory users
11 21
12 v 6.8.0 22 v 6.8.0
13 - Ability to at mention users that are participating in issue and merge req. discussion 23 - Ability to at mention users that are participating in issue and merge req. discussion
@@ -152,7 +152,7 @@ gem "rack-attack" @@ -152,7 +152,7 @@ gem "rack-attack"
152 # Ace editor 152 # Ace editor
153 gem 'ace-rails-ap' 153 gem 'ace-rails-ap'
154 154
155 -gem "sass-rails" 155 +gem "sass-rails", '~> 4.0.2'
156 gem "coffee-rails" 156 gem "coffee-rails"
157 gem "uglifier" 157 gem "uglifier"
158 gem "therubyracer" 158 gem "therubyracer"
@@ -2,26 +2,26 @@ GEM @@ -2,26 +2,26 @@ GEM
2 remote: https://rubygems.org/ 2 remote: https://rubygems.org/
3 specs: 3 specs:
4 ace-rails-ap (2.0.1) 4 ace-rails-ap (2.0.1)
5 - actionmailer (4.0.3)  
6 - actionpack (= 4.0.3) 5 + actionmailer (4.0.5)
  6 + actionpack (= 4.0.5)
7 mail (~> 2.5.4) 7 mail (~> 2.5.4)
8 - actionpack (4.0.3)  
9 - activesupport (= 4.0.3) 8 + actionpack (4.0.5)
  9 + activesupport (= 4.0.5)
10 builder (~> 3.1.0) 10 builder (~> 3.1.0)
11 erubis (~> 2.7.0) 11 erubis (~> 2.7.0)
12 rack (~> 1.5.2) 12 rack (~> 1.5.2)
13 rack-test (~> 0.6.2) 13 rack-test (~> 0.6.2)
14 - activemodel (4.0.3)  
15 - activesupport (= 4.0.3) 14 + activemodel (4.0.5)
  15 + activesupport (= 4.0.5)
16 builder (~> 3.1.0) 16 builder (~> 3.1.0)
17 - activerecord (4.0.3)  
18 - activemodel (= 4.0.3) 17 + activerecord (4.0.5)
  18 + activemodel (= 4.0.5)
19 activerecord-deprecated_finders (~> 1.0.2) 19 activerecord-deprecated_finders (~> 1.0.2)
20 - activesupport (= 4.0.3) 20 + activesupport (= 4.0.5)
21 arel (~> 4.0.0) 21 arel (~> 4.0.0)
22 activerecord-deprecated_finders (1.0.3) 22 activerecord-deprecated_finders (1.0.3)
23 - activesupport (4.0.3)  
24 - i18n (~> 0.6, >= 0.6.4) 23 + activesupport (4.0.5)
  24 + i18n (~> 0.6, >= 0.6.9)
25 minitest (~> 4.2) 25 minitest (~> 4.2)
26 multi_json (~> 1.3) 26 multi_json (~> 1.3)
27 thread_safe (~> 0.1) 27 thread_safe (~> 0.1)
@@ -162,7 +162,7 @@ GEM @@ -162,7 +162,7 @@ GEM
162 multi_json 162 multi_json
163 gitlab-grack (2.0.0.pre) 163 gitlab-grack (2.0.0.pre)
164 rack (~> 1.5.1) 164 rack (~> 1.5.1)
165 - gitlab-grit (2.6.5) 165 + gitlab-grit (2.6.7)
166 charlock_holmes (~> 0.6) 166 charlock_holmes (~> 0.6)
167 diff-lcs (~> 1.1) 167 diff-lcs (~> 1.1)
168 mime-types (~> 1.15) 168 mime-types (~> 1.15)
@@ -279,7 +279,7 @@ GEM @@ -279,7 +279,7 @@ GEM
279 mime-types (1.25.1) 279 mime-types (1.25.1)
280 mini_portile (0.5.3) 280 mini_portile (0.5.3)
281 minitest (4.7.5) 281 minitest (4.7.5)
282 - multi_json (1.9.3) 282 + multi_json (1.10.0)
283 multi_xml (0.5.5) 283 multi_xml (0.5.5)
284 multipart-post (1.2.0) 284 multipart-post (1.2.0)
285 mysql2 (0.3.11) 285 mysql2 (0.3.11)
@@ -349,13 +349,13 @@ GEM @@ -349,13 +349,13 @@ GEM
349 rack 349 rack
350 rack-test (0.6.2) 350 rack-test (0.6.2)
351 rack (>= 1.0) 351 rack (>= 1.0)
352 - rails (4.0.3)  
353 - actionmailer (= 4.0.3)  
354 - actionpack (= 4.0.3)  
355 - activerecord (= 4.0.3)  
356 - activesupport (= 4.0.3) 352 + rails (4.0.5)
  353 + actionmailer (= 4.0.5)
  354 + actionpack (= 4.0.5)
  355 + activerecord (= 4.0.5)
  356 + activesupport (= 4.0.5)
357 bundler (>= 1.3.0, < 2.0) 357 bundler (>= 1.3.0, < 2.0)
358 - railties (= 4.0.3) 358 + railties (= 4.0.5)
359 sprockets-rails (~> 2.0.0) 359 sprockets-rails (~> 2.0.0)
360 rails-observers (0.1.2) 360 rails-observers (0.1.2)
361 activemodel (~> 4.0) 361 activemodel (~> 4.0)
@@ -368,9 +368,9 @@ GEM @@ -368,9 +368,9 @@ GEM
368 i18n 368 i18n
369 require_all 369 require_all
370 ruby-progressbar 370 ruby-progressbar
371 - railties (4.0.3)  
372 - actionpack (= 4.0.3)  
373 - activesupport (= 4.0.3) 371 + railties (4.0.5)
  372 + actionpack (= 4.0.5)
  373 + activesupport (= 4.0.5)
374 rake (>= 0.8.7) 374 rake (>= 0.8.7)
375 thor (>= 0.18.1, < 2.0) 375 thor (>= 0.18.1, < 2.0)
376 raindrops (0.12.0) 376 raindrops (0.12.0)
@@ -427,11 +427,12 @@ GEM @@ -427,11 +427,12 @@ GEM
427 safe_yaml (0.9.7) 427 safe_yaml (0.9.7)
428 sanitize (2.1.0) 428 sanitize (2.1.0)
429 nokogiri (>= 1.4.4) 429 nokogiri (>= 1.4.4)
430 - sass (3.2.12)  
431 - sass-rails (4.0.1) 430 + sass (3.2.19)
  431 + sass-rails (4.0.3)
432 railties (>= 4.0.0, < 5.0) 432 railties (>= 4.0.0, < 5.0)
433 - sass (>= 3.1.10)  
434 - sprockets-rails (~> 2.0.0) 433 + sass (~> 3.2.0)
  434 + sprockets (~> 2.8, <= 2.11.0)
  435 + sprockets-rails (~> 2.0)
435 sdoc (0.3.20) 436 sdoc (0.3.20)
436 json (>= 1.1.3) 437 json (>= 1.1.3)
437 rdoc (~> 3.10) 438 rdoc (~> 3.10)
@@ -478,7 +479,7 @@ GEM @@ -478,7 +479,7 @@ GEM
478 spring (>= 0.9.1) 479 spring (>= 0.9.1)
479 spring-commands-spinach (1.0.0) 480 spring-commands-spinach (1.0.0)
480 spring (>= 0.9.1) 481 spring (>= 0.9.1)
481 - sprockets (2.10.1) 482 + sprockets (2.11.0)
482 hike (~> 1.2) 483 hike (~> 1.2)
483 multi_json (~> 1.0) 484 multi_json (~> 1.0)
484 rack (~> 1.0) 485 rack (~> 1.0)
@@ -636,7 +637,7 @@ DEPENDENCIES @@ -636,7 +637,7 @@ DEPENDENCIES
636 redis-rails 637 redis-rails
637 rspec-rails 638 rspec-rails
638 sanitize (~> 2.0) 639 sanitize (~> 2.0)
639 - sass-rails 640 + sass-rails (~> 4.0.2)
640 sdoc 641 sdoc
641 seed-fu 642 seed-fu
642 select2-rails 643 select2-rails
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 15
16 ### Canonical source 16 ### Canonical source
17 17
18 -* 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. 18 +* 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.
19 19
20 ### Code status 20 ### Code status
21 21
@@ -25,6 +25,8 @@ @@ -25,6 +25,8 @@
25 25
26 * [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq) 26 * [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
27 27
  28 +* [![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)
  29 +
28 ### Resources 30 ### Resources
29 31
30 * [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/). 32 * [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/).
@@ -33,7 +35,7 @@ @@ -33,7 +35,7 @@
33 35
34 * [GitLab CI](https://www.gitlab.com/gitlab-ci/) is a continuous integration (CI) server that is easy to integrate with GitLab. 36 * [GitLab CI](https://www.gitlab.com/gitlab-ci/) is a continuous integration (CI) server that is easy to integrate with GitLab.
35 37
36 -* Unofficial third-party [iPhone app](http://gitlabcontrol.com/)m [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) for GitLab. 38 +* 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.
37 39
38 ### Requirements 40 ### Requirements
39 41
@@ -51,7 +53,7 @@ @@ -51,7 +53,7 @@
51 53
52 * [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. 54 * [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.
53 55
54 -* [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. 56 +* [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.
55 57
56 * [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. 58 * [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.
57 59
@@ -61,6 +63,8 @@ @@ -61,6 +63,8 @@
61 63
62 * [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.). 64 * [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.).
63 65
  66 +* [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.
  67 +
64 #### Unofficial installation methods 68 #### Unofficial installation methods
65 69
66 * [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. 70 * [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.
1 -6.9.0.pre 1 +6.9.0.rc1
app/assets/javascripts/notes.js.coffee
@@ -53,6 +53,12 @@ class Notes @@ -53,6 +53,12 @@ class Notes
53 # fetch notes when tab becomes visible 53 # fetch notes when tab becomes visible
54 $(document).on "visibilitychange", @visibilityChange 54 $(document).on "visibilitychange", @visibilityChange
55 55
  56 + @notes_forms = '.js-main-target-form textarea, .js-discussion-note-form textarea'
  57 + $(document).on('keypress', @notes_forms, (e)->
  58 + if e.keyCode == 10 || (e.ctrlKey && e.keyCode == 13)
  59 + $(@).parents('form').submit()
  60 + )
  61 +
56 cleanBinding: -> 62 cleanBinding: ->
57 $(document).off "ajax:success", ".js-main-target-form" 63 $(document).off "ajax:success", ".js-main-target-form"
58 $(document).off "ajax:success", ".js-discussion-note-form" 64 $(document).off "ajax:success", ".js-discussion-note-form"
@@ -67,6 +73,7 @@ class Notes @@ -67,6 +73,7 @@ class Notes
67 $(document).off "click", ".js-discussion-reply-button" 73 $(document).off "click", ".js-discussion-reply-button"
68 $(document).off "click", ".js-add-diff-note-button" 74 $(document).off "click", ".js-add-diff-note-button"
69 $(document).off "visibilitychange" 75 $(document).off "visibilitychange"
  76 + $(document).off "keypress", @notes_forms
70 77
71 78
72 initRefresh: -> 79 initRefresh: ->
app/assets/javascripts/project_users_select.js.coffee
1 @projectUsersSelect = 1 @projectUsersSelect =
2 init: -> 2 init: ->
3 $('.ajax-project-users-select').each (i, select) -> 3 $('.ajax-project-users-select').each (i, select) ->
4 - project_id = $('body').data('project-id') 4 + project_id = $(select).data('project-id') || $('body').data('project-id')
5 5
6 $(select).select2 6 $(select).select2
7 placeholder: $(select).data('placeholder') || "Search for a user" 7 placeholder: $(select).data('placeholder') || "Search for a user"
app/assets/stylesheets/generic/files.scss
@@ -11,14 +11,11 @@ @@ -11,14 +11,11 @@
11 } 11 }
12 12
13 .file-title { 13 .file-title {
14 - background: #DDD; 14 + background: #EEE;
15 border-bottom: 1px solid #CCC; 15 border-bottom: 1px solid #CCC;
16 text-shadow: 0 1px 1px #fff; 16 text-shadow: 0 1px 1px #fff;
17 margin: 0; 17 margin: 0;
18 - font-weight: normal;  
19 - font-weight: bold;  
20 text-align: left; 18 text-align: left;
21 - color: $style_color;  
22 padding: 9px 10px; 19 padding: 9px 10px;
23 20
24 .options { 21 .options {
@@ -31,12 +28,15 @@ @@ -31,12 +28,15 @@
31 } 28 }
32 29
33 .file_name { 30 .file_name {
34 - color: $style_color; 31 + font-weight: bold;
  32 + padding-left: 3px;
35 font-size: 14px; 33 font-size: 14px;
36 - text-shadow: 0 1px 1px #fff; 34 +
37 small { 35 small {
38 - color: #999; 36 + color: #888;
39 font-size: 13px; 37 font-size: 13px;
  38 + font-weight: normal;
  39 + padding-left: 10px;
40 } 40 }
41 } 41 }
42 } 42 }
app/assets/stylesheets/generic/forms.scss
@@ -75,3 +75,26 @@ label { @@ -75,3 +75,26 @@ label {
75 width: 200px; 75 width: 200px;
76 } 76 }
77 } 77 }
  78 +
  79 +.commit-message-container {
  80 + background-color: $body-bg;
  81 + position: relative;
  82 + font-family: $monospace_font;
  83 + $left: 12px;
  84 + .max-width-marker {
  85 + color: rgba(0, 0, 0, 0.0);
  86 + font-family: inherit;
  87 + left: $left;
  88 + height: 100%;
  89 + border-right: 1px solid mix($input-border, white);
  90 + position: absolute;
  91 + z-index: 1;
  92 + }
  93 + > textarea {
  94 + background-color: rgba(0, 0, 0, 0.0);
  95 + font-family: inherit;
  96 + padding-left: $left;
  97 + position: relative;
  98 + z-index: 2;
  99 + }
  100 +}
app/assets/stylesheets/generic/issue_box.scss
@@ -12,41 +12,42 @@ @@ -12,41 +12,42 @@
12 margin:20px 0; 12 margin:20px 0;
13 background: #FFF; 13 background: #FFF;
14 border: 1px solid #EEE; 14 border: 1px solid #EEE;
  15 + @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05));
15 16
16 &.issue-box-closed { 17 &.issue-box-closed {
17 - border-color: #DA4E49; 18 + border-color: $border_danger;
18 .state { 19 .state {
19 - background-color: #f2dede;  
20 - border-color: #ebccd1;  
21 - color: #a94442; 20 + background-color: $bg_light_danger;
  21 + border-color: $border_danger;
  22 + color: $color_danger;
22 .state-label { 23 .state-label {
23 - background: #DA4E49; 24 + background-color: $bg_danger;
24 color: #FFF; 25 color: #FFF;
25 } 26 }
26 } 27 }
27 } 28 }
28 29
29 &.issue-box-merged { 30 &.issue-box-merged {
30 - border-color: #31708f; 31 + border-color: $border_primary;
31 .state { 32 .state {
32 - background-color: #d9edf7;  
33 - border-color: #bce8f1;  
34 - color: #31708f; 33 + background-color: $bg_light_primary;
  34 + border-color: $border_primary;
  35 + color: $color_primary;
35 .state-label { 36 .state-label {
36 - background: #31708f; 37 + background-color: $bg_primary;
37 color: #FFF; 38 color: #FFF;
38 } 39 }
39 } 40 }
40 } 41 }
41 42
42 &.issue-box-open { 43 &.issue-box-open {
43 - border-color: #4A4; 44 + border-color: $border_success;
44 .state { 45 .state {
45 - background-color: #dff0d8;  
46 - border-color: #d6e9c6;  
47 - color: #3c763d; 46 + background-color: $bg_light_success;
  47 + border-color: $border_success;
  48 + color: $color_success;
48 .state-label { 49 .state-label {
49 - background: #4A4; 50 + background-color: $bg_success;
50 color: #FFF; 51 color: #FFF;
51 } 52 }
52 } 53 }
@@ -70,7 +71,6 @@ @@ -70,7 +71,6 @@
70 } 71 }
71 72
72 .state { 73 .state {
73 - height: 34px;  
74 border-bottom: 1px solid #DDD; 74 border-bottom: 1px solid #DDD;
75 line-height: 32px; 75 line-height: 32px;
76 } 76 }
@@ -89,6 +89,18 @@ @@ -89,6 +89,18 @@
89 border: none; 89 border: none;
90 border-top: 1px solid #eee; 90 border-top: 1px solid #eee;
91 padding: 15px 25px; 91 padding: 15px 25px;
  92 +
  93 + // Reset text align for children
  94 + .text-right > * { text-align: left; }
  95 +
  96 + @media (max-width: $screen-xs-max) {
  97 + // Don't right align on mobile
  98 + .text-right { text-align: left; }
  99 +
  100 + .row .col-md-6 {
  101 + padding-top: 5px;
  102 + }
  103 + }
92 } 104 }
93 105
94 .description { 106 .description {
@@ -106,7 +118,11 @@ @@ -106,7 +118,11 @@
106 padding: 1px 25px; 118 padding: 1px 25px;
107 text-align: center; 119 text-align: center;
108 text-shadow: none; 120 text-shadow: none;
109 - margin-right: 20px;  
110 display: inline-block; 121 display: inline-block;
  122 + line-height: 34px;
  123 + }
  124 +
  125 + .creator {
  126 + padding: 2px 15px;
111 } 127 }
112 } 128 }
app/assets/stylesheets/generic/jquery.scss
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 width: 270px; 8 width: 270px;
9 9
10 .ui-datepicker-header { 10 .ui-datepicker-header {
11 - background: #EEE; 11 + background: #FFF;
12 border-color: #DDD; 12 border-color: #DDD;
13 } 13 }
14 14
@@ -19,20 +19,37 @@ @@ -19,20 +19,37 @@
19 } 19 }
20 20
21 &.ui-autocomplete { 21 &.ui-autocomplete {
22 - @include border-radius(0px);  
23 border-color: #DDD; 22 border-color: #DDD;
24 padding: 0; 23 padding: 0;
  24 + margin-top: 2px;
  25 + z-index: 1001;
25 26
26 .ui-menu-item a { 27 .ui-menu-item a {
27 - color: #777;  
28 -  
29 - &:hover {  
30 - background: $hover;  
31 - border-color: $primary_color;  
32 - @include border-radius(0px);  
33 - color: #333;  
34 - } 28 + padding: 4px 10px;
35 } 29 }
36 } 30 }
37 -}  
38 31
  32 + .ui-state-default {
  33 + border: 1px solid #FFF;
  34 + background: #FFF;
  35 + color: #777;
  36 + }
  37 +
  38 + .ui-state-highlight {
  39 + border: 1px solid #EEE;
  40 + background: #EEE;
  41 + }
  42 +
  43 + .ui-state-active {
  44 + border: 1px solid $bg_style_color;
  45 + background: $bg_style_color;
  46 + color: #FFF;
  47 + }
  48 +
  49 + .ui-state-hover,
  50 + .ui-state-focus {
  51 + border: 1px solid $hover;
  52 + background: $hover;
  53 + color: #333;
  54 + }
  55 +}
app/assets/stylesheets/generic/typography.scss
@@ -47,7 +47,7 @@ a { @@ -47,7 +47,7 @@ a {
47 text-decoration: underline; 47 text-decoration: underline;
48 } 48 }
49 49
50 - &.dark { 50 + &.darken {
51 color: $style_color; 51 color: $style_color;
52 } 52 }
53 53
app/assets/stylesheets/main/mixins.scss
@@ -41,31 +41,6 @@ @@ -41,31 +41,6 @@
41 * Prefilled mixins 41 * Prefilled mixins
42 * Mixins with fixed values 42 * Mixins with fixed values
43 */ 43 */
44 -@mixin bg-light-gray-gradient {  
45 - background: #f1f1f1;  
46 - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #f5f5f5), to(#e1e1e1));  
47 - background-image: -webkit-linear-gradient(#f5f5f5 6.6%, #e1e1e1);  
48 - background-image: -moz-linear-gradient(#f5f5f5 6.6%, #e1e1e1);  
49 - background-image: -ms-linear-gradient(#f5f5f5 6.6%, #e1e1e1);  
50 - background-image: -o-linear-gradient(#f5f5f5 6.6%, #e1e1e1);  
51 -}  
52 -  
53 -@mixin bg-gray-gradient {  
54 - background: #eee;  
55 - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));  
56 - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);  
57 - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);  
58 - background-image: -ms-linear-gradient(#eee 6.6%, #dfdfdf);  
59 - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);  
60 -}  
61 -  
62 -@mixin bg-dark-gray-gradient {  
63 - background: #eee;  
64 - background-image: -webkit-linear-gradient(#e9e9e9, #d7d7d7);  
65 - background-image: -moz-linear-gradient(#e9e9e9, #d7d7d7);  
66 - background-image: -ms-linear-gradient(#e9e9e9, #d7d7d7);  
67 - background-image: -o-linear-gradient(#e9e9e9, #d7d7d7);  
68 -}  
69 44
70 @mixin shade { 45 @mixin shade {
71 @include box-shadow(0 0 3px #ddd); 46 @include box-shadow(0 0 3px #ddd);
@@ -77,7 +52,6 @@ @@ -77,7 +52,6 @@
77 52
78 @mixin header-font { 53 @mixin header-font {
79 color: $style_color; 54 color: $style_color;
80 - text-shadow: 0 1px 1px #FFF;  
81 font-size: 16px; 55 font-size: 16px;
82 line-height: 44px; 56 line-height: 44px;
83 font-weight: normal; 57 font-weight: normal;
app/assets/stylesheets/main/variables.scss
@@ -8,6 +8,31 @@ $bg_style_color: #2299BB; @@ -8,6 +8,31 @@ $bg_style_color: #2299BB;
8 $list-group-active-bg: $bg_style_color; 8 $list-group-active-bg: $bg_style_color;
9 $hover: #D9EDF7; 9 $hover: #D9EDF7;
10 10
  11 +/*
  12 + * Success colors (green)
  13 + */
  14 +$border_success: #4cae4c;
  15 +$bg_success: #5cb85c;
  16 +$bg_light_success: #dff0d8;
  17 +$color_success: #3c763d;
  18 +
  19 +/*
  20 + * Danger colors (red)
  21 + */
  22 +$border_danger: #d43f3a;
  23 +$bg_danger: #d9534f;
  24 +$bg_light_danger: #f2dede;
  25 +$color_danger: #a94442;
  26 +
  27 +/*
  28 + * Primary colors (blue)
  29 + */
  30 +$border_primary: #358ebd;
  31 +$bg_primary: #429bca;
  32 +$bg_light_primary: #d9edf7;
  33 +$color_primary: #31708f;
  34 +
  35 +
11 /** 36 /**
12 * Commit Diff Colors 37 * Commit Diff Colors
13 */ 38 */
app/assets/stylesheets/sections/diff.scss
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 4
5 .diff-header { 5 .diff-header {
6 @extend .clearfix; 6 @extend .clearfix;
7 - background: #DDD; 7 + background: #EEE;
8 border-bottom: 1px solid #CCC; 8 border-bottom: 1px solid #CCC;
9 padding: 5px 5px 5px 10px; 9 padding: 5px 5px 5px 10px;
10 color: #555; 10 color: #555;
@@ -63,30 +63,21 @@ @@ -63,30 +63,21 @@
63 } 63 }
64 } 64 }
65 65
66 - .text-file-parallel div {  
67 - display: inline-block;  
68 - padding-bottom: 16px;  
69 - }  
70 - .diff-side {  
71 - overflow-x: scroll;  
72 - width: 508px;  
73 - }  
74 - .diff-side.diff-side-left{  
75 - overflow-y:hidden;  
76 - }  
77 - .diff-side table, td.diff-middle table {  
78 - }  
79 - .diff-middle {  
80 - width: 114px;  
81 - vertical-align: top;  
82 - overflow: hidden 66 + tr.line_holder.parallel{
  67 + .old_line, .new_line, .diff_line {
  68 + min-width: 50px;
  69 + }
  70 +
  71 + td.line_content.parallel{
  72 + width: 50%;
  73 + }
83 } 74 }
84 75
85 .old_line, .new_line, .diff_line { 76 .old_line, .new_line, .diff_line {
86 margin: 0px; 77 margin: 0px;
87 padding: 0px; 78 padding: 0px;
88 border: none; 79 border: none;
89 - background: #EEE; 80 + background: #F5F5F5;
90 color: #666; 81 color: #666;
91 padding: 0px 5px; 82 padding: 0px 5px;
92 border-right: 1px solid #ccc; 83 border-right: 1px solid #ccc;
@@ -304,15 +295,9 @@ @@ -304,15 +295,9 @@
304 } //.view.onion-skin 295 } //.view.onion-skin
305 } 296 }
306 .view-modes{ 297 .view-modes{
307 -  
308 padding: 10px; 298 padding: 10px;
309 text-align: center; 299 text-align: center;
310 -  
311 - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));  
312 - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);  
313 - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);  
314 - background-image: -ms-linear-gradient(#eee 6.6%, #dfdfdf);  
315 - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); 300 + background: #EEE;
316 301
317 ul, li{ 302 ul, li{
318 list-style: none; 303 list-style: none;
app/assets/stylesheets/sections/graph.scss
1 .project-network { 1 .project-network {
2 - border: 1px solid #aaa;  
3 - padding: 1px; 2 + border: 1px solid #CCC;
4 3
5 .tip { 4 .tip {
6 color: #888; 5 color: #888;
7 font-size: 14px; 6 font-size: 14px;
8 padding: 10px; 7 padding: 10px;
9 border-bottom: 1px solid #bbb; 8 border-bottom: 1px solid #bbb;
10 - @include bg-gray-gradient; 9 + background: #EEE;
11 } 10 }
12 11
13 .network-graph { 12 .network-graph {
14 - background: #f1f1f1; 13 + background: #FFF;
15 height: 500px; 14 height: 500px;
16 overflow-y: scroll; 15 overflow-y: scroll;
17 overflow-x: hidden; 16 overflow-x: hidden;
app/assets/stylesheets/sections/header.scss
@@ -14,7 +14,6 @@ header { @@ -14,7 +14,6 @@ header {
14 14
15 .nav > li > a { 15 .nav > li > a {
16 color: $style_color; 16 color: $style_color;
17 - text-shadow: 0 1px 0 #fff;  
18 font-size: 14px; 17 font-size: 14px;
19 line-height: 32px; 18 line-height: 32px;
20 padding: 6px 10px; 19 padding: 6px 10px;
@@ -190,7 +189,6 @@ header { @@ -190,7 +189,6 @@ header {
190 189
191 .nav > li > a { 190 .nav > li > a {
192 color: #AAA; 191 color: #AAA;
193 - text-shadow: 0 1px 0 #444;  
194 192
195 &:hover, &:focus, &:active { 193 &:hover, &:focus, &:active {
196 background: none; 194 background: none;
@@ -224,7 +222,6 @@ header { @@ -224,7 +222,6 @@ header {
224 background: image-url('logo-white.png') no-repeat center center; 222 background: image-url('logo-white.png') no-repeat center center;
225 background-size: 32px; 223 background-size: 32px;
226 color: #fff; 224 color: #fff;
227 - text-shadow: 0 1px 1px #444;  
228 } 225 }
229 } 226 }
230 } 227 }
@@ -236,7 +233,6 @@ header { @@ -236,7 +233,6 @@ header {
236 } 233 }
237 } 234 }
238 color: #fff; 235 color: #fff;
239 - text-shadow: 0 1px 1px #444;  
240 } 236 }
241 } 237 }
242 238
app/assets/stylesheets/sections/issues.scss
@@ -45,14 +45,6 @@ @@ -45,14 +45,6 @@
45 padding: 6px 10px; 45 padding: 6px 10px;
46 border: 1px solid #ccc; 46 border: 1px solid #ccc;
47 @include border-radius(4px); 47 @include border-radius(4px);
48 -  
49 -  
50 - input.check_all_issues {  
51 - padding: 0;  
52 - margin: 0;  
53 - position: relative;  
54 - top: 3px;  
55 - }  
56 } 48 }
57 49
58 .issues_content { 50 .issues_content {
@@ -143,3 +135,36 @@ form.edit-issue { @@ -143,3 +135,36 @@ form.edit-issue {
143 border-color: #E5E5E5; 135 border-color: #E5E5E5;
144 } 136 }
145 } 137 }
  138 +
  139 +@media (max-width: $screen-xs-max) {
  140 + .issue-btn-group {
  141 + width: 100%;
  142 + margin-top: 5px;
  143 +
  144 + .btn-group {
  145 + width: 100%;
  146 +
  147 + ul {
  148 + width: 100%;
  149 + text-align: center;
  150 + }
  151 + }
  152 +
  153 + .btn {
  154 + width: 100%;
  155 + margin-top: -1px;
  156 +
  157 + &:first-child:not(:last-child) {
  158 + border-radius: 4px 4px 0 0;
  159 + }
  160 +
  161 + &:not(:first-child):not(:last-child) {
  162 + border-radius: 0;
  163 + }
  164 +
  165 + &:last-child:not(:first-child) {
  166 + border-radius: 0 0 4px 4px;
  167 + }
  168 + }
  169 + }
  170 +}
app/assets/stylesheets/sections/merge_requests.scss
@@ -31,7 +31,6 @@ @@ -31,7 +31,6 @@
31 31
32 .mr_source_commit, 32 .mr_source_commit,
33 .mr_target_commit { 33 .mr_target_commit {
34 - margin-top: 10px;  
35 .commit { 34 .commit {
36 margin: 0; 35 margin: 0;
37 padding: 2px 0; 36 padding: 2px 0;
@@ -74,6 +73,10 @@ @@ -74,6 +73,10 @@
74 73
75 .merge-request-info { 74 .merge-request-info {
76 color: #999; 75 color: #999;
  76 +
  77 + .merge-request-labels {
  78 + display: inline-block;
  79 + }
77 } 80 }
78 } 81 }
79 } 82 }
@@ -112,3 +115,7 @@ @@ -112,3 +115,7 @@
112 } 115 }
113 } 116 }
114 } 117 }
  118 +
  119 +.merge-request-show-labels .label {
  120 + padding: 6px 10px;
  121 +}
app/assets/stylesheets/sections/notes.scss
@@ -139,6 +139,7 @@ ul.notes { @@ -139,6 +139,7 @@ ul.notes {
139 background-color: #fff; 139 background-color: #fff;
140 border-width: 1px 0; 140 border-width: 1px 0;
141 padding-top: 0; 141 padding-top: 0;
  142 + vertical-align: top;
142 143
143 li { 144 li {
144 padding: 5px; 145 padding: 5px;
app/assets/stylesheets/sections/profile.scss
@@ -76,7 +76,7 @@ @@ -76,7 +76,7 @@
76 } 76 }
77 77
78 &.modern { 78 &.modern {
79 - background: #345; 79 + background: #009871;
80 } 80 }
81 81
82 &.gray { 82 &.gray {
@@ -84,7 +84,7 @@ @@ -84,7 +84,7 @@
84 } 84 }
85 85
86 &.violet { 86 &.violet {
87 - background: #547; 87 + background: #548;
88 } 88 }
89 } 89 }
90 } 90 }
app/assets/stylesheets/sections/tree.scss
@@ -151,3 +151,5 @@ @@ -151,3 +151,5 @@
151 } 151 }
152 } 152 }
153 } 153 }
  154 +
  155 +#modal-remove-blob > .modal-dialog { width: 850px; }
app/assets/stylesheets/sections/votes.scss
@@ -40,4 +40,10 @@ @@ -40,4 +40,10 @@
40 .votes-holder { 40 .votes-holder {
41 float: right; 41 float: right;
42 width: 250px; 42 width: 250px;
  43 +
  44 + @media (max-width: $screen-xs-max) {
  45 + width: 100%;
  46 + margin-top: 5px;
  47 + margin-bottom: 10px;
  48 + }
43 } 49 }
app/assets/stylesheets/themes/ui_color.scss
@@ -16,28 +16,28 @@ @@ -16,28 +16,28 @@
16 @extend .header-dark; 16 @extend .header-dark;
17 &.navbar-gitlab { 17 &.navbar-gitlab {
18 .navbar-inner { 18 .navbar-inner {
19 - background: #547;  
20 - border-bottom: 1px solid #435; 19 + background: #548;
  20 + border-bottom: 1px solid #436;
21 .app_logo, .navbar-toggle { 21 .app_logo, .navbar-toggle {
22 &:hover { 22 &:hover {
23 - background-color: #435; 23 + background-color: #436;
24 } 24 }
25 } 25 }
26 .separator { 26 .separator {
27 - background: #435;  
28 - border-left: 1px solid #658; 27 + background: #436;
  28 + border-left: 1px solid #659;
29 } 29 }
30 .nav > li > a { 30 .nav > li > a {
31 - color: #98B; 31 + color: #98C;
32 } 32 }
33 .search-input { 33 .search-input {
34 - border-color: #98B; 34 + border-color: #98C;
35 } 35 }
36 } 36 }
37 } 37 }
38 } 38 }
39 39
40 .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { 40 .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
41 - background: #769; 41 + background: #659;
42 } 42 }
43 } 43 }
app/assets/stylesheets/themes/ui_modern.scss
@@ -16,24 +16,28 @@ @@ -16,24 +16,28 @@
16 @extend .header-dark; 16 @extend .header-dark;
17 &.navbar-gitlab { 17 &.navbar-gitlab {
18 .navbar-inner { 18 .navbar-inner {
19 - background: #345;  
20 - border-bottom: 1px solid #234; 19 + background: #00AC7E;
  20 + border-bottom: 1px solid #00AC7E;
21 .app_logo, .navbar-toggle { 21 .app_logo, .navbar-toggle {
22 &:hover { 22 &:hover {
23 - background-color: #234; 23 + background-color: #009C6E;
24 } 24 }
25 } 25 }
26 .separator { 26 .separator {
27 - background: #234;  
28 - border-left: 1px solid #456; 27 + background: #009C6F;
  28 + border-left: 1px solid #10BC8E;
29 } 29 }
30 .nav > li > a { 30 .nav > li > a {
31 - color: #89A; 31 + color: #ADC;
32 } 32 }
33 .search-input { 33 .search-input {
34 - border-color: #89A; 34 + border-color: #7fd5be;
35 } 35 }
36 } 36 }
37 } 37 }
38 } 38 }
  39 +
  40 + .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
  41 + background: #00AC7E;
  42 + }
39 } 43 }
app/controllers/application_controller.rb
@@ -117,6 +117,11 @@ class ApplicationController &lt; ActionController::Base @@ -117,6 +117,11 @@ class ApplicationController &lt; ActionController::Base
117 return access_denied! unless can?(current_user, :push_code, project) 117 return access_denied! unless can?(current_user, :push_code, project)
118 end 118 end
119 119
  120 + def authorize_labels!
  121 + # Labels should be accessible for issues and/or merge requests
  122 + authorize_read_issue! || authorize_read_merge_request!
  123 + end
  124 +
120 def access_denied! 125 def access_denied!
121 render "errors/access_denied", layout: "errors", status: 404 126 render "errors/access_denied", layout: "errors", status: 404
122 end 127 end
app/controllers/groups_controller.rb
@@ -68,7 +68,7 @@ class GroupsController &lt; ApplicationController @@ -68,7 +68,7 @@ class GroupsController &lt; ApplicationController
68 @members = group.users_groups 68 @members = group.users_groups
69 69
70 if params[:search].present? 70 if params[:search].present?
71 - users = group.users.search(params[:search]) 71 + users = group.users.search(params[:search]).to_a
72 @members = @members.where(user_id: users) 72 @members = @members.where(user_id: users)
73 end 73 end
74 74
app/controllers/projects/labels_controller.rb
1 class Projects::LabelsController < Projects::ApplicationController 1 class Projects::LabelsController < Projects::ApplicationController
2 before_filter :module_enabled 2 before_filter :module_enabled
3 3
4 - # Allow read any issue  
5 - before_filter :authorize_read_issue! 4 + before_filter :authorize_labels!
6 5
7 respond_to :js, :html 6 respond_to :js, :html
8 7
@@ -13,12 +12,18 @@ class Projects::LabelsController &lt; Projects::ApplicationController @@ -13,12 +12,18 @@ class Projects::LabelsController &lt; Projects::ApplicationController
13 def generate 12 def generate
14 Gitlab::IssuesLabels.generate(@project) 13 Gitlab::IssuesLabels.generate(@project)
15 14
16 - redirect_to project_issues_path(@project) 15 + if params[:redirect] == 'issues'
  16 + redirect_to project_issues_path(@project)
  17 + elsif params[:redirect] == 'merge_requests'
  18 + redirect_to project_merge_requests_path(@project)
  19 + end
17 end 20 end
18 21
19 protected 22 protected
20 23
21 def module_enabled 24 def module_enabled
22 - return render_404 unless @project.issues_enabled 25 + unless @project.issues_enabled || @project.merge_requests_enabled
  26 + return render_404
  27 + end
23 end 28 end
24 end 29 end
app/controllers/projects/merge_requests_controller.rb
@@ -62,11 +62,27 @@ class Projects::MergeRequestsController &lt; Projects::ApplicationController @@ -62,11 +62,27 @@ class Projects::MergeRequestsController &lt; Projects::ApplicationController
62 @merge_request.source_project = @project unless @merge_request.source_project 62 @merge_request.source_project = @project unless @merge_request.source_project
63 @merge_request.target_project ||= (@project.forked_from_project || @project) 63 @merge_request.target_project ||= (@project.forked_from_project || @project)
64 @target_branches = @merge_request.target_project.nil? ? [] : @merge_request.target_project.repository.branch_names 64 @target_branches = @merge_request.target_project.nil? ? [] : @merge_request.target_project.repository.branch_names
65 -  
66 @merge_request.target_branch ||= @merge_request.target_project.default_branch 65 @merge_request.target_branch ||= @merge_request.target_project.default_branch
67 -  
68 @source_project = @merge_request.source_project 66 @source_project = @merge_request.source_project
69 - @merge_request 67 +
  68 + if @merge_request.target_branch && @merge_request.source_branch
  69 + compare_action = Gitlab::Satellite::CompareAction.new(
  70 + current_user,
  71 + @merge_request.target_project,
  72 + @merge_request.target_branch,
  73 + @merge_request.source_project,
  74 + @merge_request.source_branch
  75 + )
  76 +
  77 + @commits = compare_action.commits
  78 + @commits.map! { |commit| Commit.new(commit) }
  79 + @commit = @commits.first
  80 +
  81 + @diffs = compare_action.diffs
  82 + @merge_request.title = @merge_request.source_branch.titleize.humanize
  83 + @target_project = @merge_request.target_project
  84 + @target_repo = @target_project.repository
  85 + end
70 end 86 end
71 87
72 def edit 88 def edit
@@ -80,7 +96,7 @@ class Projects::MergeRequestsController &lt; Projects::ApplicationController @@ -80,7 +96,7 @@ class Projects::MergeRequestsController &lt; Projects::ApplicationController
80 @merge_request = MergeRequests::CreateService.new(project, current_user, params[:merge_request]).execute 96 @merge_request = MergeRequests::CreateService.new(project, current_user, params[:merge_request]).execute
81 97
82 if @merge_request.valid? 98 if @merge_request.valid?
83 - redirect_to [@merge_request.target_project, @merge_request], notice: 'Merge request was successfully created.' 99 + redirect_to project_merge_request_path(@merge_request.target_project, @merge_request), notice: 'Merge request was successfully created.'
84 else 100 else
85 @source_project = @merge_request.source_project 101 @source_project = @merge_request.source_project
86 @target_project = @merge_request.target_project 102 @target_project = @merge_request.target_project
app/controllers/projects/wikis_controller.rb
@@ -12,9 +12,22 @@ class Projects::WikisController &lt; Projects::ApplicationController @@ -12,9 +12,22 @@ class Projects::WikisController &lt; Projects::ApplicationController
12 12
13 def show 13 def show
14 @page = @project_wiki.find_page(params[:id], params[:version_id]) 14 @page = @project_wiki.find_page(params[:id], params[:version_id])
  15 + gollum_wiki = @project_wiki.wiki
  16 + file = gollum_wiki.file(params[:id], gollum_wiki.ref, true)
15 17
16 if @page 18 if @page
17 render 'show' 19 render 'show'
  20 + elsif file
  21 + if file.on_disk?
  22 + send_file file.on_disk_path, disposition: 'inline'
  23 + else
  24 + send_data(
  25 + file.raw_data,
  26 + type: file.mime_type,
  27 + disposition: 'inline',
  28 + filename: file.name
  29 + )
  30 + end
18 else 31 else
19 return render('empty') unless can?(current_user, :write_wiki, @project) 32 return render('empty') unless can?(current_user, :write_wiki, @project)
20 @page = WikiPage.new(@project_wiki) 33 @page = WikiPage.new(@project_wiki)
app/helpers/commits_helper.rb
@@ -117,7 +117,7 @@ module CommitsHelper @@ -117,7 +117,7 @@ module CommitsHelper
117 added_lines[line_new] = { line_code: line_code, type: type, line: line } 117 added_lines[line_new] = { line_code: line_code, type: type, line: line }
118 end 118 end
119 end 119 end
120 - max_length = old_file ? old_file.sloc + added_lines.length : file.sloc 120 + max_length = old_file ? [old_file.loc, file.loc].max : file.loc
121 121
122 offset1 = 0 122 offset1 = 0
123 offset2 = 0 123 offset2 = 0
app/helpers/issues_helper.rb
@@ -82,7 +82,7 @@ module IssuesHelper @@ -82,7 +82,7 @@ module IssuesHelper
82 end 82 end
83 83
84 def milestone_options object 84 def milestone_options object
85 - options_from_collection_for_select(@project.milestones.active, 'id', 'title', object.milestone_id) 85 + options_from_collection_for_select(object.project.milestones.active, 'id', 'title', object.milestone_id)
86 end 86 end
87 87
88 def issue_box_class(item) 88 def issue_box_class(item)
app/helpers/selects_helper.rb
@@ -14,7 +14,7 @@ module SelectsHelper @@ -14,7 +14,7 @@ module SelectsHelper
14 css_class << (opts[:class] || '') 14 css_class << (opts[:class] || '')
15 value = opts[:selected] || '' 15 value = opts[:selected] || ''
16 placeholder = opts[:placeholder] || 'Select user' 16 placeholder = opts[:placeholder] || 'Select user'
17 -  
18 - hidden_field_tag(id, value, class: css_class, 'data-placeholder' => placeholder) 17 + project_id = opts[:project_id] || @project.id
  18 + hidden_field_tag(id, value, class: css_class, 'data-placeholder' => placeholder, 'data-project-id' => project_id)
19 end 19 end
20 end 20 end
app/mailers/emails/issues.rb
@@ -4,6 +4,7 @@ module Emails @@ -4,6 +4,7 @@ module Emails
4 @issue = Issue.find(issue_id) 4 @issue = Issue.find(issue_id)
5 @project = @issue.project 5 @project = @issue.project
6 @target_url = project_issue_url(@project, @issue) 6 @target_url = project_issue_url(@project, @issue)
  7 + set_message_id("issue_#{issue_id}")
7 mail(from: sender(@issue.author_id), 8 mail(from: sender(@issue.author_id),
8 to: recipient(recipient_id), 9 to: recipient(recipient_id),
9 subject: subject("#{@issue.title} (##{@issue.iid})")) 10 subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -14,6 +15,7 @@ module Emails @@ -14,6 +15,7 @@ module Emails
14 @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id 15 @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
15 @project = @issue.project 16 @project = @issue.project
16 @target_url = project_issue_url(@project, @issue) 17 @target_url = project_issue_url(@project, @issue)
  18 + set_reference("issue_#{issue_id}")
17 mail(from: sender(updated_by_user_id), 19 mail(from: sender(updated_by_user_id),
18 to: recipient(recipient_id), 20 to: recipient(recipient_id),
19 subject: subject("#{@issue.title} (##{@issue.iid})")) 21 subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -24,6 +26,7 @@ module Emails @@ -24,6 +26,7 @@ module Emails
24 @project = @issue.project 26 @project = @issue.project
25 @updated_by = User.find updated_by_user_id 27 @updated_by = User.find updated_by_user_id
26 @target_url = project_issue_url(@project, @issue) 28 @target_url = project_issue_url(@project, @issue)
  29 + set_reference("issue_#{issue_id}")
27 mail(from: sender(updated_by_user_id), 30 mail(from: sender(updated_by_user_id),
28 to: recipient(recipient_id), 31 to: recipient(recipient_id),
29 subject: subject("#{@issue.title} (##{@issue.iid})")) 32 subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -35,6 +38,7 @@ module Emails @@ -35,6 +38,7 @@ module Emails
35 @project = @issue.project 38 @project = @issue.project
36 @updated_by = User.find updated_by_user_id 39 @updated_by = User.find updated_by_user_id
37 @target_url = project_issue_url(@project, @issue) 40 @target_url = project_issue_url(@project, @issue)
  41 + set_reference("issue_#{issue_id}")
38 mail(from: sender(updated_by_user_id), 42 mail(from: sender(updated_by_user_id),
39 to: recipient(recipient_id), 43 to: recipient(recipient_id),
40 subject: subject("#{@issue.title} (##{@issue.iid})")) 44 subject: subject("#{@issue.title} (##{@issue.iid})"))
app/mailers/emails/merge_requests.rb
@@ -4,9 +4,10 @@ module Emails @@ -4,9 +4,10 @@ module Emails
4 @merge_request = MergeRequest.find(merge_request_id) 4 @merge_request = MergeRequest.find(merge_request_id)
5 @project = @merge_request.project 5 @project = @merge_request.project
6 @target_url = project_merge_request_url(@project, @merge_request) 6 @target_url = project_merge_request_url(@project, @merge_request)
  7 + set_message_id("merge_request_#{merge_request_id}")
7 mail(from: sender(@merge_request.author_id), 8 mail(from: sender(@merge_request.author_id),
8 to: recipient(recipient_id), 9 to: recipient(recipient_id),
9 - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) 10 + subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
10 end 11 end
11 12
12 def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, updated_by_user_id) 13 def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, updated_by_user_id)
@@ -14,9 +15,10 @@ module Emails @@ -14,9 +15,10 @@ module Emails
14 @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id 15 @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
15 @project = @merge_request.project 16 @project = @merge_request.project
16 @target_url = project_merge_request_url(@project, @merge_request) 17 @target_url = project_merge_request_url(@project, @merge_request)
  18 + set_reference("merge_request_#{merge_request_id}")
17 mail(from: sender(updated_by_user_id), 19 mail(from: sender(updated_by_user_id),
18 to: recipient(recipient_id), 20 to: recipient(recipient_id),
19 - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) 21 + subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
20 end 22 end
21 23
22 def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) 24 def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
@@ -24,18 +26,20 @@ module Emails @@ -24,18 +26,20 @@ module Emails
24 @updated_by = User.find updated_by_user_id 26 @updated_by = User.find updated_by_user_id
25 @project = @merge_request.project 27 @project = @merge_request.project
26 @target_url = project_merge_request_url(@project, @merge_request) 28 @target_url = project_merge_request_url(@project, @merge_request)
  29 + set_reference("merge_request_#{merge_request_id}")
27 mail(from: sender(updated_by_user_id), 30 mail(from: sender(updated_by_user_id),
28 to: recipient(recipient_id), 31 to: recipient(recipient_id),
29 - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) 32 + subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
30 end 33 end
31 34
32 def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) 35 def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
33 @merge_request = MergeRequest.find(merge_request_id) 36 @merge_request = MergeRequest.find(merge_request_id)
34 @project = @merge_request.project 37 @project = @merge_request.project
35 @target_url = project_merge_request_url(@project, @merge_request) 38 @target_url = project_merge_request_url(@project, @merge_request)
  39 + set_reference("merge_request_#{merge_request_id}")
36 mail(from: sender(updated_by_user_id), 40 mail(from: sender(updated_by_user_id),
37 to: recipient(recipient_id), 41 to: recipient(recipient_id),
38 - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) 42 + subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
39 end 43 end
40 end 44 end
41 45
app/mailers/emails/notes.rb
@@ -15,6 +15,7 @@ module Emails @@ -15,6 +15,7 @@ module Emails
15 @issue = @note.noteable 15 @issue = @note.noteable
16 @project = @note.project 16 @project = @note.project
17 @target_url = project_issue_url(@project, @issue, anchor: "note_#{@note.id}") 17 @target_url = project_issue_url(@project, @issue, anchor: "note_#{@note.id}")
  18 + set_reference("issue_#{@issue.id}")
18 mail(from: sender(@note.author_id), 19 mail(from: sender(@note.author_id),
19 to: recipient(recipient_id), 20 to: recipient(recipient_id),
20 subject: subject("#{@issue.title} (##{@issue.iid})")) 21 subject: subject("#{@issue.title} (##{@issue.iid})"))
@@ -25,9 +26,10 @@ module Emails @@ -25,9 +26,10 @@ module Emails
25 @merge_request = @note.noteable 26 @merge_request = @note.noteable
26 @project = @note.project 27 @project = @note.project
27 @target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{@note.id}") 28 @target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{@note.id}")
  29 + set_reference("merge_request_#{@merge_request.id}")
28 mail(from: sender(@note.author_id), 30 mail(from: sender(@note.author_id),
29 to: recipient(recipient_id), 31 to: recipient(recipient_id),
30 - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) 32 + subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
31 end 33 end
32 34
33 def note_wall_email(recipient_id, note_id) 35 def note_wall_email(recipient_id, note_id)
app/mailers/notify.rb
@@ -53,6 +53,22 @@ class Notify &lt; ActionMailer::Base @@ -53,6 +53,22 @@ class Notify &lt; ActionMailer::Base
53 end 53 end
54 end 54 end
55 55
  56 + # Set the Message-ID header field
  57 + #
  58 + # local_part - The local part of the message ID
  59 + #
  60 + def set_message_id(local_part)
  61 + headers["Message-ID"] = "<#{local_part}@#{Gitlab.config.gitlab.host}>"
  62 + end
  63 +
  64 + # Set the References header field
  65 + #
  66 + # local_part - The local part of the referenced message ID
  67 + #
  68 + def set_reference(local_part)
  69 + headers["References"] = "<#{local_part}@#{Gitlab.config.gitlab.host}>"
  70 + end
  71 +
56 # Formats arguments into a String suitable for use as an email subject 72 # Formats arguments into a String suitable for use as an email subject
57 # 73 #
58 # extra - Extra Strings to be inserted into the subject 74 # extra - Extra Strings to be inserted into the subject
app/models/merge_request.rb
@@ -36,7 +36,9 @@ class MergeRequest &lt; ActiveRecord::Base @@ -36,7 +36,9 @@ class MergeRequest &lt; ActiveRecord::Base
36 36
37 delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil 37 delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
38 38
39 - attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :state_event, :description 39 + attr_accessible :title, :assignee_id, :source_project_id, :source_branch,
  40 + :target_project_id, :target_branch, :milestone_id,
  41 + :state_event, :description, :label_list
40 42
41 attr_accessor :should_remove_source_branch 43 attr_accessor :should_remove_source_branch
42 44
@@ -44,6 +46,9 @@ class MergeRequest &lt; ActiveRecord::Base @@ -44,6 +46,9 @@ class MergeRequest &lt; ActiveRecord::Base
44 # It allows us to close or modify broken merge requests 46 # It allows us to close or modify broken merge requests
45 attr_accessor :allow_broken 47 attr_accessor :allow_broken
46 48
  49 + ActsAsTaggableOn.strict_case_match = true
  50 + acts_as_taggable_on :labels
  51 +
47 state_machine :state, initial: :opened do 52 state_machine :state, initial: :opened do
48 event :close do 53 event :close do
49 transition [:reopened, :opened] => :closed 54 transition [:reopened, :opened] => :closed
@@ -253,6 +258,14 @@ class MergeRequest &lt; ActiveRecord::Base @@ -253,6 +258,14 @@ class MergeRequest &lt; ActiveRecord::Base
253 end 258 end
254 end 259 end
255 260
  261 + def target_project_namespace
  262 + if target_project && target_project.namespace
  263 + target_project.namespace.path
  264 + else
  265 + "(removed)"
  266 + end
  267 + end
  268 +
256 def source_branch_exists? 269 def source_branch_exists?
257 return false unless self.source_project 270 return false unless self.source_project
258 271
app/models/merge_request_diff.rb
@@ -86,7 +86,7 @@ class MergeRequestDiff &lt; ActiveRecord::Base @@ -86,7 +86,7 @@ class MergeRequestDiff &lt; ActiveRecord::Base
86 # between target and source branches 86 # between target and source branches
87 def unmerged_commits 87 def unmerged_commits
88 commits = if merge_request.for_fork? 88 commits = if merge_request.for_fork?
89 - Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between 89 + compare_action.commits
90 else 90 else
91 repository.commits_between(target_branch, source_branch) 91 repository.commits_between(target_branch, source_branch)
92 end 92 end
@@ -150,7 +150,7 @@ class MergeRequestDiff &lt; ActiveRecord::Base @@ -150,7 +150,7 @@ class MergeRequestDiff &lt; ActiveRecord::Base
150 # between target and source branches 150 # between target and source branches
151 def unmerged_diffs 151 def unmerged_diffs
152 diffs = if merge_request.for_fork? 152 diffs = if merge_request.for_fork?
153 - Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite 153 + compare_action.diffs
154 else 154 else
155 Gitlab::Git::Diff.between(repository, source_branch, target_branch) 155 Gitlab::Git::Diff.between(repository, source_branch, target_branch)
156 end 156 end
@@ -165,4 +165,16 @@ class MergeRequestDiff &lt; ActiveRecord::Base @@ -165,4 +165,16 @@ class MergeRequestDiff &lt; ActiveRecord::Base
165 def repository 165 def repository
166 merge_request.target_project.repository 166 merge_request.target_project.repository
167 end 167 end
  168 +
  169 + private
  170 +
  171 + def compare_action
  172 + Gitlab::Satellite::CompareAction.new(
  173 + merge_request.author,
  174 + merge_request.target_project,
  175 + merge_request.target_branch,
  176 + merge_request.source_project,
  177 + merge_request.source_branch
  178 + )
  179 + end
168 end 180 end
app/models/project.rb
@@ -281,8 +281,11 @@ class Project &lt; ActiveRecord::Base @@ -281,8 +281,11 @@ class Project &lt; ActiveRecord::Base
281 self.id 281 self.id
282 end 282 end
283 283
  284 + # Tags are shared by issues and merge requests
284 def issues_labels 285 def issues_labels
285 - @issues_labels ||= (issues_default_labels + issues.tags_on(:labels)).uniq.sort_by(&:name) 286 + @issues_labels ||= (issues_default_labels +
  287 + merge_requests.tags_on(:labels) +
  288 + issues.tags_on(:labels)).uniq.sort_by(&:name)
286 end 289 end
287 290
288 def issue_exists?(issue_id) 291 def issue_exists?(issue_id)
app/models/project_wiki.rb
@@ -64,7 +64,8 @@ class ProjectWiki @@ -64,7 +64,8 @@ class ProjectWiki
64 # 64 #
65 # Returns an initialized WikiPage instance or nil 65 # Returns an initialized WikiPage instance or nil
66 def find_page(title, version = nil) 66 def find_page(title, version = nil)
67 - if page = wiki.page(title, version) 67 + page_title, page_dir = page_title_and_dir(title)
  68 + if page = wiki.page(page_title, version, page_dir)
68 WikiPage.new(self, page, true) 69 WikiPage.new(self, page, true)
69 else 70 else
70 nil 71 nil
@@ -90,6 +91,12 @@ class ProjectWiki @@ -90,6 +91,12 @@ class ProjectWiki
90 wiki.delete_page(page, commit_details(:deleted, message, page.title)) 91 wiki.delete_page(page, commit_details(:deleted, message, page.title))
91 end 92 end
92 93
  94 + def page_title_and_dir(title)
  95 + title_array = title.split("/")
  96 + title = title_array.pop
  97 + [title.gsub(/\.[^.]*$/, ""), title_array.join("/")]
  98 + end
  99 +
93 private 100 private
94 101
95 def create_repo! 102 def create_repo!
app/models/wiki_page.rb
@@ -175,14 +175,24 @@ class WikiPage @@ -175,14 +175,24 @@ class WikiPage
175 end 175 end
176 176
177 def save(method, *args) 177 def save(method, *args)
178 - if valid? && wiki.send(method, *args)  
179 - @page = wiki.wiki.paged(title) 178 + project_wiki = wiki
  179 + if valid? && project_wiki.send(method, *args)
  180 +
  181 + page_details = if method == :update_page
  182 + @page.path
  183 + else
  184 + title
  185 + end
  186 +
  187 + page_title, page_dir = project_wiki.page_title_and_dir(page_details)
  188 + gollum_wiki = project_wiki.wiki
  189 + @page = gollum_wiki.paged(page_title, page_dir)
180 190
181 set_attributes 191 set_attributes
182 192
183 @persisted = true 193 @persisted = true
184 else 194 else
185 - errors.add(:base, wiki.error_message) if wiki.error_message 195 + errors.add(:base, project_wiki.error_message) if project_wiki.error_message
186 @persisted = false 196 @persisted = false
187 end 197 end
188 @persisted 198 @persisted
app/services/system_hooks_service.rb
@@ -31,7 +31,8 @@ class SystemHooksService @@ -31,7 +31,8 @@ class SystemHooksService
31 path_with_namespace: model.path_with_namespace, 31 path_with_namespace: model.path_with_namespace,
32 project_id: model.id, 32 project_id: model.id,
33 owner_name: owner.name, 33 owner_name: owner.name,
34 - owner_email: owner.respond_to?(:email) ? owner.email : nil 34 + owner_email: owner.respond_to?(:email) ? owner.email : nil,
  35 + project_visibility: Project.visibility_levels.key(model.visibility_level_field).downcase
35 }) 36 })
36 when User 37 when User
37 data.merge!({ 38 data.merge!({
@@ -46,7 +47,8 @@ class SystemHooksService @@ -46,7 +47,8 @@ class SystemHooksService
46 project_id: model.project_id, 47 project_id: model.project_id,
47 user_name: model.user.name, 48 user_name: model.user.name,
48 user_email: model.user.email, 49 user_email: model.user.email,
49 - project_access: model.human_access 50 + project_access: model.human_access,
  51 + project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase
50 }) 52 })
51 end 53 end
52 end 54 end
app/views/admin/users/_form.html.haml
@@ -2,9 +2,9 @@ @@ -2,9 +2,9 @@
2 = form_for [:admin, @user], html: { class: 'form-horizontal' } do |f| 2 = form_for [:admin, @user], html: { class: 'form-horizontal' } do |f|
3 -if @user.errors.any? 3 -if @user.errors.any?
4 #error_explanation 4 #error_explanation
5 - %ul.unstyled.alert.alert-danger 5 + .alert.alert-danger
6 - @user.errors.full_messages.each do |msg| 6 - @user.errors.full_messages.each do |msg|
7 - %li= msg 7 + %p= msg
8 8
9 %fieldset 9 %fieldset
10 %legend Account 10 %legend Account
app/views/events/event/_note.html.haml
@@ -14,8 +14,8 @@ @@ -14,8 +14,8 @@
14 - note = event.target 14 - note = event.target
15 - if note.attachment.url 15 - if note.attachment.url
16 - if note.attachment.image? 16 - if note.attachment.image?
17 - = link_to note.attachment.url, target: '_blank' do  
18 - = image_tag note.attachment.url, class: 'note-image-attach' 17 + = link_to note.attachment.secure_url, target: '_blank' do
  18 + = image_tag note.attachment.secure_url, class: 'note-image-attach'
19 - else 19 - else
20 = link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do 20 = link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do
21 %i.icon-paper-clip 21 %i.icon-paper-clip
app/views/groups/show.html.haml
1 .dashboard 1 .dashboard
2 - .activities.col-md-8.hidden-sm 2 + .activities.col-md-8.hidden-sm.hidden-xs
3 - if current_user 3 - if current_user
4 = render "events/event_last_push", event: @last_push 4 = render "events/event_last_push", event: @last_push
5 = link_to dashboard_path, class: 'btn btn-tiny' do 5 = link_to dashboard_path, class: 'btn btn-tiny' do
app/views/layouts/_head_panel.html.haml
@@ -43,6 +43,6 @@ @@ -43,6 +43,6 @@
43 %li 43 %li
44 = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do 44 = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do
45 %i.icon-signout 45 %i.icon-signout
46 - %li 46 + %li.hidden-xs
47 = link_to current_user, class: "profile-pic", id: 'profile-pic' do 47 = link_to current_user, class: "profile-pic", id: 'profile-pic' do
48 = image_tag avatar_icon(current_user.email, 26), alt: 'User activity' 48 = image_tag avatar_icon(current_user.email, 26), alt: 'User activity'
app/views/notify/closed_merge_request_email.html.haml
1 %p 1 %p
2 - = "Merge Request !#{@merge_request.iid} was closed by #{@updated_by.name}" 2 + = "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}"
app/views/notify/closed_merge_request_email.text.haml
1 -= "Merge Request #{@merge_request.iid} was closed by #{@updated_by.name}" 1 += "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}"
2 2
3 Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} 3 Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
4 4
app/views/notify/merged_merge_request_email.html.haml
1 %p 1 %p
2 - = "Merge Request !#{@merge_request.iid} was merged" 2 + = "Merge Request ##{@merge_request.iid} was merged"
app/views/notify/merged_merge_request_email.text.haml
1 -= "Merge Request #{@merge_request.iid} was merged" 1 += "Merge Request ##{@merge_request.iid} was merged"
2 2
3 Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} 3 Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
4 4
app/views/projects/blob/_blob.html.haml
@@ -15,18 +15,18 @@ @@ -15,18 +15,18 @@
15 - else 15 - else
16 = link_to title, '#' 16 = link_to title, '#'
17 17
18 -%ul.blob-commit-info.bs-callout.bs-callout-info 18 +%ul.blob-commit-info.bs-callout.bs-callout-info.hidden-xs
19 - blob_commit = @repository.last_commit_for_path(@commit.id, @blob.path) 19 - blob_commit = @repository.last_commit_for_path(@commit.id, @blob.path)
20 = render blob_commit, project: @project 20 = render blob_commit, project: @project
21 21
22 %div#tree-content-holder.tree-content-holder 22 %div#tree-content-holder.tree-content-holder
23 .file-holder 23 .file-holder
24 - .file-title 24 + .file-title.clearfix
25 %i.icon-file 25 %i.icon-file
26 %span.file_name 26 %span.file_name
27 = blob.name 27 = blob.name
28 %small= number_to_human_size blob.size 28 %small= number_to_human_size blob.size
29 - %span.options= render "actions" 29 + %span.options.hidden-xs= render "actions"
30 - if blob.text? 30 - if blob.text?
31 = render "text", blob: blob 31 = render "text", blob: blob
32 - elsif blob.image? 32 - elsif blob.image?
app/views/projects/blob/_remove.html.haml
@@ -14,7 +14,8 @@ @@ -14,7 +14,8 @@
14 = label_tag 'commit_message', class: "control-label" do 14 = label_tag 'commit_message', class: "control-label" do
15 Commit message 15 Commit message
16 .col-sm-10 16 .col-sm-10
17 - = text_area_tag 'commit_message', params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3, class: 'form-control' 17 + = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message',
  18 + params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3, class: 'form-control')}
18 .form-group 19 .form-group
19 .col-sm-2 20 .col-sm-2
20 .col-sm-10 21 .col-sm-10
app/views/projects/commits/_parallel_view.html.haml
@@ -2,54 +2,37 @@ @@ -2,54 +2,37 @@
2 - old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file) 2 - old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file)
3 - num_lines = old_lines.length 3 - num_lines = old_lines.length
4 4
5 -%div.text-file-parallel  
6 - %div.diff-side.diff-side-left  
7 - %table  
8 - - old_lines.each do |line| 5 +%div.text-file
  6 + %table
  7 + - num_lines.times do |index|
  8 + - new_line = new_lines[index]
  9 + - old_line = old_lines[index]
  10 + %tr.line_holder.parallel
  11 + -# For old line
  12 + - if old_line.type == :file_created
  13 + %td.old_line= old_line.num
  14 + %td.line_content.parallel= "File was created"
  15 + - elsif old_line.type == :deleted
  16 + %td.old_line.old= old_line.num
  17 + %td.line_content{class: "parallel noteable_line old #{old_line.code}", "line_code" => old_line.code}= old_line.content
  18 + - else old_line.type == :no_change
  19 + %td.old_line= old_line.num
  20 + %td.line_content.parallel= old_line.content
  21 +
  22 + -# For new line
  23 + - if new_line.type == :file_deleted
  24 + %td.new_line= new_line.num
  25 + %td.line_content.parallel= "File was deleted"
  26 + - elsif new_line.type == :added
  27 + %td.new_line.new= new_line.num
  28 + %td.line_content{class: "parallel noteable_line new #{new_line.code}", "line_code" => new_line.code}= new_line.content
  29 + - else new_line.type == :no_change
  30 + %td.new_line= new_line.num
  31 + %td.line_content.parallel= new_line.content
  32 +
  33 + - if @reply_allowed
  34 + - comments1 = @line_notes.select { |n| n.line_code == old_line.code }.sort_by(&:created_at)
  35 + - comments2 = @line_notes.select { |n| n.line_code == new_line.code }.sort_by(&:created_at)
  36 + - unless comments1.empty? and comments2.empty?
  37 + = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2
9 38
10 - %tr.line_holder.parallel  
11 - - if line.type == :file_created  
12 - %td.line_content.parallel= "File was created"  
13 - - elsif line.type == :deleted  
14 - %td.line_content{class: "parallel noteable_line old #{line.code}", "line_code" => line.code }= line.content  
15 - - else line.type == :no_change  
16 - %td.line_content.parallel= line.content  
17 -  
18 - %div.diff-middle  
19 - %table  
20 - - num_lines.times do |index|  
21 - %tr  
22 - - if old_lines[index].type == :deleted  
23 - %td.old_line.old= old_lines[index].num  
24 - - else  
25 - %td.old_line= old_lines[index].num  
26 -  
27 - %td.diff_line=""  
28 -  
29 - - if new_lines[index].type == :added  
30 - %td.new_line.new= new_lines[index].num  
31 - - else  
32 - %td.new_line= new_lines[index].num  
33 -  
34 - %div.diff-side.diff-side-right  
35 - %table  
36 - - new_lines.each do |line|  
37 -  
38 - %tr.line_holder.parallel  
39 - - if line.type == :file_deleted  
40 - %td.line_content.parallel= "File was deleted"  
41 - - elsif line.type == :added  
42 - %td.line_content{class: "parallel noteable_line new #{line.code}", "line_code" => line.code }= line.content  
43 - - else line.type == :no_change  
44 - %td.line_content.parallel= line.content  
45 -  
46 -:javascript  
47 - $('.diff-side-right').on('scroll', function(){  
48 - $('.diff-side-left, .diff-middle').scrollTop($(this).scrollTop());  
49 - $('.diff-side-left').scrollLeft($(this).scrollLeft());  
50 - });  
51 -  
52 - $('.diff-side-left').on('scroll', function(){  
53 - $('.diff-side-right, .diff-middle').scrollTop($(this).scrollTop()); // might never be relevant  
54 - $('.diff-side-right').scrollLeft($(this).scrollLeft());  
55 - });  
app/views/projects/edit_tree/show.html.haml
@@ -23,7 +23,8 @@ @@ -23,7 +23,8 @@
23 = label_tag 'commit_message', class: "control-label" do 23 = label_tag 'commit_message', class: "control-label" do
24 Commit message 24 Commit message
25 .col-sm-10 25 .col-sm-10
26 - = text_area_tag 'commit_message', '', placeholder: "Update #{@blob.name}", required: true, rows: 3, class: 'form-control' 26 + = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message', '',
  27 + placeholder: "Update #{@blob.name}", required: true, rows: 3, class: 'form-control')}
27 .form-actions 28 .form-actions
28 = hidden_field_tag 'last_commit', @last_commit 29 = hidden_field_tag 'last_commit', @last_commit
29 = hidden_field_tag 'content', '', id: "file-content" 30 = hidden_field_tag 'content', '', id: "file-content"
app/views/projects/issues/_issue_context.html.haml
1 = form_for [@project, @issue], remote: true, html: {class: 'edit-issue inline-update'} do |f| 1 = form_for [@project, @issue], remote: true, html: {class: 'edit-issue inline-update'} do |f|
2 - %strong.append-right-10  
3 - Assignee: 2 + .row
  3 + .col-md-6
  4 + %strong.append-right-10
  5 + Assignee:
4 6
5 - - if can?(current_user, :modify_issue, @issue)  
6 - = project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @issue.assignee_id)  
7 - - elsif issue.assignee  
8 - = link_to_member(@project, @issue.assignee)  
9 - - else  
10 - None 7 + - if can?(current_user, :modify_issue, @issue)
  8 + = project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @issue.assignee_id)
  9 + - elsif issue.assignee
  10 + = link_to_member(@project, @issue.assignee)
  11 + - else
  12 + None
11 13
12 - .pull-right  
13 - %strong.append-right-10  
14 - Milestone:  
15 - - if can?(current_user, :modify_issue, @issue)  
16 - = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone (none):" }, {class: 'select2 select2-compact'})  
17 - = hidden_field_tag :issue_context  
18 - = f.submit class: 'btn'  
19 - - elsif issue.milestone  
20 - = link_to issue.milestone.title, project_milestone_path  
21 - - else  
22 - None 14 + .col-md-6.text-right
  15 + %strong.append-right-10
  16 + Milestone:
  17 + - if can?(current_user, :modify_issue, @issue)
  18 + = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact'})
  19 + = hidden_field_tag :issue_context
  20 + = f.submit class: 'btn'
  21 + - elsif issue.milestone
  22 + = link_to issue.milestone.title, project_milestone_path
  23 + - else
  24 + None
app/views/projects/issues/index.html.haml
1 = render "head" 1 = render "head"
2 .row 2 .row
3 .col-md-3 3 .col-md-3
4 - = render 'shared/project_filter', project_entities_path: project_issues_path(@project), labels: true 4 + = render 'shared/project_filter', project_entities_path: project_issues_path(@project),
  5 + labels: true, redirect: 'issues'
5 .col-md-9.issues-holder 6 .col-md-9.issues-holder
6 = render "issues" 7 = render "issues"
app/views/projects/issues/show.html.haml
1 %h3.page-title 1 %h3.page-title
2 Issue ##{@issue.iid} 2 Issue ##{@issue.iid}
3 3
4 - %span.pull-right 4 + %span.pull-right.issue-btn-group
5 - if can?(current_user, :write_issue, @project) 5 - if can?(current_user, :write_issue, @project)
6 = link_to new_project_issue_path(@project), class: "btn btn-grouped", title: "New Issue", id: "new_issue_link" do 6 = link_to new_project_issue_path(@project), class: "btn btn-grouped", title: "New Issue", id: "new_issue_link" do
7 %i.icon-plus 7 %i.icon-plus
@@ -16,28 +16,29 @@ @@ -16,28 +16,29 @@
16 %i.icon-edit 16 %i.icon-edit
17 Edit 17 Edit
18 18
19 -.votes-holder  
20 - #votes= render 'votes/votes_block', votable: @issue 19 +.clearfix
  20 + .votes-holder
  21 + #votes= render 'votes/votes_block', votable: @issue
21 22
22 -.back-link  
23 - = link_to project_issues_path(@project) do  
24 - &larr; To issues list  
25 - %span.milestone-nav-link  
26 - - if @issue.milestone  
27 - |  
28 - %span.light Milestone  
29 - = link_to project_milestone_path(@project, @issue.milestone) do  
30 - = @issue.milestone.title 23 + .back-link
  24 + = link_to project_issues_path(@project) do
  25 + &larr; To issues list
  26 + %span.milestone-nav-link
  27 + - if @issue.milestone
  28 + |
  29 + %span.light Milestone
  30 + = link_to project_milestone_path(@project, @issue.milestone) do
  31 + = @issue.milestone.title
31 32
32 .issue-box{ class: issue_box_class(@issue) } 33 .issue-box{ class: issue_box_class(@issue) }
33 - .state  
34 - %span.state-label 34 + .state.clearfix
  35 + .state-label.col-sm-2.col-xs-12
35 - if @issue.closed? 36 - if @issue.closed?
36 Closed 37 Closed
37 - else 38 - else
38 Open 39 Open
39 40
40 - %span.creator 41 + %span.creator.col-sm-9.col-xs-12
41 Created by #{link_to_member(@project, @issue.author)} #{time_ago_with_tooltip(@issue.created_at)} 42 Created by #{link_to_member(@project, @issue.author)} #{time_ago_with_tooltip(@issue.created_at)}
42 43
43 %h4.title 44 %h4.title
app/views/projects/merge_requests/_form.html.haml
@@ -14,33 +14,6 @@ @@ -14,33 +14,6 @@
14 - @merge_request.errors.full_messages.each do |msg| 14 - @merge_request.errors.full_messages.each do |msg|
15 %div= msg 15 %div= msg
16 16
17 - .merge-request-branches  
18 - .form-group  
19 - = label_tag nil, class: 'control-label' do  
20 - From  
21 - .col-sm-10  
22 - .clearfix  
23 - .pull-left  
24 - = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted? })  
25 - .pull-left  
26 - &nbsp;  
27 - = f.select(:source_branch, @merge_request.source_branches, { include_blank: "Select branch" }, {class: 'source_branch select2 span2'})  
28 - .mr_source_commit  
29 - %br  
30 - .form-group  
31 - = label_tag nil, class: 'control-label' do  
32 - To  
33 - .col-sm-10  
34 - .clearfix  
35 - .pull-left  
36 - - projects = @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project]  
37 - = 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? })  
38 - .pull-left  
39 - &nbsp;  
40 - = f.select(:target_branch, @merge_request.target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2'})  
41 - .mr_target_commit  
42 -  
43 - %hr  
44 .merge-request-form-info 17 .merge-request-form-info
45 .form-group 18 .form-group
46 = f.label :title, class: 'control-label' do 19 = f.label :title, class: 'control-label' do
@@ -51,6 +24,32 @@ @@ -51,6 +24,32 @@
51 .col-sm-10 24 .col-sm-10
52 = f.text_area :description, class: "form-control js-gfm-input", rows: 14 25 = f.text_area :description, class: "form-control js-gfm-input", rows: 14
53 %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. 26 %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
  27 + %hr
  28 + .form-group
  29 + .issue-assignee
  30 + = f.label :assignee_id, class: 'control-label' do
  31 + %i.icon-user
  32 + Assign to
  33 + .col-sm-10
  34 + = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id)
  35 + &nbsp;
  36 + = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link'
  37 + .form-group
  38 + .issue-milestone
  39 + = f.label :milestone_id, class: 'control-label' do
  40 + %i.icon-time
  41 + Milestone
  42 + .col-sm-10= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'})
  43 +
  44 +
  45 + - if @merge_request.persisted? # Only allow labels on edit to avoid fork vs upstream repo labels issue
  46 + .form-group
  47 + = f.label :label_list, class: 'control-label' do
  48 + %i.icon-tag
  49 + Labels
  50 + .col-sm-10
  51 + = f.text_field :label_list, maxlength: 2000, class: "form-control"
  52 + %p.hint Separate labels with commas.
54 53
55 .form-actions 54 .form-actions
56 - if @merge_request.new_record? 55 - if @merge_request.new_record?
@@ -66,20 +65,36 @@ @@ -66,20 +65,36 @@
66 65
67 :javascript 66 :javascript
68 disableButtonIfEmptyField("#merge_request_title", ".btn-save"); 67 disableButtonIfEmptyField("#merge_request_title", ".btn-save");
69 -  
70 - var source_branch = $("#merge_request_source_branch")  
71 - , target_branch = $("#merge_request_target_branch")  
72 - , target_project = $("#merge_request_target_project_id");  
73 -  
74 - $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: source_branch.val() });  
75 - $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: target_branch.val() });  
76 -  
77 - target_project.on("change", function() {  
78 - $.get("#{update_branches_project_merge_requests_path(@source_project)}", {target_project_id: $(this).val() });  
79 - });  
80 - source_branch.on("change", function() {  
81 - $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: $(this).val() });  
82 - });  
83 - target_branch.on("change", function() {  
84 - $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() }); 68 + $('.assign-to-me-link').on('click', function(e){
  69 + $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
  70 + e.preventDefault();
85 }); 71 });
  72 +
  73 + $("#merge_request_label_list")
  74 + .bind( "keydown", function( event ) {
  75 + if ( event.keyCode === $.ui.keyCode.TAB &&
  76 + $( this ).data( "autocomplete" ).menu.active ) {
  77 + event.preventDefault();
  78 + }
  79 + })
  80 + .bind("click", function(event) {
  81 + $(this).autocomplete("search", "");
  82 + })
  83 + .autocomplete({
  84 + minLength: 0,
  85 + source: function( request, response ) {
  86 + response( $.ui.autocomplete.filter(
  87 + #{raw labels_autocomplete_source}, extractLast( request.term ) ) );
  88 + },
  89 + focus: function() {
  90 + return false;
  91 + },
  92 + select: function(event, ui) {
  93 + var terms = split( this.value );
  94 + terms.pop();
  95 + terms.push( ui.item.value );
  96 + terms.push( "" );
  97 + this.value = terms.join( ", " );
  98 + return false;
  99 + }
  100 + });
app/views/projects/merge_requests/_merge_request.html.haml
@@ -11,13 +11,9 @@ @@ -11,13 +11,9 @@
11 - if merge_request.for_fork? 11 - if merge_request.for_fork?
12 %span.light 12 %span.light
13 #{merge_request.source_project_namespace}: 13 #{merge_request.source_project_namespace}:
14 - = merge_request.source_branch  
15 - %i.icon-angle-right.light  
16 - = merge_request.target_branch  
17 - - else  
18 - = merge_request.source_branch  
19 - %i.icon-angle-right.light  
20 - = merge_request.target_branch 14 + = truncate merge_request.source_branch, length: 25
  15 + %i.icon-angle-right.light
  16 + = merge_request.target_branch
21 .merge-request-info 17 .merge-request-info
22 - if merge_request.author 18 - if merge_request.author
23 authored by #{link_to_member(merge_request.source_project, merge_request.author)} 19 authored by #{link_to_member(merge_request.source_project, merge_request.author)}
@@ -35,3 +31,9 @@ @@ -35,3 +31,9 @@
35 31
36 .pull-right 32 .pull-right
37 %small updated #{time_ago_with_tooltip(merge_request.updated_at, 'bottom', 'merge_request_updated_ago')} 33 %small updated #{time_ago_with_tooltip(merge_request.updated_at, 'bottom', 'merge_request_updated_ago')}
  34 +
  35 + .merge-request-labels
  36 + - merge_request.labels.each do |label|
  37 + %span{class: "label #{label_css_class(label.name)}"}
  38 + %i.icon-tag
  39 + = label.name
app/views/projects/merge_requests/_new_compare.html.haml 0 → 100644
@@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
  1 +%h3.page-title Compare branches for new Merge Request
  2 +%hr
  3 +
  4 += form_for [@project, @merge_request], url: new_project_merge_request_path(@project), method: :get, html: { class: "merge-request-form form-inline" } do |f|
  5 + .hide.alert.alert-danger.mr-compare-errors
  6 + .merge-request-branches.row
  7 + .col-md-6
  8 + .panel.panel-default
  9 + .panel-heading
  10 + %strong Source branch
  11 + .panel-body
  12 + = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted? })
  13 + &nbsp;
  14 + = f.select(:source_branch, @merge_request.source_branches, { include_blank: "Select branch" }, {class: 'source_branch select2 span2'})
  15 + .panel-footer
  16 + .mr_source_commit
  17 +
  18 + .col-md-6
  19 + .panel.panel-default
  20 + .panel-heading
  21 + %strong Target branch
  22 + .panel-body
  23 + - projects = @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project]
  24 + = 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? })
  25 + &nbsp;
  26 + = f.select(:target_branch, @merge_request.target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2'})
  27 + .panel-footer
  28 + .mr_target_commit
  29 +
  30 + -if @merge_request.errors.any?
  31 + .alert.alert-danger
  32 + - @merge_request.errors.full_messages.each do |msg|
  33 + %div= msg
  34 +
  35 + - if @merge_request.source_branch.present? && @merge_request.target_branch.present?
  36 + .light-well
  37 + %center
  38 + %h4
  39 + There isn't anything to merge.
  40 + %p.slead
  41 + - if @merge_request.source_branch == @merge_request.target_branch
  42 + You'll need to use different branch names to get a valid comparison.
  43 + - else
  44 + %span.label-branch #{@merge_request.source_branch}
  45 + and
  46 + %span.label-branch #{@merge_request.target_branch}
  47 + are the same.
  48 +
  49 +
  50 + %hr
  51 + = f.submit 'Compare branches', class: "btn btn-primary mr-compare-btn"
  52 +
  53 +:javascript
  54 + var source_branch = $("#merge_request_source_branch")
  55 + , target_branch = $("#merge_request_target_branch")
  56 + , target_project = $("#merge_request_target_project_id");
  57 +
  58 + $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: source_branch.val() });
  59 + $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: target_branch.val() });
  60 +
  61 + target_project.on("change", function() {
  62 + $.get("#{update_branches_project_merge_requests_path(@source_project)}", {target_project_id: $(this).val() });
  63 + });
  64 + source_branch.on("change", function() {
  65 + $.get("#{branch_from_project_merge_requests_path(@source_project)}", {ref: $(this).val() });
  66 + $(".mr-compare-errors").fadeOut();
  67 + $(".mr-compare-btn").enable();
  68 + });
  69 + target_branch.on("change", function() {
  70 + $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() });
  71 + $(".mr-compare-errors").fadeOut();
  72 + $(".mr-compare-btn").enable();
  73 + });
  74 +
  75 +
  76 +:coffeescript
  77 +
  78 + $(".merge-request-form").on 'submit', ->
  79 + if $("#merge_request_source_branch").val() is "" or $('#merge_request_target_branch').val() is ""
  80 + $(".mr-compare-errors").html("You must select source and target branch to proceed")
  81 + $(".mr-compare-errors").fadeIn()
  82 + event.preventDefault()
  83 + return
  84 +
app/views/projects/merge_requests/_new_submit.html.haml 0 → 100644
@@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
  1 +%h3.page-title
  2 + New merge request
  3 +%p.slead
  4 + From
  5 + %strong.monospace
  6 + #{@merge_request.source_project_namespace}:#{@merge_request.source_branch}
  7 + into
  8 + %strong.monospace
  9 + #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
  10 +
  11 + %span.pull-right
  12 + = link_to 'Change branches', new_project_merge_request_path(@project)
  13 +
  14 += form_for [@project, @merge_request], html: { class: "merge-request-form" } do |f|
  15 + .panel.panel-default
  16 +
  17 + .panel-body
  18 + .form-group
  19 + .light
  20 + = f.label :title do
  21 + = "Title *"
  22 + = f.text_field :title, class: "form-control input-lg js-gfm-input", maxlength: 255, rows: 5, required: true
  23 + .form-group
  24 + .light
  25 + = f.label :description, "Description"
  26 + = f.text_area :description, class: "form-control js-gfm-input", rows: 10
  27 + %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
  28 + .form-group
  29 + .issue-assignee
  30 + = f.label :assignee_id do
  31 + %i.icon-user
  32 + Assign to
  33 + %div
  34 + = 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)
  35 + &nbsp;
  36 + = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link'
  37 + .form-group
  38 + .issue-milestone
  39 + = f.label :milestone_id do
  40 + %i.icon-time
  41 + Milestone
  42 + %div= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'})
  43 + .panel-footer
  44 + - if @target_repo.contribution_guide
  45 + - contribution_guide_url = project_blob_path(@target_project, tree_join(@target_repo.root_ref, @target_repo.contribution_guide.name))
  46 + %p
  47 + Please review the
  48 + %strong #{link_to "guidelines for contribution", contribution_guide_url}
  49 + to this repository.
  50 + = f.hidden_field :source_project_id
  51 + = f.hidden_field :target_project_id
  52 + = f.hidden_field :target_branch
  53 + = f.hidden_field :source_branch
  54 + = f.submit 'Submit merge request', class: "btn btn-create"
  55 +
  56 +.mr-compare
  57 + %div.ui-box
  58 + .title
  59 + Commits (#{@commits.count})
  60 + - if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
  61 + %ul.well-list
  62 + - Commit.decorate(@commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE)).each do |commit|
  63 + = render "projects/commits/inline_commit", commit: commit, project: @project
  64 + %li.warning-row.unstyled
  65 + other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden to prevent performance issues.
  66 + - else
  67 + %ul.well-list= render Commit.decorate(@commits), project: @project
  68 +
  69 + %h4 Changes
  70 + - if @diffs.present?
  71 + = render "projects/commits/diffs", diffs: @diffs, project: @project
  72 + - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
  73 + .bs-callout.bs-callout-danger
  74 + %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
  75 + %p To preserve performance the line changes are not shown.
  76 +
  77 +
  78 +:javascript
  79 + $('.assign-to-me-link').on('click', function(e){
  80 + $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
  81 + e.preventDefault();
  82 + });
app/views/projects/merge_requests/_show.html.haml
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 = render "projects/merge_requests/show/mr_box" 4 = render "projects/merge_requests/show/mr_box"
5 = render "projects/merge_requests/show/state_widget" 5 = render "projects/merge_requests/show/state_widget"
6 = render "projects/merge_requests/show/commits" 6 = render "projects/merge_requests/show/commits"
  7 + = render "projects/merge_requests/show/participants"
7 8
8 - if @commits.present? 9 - if @commits.present?
9 %ul.nav.nav-tabs 10 %ul.nav.nav-tabs
app/views/projects/merge_requests/branch_from.js.haml
1 :plain 1 :plain
2 $(".mr_source_commit").html("#{commit_to_html(@commit, @source_project, false)}"); 2 $(".mr_source_commit").html("#{commit_to_html(@commit, @source_project, false)}");
3 - var mrTitle = $('#merge_request_title');  
4 -  
5 - if(mrTitle.val().length == 0) {  
6 - mrTitle.val("#{params[:ref].titleize.humanize}");  
7 - }  
app/views/projects/merge_requests/index.html.haml
@@ -8,7 +8,8 @@ @@ -8,7 +8,8 @@
8 %hr 8 %hr
9 .row 9 .row
10 .col-md-3 10 .col-md-3
11 - = render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project) 11 + = render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project),
  12 + labels: true, redirect: 'merge_requests'
12 .col-md-9 13 .col-md-9
13 .mr-filters.append-bottom-10 14 .mr-filters.append-bottom-10
14 .dropdown.inline 15 .dropdown.inline
app/views/projects/merge_requests/new.html.haml
1 -%h3.page-title New Merge Request  
2 -%hr  
3 -= render 'form' 1 +- if @commits.present?
  2 + = render 'new_submit'
  3 +- else
  4 + = render 'new_compare'
app/views/projects/merge_requests/show/_context.html.haml
1 = form_for [@project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update'} do |f| 1 = form_for [@project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update'} do |f|
2 - %strong.append-right-10  
3 - Assignee: 2 + .row
  3 + .col-md-6
  4 + %strong.append-right-10
  5 + Assignee:
4 6
5 - - if can?(current_user, :modify_merge_request, @merge_request)  
6 - = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @merge_request.assignee_id)  
7 - - elsif merge_request.assignee  
8 - = link_to_member(@project, @merge_request.assignee)  
9 - - else  
10 - None 7 + - if can?(current_user, :modify_merge_request, @merge_request)
  8 + = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control', selected: @merge_request.assignee_id)
  9 + - elsif merge_request.assignee
  10 + = link_to_member(@project, @merge_request.assignee)
  11 + - else
  12 + None
11 13
12 - .pull-right  
13 - %strong.append-right-10  
14 - Milestone:  
15 - - if can?(current_user, :modify_merge_request, @merge_request)  
16 - = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone (none):" }, {class: 'select2 select2-compact'})  
17 - = hidden_field_tag :merge_request_context  
18 - = f.submit class: 'btn'  
19 - - elsif merge_request.milestone  
20 - = link_to merge_request.milestone.title, project_milestone_path  
21 - - else  
22 - None 14 + .col-md-6.text-right
  15 + %strong.append-right-10
  16 + Milestone:
  17 + - if can?(current_user, :modify_merge_request, @merge_request)
  18 + = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact'})
  19 + = hidden_field_tag :merge_request_context
  20 + = f.submit class: 'btn'
  21 + - elsif merge_request.milestone
  22 + = link_to merge_request.milestone.title, project_milestone_path
  23 + - else
  24 + None
app/views/projects/merge_requests/show/_mr_accept.html.haml
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 - if @show_merge_controls 12 - if @show_merge_controls
13 .automerge_widget.can_be_merged.hide 13 .automerge_widget.can_be_merged.hide
14 .clearfix 14 .clearfix
15 - = form_for [:automerge, @project, @merge_request], remote: true, method: :get do |f| 15 + = form_for [:automerge, @project, @merge_request], remote: true, method: :post do |f|
16 %h4 16 %h4
17 You can accept this request automatically. 17 You can accept this request automatically.
18 %div 18 %div
@@ -21,7 +21,6 @@ @@ -21,7 +21,6 @@
21 = link_to "click here", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" 21 = link_to "click here", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
22 for instructions. 22 for instructions.
23 23
24 -  
25 .js-toggle-container 24 .js-toggle-container
26 %p 25 %p
27 If you want to modify merge commit message - 26 If you want to modify merge commit message -
@@ -31,7 +30,8 @@ @@ -31,7 +30,8 @@
31 .form-group 30 .form-group
32 = label_tag :merge_commit_message, "Commit message", class: 'control-label' 31 = label_tag :merge_commit_message, "Commit message", class: 'control-label'
33 .col-sm-10 32 .col-sm-10
34 - = text_area_tag :merge_commit_message, @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true 33 + = render 'shared/commit_message_container', {textarea: text_area_tag(:merge_commit_message,
  34 + @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true)}
35 %p.hint 35 %p.hint
36 The recommended maximum line length is 52 characters for the first line and 72 characters for all following lines. 36 The recommended maximum line length is 52 characters for the first line and 72 characters for all following lines.
37 37
app/views/projects/merge_requests/show/_mr_box.html.haml
1 .issue-box{ class: issue_box_class(@merge_request) } 1 .issue-box{ class: issue_box_class(@merge_request) }
2 - .state  
3 - %span.state-label 2 + .state.clearfix
  3 + %span.state-label.col-sm-2.col-xs-12
4 - if @merge_request.merged? 4 - if @merge_request.merged?
5 Merged 5 Merged
6 - elsif @merge_request.closed? 6 - elsif @merge_request.closed?
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 - else 8 - else
9 Open 9 Open
10 10
11 - %span.creator 11 + %span.creator.col-sm-9.col-xs-12
12 Created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)} 12 Created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)}
13 13
14 %h4.title 14 %h4.title
app/views/projects/merge_requests/show/_mr_title.html.haml
1 %h3.page-title 1 %h3.page-title
2 = "Merge Request ##{@merge_request.iid}" 2 = "Merge Request ##{@merge_request.iid}"
3 3
4 - %span.pull-right 4 + %span.pull-right.issue-btn-group
5 - if can?(current_user, :modify_merge_request, @merge_request) 5 - if can?(current_user, :modify_merge_request, @merge_request)
6 - if @merge_request.open? 6 - if @merge_request.open?
7 .btn-group.pull-left 7 .btn-group.pull-left
@@ -39,4 +39,4 @@ @@ -39,4 +39,4 @@
39 - else 39 - else
40 %span= @merge_request.source_branch 40 %span= @merge_request.source_branch
41 &rarr; 41 &rarr;
42 - %spanh= @merge_request.target_branch 42 + %span= @merge_request.target_branch
app/views/projects/merge_requests/show/_participants.html.haml 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +.participants
  2 + %cite.cgray #{@merge_request.participants.count} participants
  3 + - @merge_request.participants.each do |participant|
  4 + = link_to_member(@project, participant, name: false, size: 24)
  5 +
  6 + .merge-request-show-labels.pull-right
  7 + - @merge_request.labels.each do |label|
  8 + %span{class: "label #{label_css_class(label.name)}"}
  9 + %i.icon-tag
  10 + = label.name
  11 + &nbsp;
app/views/projects/merge_requests/show/_state_widget.html.haml
@@ -21,14 +21,6 @@ @@ -21,14 +21,6 @@
21 #{time_ago_with_tooltip(@merge_request.merge_event.created_at)} 21 #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}
22 = render "projects/merge_requests/show/remove_source_branch" 22 = render "projects/merge_requests/show/remove_source_branch"
23 23
24 - - if !@closes_issues.empty? && @merge_request.open?  
25 - .alert.alert-info.alert-info  
26 - %span  
27 - %i.icon-ok  
28 - Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'}  
29 - = succeed '.' do  
30 - != gfm(@closes_issues.map { |i| "##{i.iid}" }.to_sentence)  
31 -  
32 - unless @commits.any? 24 - unless @commits.any?
33 %h4 Nothing to merge 25 %h4 Nothing to merge
34 %p 26 %p
@@ -38,3 +30,12 @@ @@ -38,3 +30,12 @@
38 %span.label-branch #{@merge_request.target_branch} 30 %span.label-branch #{@merge_request.target_branch}
39 %br 31 %br
40 Try to use different branches or push new code. 32 Try to use different branches or push new code.
  33 +
  34 + - if !@closes_issues.empty? && @merge_request.open?
  35 + .panel-footer
  36 + %span
  37 + %i.icon-ok
  38 + Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'}
  39 + = succeed '.' do
  40 + != gfm(@closes_issues.map { |i| "##{i.iid}" }.to_sentence)
  41 +
app/views/projects/milestones/show.html.haml
1 = render "projects/issues/head" 1 = render "projects/issues/head"
2 %h3.page-title 2 %h3.page-title
3 Milestone ##{@milestone.iid} 3 Milestone ##{@milestone.iid}
4 - %small  
5 - = @milestone.expires_at  
6 .pull-right 4 .pull-right
7 - if can?(current_user, :admin_milestone, @project) 5 - if can?(current_user, :admin_milestone, @project)
8 = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped" do 6 = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped" do
@@ -23,14 +21,16 @@ @@ -23,14 +21,16 @@
23 21
24 22
25 .issue-box{ class: issue_box_class(@milestone) } 23 .issue-box{ class: issue_box_class(@milestone) }
26 - .state  
27 - %span.state-label 24 + .state.clearfix
  25 + .state-label.col-sm-2.col-xs-12
28 - if @milestone.closed? 26 - if @milestone.closed?
29 Closed 27 Closed
30 - elsif @milestone.expired? 28 - elsif @milestone.expired?
31 Expired 29 Expired
32 - else 30 - else
33 Open 31 Open
  32 + %span.creator.col-sm-9.col-xs-12
  33 + = @milestone.expires_at
34 34
35 %h4.title 35 %h4.title
36 = gfm escape_once(@milestone.title) 36 = gfm escape_once(@milestone.title)
@@ -100,7 +100,7 @@ @@ -100,7 +100,7 @@
100 %ul.bordered-list 100 %ul.bordered-list
101 - @users.each do |user| 101 - @users.each do |user|
102 %li 102 %li
103 - = link_to user, title: user.name, class: "dark" do 103 + = link_to user, title: user.name, class: "darken" do
104 = image_tag avatar_icon(user.email, 32), class: "avatar s32" 104 = image_tag avatar_icon(user.email, 32), class: "avatar s32"
105 %strong= truncate(user.name, lenght: 40) 105 %strong= truncate(user.name, lenght: 40)
106 %br 106 %br
app/views/projects/new_tree/show.html.haml
@@ -24,7 +24,8 @@ @@ -24,7 +24,8 @@
24 = label_tag 'commit_message', class: "control-label" do 24 = label_tag 'commit_message', class: "control-label" do
25 Commit message 25 Commit message
26 .col-sm-10 26 .col-sm-10
27 - = text_area_tag 'commit_message', params[:commit_message], placeholder: "Added new file", required: true, rows: 3, class: 'form-control' 27 + = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message',
  28 + params[:commit_message], placeholder: "Added new file", required: true, rows: 3, class: 'form-control')}
28 29
29 .file-holder 30 .file-holder
30 .file-title 31 .file-title
app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
1 - note1 = notes1.first # example note 1 - note1 = notes1.first # example note
2 - note2 = notes2.first # example note 2 - note2 = notes2.first # example note
  3 +-# Check if line want not changed since comment was left
  4 +/- if !defined?(line) || line == note.diff_line
3 %tr.notes_holder.js-toggle-content 5 %tr.notes_holder.js-toggle-content
4 - -# Check if line want not changed since comment was left  
5 - /- if !defined?(line1) || line1 == note1.diff_line  
6 - if note1 6 - if note1
  7 + %td.notes_line
  8 + %span.btn.disabled
  9 + %i.icon-comment
  10 + = notes1.count
7 %td.notes_content 11 %td.notes_content
8 %ul.notes{ rel: note1.discussion_id } 12 %ul.notes{ rel: note1.discussion_id }
9 = render notes1 13 = render notes1
  14 +
10 = render "projects/notes/discussion_reply_button", note: note1 15 = render "projects/notes/discussion_reply_button", note: note1
11 - %td.notes_line2  
12 - %span.btn.disabled.parallel-comment  
13 - %i.icon-comment  
14 - = notes1.count  
15 - else 16 - else
16 %td= "" 17 %td= ""
17 %td= "" 18 %td= ""
18 19
19 - %td= ""  
20 -  
21 - -# Check if line want not changed since comment was left  
22 - /- if !defined?(line2) || line2 == note2.diff_line  
23 - if note2 20 - if note2
24 %td.notes_line 21 %td.notes_line
25 - %span.btn.disabled.parallel-comment 22 + %span.btn.disabled
26 %i.icon-comment 23 %i.icon-comment
27 = notes2.count 24 = notes2.count
28 %td.notes_content 25 %td.notes_content
29 %ul.notes{ rel: note2.discussion_id } 26 %ul.notes{ rel: note2.discussion_id }
30 = render notes2 27 = render notes2
  28 +
31 = render "projects/notes/discussion_reply_button", note: note2 29 = render "projects/notes/discussion_reply_button", note: note2
32 - else 30 - else
33 %td= "" 31 %td= ""
34 %td= "" 32 %td= ""
  33 +
app/views/projects/notes/_note.html.haml
@@ -54,8 +54,8 @@ @@ -54,8 +54,8 @@
54 - if note.attachment.url 54 - if note.attachment.url
55 .note-attachment 55 .note-attachment
56 - if note.attachment.image? 56 - if note.attachment.image?
57 - = link_to note.attachment.url, target: '_blank' do  
58 - = image_tag note.attachment.url, class: 'note-image-attach' 57 + = link_to note.attachment.secure_url, target: '_blank' do
  58 + = image_tag note.attachment.secure_url, class: 'note-image-attach'
59 .attachment.pull-right 59 .attachment.pull-right
60 = link_to note.attachment.secure_url, target: "_blank" do 60 = link_to note.attachment.secure_url, target: "_blank" do
61 %i.icon-paper-clip 61 %i.icon-paper-clip
app/views/projects/show.html.haml
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 = render 'shared/event_filter' 6 = render 'shared/event_filter'
7 .content_list 7 .content_list
8 = spinner 8 = spinner
9 - .col-md-3.project-side.hidden-sm 9 + .col-md-3.project-side.hidden-sm.hidden-xs
10 .clearfix 10 .clearfix
11 - if @project.archived? 11 - if @project.archived?
12 .alert.alert-warning 12 .alert.alert-warning
app/views/projects/wikis/_form.html.haml
1 = form_for [@project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal' } do |f| 1 = form_for [@project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal' } do |f|
2 -if @page.errors.any? 2 -if @page.errors.any?
3 #error_explanation 3 #error_explanation
4 - %h2= "#{pluralize(@page.errors.count, "error")} prohibited this wiki from being saved:"  
5 - %ul 4 + .alert.alert-danger
6 - @page.errors.full_messages.each do |msg| 5 - @page.errors.full_messages.each do |msg|
7 - %li= msg 6 + %p= msg
8 7
9 = f.hidden_field :title, value: @page.title 8 = f.hidden_field :title, value: @page.title
10 .form-group 9 .form-group
app/views/projects/wikis/_new.html.haml
@@ -9,6 +9,6 @@ @@ -9,6 +9,6 @@
9 %span Page slug 9 %span Page slug
10 = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project) 10 = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project)
11 %p.hint 11 %p.hint
12 - Please don't use spaces and slashes 12 + Please don't use spaces.
13 .modal-footer 13 .modal-footer
14 = link_to 'Build', '#', class: 'build-new-wiki btn btn-create' 14 = link_to 'Build', '#', class: 'build-new-wiki btn btn-create'
app/views/shared/_commit_message_container.html.haml 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +.commit-message-container
  2 + .max-width-marker
  3 + -# When the `ch` CSS length unit becomes widely supported `http://www.quirksmode.org/css/units-values` remove this workaround.
  4 + = 'a' * 72
  5 + = textarea
app/views/shared/_project_filter.html.haml
@@ -44,7 +44,7 @@ @@ -44,7 +44,7 @@
44 .light-well 44 .light-well
45 Add first label to your issues 45 Add first label to your issues
46 %br 46 %br
47 - or #{link_to 'generate', generate_project_labels_path(@project), method: :post} default set of labels 47 + or #{link_to 'generate', generate_project_labels_path(@project, redirect: redirect), method: :post} default set of labels
48 48
49 %fieldset 49 %fieldset
50 - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any? 50 - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any?
bin/pkgr_before_precompile.sh 0 → 100755
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +#!/bin/sh
  2 +
  3 +set -e
  4 +
  5 +for file in config/*.yml.example; do
  6 + cp ${file} config/$(basename ${file} .example)
  7 +done
  8 +
  9 +# Allow to override the Gitlab URL from an environment variable, as this will avoid having to change the configuration file for simple deployments.
  10 +config=$(echo '<% gitlab_url = URI(ENV["GITLAB_URL"] || "http://localhost:80") %>' | cat - config/gitlab.yml)
  11 +echo "$config" > config/gitlab.yml
  12 +sed -i "s/host: localhost/host: <%= gitlab_url.host %>/" config/gitlab.yml
  13 +sed -i "s/port: 80/port: <%= gitlab_url.port %>/" config/gitlab.yml
  14 +sed -i "s/https: false/https: <%= gitlab_url.scheme == 'https' %>/" config/gitlab.yml
  15 +
  16 +# No need for config file. Will be taken care of by REDIS_URL env variable
  17 +rm config/resque.yml
  18 +
  19 +# Set default unicorn.rb file
  20 +echo "" > config/unicorn.rb
  21 +
  22 +# Required for assets precompilation
  23 +sudo service postgresql start
config/application.rb
@@ -66,13 +66,16 @@ module Gitlab @@ -66,13 +66,16 @@ module Gitlab
66 # Version of your assets, change this if you want to expire all your assets 66 # Version of your assets, change this if you want to expire all your assets
67 config.assets.version = '1.0' 67 config.assets.version = '1.0'
68 68
  69 + # Relative url support
69 # Uncomment and customize the last line to run in a non-root path 70 # Uncomment and customize the last line to run in a non-root path
70 # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this. 71 # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.
71 - # Note that four settings need to be changed for this to work. 72 + # Note that following settings need to be changed for this to work.
72 # 1) In your application.rb file: config.relative_url_root = "/gitlab" 73 # 1) In your application.rb file: config.relative_url_root = "/gitlab"
73 # 2) In your gitlab.yml file: relative_url_root: /gitlab 74 # 2) In your gitlab.yml file: relative_url_root: /gitlab
74 # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" 75 # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
75 # 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab" 76 # 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab"
  77 + # 5) In lib/support/nginx/gitlab : do not use asset gzipping, remove block starting with "location ~ ^/(assets)/"
  78 + #
76 # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production 79 # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
77 # 80 #
78 # config.relative_url_root = "/gitlab" 81 # config.relative_url_root = "/gitlab"
config/gitlab.yml.example
@@ -24,15 +24,8 @@ production: &amp;base @@ -24,15 +24,8 @@ production: &amp;base
24 # Otherwise, ssh host will be set to the `host:` value above 24 # Otherwise, ssh host will be set to the `host:` value above
25 # ssh_host: ssh.host_example.com 25 # ssh_host: ssh.host_example.com
26 26
27 - # Uncomment and customize the last line to run in a non-root path  
28 - # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.  
29 - # Note that four settings need to be changed for this to work.  
30 - # 1) In your application.rb file: config.relative_url_root = "/gitlab"  
31 - # 2) In your gitlab.yml file: relative_url_root: /gitlab  
32 - # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"  
33 - # 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab"  
34 - # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production  
35 - # 27 + # WARNING: See config/application.rb under "Relative url support" for the list of
  28 + # other files that need to be changed for relative url support
36 # relative_url_root: /gitlab 29 # relative_url_root: /gitlab
37 30
38 # Uncomment and customize if you can't use the default user to run GitLab (default: 'git') 31 # Uncomment and customize if you can't use the default user to run GitLab (default: 'git')
@@ -40,10 +33,10 @@ production: &amp;base @@ -40,10 +33,10 @@ production: &amp;base
40 33
41 ## Email settings 34 ## Email settings
42 # Email address used in the "From" field in mails sent by GitLab 35 # Email address used in the "From" field in mails sent by GitLab
43 - email_from: gitlab@localhost 36 + email_from: example@example.com
44 37
45 # Email address of your support contact (default: same as email_from) 38 # Email address of your support contact (default: same as email_from)
46 - support_email: support@localhost 39 + support_email: support@example.com
47 40
48 ## User settings 41 ## User settings
49 default_projects_limit: 10 42 default_projects_limit: 10
config/routes.rb
@@ -206,7 +206,7 @@ Gitlab::Application.routes.draw do @@ -206,7 +206,7 @@ Gitlab::Application.routes.draw do
206 end 206 end
207 end 207 end
208 208
209 - resources :wikis, only: [:show, :edit, :destroy, :create], constraints: {id: /[a-zA-Z.0-9_\-]+/} do 209 + resources :wikis, only: [:show, :edit, :destroy, :create], constraints: {id: /[a-zA-Z.0-9_\-\/]+/} do
210 collection do 210 collection do
211 get :pages 211 get :pages
212 put ':id' => 'wikis#update' 212 put ':id' => 'wikis#update'
@@ -273,7 +273,7 @@ Gitlab::Application.routes.draw do @@ -273,7 +273,7 @@ Gitlab::Application.routes.draw do
273 resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do 273 resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do
274 member do 274 member do
275 get :diffs 275 get :diffs
276 - get :automerge 276 + post :automerge
277 get :automerge_check 277 get :automerge_check
278 get :ci_status 278 get :ci_status
279 end 279 end
config/unicorn.rb.example
@@ -8,14 +8,8 @@ @@ -8,14 +8,8 @@
8 # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete 8 # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
9 # documentation. 9 # documentation.
10 10
11 -# Uncomment and customize the last line to run in a non-root path  
12 -# WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this.  
13 -# Note that four settings need to be changed for this to work.  
14 -# 1) In your application.rb file: config.relative_url_root = "/gitlab"  
15 -# 2) In your gitlab.yml file: relative_url_root: /gitlab  
16 -# 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"  
17 -# 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab"  
18 -# To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production 11 +# WARNING: See config/application.rb under "Relative url support" for the list of
  12 +# other files that need to be changed for relative url support
19 # 13 #
20 # ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" 14 # ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
21 15
db/fixtures/development/04_project.rb
@@ -40,7 +40,8 @@ Gitlab::Seeder.quiet do @@ -40,7 +40,8 @@ Gitlab::Seeder.quiet do
40 import_url: url, 40 import_url: url,
41 namespace_id: group.id, 41 namespace_id: group.id,
42 name: project_path.titleize, 42 name: project_path.titleize,
43 - description: Faker::Lorem.sentence 43 + description: Faker::Lorem.sentence,
  44 + visibility_level: Gitlab::VisibilityLevel.values.sample
44 } 45 }
45 46
46 project = Projects::CreateService.new(User.first, params).execute 47 project = Projects::CreateService.new(User.first, params).execute
db/fixtures/development/10_merge_requests.rb
1 Gitlab::Seeder.quiet do 1 Gitlab::Seeder.quiet do
2 - (1..100).each do |i|  
3 - # Random Project  
4 - project = Project.all.sample  
5 -  
6 - # Random user  
7 - user = project.team.users.sample  
8 -  
9 - next unless user  
10 -  
11 - next if project.empty_repo?  
12 -  
13 - branches = project.repository.branch_names.sample(2)  
14 -  
15 - next if branches.uniq.size < 2  
16 -  
17 - user_id = user.id  
18 -  
19 - Gitlab::Seeder.by_user(user) do  
20 - MergeRequest.seed(:id, [{  
21 - id: i,  
22 - source_branch: branches.first,  
23 - target_branch: branches.last,  
24 - source_project_id: project.id,  
25 - target_project_id: project.id,  
26 - author_id: user_id,  
27 - assignee_id: user_id,  
28 - milestone: project.milestones.sample,  
29 - title: Faker::Lorem.sentence(6)  
30 - }]) 2 + Project.all.reject(&:empty_repo?).each do |project|
  3 + branches = project.repository.branch_names
  4 +
  5 + branches.each do |branch_name|
  6 + break if branches.size < 2
  7 + source_branch = branches.pop
  8 + target_branch = branches.pop
  9 +
  10 + # Random user
  11 + user = project.team.users.sample
  12 + next unless user
  13 +
  14 + params = {
  15 + source_branch: source_branch,
  16 + target_branch: target_branch,
  17 + title: Faker::Lorem.sentence(6),
  18 + description: Faker::Lorem.sentences(3).join(" ")
  19 + }
  20 +
  21 + merge_request = MergeRequests::CreateService.new(project, user, params).execute
  22 +
  23 + if merge_request.valid?
  24 + merge_request.assignee = user
  25 + merge_request.milestone = project.milestones.sample
  26 + merge_request.save
  27 + print '.'
  28 + else
  29 + print 'F'
  30 + end
31 end 31 end
32 - print('.')  
33 end 32 end
34 end 33 end
35 -  
36 -MergeRequest.all.map do |mr|  
37 - mr.set_iid  
38 - mr.save  
39 -end  
40 -  
41 -puts 'Load diffs for Merge Requests (it will take some time)...'  
42 -MergeRequest.all.each do |mr|  
43 - mr.reload_code  
44 - print '.'  
45 -end  
doc/api/README.md
@@ -21,10 +21,12 @@ @@ -21,10 +21,12 @@
21 ## Clients 21 ## Clients
22 22
23 + [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP 23 + [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP
  24 ++ [Laravel API Wrapper for GitLab CE](https://github.com/adamgoose/gitlab) - PHP / [Laravel](http://laravel.com)
24 + [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby 25 + [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby
25 + [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python 26 + [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python
26 + [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java 27 + [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java
27 + [node-gitlab](https://github.com/moul/node-gitlab) - Node.js 28 + [node-gitlab](https://github.com/moul/node-gitlab) - Node.js
  29 ++ [NGitLab](https://github.com/Scooletz/NGitLab) - .NET
28 30
29 ## Introduction 31 ## Introduction
30 32
doc/api/deploy_key_multiple_projects.md 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +# Adding deploy keys to multiple projects
  2 +
  3 +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.
  4 +
  5 +First, find the ID of the projects you're interested in, by either listing all projects:
  6 +
  7 +```
  8 +curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects
  9 +```
  10 +
  11 +Or finding the id of a group and then listing all projects in that group:
  12 +
  13 +```
  14 +curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups
  15 +
  16 +# For group 1234:
  17 +curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups/1234
  18 +```
  19 +
  20 +With those IDs, add the same deploy key to all:
  21 +```
  22 +for project_id in 321 456 987; do
  23 + curl -X POST --data '{"title": "my key", "key": "ssh-rsa AAAA..."}' --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects/${project_id}/keys
  24 +done
  25 +```
doc/api/merge_requests.md
@@ -189,6 +189,54 @@ Parameters: @@ -189,6 +189,54 @@ Parameters:
189 ``` 189 ```
190 190
191 191
  192 +## Accept MR
  193 +
  194 +Merge changes submitted with MR usign this API.
  195 +If merge success you get 200 OK.
  196 +If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged'
  197 +If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed'
  198 +If you dont have permissions to accept this merge request - you get 401
  199 +
  200 +```
  201 +PUT /projects/:id/merge_request/:merge_request_id/merge
  202 +```
  203 +
  204 +Parameters:
  205 +
  206 ++ `id` (required) - The ID of a project
  207 ++ `merge_request_id` (required) - ID of MR
  208 ++ `merge_commit_message` (optional) - Custom merge commit message
  209 +
  210 +```json
  211 +{
  212 + "id": 1,
  213 + "target_branch": "master",
  214 + "source_branch": "test1",
  215 + "project_id": 3,
  216 + "title": "test1",
  217 + "state": "merged",
  218 + "upvotes": 0,
  219 + "downvotes": 0,
  220 + "author": {
  221 + "id": 1,
  222 + "username": "admin",
  223 + "email": "admin@local.host",
  224 + "name": "Administrator",
  225 + "state": "active",
  226 + "created_at": "2012-04-29T08:46:00Z"
  227 + },
  228 + "assignee": {
  229 + "id": 1,
  230 + "username": "admin",
  231 + "email": "admin@local.host",
  232 + "name": "Administrator",
  233 + "state": "active",
  234 + "created_at": "2012-04-29T08:46:00Z"
  235 + }
  236 +}
  237 +```
  238 +
  239 +
192 ## Post comment to MR 240 ## Post comment to MR
193 241
194 Adds a comment to a merge request. 242 Adds a comment to a merge request.
doc/api/projects.md
@@ -43,7 +43,8 @@ GET /projects @@ -43,7 +43,8 @@ GET /projects
43 "owner_id": 1, 43 "owner_id": 1,
44 "path": "diaspora", 44 "path": "diaspora",
45 "updated_at": "2013-09-30T13: 46: 02Z" 45 "updated_at": "2013-09-30T13: 46: 02Z"
46 - } 46 + },
  47 + "archived": false
47 }, 48 },
48 { 49 {
49 "id": 6, 50 "id": 6,
@@ -78,7 +79,8 @@ GET /projects @@ -78,7 +79,8 @@ GET /projects
78 "owner_id": 1, 79 "owner_id": 1,
79 "path": "brightbox", 80 "path": "brightbox",
80 "updated_at": "2013-09-30T13:46:02Z" 81 "updated_at": "2013-09-30T13:46:02Z"
81 - } 82 + },
  83 + "archived": false
82 } 84 }
83 ] 85 ]
84 ``` 86 ```
@@ -157,7 +159,8 @@ Parameters: @@ -157,7 +159,8 @@ Parameters:
157 "access_level": 50, 159 "access_level": 50,
158 "notification_level": 3 160 "notification_level": 3
159 } 161 }
160 - } 162 + },
  163 + "archived": false
161 } 164 }
162 ``` 165 ```
163 166
doc/install/installation.md
1 # Select Version to Install 1 # Select Version to Install
2 -Make sure you view this installation guide from the branch (version) of GitLab you would like to install. In most cases 2 +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
3 this should be the highest numbered stable branch (example shown below). 3 this should be the highest numbered stable branch (example shown below).
4 4
5 ![capture](http://i.imgur.com/d2AlIVj.png) 5 ![capture](http://i.imgur.com/d2AlIVj.png)
6 6
7 -If this is unclear check the [GitLab Blog](https://www.gitlab.com/blog/) for installation guide links by version. 7 +If the highest number stable branch is unclear please check the [GitLab Blog](https://www.gitlab.com/blog/) for installation guide links by version.
8 8
9 # Important notes 9 # Important notes
10 10
@@ -86,7 +86,7 @@ Is the system packaged Git too old? Remove it and compile from source. @@ -86,7 +86,7 @@ Is the system packaged Git too old? Remove it and compile from source.
86 mail server. By default, Debian is shipped with exim4 whereas Ubuntu 86 mail server. By default, Debian is shipped with exim4 whereas Ubuntu
87 does not ship with one. The recommended mail server is postfix and you can install it with: 87 does not ship with one. The recommended mail server is postfix and you can install it with:
88 88
89 - sudo apt-get install -y postfix 89 + sudo apt-get install -y postfix
90 90
91 Then select 'Internet Site' and press enter to confirm the hostname. 91 Then select 'Internet Site' and press enter to confirm the hostname.
92 92
@@ -101,8 +101,8 @@ Remove the old Ruby 1.8 if present @@ -101,8 +101,8 @@ Remove the old Ruby 1.8 if present
101 Download Ruby and compile it: 101 Download Ruby and compile it:
102 102
103 mkdir /tmp/ruby && cd /tmp/ruby 103 mkdir /tmp/ruby && cd /tmp/ruby
104 - curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p353.tar.gz | tar xz  
105 - cd ruby-2.0.0-p353 104 + curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p481.tar.gz | tar xz
  105 + cd ruby-2.0.0-p481
106 ./configure --disable-install-rdoc 106 ./configure --disable-install-rdoc
107 make 107 make
108 sudo make install 108 sudo make install
@@ -121,6 +121,7 @@ Create a `git` user for Gitlab: @@ -121,6 +121,7 @@ Create a `git` user for Gitlab:
121 # 4. Database 121 # 4. Database
122 122
123 We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](database_mysql.md). 123 We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](database_mysql.md).
  124 +NOTE: because we need to make use of extensions you need at least pgsql 9.1.
124 125
125 # Install the database packages 126 # Install the database packages
126 sudo apt-get install -y postgresql-9.1 postgresql-client libpq-dev 127 sudo apt-get install -y postgresql-9.1 postgresql-client libpq-dev
@@ -129,7 +130,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da @@ -129,7 +130,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
129 sudo -u postgres psql -d template1 130 sudo -u postgres psql -d template1
130 131
131 # Create a user for GitLab. 132 # Create a user for GitLab.
132 - template1=# CREATE USER git; 133 + template1=# CREATE USER git CREATEDB;
133 134
134 # Create the GitLab production database & grant all privileges on database 135 # Create the GitLab production database & grant all privileges on database
135 template1=# CREATE DATABASE gitlabhq_production OWNER git; 136 template1=# CREATE DATABASE gitlabhq_production OWNER git;
@@ -149,13 +150,13 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da @@ -149,13 +150,13 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
149 ## Clone the Source 150 ## Clone the Source
150 151
151 # Clone GitLab repository 152 # Clone GitLab repository
152 - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-8-stable gitlab 153 + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-9-stable gitlab
153 154
154 # Go to gitlab dir 155 # Go to gitlab dir
155 cd /home/git/gitlab 156 cd /home/git/gitlab
156 157
157 **Note:** 158 **Note:**
158 -You can change `6-8-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! 159 +You can change `6-9-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
159 160
160 ## Configure it 161 ## Configure it
161 162
@@ -200,7 +201,7 @@ You can change `6-8-stable` to `master` if you want the *bleeding edge* version, @@ -200,7 +201,7 @@ You can change `6-8-stable` to `master` if you want the *bleeding edge* version,
200 # Configure Git global settings for git user, useful when editing via web 201 # Configure Git global settings for git user, useful when editing via web
201 # Edit user.email according to what is set in gitlab.yml 202 # Edit user.email according to what is set in gitlab.yml
202 sudo -u git -H git config --global user.name "GitLab" 203 sudo -u git -H git config --global user.name "GitLab"
203 - sudo -u git -H git config --global user.email "gitlab@localhost" 204 + sudo -u git -H git config --global user.email "example@example.com"
204 sudo -u git -H git config --global core.autocrlf input 205 sudo -u git -H git config --global core.autocrlf input
205 206
206 **Important Note:** 207 **Important Note:**
@@ -243,15 +244,6 @@ that were [fixed](https://github.com/bundler/bundler/pull/2817) in 1.5.2. @@ -243,15 +244,6 @@ that were [fixed](https://github.com/bundler/bundler/pull/2817) in 1.5.2.
243 # Or if you use MySQL (note, the option says "without ... postgres") 244 # Or if you use MySQL (note, the option says "without ... postgres")
244 sudo -u git -H bundle install --deployment --without development test postgres aws 245 sudo -u git -H bundle install --deployment --without development test postgres aws
245 246
246 -  
247 -## Initialize Database and Activate Advanced Features  
248 -  
249 - sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production  
250 -  
251 - # Type 'yes' to create the database tables.  
252 -  
253 - # When done you see 'Administrator account created:'  
254 -  
255 ## Install GitLab shell 247 ## Install GitLab shell
256 248
257 GitLab Shell is an ssh access and repository management software developed specially for GitLab. 249 GitLab Shell is an ssh access and repository management software developed specially for GitLab.
@@ -260,11 +252,20 @@ GitLab Shell is an ssh access and repository management software developed speci @@ -260,11 +252,20 @@ GitLab Shell is an ssh access and repository management software developed speci
260 cd /home/git/gitlab 252 cd /home/git/gitlab
261 253
262 # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed): 254 # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
263 - sudo -u git -H bundle exec rake gitlab:shell:install[v1.9.3] REDIS_URL=redis://localhost:6379 255 + sudo -u git -H bundle exec rake gitlab:shell:install[v1.9.4] REDIS_URL=redis://localhost:6379 RAILS_ENV=production
264 256
265 # By default, the gitlab-shell config is generated from your main gitlab config. You can review (and modify) it as follows: 257 # By default, the gitlab-shell config is generated from your main gitlab config. You can review (and modify) it as follows:
266 sudo -u git -H editor /home/git/gitlab-shell/config.yml 258 sudo -u git -H editor /home/git/gitlab-shell/config.yml
267 259
  260 +
  261 +## Initialize Database and Activate Advanced Features
  262 +
  263 + sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production
  264 +
  265 + # Type 'yes' to create the database tables.
  266 +
  267 + # When done you see 'Administrator account created:'
  268 +
268 ## Install Init Script 269 ## Install Init Script
269 270
270 Download the init script (will be /etc/init.d/gitlab): 271 Download the init script (will be /etc/init.d/gitlab):
@@ -302,11 +303,6 @@ Check if GitLab and its environment are configured correctly: @@ -302,11 +303,6 @@ Check if GitLab and its environment are configured correctly:
302 sudo /etc/init.d/gitlab restart 303 sudo /etc/init.d/gitlab restart
303 304
304 305
305 -## Compile assets  
306 -  
307 - sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production  
308 -  
309 -  
310 # 6. Nginx 306 # 6. Nginx
311 307
312 **Note:** 308 **Note:**
@@ -413,22 +409,22 @@ GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already @@ -413,22 +409,22 @@ GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already
413 These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation. 409 These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation.
414 410
415 * Stop GitLab 411 * Stop GitLab
416 - `sudo service gitlab stop` 412 + `sudo service gitlab stop`
417 413
418 * 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) 414 * 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)
419 415
420 * Add the gem to your [Gemfile](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/Gemfile) 416 * Add the gem to your [Gemfile](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/Gemfile)
421 `gem "omniauth-your-auth-provider"` 417 `gem "omniauth-your-auth-provider"`
422 * If you're using MySQL, install the new Omniauth provider gem by running the following command: 418 * If you're using MySQL, install the new Omniauth provider gem by running the following command:
423 - `sudo -u git -H bundle install --without development test postgres --path vendor/bundle --no-deployment` 419 + `sudo -u git -H bundle install --without development test postgres --path vendor/bundle --no-deployment`
424 420
425 * If you're using PostgreSQL, install the new Omniauth provider gem by running the following command: 421 * If you're using PostgreSQL, install the new Omniauth provider gem by running the following command:
426 - `sudo -u git -H bundle install --without development test mysql --path vendor/bundle --no-deployment` 422 + `sudo -u git -H bundle install --without development test mysql --path vendor/bundle --no-deployment`
427 423
428 > These are the same commands you used in the [Install Gems section](#install-gems) with `--path vendor/bundle --no-deployment` instead of `--deployment`. 424 > These are the same commands you used in the [Install Gems section](#install-gems) with `--path vendor/bundle --no-deployment` instead of `--deployment`.
429 425
430 * Start GitLab 426 * Start GitLab
431 - `sudo service gitlab start` 427 + `sudo service gitlab start`
432 428
433 429
434 ### Examples 430 ### Examples
doc/install/requirements.md
@@ -53,7 +53,7 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) but GitLab @@ -53,7 +53,7 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) but GitLab
53 53
54 ## Memory 54 ## Memory
55 55
56 -- 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 56 +- 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
57 - 1GB supports up to 100 users (with individual repositories under 250MB, otherwise git memory usage necessitates using swap space) 57 - 1GB supports up to 100 users (with individual repositories under 250MB, otherwise git memory usage necessitates using swap space)
58 - **2GB** is the **recommended** memory size and supports up to 500 users 58 - **2GB** is the **recommended** memory size and supports up to 500 users
59 - 4GB supports up to 2,000 users 59 - 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 @@ -74,11 +74,14 @@ Apart from a local hard drive you can also mount a volume that supports the netw
74 74
75 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. 75 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.
76 76
  77 +## Database
  78 +
  79 +If you want to run the database separately, the **recommended** database size is **1 MB per user**
77 80
78 # Supported webbrowsers 81 # Supported webbrowsers
79 82
80 - Chrome (Latest stable version) 83 - Chrome (Latest stable version)
81 - Firefox (Latest released version) 84 - Firefox (Latest released version)
82 -- Safari 7+ (Know problem: required fields in html5 do not work) 85 +- Safari 7+ (known problem: required fields in html5 do not work)
83 - Opera (Latest released version) 86 - Opera (Latest released version)
84 - IE 10+ 87 - IE 10+
doc/integration/README.md
@@ -7,3 +7,5 @@ See the documentation below for details on how to configure these services. @@ -7,3 +7,5 @@ See the documentation below for details on how to configure these services.
7 + [LDAP](ldap.md) Set up sign in via LDAP 7 + [LDAP](ldap.md) Set up sign in via LDAP
8 + [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, and Google via OAuth. 8 + [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, and Google via OAuth.
9 + [Slack](slack.md) Integrate with the Slack chat service 9 + [Slack](slack.md) Integrate with the Slack chat service
  10 +
  11 +Jenkins support is [available in GitLab EE](http://doc.gitlab.com/ee/integration/jenkins.html).
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 @@ -2,8 +2,10 @@ GitLab has a great issue tracker but you can also use an external issue tracker
2 2
3 - the 'Issues' link on the GitLab project pages takes you to the appropriate JIRA issue index; 3 - the 'Issues' link on the GitLab project pages takes you to the appropriate JIRA issue index;
4 - clicking 'New issue' on the project dashboard creates a new JIRA issue; 4 - clicking 'New issue' on the project dashboard creates a new JIRA issue;
5 -- To reference JIRA issue PROJECT-1234 in comments, use syntax #PROJECT-1234. Commit messages get turned into HTML links to the corresponding JIRA issue. 5 +- To reference JIRA issue PROJECT-1234 in comments, use syntax PROJECT-1234. Commit messages get turned into HTML links to the corresponding JIRA issue.
6 6
7 ![jira screenshot](jira-integration-points.png) 7 ![jira screenshot](jira-integration-points.png)
8 8
9 -You can configure the integration in the gitlab.yml configuration file.  
10 \ No newline at end of file 9 \ No newline at end of file
  10 +You can configure the integration in the gitlab.yml configuration file.
  11 +
  12 +Support to add your commits to the Jira ticket automatically is [available in GitLab EE](http://doc.gitlab.com/ee/integration/jira.html).
doc/public_access/public_access.md
@@ -4,7 +4,7 @@ Internal projects will only be available to authenticated users. @@ -4,7 +4,7 @@ Internal projects will only be available to authenticated users.
4 4
5 #### Public projects 5 #### Public projects
6 Public projects can be cloned **without any** authentication. 6 Public projects can be cloned **without any** authentication.
7 -It will also be listen on the [public access directory](/public). 7 +It will also be listed on the [public access directory](/public).
8 **Any logged in user** will have [Guest](/help/permissions) permissions on the repository. 8 **Any logged in user** will have [Guest](/help/permissions) permissions on the repository.
9 9
10 #### Internal projects 10 #### Internal projects
doc/raketasks/maintenance.md
@@ -24,9 +24,9 @@ Version: 5.1.0.beta2 @@ -24,9 +24,9 @@ Version: 5.1.0.beta2
24 Revision: 4da8b37 24 Revision: 4da8b37
25 Directory: /home/git/gitlab 25 Directory: /home/git/gitlab
26 DB Adapter: mysql2 26 DB Adapter: mysql2
27 -URL: http://localhost  
28 -HTTP Clone URL: http://localhost/some-project.git  
29 -SSH Clone URL: git@localhost:some-project.git 27 +URL: http://example.com
  28 +HTTP Clone URL: http://example.com/some-project.git
  29 +SSH Clone URL: git@example.com:some-project.git
30 Using LDAP: no 30 Using LDAP: no
31 Using Omniauth: no 31 Using Omniauth: no
32 32
doc/release/monthly.md
1 -# Things to do when creating new monthly minor or major release  
2 -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). 1 +# Monthly Release
  2 +NOTE: This is a guide for GitLab developers.
3 3
4 -## Install guide up to date? 4 +# **15th - Code Freeze & Release Manager**
5 5
6 -* References correct GitLab branch `x-x-stable` and correct GitLab shell tag? 6 +### **1. Stop merging in code, except for important bugfixes**
7 7
8 -## Make upgrade guide 8 +### **2. Release Manager**
9 9
10 -### From x.x to x.x 10 +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.
11 11
12 -#### 0. Any major changes? Database updates? Web server change? File structure changes? 12 +# **18th - Releasing RC1**
  13 +
  14 +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.
  15 +
  16 +### **1. Create an issue for RC1 release**
  17 +
  18 +### **2. Update the installation guide**
  19 +
  20 +1. Check if it references the correct branch `x-x-stable` (doesn't exist yet, but that is okay)
  21 +2. Check the [GitLab Shell version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L782)
  22 +3. Check the [Git version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L794)
  23 +4. There might be other changes. Ask around.
  24 +
  25 +### **3. Create an update guide**
  26 +
  27 +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.
  28 +
  29 +#### 0. Any major changes?
  30 +List any major changes here, so the user is aware of them before starting to upgrade. For instance:
  31 +- Database updates
  32 +- Web server changes
  33 +- File structure changes
13 34
14 #### 1. Make backup 35 #### 1. Make backup
15 36
@@ -17,9 +38,9 @@ NOTE: This is a guide for GitLab developers. If you are trying to install GitLab @@ -17,9 +38,9 @@ NOTE: This is a guide for GitLab developers. If you are trying to install GitLab
17 38
18 #### 3. Do users need to update dependencies like `git`? 39 #### 3. Do users need to update dependencies like `git`?
19 40
20 -- Check the [GitLab Shell version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L782) 41 +- 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.
21 42
22 -- Check the [Git version](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/check.rake#L794) 43 +- 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.
23 44
24 #### 4. Get latest code 45 #### 4. Get latest code
25 46
@@ -29,7 +50,7 @@ NOTE: This is a guide for GitLab developers. If you are trying to install GitLab @@ -29,7 +50,7 @@ NOTE: This is a guide for GitLab developers. If you are trying to install GitLab
29 50
30 #### 7. Any config files updated since last release? 51 #### 7. Any config files updated since last release?
31 52
32 -Check if any of these changed since last release (~22nd of last month depending on when last release branch was created): 53 +Check if any of these changed since last release:
33 54
34 * https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/nginx/gitlab 55 * https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/nginx/gitlab
35 * https://gitlab.com/gitlab-org/gitlab-shell/commits/master/config.yml.example 56 * 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 @@ -40,13 +61,14 @@ Check if any of these changed since last release (~22nd of last month depending
40 61
41 #### 8. Need to update init script? 62 #### 8. Need to update init script?
42 63
43 -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 64 +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
44 65
45 #### 9. Start application 66 #### 9. Start application
46 67
47 #### 10. Check application status 68 #### 10. Check application status
48 69
49 -## Make sure the code quality indicatiors are good 70 +### **4. Code quality indicatiors**
  71 +Make sure the code quality indicators are green / good.
50 72
51 * [![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) 73 * [![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)
52 74
@@ -58,49 +80,88 @@ Check if changed since last release (~22nd of last month depending on when last @@ -58,49 +80,88 @@ Check if changed since last release (~22nd of last month depending on when last
58 80
59 * [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq) 81 * [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
60 82
61 -## Release Schedule  
62 -  
63 -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:  
64 -  
65 -* 1-7th: Official merge window (see contributing guide).  
66 -* 8-14th: Work on bugfixes, sponsored features and GitLab EE.  
67 -* 15th: Code freeze  
68 - - Stop merging into master, except essential bugfixes  
69 - - Select a Release Manager  
70 -* 18th: Release Candidate 1  
71 - - Set VERSION to x.x.0.rc1  
72 - - Create annotated tag x.x.0.rc1  
73 - - Push the changes to GitLab.com, dev.gitlab.com, GitHub  
74 - - Tweet about the release  
75 - - Create a new branch on cloud for rc1  
76 - - Deploy the new branch on Cloud after tests pass  
77 -* 20st: Optional release candidate 2 (x.x.0.rc2, only if rc1 had problems)  
78 -* 22nd: Release  
79 - - Create x-x-stable branch and push to the repositories  
80 - - QA  
81 - - Fix anything coming out of the QA  
82 - - Set VERSION to x.x.0  
83 - - Create annotated tag x.x.0  
84 - - Push VERSION + Tag to master, merge into x-x-stable  
85 - - Publish blog for new release  
86 - - Tweet to blog (see below)  
87 -* 22th: release GitLab EE  
88 -* 23nd: optional patch releases (x.x.1, x.x.2, etc., only if there are serious problems)  
89 -* 25th: release GitLab CI  
90 -  
91 -# Write a blog post 83 +### **5. Set VERSION**
  84 +
  85 +Set VERSION tot x.x.0.rc1
  86 +
  87 +
  88 +### **6. Tag**
  89 +
  90 +Create an annotated tag that points to the version change commit.
  91 +```
  92 +git tag -a vx.x.0.rc1 -m 'Version x.x.0.rc1'
  93 +```
  94 +
  95 +### **7. Tweet**
  96 +
  97 +Tweet about the RC release:
  98 +
  99 +> GitLab x.x.x.rc1 is out. This is a release candidate intended for testing only. Please let us know if you find regressions.
  100 +
  101 +### **8. Update Cloud**
  102 +
  103 +Merge the RC1 code into Cloud. Once the build is green, deploy in the morning.
  104 +
  105 +It is important to do this as soon as possible, so we can catch any errors before we release the full version.
92 106
93 -* Mention what GitLab is on the second line: GitLab is open source software to collaborate on code.  
94 -* Select and thank the the Most Valuable Person (MVP) of this release.  
95 -* 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.  
96 107
97 -# Tweet 108 +# **22nd - Release CE and EE**
98 109
99 -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. 110 +For GitLab EE, append -ee to the branches and tags.
100 111
101 -For a RC, make sure to explain what a RC is. 112 +`x-x-stable-ee`
  113 +
  114 +`v.x.x.0-ee`
  115 +
  116 +### **1. Create x-x-stable branch and push to the repositories**
  117 +
  118 +```
  119 +git checkout master
  120 +git pull
  121 +git checkout -b x-x-stable
  122 +git push <remote> x-x-stable
  123 +```
  124 +
  125 +### **2. Build the Omnibus packages**
  126 +[Follow this guide](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md)
  127 +
  128 +### **3. QA**
  129 +Use the omnibus packages to test using [this guide](https://dev.gitlab.org/gitlab/gitlab-ee/blob/master/doc/release/manual_testing.md)
  130 +
  131 +
  132 +### **4. Fix anything coming out of the QA**
  133 +
  134 +### **5. Set VERSION to x.x.0**
  135 +
  136 +### **6. Create annotated tag vx.x.0**
  137 +```
  138 +git tag -a vx.x.0 -m 'Version x.x.0'
  139 +```
  140 +
  141 +### **7. Push VERSION + Tag to master, merge into x-x-stable**
  142 +```
  143 +git push origin master
  144 +```
  145 +
  146 +Next, merge the VERSION into the x-x-stable branch.
  147 +
  148 +### **8. Push to remotes**
  149 +
  150 +For GitLab CE, push to dev, GitLab.com and GitHub.
  151 +
  152 +For GitLab EE, push to the subscribers repo.
  153 +
  154 +NOTE: You might not have the rights to push to master on dev. Ask Dmitriy.
  155 +
  156 +### **9. Publish blog for new release**
  157 +* Mention what GitLab is on the second line: GitLab is open source software to collaborate on code.
  158 +* Select and thank the the Most Valuable Person (MVP) of this release.
  159 +* 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.
102 160
103 -A patch release tweet should specify the fixes it brings and link to the corresponding blog post. 161 +### **10. Tweet to blog**
104 162
  163 +Send out a tweet to share the good news with the world. List the features in short and link to the blog post.
105 164
  165 +# **23rd - Optional Patch Release**
106 166
  167 +# **25th - Release GitLab CI**