Commit f5147780ff2290332d8979d399cfd55bf4a5fd37
Exists in
spb-stable
and in
2 other branches
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.
... | ... | @@ -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 | ... | ... |
CHANGELOG
... | ... | @@ -8,6 +8,16 @@ v 6.9.0 |
8 | 8 | - Fix syntax highlighting for code comments blocks |
9 | 9 | - Improve comments loading logic |
10 | 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 | 22 | v 6.8.0 |
13 | 23 | - Ability to at mention users that are participating in issue and merge req. discussion | ... | ... |
Gemfile
Gemfile.lock
... | ... | @@ -2,26 +2,26 @@ GEM |
2 | 2 | remote: https://rubygems.org/ |
3 | 3 | specs: |
4 | 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 | 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 | 10 | builder (~> 3.1.0) |
11 | 11 | erubis (~> 2.7.0) |
12 | 12 | rack (~> 1.5.2) |
13 | 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 | 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 | 19 | activerecord-deprecated_finders (~> 1.0.2) |
20 | - activesupport (= 4.0.3) | |
20 | + activesupport (= 4.0.5) | |
21 | 21 | arel (~> 4.0.0) |
22 | 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 | 25 | minitest (~> 4.2) |
26 | 26 | multi_json (~> 1.3) |
27 | 27 | thread_safe (~> 0.1) |
... | ... | @@ -162,7 +162,7 @@ GEM |
162 | 162 | multi_json |
163 | 163 | gitlab-grack (2.0.0.pre) |
164 | 164 | rack (~> 1.5.1) |
165 | - gitlab-grit (2.6.5) | |
165 | + gitlab-grit (2.6.7) | |
166 | 166 | charlock_holmes (~> 0.6) |
167 | 167 | diff-lcs (~> 1.1) |
168 | 168 | mime-types (~> 1.15) |
... | ... | @@ -279,7 +279,7 @@ GEM |
279 | 279 | mime-types (1.25.1) |
280 | 280 | mini_portile (0.5.3) |
281 | 281 | minitest (4.7.5) |
282 | - multi_json (1.9.3) | |
282 | + multi_json (1.10.0) | |
283 | 283 | multi_xml (0.5.5) |
284 | 284 | multipart-post (1.2.0) |
285 | 285 | mysql2 (0.3.11) |
... | ... | @@ -349,13 +349,13 @@ GEM |
349 | 349 | rack |
350 | 350 | rack-test (0.6.2) |
351 | 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 | 357 | bundler (>= 1.3.0, < 2.0) |
358 | - railties (= 4.0.3) | |
358 | + railties (= 4.0.5) | |
359 | 359 | sprockets-rails (~> 2.0.0) |
360 | 360 | rails-observers (0.1.2) |
361 | 361 | activemodel (~> 4.0) |
... | ... | @@ -368,9 +368,9 @@ GEM |
368 | 368 | i18n |
369 | 369 | require_all |
370 | 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 | 374 | rake (>= 0.8.7) |
375 | 375 | thor (>= 0.18.1, < 2.0) |
376 | 376 | raindrops (0.12.0) |
... | ... | @@ -427,11 +427,12 @@ GEM |
427 | 427 | safe_yaml (0.9.7) |
428 | 428 | sanitize (2.1.0) |
429 | 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 | 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 | 436 | sdoc (0.3.20) |
436 | 437 | json (>= 1.1.3) |
437 | 438 | rdoc (~> 3.10) |
... | ... | @@ -478,7 +479,7 @@ GEM |
478 | 479 | spring (>= 0.9.1) |
479 | 480 | spring-commands-spinach (1.0.0) |
480 | 481 | spring (>= 0.9.1) |
481 | - sprockets (2.10.1) | |
482 | + sprockets (2.11.0) | |
482 | 483 | hike (~> 1.2) |
483 | 484 | multi_json (~> 1.0) |
484 | 485 | rack (~> 1.0) |
... | ... | @@ -636,7 +637,7 @@ DEPENDENCIES |
636 | 637 | redis-rails |
637 | 638 | rspec-rails |
638 | 639 | sanitize (~> 2.0) |
639 | - sass-rails | |
640 | + sass-rails (~> 4.0.2) | |
640 | 641 | sdoc |
641 | 642 | seed-fu |
642 | 643 | select2-rails | ... | ... |
README.md
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | |
16 | 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 | 20 | ### Code status |
21 | 21 | |
... | ... | @@ -25,6 +25,8 @@ |
25 | 25 | |
26 | 26 | * [](https://coveralls.io/r/gitlabhq/gitlabhq) |
27 | 27 | |
28 | +* [](https://www.pullreview.com/gitlab.gitlab.com/gitlab-org/gitlab-ce/reviews/master) | |
29 | + | |
28 | 30 | ### Resources |
29 | 31 | |
30 | 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 | 35 | |
34 | 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 | 40 | ### Requirements |
39 | 41 | |
... | ... | @@ -51,7 +53,7 @@ |
51 | 53 | |
52 | 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 | 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 | 63 | |
62 | 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 | 68 | #### Unofficial installation methods |
65 | 69 | |
66 | 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. | ... | ... |
VERSION
app/assets/javascripts/notes.js.coffee
... | ... | @@ -53,6 +53,12 @@ class Notes |
53 | 53 | # fetch notes when tab becomes visible |
54 | 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 | 62 | cleanBinding: -> |
57 | 63 | $(document).off "ajax:success", ".js-main-target-form" |
58 | 64 | $(document).off "ajax:success", ".js-discussion-note-form" |
... | ... | @@ -67,6 +73,7 @@ class Notes |
67 | 73 | $(document).off "click", ".js-discussion-reply-button" |
68 | 74 | $(document).off "click", ".js-add-diff-note-button" |
69 | 75 | $(document).off "visibilitychange" |
76 | + $(document).off "keypress", @notes_forms | |
70 | 77 | |
71 | 78 | |
72 | 79 | initRefresh: -> | ... | ... |
app/assets/javascripts/project_users_select.js.coffee
1 | 1 | @projectUsersSelect = |
2 | 2 | init: -> |
3 | 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 | 6 | $(select).select2 |
7 | 7 | placeholder: $(select).data('placeholder') || "Search for a user" | ... | ... |
app/assets/stylesheets/generic/files.scss
... | ... | @@ -11,14 +11,11 @@ |
11 | 11 | } |
12 | 12 | |
13 | 13 | .file-title { |
14 | - background: #DDD; | |
14 | + background: #EEE; | |
15 | 15 | border-bottom: 1px solid #CCC; |
16 | 16 | text-shadow: 0 1px 1px #fff; |
17 | 17 | margin: 0; |
18 | - font-weight: normal; | |
19 | - font-weight: bold; | |
20 | 18 | text-align: left; |
21 | - color: $style_color; | |
22 | 19 | padding: 9px 10px; |
23 | 20 | |
24 | 21 | .options { |
... | ... | @@ -31,12 +28,15 @@ |
31 | 28 | } |
32 | 29 | |
33 | 30 | .file_name { |
34 | - color: $style_color; | |
31 | + font-weight: bold; | |
32 | + padding-left: 3px; | |
35 | 33 | font-size: 14px; |
36 | - text-shadow: 0 1px 1px #fff; | |
34 | + | |
37 | 35 | small { |
38 | - color: #999; | |
36 | + color: #888; | |
39 | 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 | 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 | 12 | margin:20px 0; |
13 | 13 | background: #FFF; |
14 | 14 | border: 1px solid #EEE; |
15 | + @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05)); | |
15 | 16 | |
16 | 17 | &.issue-box-closed { |
17 | - border-color: #DA4E49; | |
18 | + border-color: $border_danger; | |
18 | 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 | 23 | .state-label { |
23 | - background: #DA4E49; | |
24 | + background-color: $bg_danger; | |
24 | 25 | color: #FFF; |
25 | 26 | } |
26 | 27 | } |
27 | 28 | } |
28 | 29 | |
29 | 30 | &.issue-box-merged { |
30 | - border-color: #31708f; | |
31 | + border-color: $border_primary; | |
31 | 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 | 36 | .state-label { |
36 | - background: #31708f; | |
37 | + background-color: $bg_primary; | |
37 | 38 | color: #FFF; |
38 | 39 | } |
39 | 40 | } |
40 | 41 | } |
41 | 42 | |
42 | 43 | &.issue-box-open { |
43 | - border-color: #4A4; | |
44 | + border-color: $border_success; | |
44 | 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 | 49 | .state-label { |
49 | - background: #4A4; | |
50 | + background-color: $bg_success; | |
50 | 51 | color: #FFF; |
51 | 52 | } |
52 | 53 | } |
... | ... | @@ -70,7 +71,6 @@ |
70 | 71 | } |
71 | 72 | |
72 | 73 | .state { |
73 | - height: 34px; | |
74 | 74 | border-bottom: 1px solid #DDD; |
75 | 75 | line-height: 32px; |
76 | 76 | } |
... | ... | @@ -89,6 +89,18 @@ |
89 | 89 | border: none; |
90 | 90 | border-top: 1px solid #eee; |
91 | 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 | 106 | .description { |
... | ... | @@ -106,7 +118,11 @@ |
106 | 118 | padding: 1px 25px; |
107 | 119 | text-align: center; |
108 | 120 | text-shadow: none; |
109 | - margin-right: 20px; | |
110 | 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 | 8 | width: 270px; |
9 | 9 | |
10 | 10 | .ui-datepicker-header { |
11 | - background: #EEE; | |
11 | + background: #FFF; | |
12 | 12 | border-color: #DDD; |
13 | 13 | } |
14 | 14 | |
... | ... | @@ -19,20 +19,37 @@ |
19 | 19 | } |
20 | 20 | |
21 | 21 | &.ui-autocomplete { |
22 | - @include border-radius(0px); | |
23 | 22 | border-color: #DDD; |
24 | 23 | padding: 0; |
24 | + margin-top: 2px; | |
25 | + z-index: 1001; | |
25 | 26 | |
26 | 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
app/assets/stylesheets/main/mixins.scss
... | ... | @@ -41,31 +41,6 @@ |
41 | 41 | * Prefilled mixins |
42 | 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 | 45 | @mixin shade { |
71 | 46 | @include box-shadow(0 0 3px #ddd); |
... | ... | @@ -77,7 +52,6 @@ |
77 | 52 | |
78 | 53 | @mixin header-font { |
79 | 54 | color: $style_color; |
80 | - text-shadow: 0 1px 1px #FFF; | |
81 | 55 | font-size: 16px; |
82 | 56 | line-height: 44px; |
83 | 57 | font-weight: normal; | ... | ... |
app/assets/stylesheets/main/variables.scss
... | ... | @@ -8,6 +8,31 @@ $bg_style_color: #2299BB; |
8 | 8 | $list-group-active-bg: $bg_style_color; |
9 | 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 | 37 | * Commit Diff Colors |
13 | 38 | */ | ... | ... |
app/assets/stylesheets/sections/diff.scss
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | |
5 | 5 | .diff-header { |
6 | 6 | @extend .clearfix; |
7 | - background: #DDD; | |
7 | + background: #EEE; | |
8 | 8 | border-bottom: 1px solid #CCC; |
9 | 9 | padding: 5px 5px 5px 10px; |
10 | 10 | color: #555; |
... | ... | @@ -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 | 76 | .old_line, .new_line, .diff_line { |
86 | 77 | margin: 0px; |
87 | 78 | padding: 0px; |
88 | 79 | border: none; |
89 | - background: #EEE; | |
80 | + background: #F5F5F5; | |
90 | 81 | color: #666; |
91 | 82 | padding: 0px 5px; |
92 | 83 | border-right: 1px solid #ccc; |
... | ... | @@ -304,15 +295,9 @@ |
304 | 295 | } //.view.onion-skin |
305 | 296 | } |
306 | 297 | .view-modes{ |
307 | - | |
308 | 298 | padding: 10px; |
309 | 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 | 302 | ul, li{ |
318 | 303 | list-style: none; | ... | ... |
app/assets/stylesheets/sections/graph.scss
1 | 1 | .project-network { |
2 | - border: 1px solid #aaa; | |
3 | - padding: 1px; | |
2 | + border: 1px solid #CCC; | |
4 | 3 | |
5 | 4 | .tip { |
6 | 5 | color: #888; |
7 | 6 | font-size: 14px; |
8 | 7 | padding: 10px; |
9 | 8 | border-bottom: 1px solid #bbb; |
10 | - @include bg-gray-gradient; | |
9 | + background: #EEE; | |
11 | 10 | } |
12 | 11 | |
13 | 12 | .network-graph { |
14 | - background: #f1f1f1; | |
13 | + background: #FFF; | |
15 | 14 | height: 500px; |
16 | 15 | overflow-y: scroll; |
17 | 16 | overflow-x: hidden; | ... | ... |
app/assets/stylesheets/sections/header.scss
... | ... | @@ -14,7 +14,6 @@ header { |
14 | 14 | |
15 | 15 | .nav > li > a { |
16 | 16 | color: $style_color; |
17 | - text-shadow: 0 1px 0 #fff; | |
18 | 17 | font-size: 14px; |
19 | 18 | line-height: 32px; |
20 | 19 | padding: 6px 10px; |
... | ... | @@ -190,7 +189,6 @@ header { |
190 | 189 | |
191 | 190 | .nav > li > a { |
192 | 191 | color: #AAA; |
193 | - text-shadow: 0 1px 0 #444; | |
194 | 192 | |
195 | 193 | &:hover, &:focus, &:active { |
196 | 194 | background: none; |
... | ... | @@ -224,7 +222,6 @@ header { |
224 | 222 | background: image-url('logo-white.png') no-repeat center center; |
225 | 223 | background-size: 32px; |
226 | 224 | color: #fff; |
227 | - text-shadow: 0 1px 1px #444; | |
228 | 225 | } |
229 | 226 | } |
230 | 227 | } |
... | ... | @@ -236,7 +233,6 @@ header { |
236 | 233 | } |
237 | 234 | } |
238 | 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 | 45 | padding: 6px 10px; |
46 | 46 | border: 1px solid #ccc; |
47 | 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 | 50 | .issues_content { |
... | ... | @@ -143,3 +135,36 @@ form.edit-issue { |
143 | 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 | 31 | |
32 | 32 | .mr_source_commit, |
33 | 33 | .mr_target_commit { |
34 | - margin-top: 10px; | |
35 | 34 | .commit { |
36 | 35 | margin: 0; |
37 | 36 | padding: 2px 0; |
... | ... | @@ -74,6 +73,10 @@ |
74 | 73 | |
75 | 74 | .merge-request-info { |
76 | 75 | color: #999; |
76 | + | |
77 | + .merge-request-labels { | |
78 | + display: inline-block; | |
79 | + } | |
77 | 80 | } |
78 | 81 | } |
79 | 82 | } |
... | ... | @@ -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
app/assets/stylesheets/sections/profile.scss
app/assets/stylesheets/sections/tree.scss
app/assets/stylesheets/sections/votes.scss
app/assets/stylesheets/themes/ui_color.scss
... | ... | @@ -16,28 +16,28 @@ |
16 | 16 | @extend .header-dark; |
17 | 17 | &.navbar-gitlab { |
18 | 18 | .navbar-inner { |
19 | - background: #547; | |
20 | - border-bottom: 1px solid #435; | |
19 | + background: #548; | |
20 | + border-bottom: 1px solid #436; | |
21 | 21 | .app_logo, .navbar-toggle { |
22 | 22 | &:hover { |
23 | - background-color: #435; | |
23 | + background-color: #436; | |
24 | 24 | } |
25 | 25 | } |
26 | 26 | .separator { |
27 | - background: #435; | |
28 | - border-left: 1px solid #658; | |
27 | + background: #436; | |
28 | + border-left: 1px solid #659; | |
29 | 29 | } |
30 | 30 | .nav > li > a { |
31 | - color: #98B; | |
31 | + color: #98C; | |
32 | 32 | } |
33 | 33 | .search-input { |
34 | - border-color: #98B; | |
34 | + border-color: #98C; | |
35 | 35 | } |
36 | 36 | } |
37 | 37 | } |
38 | 38 | } |
39 | 39 | |
40 | 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 | 16 | @extend .header-dark; |
17 | 17 | &.navbar-gitlab { |
18 | 18 | .navbar-inner { |
19 | - background: #345; | |
20 | - border-bottom: 1px solid #234; | |
19 | + background: #00AC7E; | |
20 | + border-bottom: 1px solid #00AC7E; | |
21 | 21 | .app_logo, .navbar-toggle { |
22 | 22 | &:hover { |
23 | - background-color: #234; | |
23 | + background-color: #009C6E; | |
24 | 24 | } |
25 | 25 | } |
26 | 26 | .separator { |
27 | - background: #234; | |
28 | - border-left: 1px solid #456; | |
27 | + background: #009C6F; | |
28 | + border-left: 1px solid #10BC8E; | |
29 | 29 | } |
30 | 30 | .nav > li > a { |
31 | - color: #89A; | |
31 | + color: #ADC; | |
32 | 32 | } |
33 | 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 < ActionController::Base |
117 | 117 | return access_denied! unless can?(current_user, :push_code, project) |
118 | 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 | 125 | def access_denied! |
121 | 126 | render "errors/access_denied", layout: "errors", status: 404 |
122 | 127 | end | ... | ... |
app/controllers/groups_controller.rb
... | ... | @@ -68,7 +68,7 @@ class GroupsController < ApplicationController |
68 | 68 | @members = group.users_groups |
69 | 69 | |
70 | 70 | if params[:search].present? |
71 | - users = group.users.search(params[:search]) | |
71 | + users = group.users.search(params[:search]).to_a | |
72 | 72 | @members = @members.where(user_id: users) |
73 | 73 | end |
74 | 74 | ... | ... |
app/controllers/projects/labels_controller.rb
1 | 1 | class Projects::LabelsController < Projects::ApplicationController |
2 | 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 | 6 | respond_to :js, :html |
8 | 7 | |
... | ... | @@ -13,12 +12,18 @@ class Projects::LabelsController < Projects::ApplicationController |
13 | 12 | def generate |
14 | 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 | 20 | end |
18 | 21 | |
19 | 22 | protected |
20 | 23 | |
21 | 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 | 28 | end |
24 | 29 | end | ... | ... |
app/controllers/projects/merge_requests_controller.rb
... | ... | @@ -62,11 +62,27 @@ class Projects::MergeRequestsController < Projects::ApplicationController |
62 | 62 | @merge_request.source_project = @project unless @merge_request.source_project |
63 | 63 | @merge_request.target_project ||= (@project.forked_from_project || @project) |
64 | 64 | @target_branches = @merge_request.target_project.nil? ? [] : @merge_request.target_project.repository.branch_names |
65 | - | |
66 | 65 | @merge_request.target_branch ||= @merge_request.target_project.default_branch |
67 | - | |
68 | 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 | 86 | end |
71 | 87 | |
72 | 88 | def edit |
... | ... | @@ -80,7 +96,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController |
80 | 96 | @merge_request = MergeRequests::CreateService.new(project, current_user, params[:merge_request]).execute |
81 | 97 | |
82 | 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 | 100 | else |
85 | 101 | @source_project = @merge_request.source_project |
86 | 102 | @target_project = @merge_request.target_project | ... | ... |
app/controllers/projects/wikis_controller.rb
... | ... | @@ -12,9 +12,22 @@ class Projects::WikisController < Projects::ApplicationController |
12 | 12 | |
13 | 13 | def show |
14 | 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 | 18 | if @page |
17 | 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 | 31 | else |
19 | 32 | return render('empty') unless can?(current_user, :write_wiki, @project) |
20 | 33 | @page = WikiPage.new(@project_wiki) | ... | ... |
app/helpers/commits_helper.rb
... | ... | @@ -117,7 +117,7 @@ module CommitsHelper |
117 | 117 | added_lines[line_new] = { line_code: line_code, type: type, line: line } |
118 | 118 | end |
119 | 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 | 122 | offset1 = 0 |
123 | 123 | offset2 = 0 | ... | ... |
app/helpers/issues_helper.rb
... | ... | @@ -82,7 +82,7 @@ module IssuesHelper |
82 | 82 | end |
83 | 83 | |
84 | 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 | 86 | end |
87 | 87 | |
88 | 88 | def issue_box_class(item) | ... | ... |
app/helpers/selects_helper.rb
... | ... | @@ -14,7 +14,7 @@ module SelectsHelper |
14 | 14 | css_class << (opts[:class] || '') |
15 | 15 | value = opts[:selected] || '' |
16 | 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 | 19 | end |
20 | 20 | end | ... | ... |
app/mailers/emails/issues.rb
... | ... | @@ -4,6 +4,7 @@ module Emails |
4 | 4 | @issue = Issue.find(issue_id) |
5 | 5 | @project = @issue.project |
6 | 6 | @target_url = project_issue_url(@project, @issue) |
7 | + set_message_id("issue_#{issue_id}") | |
7 | 8 | mail(from: sender(@issue.author_id), |
8 | 9 | to: recipient(recipient_id), |
9 | 10 | subject: subject("#{@issue.title} (##{@issue.iid})")) |
... | ... | @@ -14,6 +15,7 @@ module Emails |
14 | 15 | @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id |
15 | 16 | @project = @issue.project |
16 | 17 | @target_url = project_issue_url(@project, @issue) |
18 | + set_reference("issue_#{issue_id}") | |
17 | 19 | mail(from: sender(updated_by_user_id), |
18 | 20 | to: recipient(recipient_id), |
19 | 21 | subject: subject("#{@issue.title} (##{@issue.iid})")) |
... | ... | @@ -24,6 +26,7 @@ module Emails |
24 | 26 | @project = @issue.project |
25 | 27 | @updated_by = User.find updated_by_user_id |
26 | 28 | @target_url = project_issue_url(@project, @issue) |
29 | + set_reference("issue_#{issue_id}") | |
27 | 30 | mail(from: sender(updated_by_user_id), |
28 | 31 | to: recipient(recipient_id), |
29 | 32 | subject: subject("#{@issue.title} (##{@issue.iid})")) |
... | ... | @@ -35,6 +38,7 @@ module Emails |
35 | 38 | @project = @issue.project |
36 | 39 | @updated_by = User.find updated_by_user_id |
37 | 40 | @target_url = project_issue_url(@project, @issue) |
41 | + set_reference("issue_#{issue_id}") | |
38 | 42 | mail(from: sender(updated_by_user_id), |
39 | 43 | to: recipient(recipient_id), |
40 | 44 | subject: subject("#{@issue.title} (##{@issue.iid})")) | ... | ... |
app/mailers/emails/merge_requests.rb
... | ... | @@ -4,9 +4,10 @@ module Emails |
4 | 4 | @merge_request = MergeRequest.find(merge_request_id) |
5 | 5 | @project = @merge_request.project |
6 | 6 | @target_url = project_merge_request_url(@project, @merge_request) |
7 | + set_message_id("merge_request_#{merge_request_id}") | |
7 | 8 | mail(from: sender(@merge_request.author_id), |
8 | 9 | to: recipient(recipient_id), |
9 | - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) | |
10 | + subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) | |
10 | 11 | end |
11 | 12 | |
12 | 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 | 15 | @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id |
15 | 16 | @project = @merge_request.project |
16 | 17 | @target_url = project_merge_request_url(@project, @merge_request) |
18 | + set_reference("merge_request_#{merge_request_id}") | |
17 | 19 | mail(from: sender(updated_by_user_id), |
18 | 20 | to: recipient(recipient_id), |
19 | - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) | |
21 | + subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) | |
20 | 22 | end |
21 | 23 | |
22 | 24 | def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) |
... | ... | @@ -24,18 +26,20 @@ module Emails |
24 | 26 | @updated_by = User.find updated_by_user_id |
25 | 27 | @project = @merge_request.project |
26 | 28 | @target_url = project_merge_request_url(@project, @merge_request) |
29 | + set_reference("merge_request_#{merge_request_id}") | |
27 | 30 | mail(from: sender(updated_by_user_id), |
28 | 31 | to: recipient(recipient_id), |
29 | - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) | |
32 | + subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) | |
30 | 33 | end |
31 | 34 | |
32 | 35 | def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) |
33 | 36 | @merge_request = MergeRequest.find(merge_request_id) |
34 | 37 | @project = @merge_request.project |
35 | 38 | @target_url = project_merge_request_url(@project, @merge_request) |
39 | + set_reference("merge_request_#{merge_request_id}") | |
36 | 40 | mail(from: sender(updated_by_user_id), |
37 | 41 | to: recipient(recipient_id), |
38 | - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) | |
42 | + subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) | |
39 | 43 | end |
40 | 44 | end |
41 | 45 | ... | ... |
app/mailers/emails/notes.rb
... | ... | @@ -15,6 +15,7 @@ module Emails |
15 | 15 | @issue = @note.noteable |
16 | 16 | @project = @note.project |
17 | 17 | @target_url = project_issue_url(@project, @issue, anchor: "note_#{@note.id}") |
18 | + set_reference("issue_#{@issue.id}") | |
18 | 19 | mail(from: sender(@note.author_id), |
19 | 20 | to: recipient(recipient_id), |
20 | 21 | subject: subject("#{@issue.title} (##{@issue.iid})")) |
... | ... | @@ -25,9 +26,10 @@ module Emails |
25 | 26 | @merge_request = @note.noteable |
26 | 27 | @project = @note.project |
27 | 28 | @target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{@note.id}") |
29 | + set_reference("merge_request_#{@merge_request.id}") | |
28 | 30 | mail(from: sender(@note.author_id), |
29 | 31 | to: recipient(recipient_id), |
30 | - subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) | |
32 | + subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) | |
31 | 33 | end |
32 | 34 | |
33 | 35 | def note_wall_email(recipient_id, note_id) | ... | ... |
app/mailers/notify.rb
... | ... | @@ -53,6 +53,22 @@ class Notify < ActionMailer::Base |
53 | 53 | end |
54 | 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 | 72 | # Formats arguments into a String suitable for use as an email subject |
57 | 73 | # |
58 | 74 | # extra - Extra Strings to be inserted into the subject | ... | ... |
app/models/merge_request.rb
... | ... | @@ -36,7 +36,9 @@ class MergeRequest < ActiveRecord::Base |
36 | 36 | |
37 | 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 | 43 | attr_accessor :should_remove_source_branch |
42 | 44 | |
... | ... | @@ -44,6 +46,9 @@ class MergeRequest < ActiveRecord::Base |
44 | 46 | # It allows us to close or modify broken merge requests |
45 | 47 | attr_accessor :allow_broken |
46 | 48 | |
49 | + ActsAsTaggableOn.strict_case_match = true | |
50 | + acts_as_taggable_on :labels | |
51 | + | |
47 | 52 | state_machine :state, initial: :opened do |
48 | 53 | event :close do |
49 | 54 | transition [:reopened, :opened] => :closed |
... | ... | @@ -253,6 +258,14 @@ class MergeRequest < ActiveRecord::Base |
253 | 258 | end |
254 | 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 | 269 | def source_branch_exists? |
257 | 270 | return false unless self.source_project |
258 | 271 | ... | ... |
app/models/merge_request_diff.rb
... | ... | @@ -86,7 +86,7 @@ class MergeRequestDiff < ActiveRecord::Base |
86 | 86 | # between target and source branches |
87 | 87 | def unmerged_commits |
88 | 88 | commits = if merge_request.for_fork? |
89 | - Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between | |
89 | + compare_action.commits | |
90 | 90 | else |
91 | 91 | repository.commits_between(target_branch, source_branch) |
92 | 92 | end |
... | ... | @@ -150,7 +150,7 @@ class MergeRequestDiff < ActiveRecord::Base |
150 | 150 | # between target and source branches |
151 | 151 | def unmerged_diffs |
152 | 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 | 154 | else |
155 | 155 | Gitlab::Git::Diff.between(repository, source_branch, target_branch) |
156 | 156 | end |
... | ... | @@ -165,4 +165,16 @@ class MergeRequestDiff < ActiveRecord::Base |
165 | 165 | def repository |
166 | 166 | merge_request.target_project.repository |
167 | 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 | 180 | end | ... | ... |
app/models/project.rb
... | ... | @@ -281,8 +281,11 @@ class Project < ActiveRecord::Base |
281 | 281 | self.id |
282 | 282 | end |
283 | 283 | |
284 | + # Tags are shared by issues and merge requests | |
284 | 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 | 289 | end |
287 | 290 | |
288 | 291 | def issue_exists?(issue_id) | ... | ... |
app/models/project_wiki.rb
... | ... | @@ -64,7 +64,8 @@ class ProjectWiki |
64 | 64 | # |
65 | 65 | # Returns an initialized WikiPage instance or nil |
66 | 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 | 69 | WikiPage.new(self, page, true) |
69 | 70 | else |
70 | 71 | nil |
... | ... | @@ -90,6 +91,12 @@ class ProjectWiki |
90 | 91 | wiki.delete_page(page, commit_details(:deleted, message, page.title)) |
91 | 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 | 100 | private |
94 | 101 | |
95 | 102 | def create_repo! | ... | ... |
app/models/wiki_page.rb
... | ... | @@ -175,14 +175,24 @@ class WikiPage |
175 | 175 | end |
176 | 176 | |
177 | 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 | 191 | set_attributes |
182 | 192 | |
183 | 193 | @persisted = true |
184 | 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 | 196 | @persisted = false |
187 | 197 | end |
188 | 198 | @persisted | ... | ... |
app/services/system_hooks_service.rb
... | ... | @@ -31,7 +31,8 @@ class SystemHooksService |
31 | 31 | path_with_namespace: model.path_with_namespace, |
32 | 32 | project_id: model.id, |
33 | 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 | 37 | when User |
37 | 38 | data.merge!({ |
... | ... | @@ -46,7 +47,8 @@ class SystemHooksService |
46 | 47 | project_id: model.project_id, |
47 | 48 | user_name: model.user.name, |
48 | 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 | 53 | end |
52 | 54 | end | ... | ... |
app/views/admin/users/_form.html.haml
... | ... | @@ -2,9 +2,9 @@ |
2 | 2 | = form_for [:admin, @user], html: { class: 'form-horizontal' } do |f| |
3 | 3 | -if @user.errors.any? |
4 | 4 | #error_explanation |
5 | - %ul.unstyled.alert.alert-danger | |
5 | + .alert.alert-danger | |
6 | 6 | - @user.errors.full_messages.each do |msg| |
7 | - %li= msg | |
7 | + %p= msg | |
8 | 8 | |
9 | 9 | %fieldset |
10 | 10 | %legend Account | ... | ... |
app/views/events/event/_note.html.haml
... | ... | @@ -14,8 +14,8 @@ |
14 | 14 | - note = event.target |
15 | 15 | - if note.attachment.url |
16 | 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 | 19 | - else |
20 | 20 | = link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do |
21 | 21 | %i.icon-paper-clip | ... | ... |
app/views/groups/show.html.haml
app/views/layouts/_head_panel.html.haml
... | ... | @@ -43,6 +43,6 @@ |
43 | 43 | %li |
44 | 44 | = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do |
45 | 45 | %i.icon-signout |
46 | - %li | |
46 | + %li.hidden-xs | |
47 | 47 | = link_to current_user, class: "profile-pic", id: 'profile-pic' do |
48 | 48 | = image_tag avatar_icon(current_user.email, 26), alt: 'User activity' | ... | ... |
app/views/notify/closed_merge_request_email.html.haml
app/views/notify/closed_merge_request_email.text.haml
app/views/notify/merged_merge_request_email.html.haml
app/views/notify/merged_merge_request_email.text.haml
app/views/projects/blob/_blob.html.haml
... | ... | @@ -15,18 +15,18 @@ |
15 | 15 | - else |
16 | 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 | 19 | - blob_commit = @repository.last_commit_for_path(@commit.id, @blob.path) |
20 | 20 | = render blob_commit, project: @project |
21 | 21 | |
22 | 22 | %div#tree-content-holder.tree-content-holder |
23 | 23 | .file-holder |
24 | - .file-title | |
24 | + .file-title.clearfix | |
25 | 25 | %i.icon-file |
26 | 26 | %span.file_name |
27 | 27 | = blob.name |
28 | 28 | %small= number_to_human_size blob.size |
29 | - %span.options= render "actions" | |
29 | + %span.options.hidden-xs= render "actions" | |
30 | 30 | - if blob.text? |
31 | 31 | = render "text", blob: blob |
32 | 32 | - elsif blob.image? | ... | ... |
app/views/projects/blob/_remove.html.haml
... | ... | @@ -14,7 +14,8 @@ |
14 | 14 | = label_tag 'commit_message', class: "control-label" do |
15 | 15 | Commit message |
16 | 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 | 19 | .form-group |
19 | 20 | .col-sm-2 |
20 | 21 | .col-sm-10 | ... | ... |
app/views/projects/commits/_parallel_view.html.haml
... | ... | @@ -2,54 +2,37 @@ |
2 | 2 | - old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file) |
3 | 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 | 23 | = label_tag 'commit_message', class: "control-label" do |
24 | 24 | Commit message |
25 | 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 | 28 | .form-actions |
28 | 29 | = hidden_field_tag 'last_commit', @last_commit |
29 | 30 | = hidden_field_tag 'content', '', id: "file-content" | ... | ... |
app/views/projects/issues/_issue_context.html.haml
1 | 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 | 1 | = render "head" |
2 | 2 | .row |
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 | 6 | .col-md-9.issues-holder |
6 | 7 | = render "issues" | ... | ... |
app/views/projects/issues/show.html.haml
1 | 1 | %h3.page-title |
2 | 2 | Issue ##{@issue.iid} |
3 | 3 | |
4 | - %span.pull-right | |
4 | + %span.pull-right.issue-btn-group | |
5 | 5 | - if can?(current_user, :write_issue, @project) |
6 | 6 | = link_to new_project_issue_path(@project), class: "btn btn-grouped", title: "New Issue", id: "new_issue_link" do |
7 | 7 | %i.icon-plus |
... | ... | @@ -16,28 +16,29 @@ |
16 | 16 | %i.icon-edit |
17 | 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 | - ← 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 | + ← 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 | 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 | 36 | - if @issue.closed? |
36 | 37 | Closed |
37 | 38 | - else |
38 | 39 | Open |
39 | 40 | |
40 | - %span.creator | |
41 | + %span.creator.col-sm-9.col-xs-12 | |
41 | 42 | Created by #{link_to_member(@project, @issue.author)} #{time_ago_with_tooltip(@issue.created_at)} |
42 | 43 | |
43 | 44 | %h4.title | ... | ... |
app/views/projects/merge_requests/_form.html.haml
... | ... | @@ -14,33 +14,6 @@ |
14 | 14 | - @merge_request.errors.full_messages.each do |msg| |
15 | 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 | - | |
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 | - | |
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 | 17 | .merge-request-form-info |
45 | 18 | .form-group |
46 | 19 | = f.label :title, class: 'control-label' do |
... | ... | @@ -51,6 +24,32 @@ |
51 | 24 | .col-sm-10 |
52 | 25 | = f.text_area :description, class: "form-control js-gfm-input", rows: 14 |
53 | 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 | + | |
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 | 54 | .form-actions |
56 | 55 | - if @merge_request.new_record? |
... | ... | @@ -66,20 +65,36 @@ |
66 | 65 | |
67 | 66 | :javascript |
68 | 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 | 11 | - if merge_request.for_fork? |
12 | 12 | %span.light |
13 | 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 | 17 | .merge-request-info |
22 | 18 | - if merge_request.author |
23 | 19 | authored by #{link_to_member(merge_request.source_project, merge_request.author)} |
... | ... | @@ -35,3 +31,9 @@ |
35 | 31 | |
36 | 32 | .pull-right |
37 | 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 @@ |
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 | + | |
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 | + | |
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 | + | ... | ... |
... | ... | @@ -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 | + | |
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 | 4 | = render "projects/merge_requests/show/mr_box" |
5 | 5 | = render "projects/merge_requests/show/state_widget" |
6 | 6 | = render "projects/merge_requests/show/commits" |
7 | + = render "projects/merge_requests/show/participants" | |
7 | 8 | |
8 | 9 | - if @commits.present? |
9 | 10 | %ul.nav.nav-tabs | ... | ... |
app/views/projects/merge_requests/branch_from.js.haml
app/views/projects/merge_requests/index.html.haml
... | ... | @@ -8,7 +8,8 @@ |
8 | 8 | %hr |
9 | 9 | .row |
10 | 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 | 13 | .col-md-9 |
13 | 14 | .mr-filters.append-bottom-10 |
14 | 15 | .dropdown.inline | ... | ... |
app/views/projects/merge_requests/new.html.haml
app/views/projects/merge_requests/show/_context.html.haml
1 | 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 | 12 | - if @show_merge_controls |
13 | 13 | .automerge_widget.can_be_merged.hide |
14 | 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 | 16 | %h4 |
17 | 17 | You can accept this request automatically. |
18 | 18 | %div |
... | ... | @@ -21,7 +21,6 @@ |
21 | 21 | = link_to "click here", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" |
22 | 22 | for instructions. |
23 | 23 | |
24 | - | |
25 | 24 | .js-toggle-container |
26 | 25 | %p |
27 | 26 | If you want to modify merge commit message - |
... | ... | @@ -31,7 +30,8 @@ |
31 | 30 | .form-group |
32 | 31 | = label_tag :merge_commit_message, "Commit message", class: 'control-label' |
33 | 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 | 35 | %p.hint |
36 | 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 | 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 | 4 | - if @merge_request.merged? |
5 | 5 | Merged |
6 | 6 | - elsif @merge_request.closed? |
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | - else |
9 | 9 | Open |
10 | 10 | |
11 | - %span.creator | |
11 | + %span.creator.col-sm-9.col-xs-12 | |
12 | 12 | Created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)} |
13 | 13 | |
14 | 14 | %h4.title | ... | ... |
app/views/projects/merge_requests/show/_mr_title.html.haml
1 | 1 | %h3.page-title |
2 | 2 | = "Merge Request ##{@merge_request.iid}" |
3 | 3 | |
4 | - %span.pull-right | |
4 | + %span.pull-right.issue-btn-group | |
5 | 5 | - if can?(current_user, :modify_merge_request, @merge_request) |
6 | 6 | - if @merge_request.open? |
7 | 7 | .btn-group.pull-left |
... | ... | @@ -39,4 +39,4 @@ |
39 | 39 | - else |
40 | 40 | %span= @merge_request.source_branch |
41 | 41 | → |
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 @@ |
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 | + | ... | ... |
app/views/projects/merge_requests/show/_state_widget.html.haml
... | ... | @@ -21,14 +21,6 @@ |
21 | 21 | #{time_ago_with_tooltip(@merge_request.merge_event.created_at)} |
22 | 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 | 24 | - unless @commits.any? |
33 | 25 | %h4 Nothing to merge |
34 | 26 | %p |
... | ... | @@ -38,3 +30,12 @@ |
38 | 30 | %span.label-branch #{@merge_request.target_branch} |
39 | 31 | %br |
40 | 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 | 1 | = render "projects/issues/head" |
2 | 2 | %h3.page-title |
3 | 3 | Milestone ##{@milestone.iid} |
4 | - %small | |
5 | - = @milestone.expires_at | |
6 | 4 | .pull-right |
7 | 5 | - if can?(current_user, :admin_milestone, @project) |
8 | 6 | = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped" do |
... | ... | @@ -23,14 +21,16 @@ |
23 | 21 | |
24 | 22 | |
25 | 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 | 26 | - if @milestone.closed? |
29 | 27 | Closed |
30 | 28 | - elsif @milestone.expired? |
31 | 29 | Expired |
32 | 30 | - else |
33 | 31 | Open |
32 | + %span.creator.col-sm-9.col-xs-12 | |
33 | + = @milestone.expires_at | |
34 | 34 | |
35 | 35 | %h4.title |
36 | 36 | = gfm escape_once(@milestone.title) |
... | ... | @@ -100,7 +100,7 @@ |
100 | 100 | %ul.bordered-list |
101 | 101 | - @users.each do |user| |
102 | 102 | %li |
103 | - = link_to user, title: user.name, class: "dark" do | |
103 | + = link_to user, title: user.name, class: "darken" do | |
104 | 104 | = image_tag avatar_icon(user.email, 32), class: "avatar s32" |
105 | 105 | %strong= truncate(user.name, lenght: 40) |
106 | 106 | %br | ... | ... |
app/views/projects/new_tree/show.html.haml
... | ... | @@ -24,7 +24,8 @@ |
24 | 24 | = label_tag 'commit_message', class: "control-label" do |
25 | 25 | Commit message |
26 | 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 | 30 | .file-holder |
30 | 31 | .file-title | ... | ... |
app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
1 | 1 | - note1 = notes1.first # example note |
2 | 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 | 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 | 6 | - if note1 |
7 | + %td.notes_line | |
8 | + %span.btn.disabled | |
9 | + %i.icon-comment | |
10 | + = notes1.count | |
7 | 11 | %td.notes_content |
8 | 12 | %ul.notes{ rel: note1.discussion_id } |
9 | 13 | = render notes1 |
14 | + | |
10 | 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 | 16 | - else |
16 | 17 | %td= "" |
17 | 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 | 20 | - if note2 |
24 | 21 | %td.notes_line |
25 | - %span.btn.disabled.parallel-comment | |
22 | + %span.btn.disabled | |
26 | 23 | %i.icon-comment |
27 | 24 | = notes2.count |
28 | 25 | %td.notes_content |
29 | 26 | %ul.notes{ rel: note2.discussion_id } |
30 | 27 | = render notes2 |
28 | + | |
31 | 29 | = render "projects/notes/discussion_reply_button", note: note2 |
32 | 30 | - else |
33 | 31 | %td= "" |
34 | 32 | %td= "" |
33 | + | ... | ... |
app/views/projects/notes/_note.html.haml
... | ... | @@ -54,8 +54,8 @@ |
54 | 54 | - if note.attachment.url |
55 | 55 | .note-attachment |
56 | 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 | 59 | .attachment.pull-right |
60 | 60 | = link_to note.attachment.secure_url, target: "_blank" do |
61 | 61 | %i.icon-paper-clip | ... | ... |
app/views/projects/show.html.haml
app/views/projects/wikis/_form.html.haml
1 | 1 | = form_for [@project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal' } do |f| |
2 | 2 | -if @page.errors.any? |
3 | 3 | #error_explanation |
4 | - %h2= "#{pluralize(@page.errors.count, "error")} prohibited this wiki from being saved:" | |
5 | - %ul | |
4 | + .alert.alert-danger | |
6 | 5 | - @page.errors.full_messages.each do |msg| |
7 | - %li= msg | |
6 | + %p= msg | |
8 | 7 | |
9 | 8 | = f.hidden_field :title, value: @page.title |
10 | 9 | .form-group | ... | ... |
app/views/projects/wikis/_new.html.haml
... | ... | @@ -9,6 +9,6 @@ |
9 | 9 | %span Page slug |
10 | 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 | 11 | %p.hint |
12 | - Please don't use spaces and slashes | |
12 | + Please don't use spaces. | |
13 | 13 | .modal-footer |
14 | 14 | = link_to 'Build', '#', class: 'build-new-wiki btn btn-create' | ... | ... |
app/views/shared/_project_filter.html.haml
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | .light-well |
45 | 45 | Add first label to your issues |
46 | 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 | 49 | %fieldset |
50 | 50 | - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any? | ... | ... |
... | ... | @@ -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 | 66 | # Version of your assets, change this if you want to expire all your assets |
67 | 67 | config.assets.version = '1.0' |
68 | 68 | |
69 | + # Relative url support | |
69 | 70 | # Uncomment and customize the last line to run in a non-root path |
70 | 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 | 73 | # 1) In your application.rb file: config.relative_url_root = "/gitlab" |
73 | 74 | # 2) In your gitlab.yml file: relative_url_root: /gitlab |
74 | 75 | # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" |
75 | 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 | 79 | # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production |
77 | 80 | # |
78 | 81 | # config.relative_url_root = "/gitlab" | ... | ... |
config/gitlab.yml.example
... | ... | @@ -24,15 +24,8 @@ production: &base |
24 | 24 | # Otherwise, ssh host will be set to the `host:` value above |
25 | 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 | 29 | # relative_url_root: /gitlab |
37 | 30 | |
38 | 31 | # Uncomment and customize if you can't use the default user to run GitLab (default: 'git') |
... | ... | @@ -40,10 +33,10 @@ production: &base |
40 | 33 | |
41 | 34 | ## Email settings |
42 | 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 | 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 | 41 | ## User settings |
49 | 42 | default_projects_limit: 10 | ... | ... |
config/routes.rb
... | ... | @@ -206,7 +206,7 @@ Gitlab::Application.routes.draw do |
206 | 206 | end |
207 | 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 | 210 | collection do |
211 | 211 | get :pages |
212 | 212 | put ':id' => 'wikis#update' |
... | ... | @@ -273,7 +273,7 @@ Gitlab::Application.routes.draw do |
273 | 273 | resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do |
274 | 274 | member do |
275 | 275 | get :diffs |
276 | - get :automerge | |
276 | + post :automerge | |
277 | 277 | get :automerge_check |
278 | 278 | get :ci_status |
279 | 279 | end | ... | ... |
config/unicorn.rb.example
... | ... | @@ -8,14 +8,8 @@ |
8 | 8 | # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete |
9 | 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 | 14 | # ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" |
21 | 15 | ... | ... |
db/fixtures/development/04_project.rb
... | ... | @@ -40,7 +40,8 @@ Gitlab::Seeder.quiet do |
40 | 40 | import_url: url, |
41 | 41 | namespace_id: group.id, |
42 | 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 | 47 | project = Projects::CreateService.new(User.first, params).execute | ... | ... |
db/fixtures/development/10_merge_requests.rb
1 | 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 | 31 | end |
32 | - print('.') | |
33 | 32 | end |
34 | 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 | 21 | ## Clients |
22 | 22 | |
23 | 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 | 25 | + [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby |
25 | 26 | + [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python |
26 | 27 | + [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java |
27 | 28 | + [node-gitlab](https://github.com/moul/node-gitlab) - Node.js |
29 | ++ [NGitLab](https://github.com/Scooletz/NGitLab) - .NET | |
28 | 30 | |
29 | 31 | ## Introduction |
30 | 32 | ... | ... |
... | ... | @@ -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 | 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 | 240 | ## Post comment to MR |
193 | 241 | |
194 | 242 | Adds a comment to a merge request. | ... | ... |
doc/api/projects.md
... | ... | @@ -43,7 +43,8 @@ GET /projects |
43 | 43 | "owner_id": 1, |
44 | 44 | "path": "diaspora", |
45 | 45 | "updated_at": "2013-09-30T13: 46: 02Z" |
46 | - } | |
46 | + }, | |
47 | + "archived": false | |
47 | 48 | }, |
48 | 49 | { |
49 | 50 | "id": 6, |
... | ... | @@ -78,7 +79,8 @@ GET /projects |
78 | 79 | "owner_id": 1, |
79 | 80 | "path": "brightbox", |
80 | 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 | 159 | "access_level": 50, |
158 | 160 | "notification_level": 3 |
159 | 161 | } |
160 | - } | |
162 | + }, | |
163 | + "archived": false | |
161 | 164 | } |
162 | 165 | ``` |
163 | 166 | ... | ... |
doc/install/installation.md
1 | 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 | 3 | this should be the highest numbered stable branch (example shown below). |
4 | 4 | |
5 | 5 |  |
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 | 9 | # Important notes |
10 | 10 | |
... | ... | @@ -86,7 +86,7 @@ Is the system packaged Git too old? Remove it and compile from source. |
86 | 86 | mail server. By default, Debian is shipped with exim4 whereas Ubuntu |
87 | 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 | 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 | 101 | Download Ruby and compile it: |
102 | 102 | |
103 | 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 | 106 | ./configure --disable-install-rdoc |
107 | 107 | make |
108 | 108 | sudo make install |
... | ... | @@ -121,6 +121,7 @@ Create a `git` user for Gitlab: |
121 | 121 | # 4. Database |
122 | 122 | |
123 | 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 | 126 | # Install the database packages |
126 | 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 | 130 | sudo -u postgres psql -d template1 |
130 | 131 | |
131 | 132 | # Create a user for GitLab. |
132 | - template1=# CREATE USER git; | |
133 | + template1=# CREATE USER git CREATEDB; | |
133 | 134 | |
134 | 135 | # Create the GitLab production database & grant all privileges on database |
135 | 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 | 150 | ## Clone the Source |
150 | 151 | |
151 | 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 | 155 | # Go to gitlab dir |
155 | 156 | cd /home/git/gitlab |
156 | 157 | |
157 | 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 | 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 | 201 | # Configure Git global settings for git user, useful when editing via web |
201 | 202 | # Edit user.email according to what is set in gitlab.yml |
202 | 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 | 205 | sudo -u git -H git config --global core.autocrlf input |
205 | 206 | |
206 | 207 | **Important Note:** |
... | ... | @@ -243,15 +244,6 @@ that were [fixed](https://github.com/bundler/bundler/pull/2817) in 1.5.2. |
243 | 244 | # Or if you use MySQL (note, the option says "without ... postgres") |
244 | 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 | 247 | ## Install GitLab shell |
256 | 248 | |
257 | 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 | 252 | cd /home/git/gitlab |
261 | 253 | |
262 | 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 | 257 | # By default, the gitlab-shell config is generated from your main gitlab config. You can review (and modify) it as follows: |
266 | 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 | 269 | ## Install Init Script |
269 | 270 | |
270 | 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 | 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 | 306 | # 6. Nginx |
311 | 307 | |
312 | 308 | **Note:** |
... | ... | @@ -413,22 +409,22 @@ GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already |
413 | 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 | 411 | * Stop GitLab |
416 | - `sudo service gitlab stop` | |
412 | + `sudo service gitlab stop` | |
417 | 413 | |
418 | 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 | 416 | * Add the gem to your [Gemfile](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/Gemfile) |
421 | 417 | `gem "omniauth-your-auth-provider"` |
422 | 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 | 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 | 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 | 426 | * Start GitLab |
431 | - `sudo service gitlab start` | |
427 | + `sudo service gitlab start` | |
432 | 428 | |
433 | 429 | |
434 | 430 | ### Examples | ... | ... |
doc/install/requirements.md
... | ... | @@ -53,7 +53,7 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) but GitLab |
53 | 53 | |
54 | 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 | 57 | - 1GB supports up to 100 users (with individual repositories under 250MB, otherwise git memory usage necessitates using swap space) |
58 | 58 | - **2GB** is the **recommended** memory size and supports up to 500 users |
59 | 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 | 74 | |
75 | 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 | 81 | # Supported webbrowsers |
79 | 82 | |
80 | 83 | - Chrome (Latest stable version) |
81 | 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 | 86 | - Opera (Latest released version) |
84 | 87 | - IE 10+ | ... | ... |
doc/integration/README.md
... | ... | @@ -7,3 +7,5 @@ See the documentation below for details on how to configure these services. |
7 | 7 | + [LDAP](ldap.md) Set up sign in via LDAP |
8 | 8 | + [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, and Google via OAuth. |
9 | 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 | 2 | |
3 | 3 | - the 'Issues' link on the GitLab project pages takes you to the appropriate JIRA issue index; |
4 | 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 | 7 |  |
8 | 8 | |
9 | -You can configure the integration in the gitlab.yml configuration file. | |
10 | 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 | 4 | |
5 | 5 | #### Public projects |
6 | 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 | 8 | **Any logged in user** will have [Guest](/help/permissions) permissions on the repository. |
9 | 9 | |
10 | 10 | #### Internal projects | ... | ... |
doc/raketasks/maintenance.md
... | ... | @@ -24,9 +24,9 @@ Version: 5.1.0.beta2 |
24 | 24 | Revision: 4da8b37 |
25 | 25 | Directory: /home/git/gitlab |
26 | 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 | 30 | Using LDAP: no |
31 | 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 | 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 | 38 | |
18 | 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 | 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 | 50 | |
30 | 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 | 55 | * https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/nginx/gitlab |
35 | 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 | 61 | |
41 | 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 | 66 | #### 9. Start application |
46 | 67 | |
47 | 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 | 73 | * [](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 | 80 | |
59 | 81 | * [](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** | ... | ... |