Commit cfc4a2dbe3652180c1d08d5d9e154e28cbb340fb

Authored by Franz-Robert van Vugt
2 parents f03820eb fc5ac145

Merge branch 'master' of https://github.com/gitlabhq/gitlabhq into patch-1

Showing 170 changed files with 2246 additions and 1429 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 170 files displayed.

1 ---color --drb 1 +--color
@@ -19,10 +19,10 @@ rvm: @@ -19,10 +19,10 @@ rvm:
19 services: 19 services:
20 - redis-server 20 - redis-server
21 before_script: 21 before_script:
22 - - "bundle exec rake db:setup"  
23 - - "bundle exec rake db:seed_fu"  
24 - "cp config/database.yml.$DB config/database.yml" 22 - "cp config/database.yml.$DB config/database.yml"
25 - "cp config/gitlab.yml.example config/gitlab.yml" 23 - "cp config/gitlab.yml.example config/gitlab.yml"
  24 + - "bundle exec rake db:setup"
  25 + - "bundle exec rake db:seed_fu"
26 script: "bundle exec rake $TASK --trace" 26 script: "bundle exec rake $TASK --trace"
27 notifications: 27 notifications:
28 email: false 28 email: false
  1 +v 6.8.0
  2 + - Ability to at mention users that are participating in issue and merge req. discussion
  3 + - Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu)
  4 + - Make user search case-insensitive (Christopher Arnold)
  5 +
  6 +v 6.7.2
  7 + - Fix upgrader script
  8 +
  9 +v 6.7.1
  10 + - Fix GitLab CI integration
  11 +
1 v 6.7.0 12 v 6.7.0
2 - Increased the example Nginx client_max_body_size from 5MB to 20MB, consider updating it manually on existing installations 13 - Increased the example Nginx client_max_body_size from 5MB to 20MB, consider updating it manually on existing installations
3 - Add support for Gemnasium as a Project Service (Olivier Gonzalez) 14 - Add support for Gemnasium as a Project Service (Olivier Gonzalez)
@@ -9,6 +20,7 @@ v 6.7.0 @@ -9,6 +20,7 @@ v 6.7.0
9 - Show contribution guide link for new issue form (Jeroen van Baarsen) 20 - Show contribution guide link for new issue form (Jeroen van Baarsen)
10 - Fix CI status for merge requests from fork 21 - Fix CI status for merge requests from fork
11 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) 22 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
  23 + - New page load indicator that includes a spinner that scrolls with the page
12 - Converted all the help sections into markdown 24 - Converted all the help sections into markdown
13 - LDAP user filters 25 - LDAP user filters
14 - Streamline the content of notification emails (Pierre de La Morinerie) 26 - Streamline the content of notification emails (Pierre de La Morinerie)
@@ -24,6 +36,12 @@ v 6.7.0 @@ -24,6 +36,12 @@ v 6.7.0
24 - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5) 36 - Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5)
25 - Create and Update MR calls now support the description parameter (Greg Messner) 37 - Create and Update MR calls now support the description parameter (Greg Messner)
26 - Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository 38 - Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository
  39 + - Added Slack service integration (Federico Ravasio)
  40 + - Better API responses for access_levels (sponsored by O'Reilly Media)
  41 + - Requires at least 2 unicorn workers
  42 + - Requires gitlab-shell v1.9+
  43 + - Replaced gemoji(due to closed licencing problem) with Phantom Open Emoji library(combined SIL Open Font License, MIT License and the CC 3.0 License)
  44 + - Fix `/:username.keys` response content type (Dmitry Medvinsky)
27 45
28 v 6.6.5 46 v 6.6.5
29 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard) 47 - Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
CONTRIBUTING.md
@@ -24,9 +24,12 @@ Issues and merge requests should be in English and contain appropriate language @@ -24,9 +24,12 @@ Issues and merge requests should be in English and contain appropriate language
24 24
25 To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). 25 To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
26 26
27 -The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious bugs or misbehavior in the latest [stable or development release of GitLab](MAINTENANCE.md). When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. 27 +The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious errors in the latest [stable or development release of GitLab](MAINTENANCE.md).
  28 +If something is wrong but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request.
  29 +When submitting an issue please conform to the issue submission guidelines listed below.
  30 +Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue.
28 31
29 -Do not use the issue tracker for feature requests. We have a specific [feedback and suggestions forum](http://feedback.gitlab.com) for this purpose. 32 +Do not use the issue tracker for feature requests. We have a specific [feature request forum](http://feedback.gitlab.com) for this purpose.
30 33
31 Please send a merge request with a tested solution or a merge request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there. 34 Please send a merge request with a tested solution or a merge request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there.
32 35
@@ -48,7 +51,7 @@ Please send a merge request with a tested solution or a merge request with a fai @@ -48,7 +51,7 @@ Please send a merge request with a tested solution or a merge request with a fai
48 51
49 ## Merge requests 52 ## Merge requests
50 53
51 -We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. If you want to add a new feature that is not marked it is best to first create a feedback issue (if there isn't one already) and leave a comment asking for it to be marked accepting merge requests. Please include screenshots or wireframes if the feature will also change the UI. 54 +We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge requests' on our feature request forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. If you want to add a new feature that is not marked it is best to first create a feedback issue (if there isn't one already) and leave a comment asking for it to be marked accepting merge requests. Please include screenshots or wireframes if the feature will also change the UI.
52 55
53 ### Merge request guidelines 56 ### Merge request guidelines
54 57
@@ -64,7 +67,8 @@ If you can, please submit a merge request with the fix or improvements including @@ -64,7 +67,8 @@ If you can, please submit a merge request with the fix or improvements including
64 1. The MR title should describes the change you want to make 67 1. The MR title should describes the change you want to make
65 1. The MR description should give a motive for your change and the method you used to achieve it 68 1. The MR description should give a motive for your change and the method you used to achieve it
66 1. If the MR changes the UI it should include before and after screenshots 69 1. If the MR changes the UI it should include before and after screenshots
67 -1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feedback items](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR 70 +1. If the MR changes CSS classes please include the list of affected pages `grep css-class ./app -R`
  71 +1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feature requests](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR
68 1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submittion 72 1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submittion
69 1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md). 73 1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md).
70 74
@@ -74,6 +78,14 @@ Please keep the change in a single MR **as small as possible**. If you want to c @@ -74,6 +78,14 @@ Please keep the change in a single MR **as small as possible**. If you want to c
74 78
75 For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). Please ensure that your merge request meets the following contribution acceptance criteria. 79 For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). Please ensure that your merge request meets the following contribution acceptance criteria.
76 80
  81 +**Please format your merge request description as follows:**
  82 +
  83 +1. What does this MR do?
  84 +2. Are there points in the code the reviewer needs to double check?
  85 +3. Why was this MR needed?
  86 +4. What are the relevant issue numbers / [Feature requests](http://feedback.gitlab.com/)?
  87 +5. Screenshots (If appropiate)
  88 +
77 ## Contribution acceptance criteria 89 ## Contribution acceptance criteria
78 90
79 1. The change is as small as possible (see the above paragraph for details) 91 1. The change is as small as possible (see the above paragraph for details)
@@ -132,6 +132,9 @@ gem "gitlab-flowdock-git-hook", "~> 0.4.2" @@ -132,6 +132,9 @@ gem "gitlab-flowdock-git-hook", "~> 0.4.2"
132 # Gemnasium integration 132 # Gemnasium integration
133 gem "gemnasium-gitlab-service", "~> 0.2" 133 gem "gemnasium-gitlab-service", "~> 0.2"
134 134
  135 +# Slack integration
  136 +gem "slack-notifier", "~> 0.2.0"
  137 +
135 # d3 138 # d3
136 gem "d3_rails", "~> 3.1.4" 139 gem "d3_rails", "~> 3.1.4"
137 140
@@ -162,8 +165,9 @@ gem "modernizr", "2.6.2" @@ -162,8 +165,9 @@ gem "modernizr", "2.6.2"
162 gem "raphael-rails", "~> 2.1.2" 165 gem "raphael-rails", "~> 2.1.2"
163 gem 'bootstrap-sass', '~> 3.0' 166 gem 'bootstrap-sass', '~> 3.0'
164 gem "font-awesome-rails", '~> 3.2' 167 gem "font-awesome-rails", '~> 3.2'
165 -gem "gemoji", "~> 1.3.0" 168 +gem "gitlab_emoji", "~> 0.0.1.1"
166 gem "gon", '~> 5.0.0' 169 gem "gon", '~> 5.0.0'
  170 +gem 'nprogress-rails'
167 171
168 group :development do 172 group :development do
169 gem "annotate", "~> 2.6.0.beta2" 173 gem "annotate", "~> 2.6.0.beta2"
@@ -214,7 +218,6 @@ group :development, :test do @@ -214,7 +218,6 @@ group :development, :test do
214 # PhantomJS driver for Capybara 218 # PhantomJS driver for Capybara
215 gem 'poltergeist', '~> 1.4.1' 219 gem 'poltergeist', '~> 1.4.1'
216 220
217 - gem 'spork', '~> 1.0rc'  
218 gem 'jasmine', '2.0.0.rc5' 221 gem 'jasmine', '2.0.0.rc5'
219 222
220 gem "spring", '1.1.1' 223 gem "spring", '1.1.1'
@@ -128,6 +128,8 @@ GEM @@ -128,6 +128,8 @@ GEM
128 mail (~> 2.2) 128 mail (~> 2.2)
129 email_validator (1.4.0) 129 email_validator (1.4.0)
130 activemodel 130 activemodel
  131 + emoji (1.0.1)
  132 + json
131 enumerize (0.7.0) 133 enumerize (0.7.0)
132 activesupport (>= 3.2) 134 activesupport (>= 3.2)
133 equalizer (0.0.8) 135 equalizer (0.0.8)
@@ -165,7 +167,6 @@ GEM @@ -165,7 +167,6 @@ GEM
165 formatador (0.2.4) 167 formatador (0.2.4)
166 gemnasium-gitlab-service (0.2.1) 168 gemnasium-gitlab-service (0.2.1)
167 rugged (~> 0.19) 169 rugged (~> 0.19)
168 - gemoji (1.3.1)  
169 gherkin-ruby (0.3.1) 170 gherkin-ruby (0.3.1)
170 racc 171 racc
171 github-markdown (0.5.5) 172 github-markdown (0.5.5)
@@ -190,6 +191,8 @@ GEM @@ -190,6 +191,8 @@ GEM
190 charlock_holmes (~> 0.6.6) 191 charlock_holmes (~> 0.6.6)
191 escape_utils (~> 0.2.4) 192 escape_utils (~> 0.2.4)
192 mime-types (~> 1.19) 193 mime-types (~> 1.19)
  194 + gitlab_emoji (0.0.1.1)
  195 + emoji (~> 1.0.1)
193 gitlab_git (5.7.1) 196 gitlab_git (5.7.1)
194 activesupport (~> 4.0.0) 197 activesupport (~> 4.0.0)
195 charlock_holmes (~> 0.6.9) 198 charlock_holmes (~> 0.6.9)
@@ -297,6 +300,7 @@ GEM @@ -297,6 +300,7 @@ GEM
297 net-ssh (>= 1.99.1) 300 net-ssh (>= 1.99.1)
298 net-ssh (2.7.0) 301 net-ssh (2.7.0)
299 nokogiri (1.5.10) 302 nokogiri (1.5.10)
  303 + nprogress-rails (0.1.2.3)
300 oauth (0.4.7) 304 oauth (0.4.7)
301 oauth2 (0.8.1) 305 oauth2 (0.8.1)
302 faraday (~> 0.8) 306 faraday (~> 0.8)
@@ -468,6 +472,7 @@ GEM @@ -468,6 +472,7 @@ GEM
468 rack-protection (~> 1.4) 472 rack-protection (~> 1.4)
469 tilt (~> 1.3, >= 1.3.4) 473 tilt (~> 1.3, >= 1.3.4)
470 six (0.2.0) 474 six (0.2.0)
  475 + slack-notifier (0.2.0)
471 slim (2.0.2) 476 slim (2.0.2)
472 temple (~> 0.6.6) 477 temple (~> 0.6.6)
473 tilt (>= 1.3.3, < 2.1) 478 tilt (>= 1.3.3, < 2.1)
@@ -479,7 +484,6 @@ GEM @@ -479,7 +484,6 @@ GEM
479 capybara (>= 2.0.0) 484 capybara (>= 2.0.0)
480 railties (>= 3) 485 railties (>= 3)
481 spinach (>= 0.4) 486 spinach (>= 0.4)
482 - spork (1.0.0rc4)  
483 spring (1.1.1) 487 spring (1.1.1)
484 spring-commands-rspec (1.0.1) 488 spring-commands-rspec (1.0.1)
485 spring (>= 0.9.1) 489 spring (>= 0.9.1)
@@ -591,12 +595,12 @@ DEPENDENCIES @@ -591,12 +595,12 @@ DEPENDENCIES
591 font-awesome-rails (~> 3.2) 595 font-awesome-rails (~> 3.2)
592 foreman 596 foreman
593 gemnasium-gitlab-service (~> 0.2) 597 gemnasium-gitlab-service (~> 0.2)
594 - gemoji (~> 1.3.0)  
595 github-markup (~> 0.7.4)! 598 github-markup (~> 0.7.4)!
596 gitlab-flowdock-git-hook (~> 0.4.2) 599 gitlab-flowdock-git-hook (~> 0.4.2)
597 gitlab-gollum-lib (~> 1.1.0) 600 gitlab-gollum-lib (~> 1.1.0)
598 gitlab-grack (~> 2.0.0.pre) 601 gitlab-grack (~> 2.0.0.pre)
599 gitlab-linguist (~> 3.0.0) 602 gitlab-linguist (~> 3.0.0)
  603 + gitlab_emoji (~> 0.0.1.1)
600 gitlab_git (~> 5.7.1) 604 gitlab_git (~> 5.7.1)
601 gitlab_meta (= 6.0) 605 gitlab_meta (= 6.0)
602 gitlab_omniauth-ldap (= 1.0.4) 606 gitlab_omniauth-ldap (= 1.0.4)
@@ -620,6 +624,7 @@ DEPENDENCIES @@ -620,6 +624,7 @@ DEPENDENCIES
620 minitest (~> 4.7.0) 624 minitest (~> 4.7.0)
621 modernizr (= 2.6.2) 625 modernizr (= 2.6.2)
622 mysql2 626 mysql2
  627 + nprogress-rails
623 omniauth (~> 1.1.3) 628 omniauth (~> 1.1.3)
624 omniauth-github 629 omniauth-github
625 omniauth-google-oauth2 630 omniauth-google-oauth2
@@ -652,9 +657,9 @@ DEPENDENCIES @@ -652,9 +657,9 @@ DEPENDENCIES
652 simplecov 657 simplecov
653 sinatra 658 sinatra
654 six 659 six
  660 + slack-notifier (~> 0.2.0)
655 slim 661 slim
656 spinach-rails 662 spinach-rails
657 - spork (~> 1.0rc)  
658 spring (= 1.1.1) 663 spring (= 1.1.1)
659 spring-commands-rspec (= 1.0.1) 664 spring-commands-rspec (= 1.0.1)
660 spring-commands-spinach (= 1.0.0) 665 spring-commands-spinach (= 1.0.0)
@@ -24,8 +24,6 @@ Below we describe the contributing process to GitLab for two reasons. So that co @@ -24,8 +24,6 @@ Below we describe the contributing process to GitLab for two reasons. So that co
24 - Monitors for new merge requests (at least once a week) 24 - Monitors for new merge requests (at least once a week)
25 - Manages their work queue by looking at issues and merge requests assigned to them 25 - Manages their work queue by looking at issues and merge requests assigned to them
26 - Close fixed issues (via commit messages or manually) 26 - Close fixed issues (via commit messages or manually)
27 -- Codes [new features](http://feedback.gitlab.com/forums/176466-general/filters/top)!  
28 -- Response guidelines  
29 - Be kind to people trying to contribute. Be aware that people can be a non-native or a native English speaker, they might not understand thing or they might be very sensitive to how your word things. Use emoji to express your feelings (heart, star, smile, etc.). Some good tips about giving feedback to merge requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review). 27 - Be kind to people trying to contribute. Be aware that people can be a non-native or a native English speaker, they might not understand thing or they might be very sensitive to how your word things. Use emoji to express your feelings (heart, star, smile, etc.). Some good tips about giving feedback to merge requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review).
30 28
31 ## Priorities of the issue team 29 ## Priorities of the issue team
@@ -73,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue @@ -73,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue
73 71
74 ### Feature requests 72 ### Feature requests
75 73
76 -Thanks for your interest in GitLab. We don't use the issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. 74 +Thank you for your interest in improving GitLab. We don't use the issue tracker for feature requests. Things that are wrong but are not a regression compared to older versions of GitLab are considered feature requests and not issues. Please the [feature request forum](http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
77 75
78 ### Issue report for old version 76 ### Issue report for old version
79 77
1 -web: bundle exec unicorn_rails -p $PORT -E development 1 +web: bundle exec unicorn_rails -p $PORT -E development -c config/unicorn_development.rb
2 worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell 2 worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell
@@ -71,7 +71,7 @@ Since 2011 GitLab is released on the 22nd of every month. Every new release incl @@ -71,7 +71,7 @@ Since 2011 GitLab is released on the 22nd of every month. Every new release incl
71 71
72 It is recommended to follow a monthly upgrade schedule. Security releases come out when needed. For more information about the release process see the documentation for [monthly](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/monthly.md) and [security](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/security.md) releases. 72 It is recommended to follow a monthly upgrade schedule. Security releases come out when needed. For more information about the release process see the documentation for [monthly](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/monthly.md) and [security](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/security.md) releases.
73 73
74 -* Features that will be in the next releases are listed on [the feedback and suggestions forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457). 74 +* Features that will be in the next releases are listed on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
75 75
76 ### Run in production mode 76 ### Run in production mode
77 77
@@ -96,14 +96,9 @@ or start each component separately @@ -96,14 +96,9 @@ or start each component separately
96 96
97 ### Run the tests 97 ### Run the tests
98 98
99 -* Seed the database  
100 -  
101 - bundle exec rake db:setup RAILS_ENV=test  
102 - bundle exec rake db:seed_fu RAILS_ENV=test  
103 -  
104 * Run all tests 99 * Run all tests
105 100
106 - bundle exec rake gitlab:test RAILS_ENV=test 101 + bundle exec rake test
107 102
108 * [RSpec](http://rspec.info/) unit and functional tests 103 * [RSpec](http://rspec.info/) unit and functional tests
109 104
@@ -134,22 +129,4 @@ or start each component separately @@ -134,22 +129,4 @@ or start each component separately
134 129
135 ### Getting help 130 ### Getting help
136 131
137 -* [Maintenance policy](MAINTENANCE.md) specifies what versions are supported.  
138 -  
139 -* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) contains solutions to common problems.  
140 -  
141 -* [Mailing list](https://groups.google.com/forum/#!forum/gitlabhq) and [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) are the best places to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and has resolved it. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.  
142 -  
143 -* [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab.  
144 -  
145 -* [Contributing guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) describes how to submit merge requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed.  
146 -  
147 -* [Support subscription](http://www.gitlab.com/subscription/) connects you to the knowledge of GitLab experts that will resolve your issues and answer your questions.  
148 -  
149 -* [Consultancy](http://www.gitlab.com/consultancy/) from the GitLab experts for installations, upgrades and customizations.  
150 -  
151 -* [#gitlab IRC channel](http://www.freenode.net/) on Freenode to get in touch with other GitLab users and get help, it's managed by James Newton (newton), Drew Blessing (dblessing), and Sam Gleske (sag47).  
152 -  
153 -* [Book](http://www.packtpub.com/gitlab-repository-management/book) written by GitLab enthusiast Jonathan M. Hethey is unofficial but it offers a good overview.  
154 -  
155 -* [Gitter chat room](https://gitter.im/gitlabhq/gitlabhq#) here you can ask questions when you need help. 132 +Please see [Getting help for GitLab](https://www.gitlab.com/getting-help/) on our website for the many options to get help.
1 -6.7.0.pre 1 +6.8.0.pre
app/assets/javascripts/application.js
@@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
1 -// This is a manifest file that'll be compiled into including all the files listed below.  
2 -// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically  
3 -// be included in the compiled file accessible from http://example.com/assets/application.js  
4 -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the  
5 -// the compiled file.  
6 -//  
7 -//= require jquery  
8 -//= require jquery.ui.all  
9 -//= require jquery_ujs  
10 -//= require jquery.cookie  
11 -//= require jquery.endless-scroll  
12 -//= require jquery.highlight  
13 -//= require jquery.history  
14 -//= require jquery.waitforimages  
15 -//= require jquery.atwho  
16 -//= require jquery.scrollto  
17 -//= require jquery.blockUI  
18 -//= require turbolinks  
19 -//= require jquery.turbolinks  
20 -//= require bootstrap  
21 -//= require modernizr  
22 -//= require select2  
23 -//= require raphael  
24 -//= require g.raphael-min  
25 -//= require g.bar-min  
26 -//= require branch-graph  
27 -//= require highlightjs.min  
28 -//= require ace/ace  
29 -//= require_tree .  
30 -//= require d3  
31 -//= require underscore  
app/assets/javascripts/application.js.coffee 0 → 100644
@@ -0,0 +1,154 @@ @@ -0,0 +1,154 @@
  1 +# This is a manifest file that'll be compiled into including all the files listed below.
  2 +# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
  3 +# be included in the compiled file accessible from http://example.com/assets/application.js
  4 +# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
  5 +# the compiled file.
  6 +#
  7 +#= require jquery
  8 +#= require jquery.ui.all
  9 +#= require jquery_ujs
  10 +#= require jquery.cookie
  11 +#= require jquery.endless-scroll
  12 +#= require jquery.highlight
  13 +#= require jquery.history
  14 +#= require jquery.waitforimages
  15 +#= require jquery.atwho
  16 +#= require jquery.scrollto
  17 +#= require jquery.blockUI
  18 +#= require turbolinks
  19 +#= require jquery.turbolinks
  20 +#= require bootstrap
  21 +#= require modernizr
  22 +#= require select2
  23 +#= require raphael
  24 +#= require g.raphael-min
  25 +#= require g.bar-min
  26 +#= require branch-graph
  27 +#= require highlightjs.min
  28 +#= require ace/ace
  29 +#= require d3
  30 +#= require underscore
  31 +#= require nprogress
  32 +#= require nprogress-turbolinks
  33 +#= require_tree .
  34 +
  35 +window.slugify = (text) ->
  36 + text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
  37 +
  38 +window.ajaxGet = (url) ->
  39 + $.ajax({type: "GET", url: url, dataType: "script"})
  40 +
  41 +window.showAndHide = (selector) ->
  42 +
  43 +window.errorMessage = (message) ->
  44 + ehtml = $("<p>")
  45 + ehtml.addClass("error_message")
  46 + ehtml.html(message)
  47 + ehtml
  48 +
  49 +window.split = (val) ->
  50 + return val.split( /,\s*/ )
  51 +
  52 +window.extractLast = (term) ->
  53 + return split( term ).pop()
  54 +
  55 +# Disable button if text field is empty
  56 +window.disableButtonIfEmptyField = (field_selector, button_selector) ->
  57 + field = $(field_selector)
  58 + closest_submit = field.closest("form").find(button_selector)
  59 +
  60 + closest_submit.disable() if field.val() is ""
  61 +
  62 + field.on "input", ->
  63 + if $(@).val() is ""
  64 + closest_submit.disable()
  65 + else
  66 + closest_submit.enable()
  67 +
  68 +window.sanitize = (str) ->
  69 + return str.replace(/<(?:.|\n)*?>/gm, '')
  70 +
  71 +window.linkify = (str) ->
  72 + exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
  73 + return str.replace(exp,"<a href='$1'>$1</a>")
  74 +
  75 +window.simpleFormat = (str) ->
  76 + linkify(sanitize(str).replace(/\n/g, '<br />'))
  77 +
  78 +window.unbindEvents = ->
  79 + $(document).unbind('scroll')
  80 + $(document).off('scroll')
  81 +
  82 +document.addEventListener("page:fetch", unbindEvents)
  83 +
  84 +$ ->
  85 + # Click a .one_click_select field, select the contents
  86 + $(".one_click_select").on 'click', -> $(@).select()
  87 +
  88 + $('.remove-row').bind 'ajax:success', ->
  89 + $(this).closest('li').fadeOut()
  90 +
  91 + # Initialize select2 selects
  92 + $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true)
  93 +
  94 + # Initialize tooltips
  95 + $('.has_tooltip').tooltip()
  96 +
  97 + # Bottom tooltip
  98 + $('.has_bottom_tooltip').tooltip(placement: 'bottom')
  99 +
  100 + # Form submitter
  101 + $('.trigger-submit').on 'change', ->
  102 + $(@).parents('form').submit()
  103 +
  104 + $("abbr.timeago").timeago()
  105 + $('.js-timeago').timeago()
  106 +
  107 + # Flash
  108 + if (flash = $(".flash-container")).length > 0
  109 + flash.click -> $(@).fadeOut()
  110 + flash.show()
  111 + setTimeout (-> flash.fadeOut()), 5000
  112 +
  113 + # Disable form buttons while a form is submitting
  114 + $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
  115 + buttons = $('[type="submit"]', @)
  116 +
  117 + switch e.type
  118 + when 'ajax:beforeSend', 'submit'
  119 + buttons.disable()
  120 + else
  121 + buttons.enable()
  122 +
  123 + # Show/Hide the profile menu when hovering the account box
  124 + $('.account-box').hover -> $(@).toggleClass('hover')
  125 +
  126 + # Focus search field by pressing 's' key
  127 + $(document).keypress (e) ->
  128 + # Don't do anything if typing in an input
  129 + return if $(e.target).is(":input")
  130 +
  131 + switch e.which
  132 + when 115
  133 + $("#search").focus()
  134 + e.preventDefault()
  135 + when 63
  136 + new Shortcuts()
  137 + e.preventDefault()
  138 +
  139 +
  140 + # Commit show suppressed diff
  141 + $(".diff-content").on "click", ".supp_diff_link", ->
  142 + $(@).next('table').show()
  143 + $(@).remove()
  144 +
  145 +(($) ->
  146 + # Disable an element and add the 'disabled' Bootstrap class
  147 + $.fn.extend disable: ->
  148 + $(@).attr('disabled', 'disabled').addClass('disabled')
  149 +
  150 + # Enable an element and remove the 'disabled' Bootstrap class
  151 + $.fn.extend enable: ->
  152 + $(@).removeAttr('disabled').removeClass('disabled')
  153 +
  154 +)(jQuery)
app/assets/javascripts/gfm_auto_complete.js.coffee
@@ -6,7 +6,6 @@ GitLab.GfmAutoComplete = @@ -6,7 +6,6 @@ GitLab.GfmAutoComplete =
6 dataSource: '' 6 dataSource: ''
7 # Emoji 7 # Emoji
8 Emoji: 8 Emoji:
9 - assetBase: ''  
10 template: '<li data-value="${insert}">${name} <img alt="${name}" height="20" src="${image}" width="20" /></li>' 9 template: '<li data-value="${insert}">${name} <img alt="${name}" height="20" src="${image}" width="20" /></li>'
11 10
12 # Team Members 11 # Team Members
@@ -27,7 +26,7 @@ GitLab.GfmAutoComplete = @@ -27,7 +26,7 @@ GitLab.GfmAutoComplete =
27 tpl: @Emoji.template 26 tpl: @Emoji.template
28 callbacks: 27 callbacks:
29 before_save: (emojis) => 28 before_save: (emojis) =>
30 - $.map emojis, (em) => name: em, insert: em+ ':', image: "#{@Emoji.assetBase}/#{em}.png" 29 + $.map emojis, (em) => name: em.name, insert: em.name+ ':', image: em.path
31 30
32 # Team Members 31 # Team Members
33 input.atwho 32 input.atwho
app/assets/javascripts/main.js.coffee
@@ -1,128 +0,0 @@ @@ -1,128 +0,0 @@
1 -window.slugify = (text) ->  
2 - text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()  
3 -  
4 -window.ajaxGet = (url) ->  
5 - $.ajax({type: "GET", url: url, dataType: "script"})  
6 -  
7 -window.showAndHide = (selector) ->  
8 -  
9 -window.errorMessage = (message) ->  
10 - ehtml = $("<p>")  
11 - ehtml.addClass("error_message")  
12 - ehtml.html(message)  
13 - ehtml  
14 -  
15 -window.split = (val) ->  
16 - return val.split( /,\s*/ )  
17 -  
18 -window.extractLast = (term) ->  
19 - return split( term ).pop()  
20 -  
21 -# Disable button if text field is empty  
22 -window.disableButtonIfEmptyField = (field_selector, button_selector) ->  
23 - field = $(field_selector)  
24 - closest_submit = field.closest("form").find(button_selector)  
25 -  
26 - closest_submit.disable() if field.val() is ""  
27 -  
28 - field.on "input", ->  
29 - if $(@).val() is ""  
30 - closest_submit.disable()  
31 - else  
32 - closest_submit.enable()  
33 -  
34 -window.sanitize = (str) ->  
35 - return str.replace(/<(?:.|\n)*?>/gm, '')  
36 -  
37 -window.linkify = (str) ->  
38 - exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig  
39 - return str.replace(exp,"<a href='$1'>$1</a>")  
40 -  
41 -window.simpleFormat = (str) ->  
42 - linkify(sanitize(str).replace(/\n/g, '<br />'))  
43 -  
44 -window.startSpinner = ->  
45 - $('.turbolink-spinner').fadeIn()  
46 -  
47 -window.stopSpinner = ->  
48 - $('.turbolink-spinner').fadeOut()  
49 -  
50 -window.unbindEvents = ->  
51 - $(document).unbind('scroll')  
52 - $(document).off('scroll')  
53 -  
54 -document.addEventListener("page:fetch", startSpinner)  
55 -document.addEventListener("page:fetch", unbindEvents)  
56 -document.addEventListener("page:change", stopSpinner)  
57 -  
58 -$ ->  
59 - # Click a .one_click_select field, select the contents  
60 - $(".one_click_select").on 'click', -> $(@).select()  
61 -  
62 - $('.remove-row').bind 'ajax:success', ->  
63 - $(this).closest('li').fadeOut()  
64 -  
65 - # Initialize select2 selects  
66 - $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true)  
67 -  
68 - # Initialize tooltips  
69 - $('.has_tooltip').tooltip()  
70 -  
71 - # Bottom tooltip  
72 - $('.has_bottom_tooltip').tooltip(placement: 'bottom')  
73 -  
74 - # Form submitter  
75 - $('.trigger-submit').on 'change', ->  
76 - $(@).parents('form').submit()  
77 -  
78 - $("abbr.timeago").timeago()  
79 - $('.js-timeago').timeago()  
80 -  
81 - # Flash  
82 - if (flash = $(".flash-container")).length > 0  
83 - flash.click -> $(@).fadeOut()  
84 - flash.show()  
85 - setTimeout (-> flash.fadeOut()), 5000  
86 -  
87 - # Disable form buttons while a form is submitting  
88 - $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->  
89 - buttons = $('[type="submit"]', @)  
90 -  
91 - switch e.type  
92 - when 'ajax:beforeSend', 'submit'  
93 - buttons.disable()  
94 - else  
95 - buttons.enable()  
96 -  
97 - # Show/Hide the profile menu when hovering the account box  
98 - $('.account-box').hover -> $(@).toggleClass('hover')  
99 -  
100 - # Focus search field by pressing 's' key  
101 - $(document).keypress (e) ->  
102 - # Don't do anything if typing in an input  
103 - return if $(e.target).is(":input")  
104 -  
105 - switch e.which  
106 - when 115  
107 - $("#search").focus()  
108 - e.preventDefault()  
109 - when 63  
110 - new Shortcuts()  
111 - e.preventDefault()  
112 -  
113 -  
114 - # Commit show suppressed diff  
115 - $(".diff-content").on "click", ".supp_diff_link", ->  
116 - $(@).next('table').show()  
117 - $(@).remove()  
118 -  
119 -(($) ->  
120 - # Disable an element and add the 'disabled' Bootstrap class  
121 - $.fn.extend disable: ->  
122 - $(@).attr('disabled', 'disabled').addClass('disabled')  
123 -  
124 - # Enable an element and remove the 'disabled' Bootstrap class  
125 - $.fn.extend enable: ->  
126 - $(@).removeAttr('disabled').removeClass('disabled')  
127 -  
128 -)(jQuery)  
app/assets/stylesheets/application.scss
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 *= require select2 7 *= require select2
8 *= require highlightjs.min 8 *= require highlightjs.min
9 *= require_self 9 *= require_self
  10 + *= require nprogress
  11 + *= require nprogress-bootstrap
10 */ 12 */
11 13
12 @import "main/variables.scss"; 14 @import "main/variables.scss";
app/assets/stylesheets/generic/common.scss
@@ -355,3 +355,7 @@ table { @@ -355,3 +355,7 @@ table {
355 @media (max-width: $screen-xs-max) { 355 @media (max-width: $screen-xs-max) {
356 .container .content { margin-top: 20px; } 356 .container .content { margin-top: 20px; }
357 } 357 }
  358 +
  359 +.wiki .highlight, .note-body .highlight {
  360 + margin-bottom: 9px;
  361 +}
app/assets/stylesheets/generic/typography.scss
@@ -88,9 +88,6 @@ a:focus { @@ -88,9 +88,6 @@ a:focus {
88 .wiki { 88 .wiki {
89 @include md-typography; 89 @include md-typography;
90 90
91 - font-size: 14px;  
92 - line-height: 1.6;  
93 -  
94 /* Link to current header. */ 91 /* Link to current header. */
95 h1, h2, h3, h4, h5, h6 { 92 h1, h2, h3, h4, h5, h6 {
96 position: relative; 93 position: relative;
@@ -120,3 +117,11 @@ a:focus { @@ -120,3 +117,11 @@ a:focus {
120 .md { 117 .md {
121 @include md-typography; 118 @include md-typography;
122 } 119 }
  120 +
  121 +/**
  122 + * Textareas intended for GFM
  123 + *
  124 + */
  125 +textarea.js-gfm-input {
  126 + font-family: $monospace_font;
  127 +}
app/assets/stylesheets/main/mixins.scss
@@ -84,6 +84,9 @@ @@ -84,6 +84,9 @@
84 } 84 }
85 85
86 @mixin md-typography { 86 @mixin md-typography {
  87 + font-size: 14px;
  88 + line-height: 1.6;
  89 +
87 img { 90 img {
88 max-width: 100%; 91 max-width: 100%;
89 } 92 }
app/assets/stylesheets/print.scss 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +/* Generic print styles */
  2 +header, nav, nav.main-nav, nav.navbar-collapse, nav.navbar-collapse.collapse {display: none!important;}
  3 +.profiler-results {display: none;}
  4 +
  5 +/* Styles targeted specifically at printing files */
  6 +.tree-ref-holder, .tree-holder .breadcrumb, .blob-commit-info {display: none;}
  7 +.file-title {display: none;}
  8 +.file-holder {border: none;}
  9 +
  10 +.wiki h1, .wiki h2, .wiki h3, .wiki h4, .wiki h5, .wiki h6 {margin-top: 17px; }
  11 +.wiki h1 {font-size: 30px;}
  12 +.wiki h2 {font-size: 22px;}
  13 +.wiki h3 {font-size: 18px; font-weight: bold; }
app/assets/stylesheets/sections/dashboard.scss
@@ -61,7 +61,7 @@ @@ -61,7 +61,7 @@
61 } 61 }
62 62
63 .project-row, .group-row { 63 .project-row, .group-row {
64 - padding: 10px 12px !important; 64 + padding: 8px 12px !important;
65 font-size: 14px; 65 font-size: 14px;
66 line-height: 24px; 66 line-height: 24px;
67 67
app/assets/stylesheets/sections/diff.scss
@@ -62,6 +62,29 @@ @@ -62,6 +62,29 @@
62 font-size: 12px; 62 font-size: 12px;
63 } 63 }
64 } 64 }
  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 + height: 700px;
  74 + }
  75 + .diff-side.diff-side-left{
  76 + overflow-y:hidden;
  77 + }
  78 + .diff-side table, td.diff-middle table {
  79 + height: 700px;
  80 + }
  81 + .diff-middle {
  82 + width: 114px;
  83 + vertical-align: top;
  84 + height: 700px;
  85 + overflow: hidden
  86 + }
  87 +
65 .old_line, .new_line, .diff_line { 88 .old_line, .new_line, .diff_line {
66 margin: 0px; 89 margin: 0px;
67 padding: 0px; 90 padding: 0px;
@@ -125,8 +148,6 @@ @@ -125,8 +148,6 @@
125 } 148 }
126 &.parallel { 149 &.parallel {
127 display: table-cell; 150 display: table-cell;
128 - overflow: hidden;  
129 - width: 50%;  
130 } 151 }
131 } 152 }
132 } 153 }
app/assets/stylesheets/sections/events.scss
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 } 42 }
43 } 43 }
44 44
45 - padding: 14px 0px; 45 + padding: 12px 0px;
46 border-bottom: 1px solid #eee; 46 border-bottom: 1px solid #eee;
47 .event-title { 47 .event-title {
48 color: #333; 48 color: #333;
@@ -63,6 +63,10 @@ @@ -63,6 +63,10 @@
63 color: #666; 63 color: #666;
64 margin-top: 5px; 64 margin-top: 5px;
65 65
  66 + .md {
  67 + font-size: 13px;
  68 + }
  69 +
66 pre { 70 pre {
67 border: none; 71 border: none;
68 background: #f9f9f9; 72 background: #f9f9f9;
app/assets/stylesheets/sections/header.scss
@@ -273,3 +273,9 @@ header { @@ -273,3 +273,9 @@ header {
273 } 273 }
274 } 274 }
275 } 275 }
  276 +
  277 +@media (max-width: $screen-xs-max) {
  278 + #nprogress .spinner {
  279 + right: 35px !important;
  280 + }
  281 +}
app/assets/stylesheets/sections/notes.scss
@@ -27,11 +27,15 @@ ul.notes { @@ -27,11 +27,15 @@ ul.notes {
27 27
28 .discussion-last-update, 28 .discussion-last-update,
29 .note-last-update { 29 .note-last-update {
30 - font-style: italic; 30 + &:before {
  31 + content: "\00b7";
  32 + }
  33 + font-size: 13px;
31 } 34 }
32 .author { 35 .author {
33 - color: $style_color; 36 + color: #555;
34 font-weight: bold; 37 font-weight: bold;
  38 + font-size: 14px;
35 &:hover { 39 &:hover {
36 color: $primary_color; 40 color: $primary_color;
37 } 41 }
app/controllers/passwords_controller.rb 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +class PasswordsController < Devise::PasswordsController
  2 +
  3 + def create
  4 + email = resource_params[:email]
  5 + resource_found = resource_class.find_by_email(email)
  6 + if resource_found && resource_found.ldap_user?
  7 + flash[:alert] = "Cannot reset password for LDAP user."
  8 + respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name)) and return
  9 + end
  10 +
  11 + self.resource = resource_class.send_reset_password_instructions(resource_params)
  12 + if successfully_sent?(resource)
  13 + respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
  14 + else
  15 + respond_with(resource)
  16 + end
  17 + end
  18 +end
app/controllers/profiles/keys_controller.rb
@@ -41,7 +41,7 @@ class Profiles::KeysController &lt; ApplicationController @@ -41,7 +41,7 @@ class Profiles::KeysController &lt; ApplicationController
41 begin 41 begin
42 user = User.find_by_username(params[:username]) 42 user = User.find_by_username(params[:username])
43 if user.present? 43 if user.present?
44 - render text: user.all_ssh_keys.join("\n") 44 + render text: user.all_ssh_keys.join("\n"), content_type: "text/plain"
45 else 45 else
46 render_404 and return 46 render_404 and return
47 end 47 end
app/controllers/projects/issues_controller.rb
@@ -76,7 +76,7 @@ class Projects::IssuesController &lt; Projects::ApplicationController @@ -76,7 +76,7 @@ class Projects::IssuesController &lt; Projects::ApplicationController
76 end 76 end
77 77
78 def update 78 def update
79 - @issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id)) 79 + @issue.update_attributes(params[:issue])
80 @issue.reset_events_cache 80 @issue.reset_events_cache
81 81
82 respond_to do |format| 82 respond_to do |format|
app/controllers/projects/merge_requests_controller.rb
@@ -109,7 +109,7 @@ class Projects::MergeRequestsController &lt; Projects::ApplicationController @@ -109,7 +109,7 @@ class Projects::MergeRequestsController &lt; Projects::ApplicationController
109 params[:merge_request].delete(:source_project_id) 109 params[:merge_request].delete(:source_project_id)
110 params[:merge_request].delete(:target_project_id) 110 params[:merge_request].delete(:target_project_id)
111 111
112 - if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id)) 112 + if @merge_request.update_attributes(params[:merge_request])
113 @merge_request.reset_events_cache 113 @merge_request.reset_events_cache
114 114
115 respond_to do |format| 115 respond_to do |format|
app/controllers/projects/milestones_controller.rb
@@ -38,7 +38,6 @@ class Projects::MilestonesController &lt; Projects::ApplicationController @@ -38,7 +38,6 @@ class Projects::MilestonesController &lt; Projects::ApplicationController
38 38
39 def create 39 def create
40 @milestone = @project.milestones.new(params[:milestone]) 40 @milestone = @project.milestones.new(params[:milestone])
41 - @milestone.author_id_of_changes = current_user.id  
42 41
43 if @milestone.save 42 if @milestone.save
44 redirect_to project_milestone_path(@project, @milestone) 43 redirect_to project_milestone_path(@project, @milestone)
@@ -48,7 +47,7 @@ class Projects::MilestonesController &lt; Projects::ApplicationController @@ -48,7 +47,7 @@ class Projects::MilestonesController &lt; Projects::ApplicationController
48 end 47 end
49 48
50 def update 49 def update
51 - @milestone.update_attributes(params[:milestone].merge(author_id_of_changes: current_user.id)) 50 + @milestone.update_attributes(params[:milestone])
52 51
53 respond_to do |format| 52 respond_to do |format|
54 format.js 53 format.js
app/controllers/projects_controller.rb
@@ -123,11 +123,20 @@ class ProjectsController &lt; ApplicationController @@ -123,11 +123,20 @@ class ProjectsController &lt; ApplicationController
123 end 123 end
124 124
125 def autocomplete_sources 125 def autocomplete_sources
  126 + note_type = params['type']
  127 + note_id = params['type_id']
  128 + participating = if note_type && note_id
  129 + participants_in(note_type, note_id)
  130 + else
  131 + []
  132 + end
  133 + team_members = sorted(@project.team.members)
  134 + participants = team_members + participating
126 @suggestions = { 135 @suggestions = {
127 - emojis: Emoji.names, 136 + emojis: Emoji.names.map { |e| { name: e, path: view_context.image_url("emoji/#{e}.png") } },
128 issues: @project.issues.select([:iid, :title, :description]), 137 issues: @project.issues.select([:iid, :title, :description]),
129 mergerequests: @project.merge_requests.select([:iid, :title, :description]), 138 mergerequests: @project.merge_requests.select([:iid, :title, :description]),
130 - members: @project.team.members.sort_by(&:username).map { |user| { username: user.username, name: user.name } } 139 + members: participants.uniq
131 } 140 }
132 141
133 respond_to do |format| 142 respond_to do |format|
@@ -162,4 +171,25 @@ class ProjectsController &lt; ApplicationController @@ -162,4 +171,25 @@ class ProjectsController &lt; ApplicationController
162 def user_layout 171 def user_layout
163 current_user ? "projects" : "public_projects" 172 current_user ? "projects" : "public_projects"
164 end 173 end
  174 +
  175 + def participants_in(type, id)
  176 + users = case type
  177 + when "Issue"
  178 + issue = @project.issues.find_by_iid(id)
  179 + issue ? issue.participants : []
  180 + when "MergeRequest"
  181 + merge_request = @project.merge_requests.find_by_iid(id)
  182 + merge_request ? merge_request.participants : []
  183 + when "Commit"
  184 + author_ids = Note.for_commit_id(id).pluck(:author_id).uniq
  185 + User.where(id: author_ids)
  186 + else
  187 + []
  188 + end
  189 + sorted(users)
  190 + end
  191 +
  192 + def sorted(users)
  193 + users.uniq.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
  194 + end
165 end 195 end
app/finders/base_finder.rb
@@ -47,9 +47,9 @@ class BaseFinder @@ -47,9 +47,9 @@ class BaseFinder
47 [] 47 []
48 end 48 end
49 elsif current_user && params[:authorized_only].presence 49 elsif current_user && params[:authorized_only].presence
50 - klass.of_projects(current_user.authorized_projects) 50 + klass.of_projects(current_user.authorized_projects).references(:project)
51 else 51 else
52 - klass.of_projects(Project.accessible_to(current_user)) 52 + klass.of_projects(Project.accessible_to(current_user)).references(:project)
53 end 53 end
54 end 54 end
55 55
app/helpers/commits_helper.rb
@@ -105,8 +105,80 @@ module CommitsHelper @@ -105,8 +105,80 @@ module CommitsHelper
105 branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe 105 branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe
106 end 106 end
107 107
108 - def get_old_file(project, commit, diff)  
109 - project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id 108 + def parallel_diff_lines(project, commit, diff, file)
  109 + old_file = project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id
  110 + deleted_lines = {}
  111 + added_lines = {}
  112 + each_diff_line(diff, 0) do |line, type, line_code, line_new, line_old|
  113 + if type == "old"
  114 + deleted_lines[line_old] = { line_code: line_code, type: type, line: line }
  115 + elsif type == "new"
  116 + added_lines[line_new] = { line_code: line_code, type: type, line: line }
  117 + end
  118 + end
  119 + max_length = old_file ? old_file.sloc + added_lines.length : file.sloc
  120 +
  121 + offset1 = 0
  122 + offset2 = 0
  123 + old_lines = []
  124 + new_lines = []
  125 +
  126 + max_length.times do |line_index|
  127 + line_index1 = line_index - offset1
  128 + line_index2 = line_index - offset2
  129 + deleted_line = deleted_lines[line_index1 + 1]
  130 + added_line = added_lines[line_index2 + 1]
  131 + old_line = old_file.lines[line_index1] if old_file
  132 + new_line = file.lines[line_index2]
  133 +
  134 + if deleted_line && added_line
  135 + elsif deleted_line
  136 + new_line = nil
  137 + offset2 += 1
  138 + elsif added_line
  139 + old_line = nil
  140 + offset1 += 1
  141 + end
  142 +
  143 + old_lines[line_index] = DiffLine.new
  144 + new_lines[line_index] = DiffLine.new
  145 +
  146 + # old
  147 + if line_index == 0 && diff.new_file
  148 + old_lines[line_index].type = :file_created
  149 + old_lines[line_index].content = 'File was created'
  150 + elsif deleted_line
  151 + old_lines[line_index].type = :deleted
  152 + old_lines[line_index].content = old_line
  153 + old_lines[line_index].num = line_index1 + 1
  154 + old_lines[line_index].code = deleted_line[:line_code]
  155 + elsif old_line
  156 + old_lines[line_index].type = :no_change
  157 + old_lines[line_index].content = old_line
  158 + old_lines[line_index].num = line_index1 + 1
  159 + else
  160 + old_lines[line_index].type = :added
  161 + end
  162 +
  163 + # new
  164 + if line_index == 0 && diff.deleted_file
  165 + new_lines[line_index].type = :file_deleted
  166 + new_lines[line_index].content = "File was deleted"
  167 + elsif added_line
  168 + new_lines[line_index].type = :added
  169 + new_lines[line_index].num = line_index2 + 1
  170 + new_lines[line_index].content = new_line
  171 + new_lines[line_index].code = added_line[:line_code]
  172 + elsif new_line
  173 + new_lines[line_index].type = :no_change
  174 + new_lines[line_index].num = line_index2 + 1
  175 + new_lines[line_index].content = new_line
  176 + else
  177 + new_lines[line_index].type = :deleted
  178 + end
  179 + end
  180 +
  181 + return old_lines, new_lines
110 end 182 end
111 183
112 protected 184 protected
app/helpers/merge_requests_helper.rb
@@ -20,7 +20,7 @@ module MergeRequestsHelper @@ -20,7 +20,7 @@ module MergeRequestsHelper
20 target_project_id: target_project.id, 20 target_project_id: target_project.id,
21 source_branch: event.branch_name, 21 source_branch: event.branch_name,
22 target_branch: target_project.repository.root_ref, 22 target_branch: target_project.repository.root_ref,
23 - title: event.branch_name.titleize 23 + title: event.branch_name.humanize
24 } 24 }
25 end 25 end
26 26
app/helpers/tree_helper.rb
@@ -40,7 +40,7 @@ module TreeHelper @@ -40,7 +40,7 @@ module TreeHelper
40 # Returns boolean 40 # Returns boolean
41 def markup?(filename) 41 def markup?(filename)
42 filename.downcase.end_with?(*%w(.textile .rdoc .org .creole 42 filename.downcase.end_with?(*%w(.textile .rdoc .org .creole
43 - .mediawiki .rst .asciidoc .pod)) 43 + .mediawiki .rst .adoc .asciidoc .pod))
44 end 44 end
45 45
46 def gitlab_markdown?(filename) 46 def gitlab_markdown?(filename)
app/mailers/emails/merge_requests.rb
@@ -29,11 +29,11 @@ module Emails @@ -29,11 +29,11 @@ module Emails
29 subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) 29 subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
30 end 30 end
31 31
32 - def merged_merge_request_email(recipient_id, merge_request_id) 32 + def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
33 @merge_request = MergeRequest.find(merge_request_id) 33 @merge_request = MergeRequest.find(merge_request_id)
34 @project = @merge_request.project 34 @project = @merge_request.project
35 @target_url = project_merge_request_url(@project, @merge_request) 35 @target_url = project_merge_request_url(@project, @merge_request)
36 - mail(from: sender(@merge_request.author_id_of_changes), 36 + mail(from: sender(updated_by_user_id),
37 to: recipient(recipient_id), 37 to: recipient(recipient_id),
38 subject: subject("#{@merge_request.title} (!#{@merge_request.iid})")) 38 subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
39 end 39 end
app/models/concerns/issuable.rb
@@ -37,8 +37,6 @@ module Issuable @@ -37,8 +37,6 @@ module Issuable
37 allow_nil: true, 37 allow_nil: true,
38 prefix: true 38 prefix: true
39 39
40 - attr_accessor :author_id_of_changes  
41 -  
42 attr_mentionable :title, :description 40 attr_mentionable :title, :description
43 end 41 end
44 42
app/models/diff_line.rb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +class DiffLine
  2 + attr_accessor :type, :content, :num, :code
  3 +end
app/models/event.rb
@@ -47,14 +47,6 @@ class Event &lt; ActiveRecord::Base @@ -47,14 +47,6 @@ class Event &lt; ActiveRecord::Base
47 scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent } 47 scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent }
48 48
49 class << self 49 class << self
50 - def determine_action(record)  
51 - if [Issue, MergeRequest].include? record.class  
52 - Event::CREATED  
53 - elsif record.kind_of? Note  
54 - Event::COMMENTED  
55 - end  
56 - end  
57 -  
58 def create_ref_event(project, user, ref, action = 'add', prefix = 'refs/heads') 50 def create_ref_event(project, user, ref, action = 'add', prefix = 'refs/heads')
59 commit = project.repository.commit(ref.target) 51 commit = project.repository.commit(ref.target)
60 52
app/models/issue.rb
@@ -30,8 +30,7 @@ class Issue &lt; ActiveRecord::Base @@ -30,8 +30,7 @@ class Issue &lt; ActiveRecord::Base
30 scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) } 30 scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) }
31 31
32 attr_accessible :title, :assignee_id, :position, :description, 32 attr_accessible :title, :assignee_id, :position, :description,
33 - :milestone_id, :label_list, :author_id_of_changes,  
34 - :state_event 33 + :milestone_id, :label_list, :state_event
35 34
36 acts_as_taggable_on :labels 35 acts_as_taggable_on :labels
37 36
app/models/merge_request.rb
@@ -38,7 +38,7 @@ class MergeRequest &lt; ActiveRecord::Base @@ -38,7 +38,7 @@ class MergeRequest &lt; ActiveRecord::Base
38 38
39 delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil 39 delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
40 40
41 - attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :author_id_of_changes, :state_event, :description 41 + attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :state_event, :description
42 42
43 attr_accessor :should_remove_source_branch 43 attr_accessor :should_remove_source_branch
44 44
app/models/milestone.rb
@@ -16,8 +16,7 @@ @@ -16,8 +16,7 @@
16 class Milestone < ActiveRecord::Base 16 class Milestone < ActiveRecord::Base
17 include InternalId 17 include InternalId
18 18
19 - attr_accessible :title, :description, :due_date, :state_event, :author_id_of_changes  
20 - attr_accessor :author_id_of_changes 19 + attr_accessible :title, :description, :due_date, :state_event
21 20
22 belongs_to :project 21 belongs_to :project
23 has_many :issues 22 has_many :issues
@@ -89,6 +88,6 @@ class Milestone &lt; ActiveRecord::Base @@ -89,6 +88,6 @@ class Milestone &lt; ActiveRecord::Base
89 end 88 end
90 89
91 def author_id 90 def author_id
92 - author_id_of_changes 91 + nil
93 end 92 end
94 end 93 end
app/models/note.rb
@@ -199,7 +199,8 @@ class Note &lt; ActiveRecord::Base @@ -199,7 +199,8 @@ class Note &lt; ActiveRecord::Base
199 def downvote? 199 def downvote?
200 votable? && (note.start_with?('-1') || 200 votable? && (note.start_with?('-1') ||
201 note.start_with?(':-1:') || 201 note.start_with?(':-1:') ||
202 - note.start_with?(':thumbsdown:') 202 + note.start_with?(':thumbsdown:') ||
  203 + note.start_with?(':thumbs_down_sign:')
203 ) 204 )
204 end 205 end
205 206
@@ -249,7 +250,8 @@ class Note &lt; ActiveRecord::Base @@ -249,7 +250,8 @@ class Note &lt; ActiveRecord::Base
249 def upvote? 250 def upvote?
250 votable? && (note.start_with?('+1') || 251 votable? && (note.start_with?('+1') ||
251 note.start_with?(':+1:') || 252 note.start_with?(':+1:') ||
252 - note.start_with?(':thumbsup:') 253 + note.start_with?(':thumbsup:') ||
  254 + note.start_with?(':thumbs_up_sign:')
253 ) 255 )
254 end 256 end
255 257
app/models/project.rb
@@ -56,6 +56,7 @@ class Project &lt; ActiveRecord::Base @@ -56,6 +56,7 @@ class Project &lt; ActiveRecord::Base
56 has_one :flowdock_service, dependent: :destroy 56 has_one :flowdock_service, dependent: :destroy
57 has_one :assembla_service, dependent: :destroy 57 has_one :assembla_service, dependent: :destroy
58 has_one :gemnasium_service, dependent: :destroy 58 has_one :gemnasium_service, dependent: :destroy
  59 + has_one :slack_service, dependent: :destroy
59 has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" 60 has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
60 has_one :forked_from_project, through: :forked_project_link 61 has_one :forked_from_project, through: :forked_project_link
61 # Merge Requests for target project should be removed with it 62 # Merge Requests for target project should be removed with it
@@ -304,7 +305,7 @@ class Project &lt; ActiveRecord::Base @@ -304,7 +305,7 @@ class Project &lt; ActiveRecord::Base
304 end 305 end
305 306
306 def available_services_names 307 def available_services_names
307 - %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium) 308 + %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack)
308 end 309 end
309 310
310 def gitlab_ci? 311 def gitlab_ci?
app/models/project_services/slack_message.rb 0 → 100644
@@ -0,0 +1,95 @@ @@ -0,0 +1,95 @@
  1 +require 'slack-notifier'
  2 +
  3 +class SlackMessage
  4 + def initialize(params)
  5 + @after = params.fetch(:after)
  6 + @before = params.fetch(:before)
  7 + @commits = params.fetch(:commits, [])
  8 + @project_name = params.fetch(:project_name)
  9 + @project_url = params.fetch(:project_url)
  10 + @ref = params.fetch(:ref).gsub('refs/heads/', '')
  11 + @username = params.fetch(:user_name)
  12 + end
  13 +
  14 + def compose
  15 + format(message)
  16 + end
  17 +
  18 + private
  19 +
  20 + attr_reader :after
  21 + attr_reader :before
  22 + attr_reader :commits
  23 + attr_reader :project_name
  24 + attr_reader :project_url
  25 + attr_reader :ref
  26 + attr_reader :username
  27 +
  28 + def message
  29 + if new_branch?
  30 + new_branch_message
  31 + elsif removed_branch?
  32 + removed_branch_message
  33 + else
  34 + push_message << commit_messages
  35 + end
  36 + end
  37 +
  38 + def format(string)
  39 + Slack::Notifier::LinkFormatter.format(string)
  40 + end
  41 +
  42 + def new_branch_message
  43 + "#{username} pushed new branch #{branch_link} to #{project_link}"
  44 + end
  45 +
  46 + def removed_branch_message
  47 + "#{username} removed branch #{ref} from #{project_link}"
  48 + end
  49 +
  50 + def push_message
  51 + "#{username} pushed to branch #{branch_link} of #{project_link} (#{compare_link})"
  52 + end
  53 +
  54 + def commit_messages
  55 + commits.each_with_object('') do |commit, str|
  56 + str << compose_commit_message(commit)
  57 + end
  58 + end
  59 +
  60 + def compose_commit_message(commit)
  61 + id = commit.fetch(:id)[0..5]
  62 + message = commit.fetch(:message)
  63 + url = commit.fetch(:url)
  64 +
  65 + "\n - #{message} ([#{id}](#{url}))"
  66 + end
  67 +
  68 + def new_branch?
  69 + before =~ /000000/
  70 + end
  71 +
  72 + def removed_branch?
  73 + after =~ /000000/
  74 + end
  75 +
  76 + def branch_url
  77 + "#{project_url}/commits/#{ref}"
  78 + end
  79 +
  80 + def compare_url
  81 + "#{project_url}/compare/#{before}...#{after}"
  82 + end
  83 +
  84 + def branch_link
  85 + "[#{ref}](#{branch_url})"
  86 + end
  87 +
  88 + def project_link
  89 + "[#{project_name}](#{project_url})"
  90 + end
  91 +
  92 + def compare_link
  93 + "[Compare changes](#{compare_url})"
  94 + end
  95 +end
app/models/project_services/slack_service.rb 0 → 100644
@@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
  1 +# == Schema Information
  2 +#
  3 +# Table name: services
  4 +#
  5 +# id :integer not null, primary key
  6 +# type :string(255)
  7 +# title :string(255)
  8 +# token :string(255)
  9 +# project_id :integer not null
  10 +# created_at :datetime not null
  11 +# updated_at :datetime not null
  12 +# active :boolean default(FALSE), not null
  13 +# project_url :string(255)
  14 +# subdomain :string(255)
  15 +# room :string(255)
  16 +# api_key :string(255)
  17 +#
  18 +
  19 +class SlackService < Service
  20 + attr_accessible :room
  21 + attr_accessible :subdomain
  22 +
  23 + validates :room, presence: true, if: :activated?
  24 + validates :subdomain, presence: true, if: :activated?
  25 + validates :token, presence: true, if: :activated?
  26 +
  27 + def title
  28 + 'Slack'
  29 + end
  30 +
  31 + def description
  32 + 'A team communication tool for the 21st century'
  33 + end
  34 +
  35 + def to_param
  36 + 'slack'
  37 + end
  38 +
  39 + def fields
  40 + [
  41 + { type: 'text', name: 'subdomain', placeholder: '' },
  42 + { type: 'text', name: 'token', placeholder: '' },
  43 + { type: 'text', name: 'room', placeholder: 'Ex. #general' },
  44 + ]
  45 + end
  46 +
  47 + def execute(push_data)
  48 + message = SlackMessage.new(push_data.merge(
  49 + project_url: project_url,
  50 + project_name: project_name
  51 + ))
  52 +
  53 + notifier = Slack::Notifier.new(subdomain, token)
  54 + notifier.channel = room
  55 + notifier.username = 'GitLab'
  56 + notifier.ping(message.compose)
  57 + end
  58 +
  59 + private
  60 +
  61 + def project_name
  62 + project.name_with_namespace.gsub(/\s/, '')
  63 + end
  64 +
  65 + def project_url
  66 + project.web_url
  67 + end
  68 +end
app/models/user.rb
@@ -204,7 +204,7 @@ class User &lt; ActiveRecord::Base @@ -204,7 +204,7 @@ class User &lt; ActiveRecord::Base
204 end 204 end
205 205
206 def search query 206 def search query
207 - where("name LIKE :query OR email LIKE :query OR username LIKE :query", query: "%#{query}%") 207 + where("lower(name) LIKE :query OR lower(email) LIKE :query OR lower(username) LIKE :query", query: "%#{query.downcase}%")
208 end 208 end
209 209
210 def by_username_or_id(name_or_id) 210 def by_username_or_id(name_or_id)
@@ -249,7 +249,7 @@ class User &lt; ActiveRecord::Base @@ -249,7 +249,7 @@ class User &lt; ActiveRecord::Base
249 def namespace_uniq 249 def namespace_uniq
250 namespace_name = self.username 250 namespace_name = self.username
251 if Namespace.find_by(path: namespace_name) 251 if Namespace.find_by(path: namespace_name)
252 - self.errors.add :username, "already exist" 252 + self.errors.add :username, "already exists"
253 end 253 end
254 end 254 end
255 255
app/observers/activity_observer.rb
@@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
1 -class ActivityObserver < BaseObserver  
2 - observe :issue, :note, :milestone  
3 -  
4 - def after_create(record)  
5 - event_author_id = record.author_id  
6 -  
7 - if record.kind_of?(Note)  
8 - # Skip system notes, like status changes and cross-references.  
9 - return true if record.system?  
10 -  
11 - # Skip wall notes to prevent spamming of dashboard  
12 - return true if record.noteable_type.blank?  
13 - end  
14 -  
15 - if event_author_id  
16 - create_event(record, Event.determine_action(record))  
17 - end  
18 - end  
19 -  
20 - def after_close(record, transition)  
21 - create_event(record, Event::CLOSED)  
22 - end  
23 -  
24 - def after_reopen(record, transition)  
25 - create_event(record, Event::REOPENED)  
26 - end  
27 -  
28 - protected  
29 -  
30 - def create_event(record, status)  
31 - Event.create(  
32 - project: record.project,  
33 - target_id: record.id,  
34 - target_type: record.class.name,  
35 - action: status,  
36 - author_id: current_user.id  
37 - )  
38 - end  
39 -end  
app/observers/base_observer.rb
@@ -3,6 +3,10 @@ class BaseObserver &lt; ActiveRecord::Observer @@ -3,6 +3,10 @@ class BaseObserver &lt; ActiveRecord::Observer
3 NotificationService.new 3 NotificationService.new
4 end 4 end
5 5
  6 + def event_service
  7 + EventCreateService.new
  8 + end
  9 +
6 def log_info message 10 def log_info message
7 Gitlab::AppLogger.info message 11 Gitlab::AppLogger.info message
8 end 12 end
app/observers/issue_observer.rb
1 class IssueObserver < BaseObserver 1 class IssueObserver < BaseObserver
2 def after_create(issue) 2 def after_create(issue)
3 notification.new_issue(issue, current_user) 3 notification.new_issue(issue, current_user)
  4 + event_service.open_issue(issue, current_user)
4 issue.create_cross_references!(issue.project, current_user) 5 issue.create_cross_references!(issue.project, current_user)
5 execute_hooks(issue) 6 execute_hooks(issue)
6 end 7 end
7 8
8 def after_close(issue, transition) 9 def after_close(issue, transition)
9 notification.close_issue(issue, current_user) 10 notification.close_issue(issue, current_user)
  11 + event_service.close_issue(issue, current_user)
10 create_note(issue) 12 create_note(issue)
11 execute_hooks(issue) 13 execute_hooks(issue)
12 end 14 end
13 15
14 def after_reopen(issue, transition) 16 def after_reopen(issue, transition)
  17 + event_service.reopen_issue(issue, current_user)
15 create_note(issue) 18 create_note(issue)
16 execute_hooks(issue) 19 execute_hooks(issue)
17 end 20 end
app/observers/merge_request_observer.rb
1 -class MergeRequestObserver < ActivityObserver  
2 - observe :merge_request  
3 - 1 +class MergeRequestObserver < BaseObserver
4 def after_create(merge_request) 2 def after_create(merge_request)
5 - if merge_request.author_id  
6 - create_event(merge_request, Event.determine_action(merge_request))  
7 - end  
8 - 3 + event_service.open_mr(merge_request, current_user)
9 notification.new_merge_request(merge_request, current_user) 4 notification.new_merge_request(merge_request, current_user)
10 merge_request.create_cross_references!(merge_request.project, current_user) 5 merge_request.create_cross_references!(merge_request.project, current_user)
11 execute_hooks(merge_request) 6 execute_hooks(merge_request)
12 end 7 end
13 8
14 def after_close(merge_request, transition) 9 def after_close(merge_request, transition)
15 - create_event(merge_request, Event::CLOSED) 10 + event_service.close_mr(merge_request, current_user)
16 notification.close_mr(merge_request, current_user) 11 notification.close_mr(merge_request, current_user)
17 create_note(merge_request) 12 create_note(merge_request)
18 execute_hooks(merge_request) 13 execute_hooks(merge_request)
19 end 14 end
20 15
21 def after_reopen(merge_request, transition) 16 def after_reopen(merge_request, transition)
22 - create_event(merge_request, Event::REOPENED) 17 + event_service.reopen_mr(merge_request, current_user)
23 create_note(merge_request) 18 create_note(merge_request)
24 execute_hooks(merge_request) 19 execute_hooks(merge_request)
25 merge_request.reload_code 20 merge_request.reload_code
@@ -33,16 +28,6 @@ class MergeRequestObserver &lt; ActivityObserver @@ -33,16 +28,6 @@ class MergeRequestObserver &lt; ActivityObserver
33 execute_hooks(merge_request) 28 execute_hooks(merge_request)
34 end 29 end
35 30
36 - def create_event(record, status)  
37 - Event.create(  
38 - project: record.target_project,  
39 - target_id: record.id,  
40 - target_type: record.class.name,  
41 - action: status,  
42 - author_id: current_user.id  
43 - )  
44 - end  
45 -  
46 private 31 private
47 32
48 # Create merge request note with service comment like 'Status changed to closed' 33 # Create merge request note with service comment like 'Status changed to closed'
app/observers/milestone_observer.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +class MilestoneObserver < BaseObserver
  2 + def after_create(milestone)
  3 + event_service.open_milestone(milestone, current_user)
  4 + end
  5 +
  6 + def after_close(milestone, transition)
  7 + event_service.close_milestone(milestone, current_user)
  8 + end
  9 +
  10 + def after_reopen(milestone, transition)
  11 + event_service.reopen_milestone(milestone, current_user)
  12 + end
  13 +end
app/observers/note_observer.rb
@@ -2,6 +2,12 @@ class NoteObserver &lt; BaseObserver @@ -2,6 +2,12 @@ class NoteObserver &lt; BaseObserver
2 def after_create(note) 2 def after_create(note)
3 notification.new_note(note) 3 notification.new_note(note)
4 4
  5 + # Skip system notes, like status changes and cross-references.
  6 + # Skip wall notes to prevent spamming of dashboard
  7 + if note.noteable_type.present? && !note.system
  8 + event_service.leave_note(note, current_user)
  9 + end
  10 +
5 unless note.system? 11 unless note.system?
6 # Create a cross-reference note if this Note contains GFM that names an 12 # Create a cross-reference note if this Note contains GFM that names an
7 # issue, merge request, or commit. 13 # issue, merge request, or commit.
app/services/event_create_service.rb 0 → 100644
@@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
  1 +# EventCreateService class
  2 +#
  3 +# Used for creating events feed on dashboard after certain user action
  4 +#
  5 +# Ex.
  6 +# EventCreateService.new.new_issue(issue, current_user)
  7 +#
  8 +class EventCreateService
  9 + def open_issue(issue, current_user)
  10 + create_event(issue, current_user, Event::CREATED)
  11 + end
  12 +
  13 + def close_issue(issue, current_user)
  14 + create_event(issue, current_user, Event::CLOSED)
  15 + end
  16 +
  17 + def reopen_issue(issue, current_user)
  18 + create_event(issue, current_user, Event::REOPENED)
  19 + end
  20 +
  21 + def open_mr(merge_request, current_user)
  22 + create_event(merge_request, current_user, Event::CREATED)
  23 + end
  24 +
  25 + def close_mr(merge_request, current_user)
  26 + create_event(merge_request, current_user, Event::CLOSED)
  27 + end
  28 +
  29 + def reopen_mr(merge_request, current_user)
  30 + create_event(merge_request, current_user, Event::REOPENED)
  31 + end
  32 +
  33 + def merge_mr(merge_request, current_user)
  34 + create_event(merge_request, current_user, Event::MERGED)
  35 + end
  36 +
  37 + def open_milestone(milestone, current_user)
  38 + create_event(milestone, current_user, Event::CREATED)
  39 + end
  40 +
  41 + def close_milestone(milestone, current_user)
  42 + create_event(milestone, current_user, Event::CLOSED)
  43 + end
  44 +
  45 + def reopen_milestone(milestone, current_user)
  46 + create_event(milestone, current_user, Event::REOPENED)
  47 + end
  48 +
  49 + def leave_note(note, current_user)
  50 + create_event(note, current_user, Event::COMMENTED)
  51 + end
  52 +
  53 + private
  54 +
  55 + def create_event(record, current_user, status)
  56 + Event.create(
  57 + project: record.project,
  58 + target_id: record.id,
  59 + target_type: record.class.name,
  60 + action: status,
  61 + author_id: current_user.id
  62 + )
  63 + end
  64 +end
app/services/merge_requests/auto_merge_service.rb
@@ -9,11 +9,10 @@ module MergeRequests @@ -9,11 +9,10 @@ module MergeRequests
9 merge_request.lock 9 merge_request.lock
10 10
11 if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message) 11 if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message)
12 - merge_request.author_id_of_changes = current_user.id  
13 merge_request.merge 12 merge_request.merge
14 13
15 - notification.merge_mr(merge_request)  
16 - create_merge_event(merge_request) 14 + notification.merge_mr(merge_request, current_user)
  15 + create_merge_event(merge_request, current_user)
17 execute_project_hooks(merge_request) 16 execute_project_hooks(merge_request)
18 17
19 true 18 true
app/services/merge_requests/base_merge_service.rb
@@ -7,14 +7,8 @@ module MergeRequests @@ -7,14 +7,8 @@ module MergeRequests
7 NotificationService.new 7 NotificationService.new
8 end 8 end
9 9
10 - def create_merge_event(merge_request)  
11 - Event.create(  
12 - project: merge_request.target_project,  
13 - target_id: merge_request.id,  
14 - target_type: merge_request.class.name,  
15 - action: Event::MERGED,  
16 - author_id: merge_request.author_id_of_changes  
17 - ) 10 + def create_merge_event(merge_request, current_user)
  11 + EventCreateService.new.merge_mr(merge_request, current_user)
18 end 12 end
19 13
20 def execute_project_hooks(merge_request) 14 def execute_project_hooks(merge_request)
app/services/merge_requests/merge_service.rb
@@ -7,11 +7,10 @@ module MergeRequests @@ -7,11 +7,10 @@ module MergeRequests
7 # to target branch 7 # to target branch
8 class MergeService < BaseMergeService 8 class MergeService < BaseMergeService
9 def execute(merge_request, current_user, commit_message) 9 def execute(merge_request, current_user, commit_message)
10 - merge_request.author_id_of_changes = current_user.id  
11 merge_request.merge 10 merge_request.merge
12 11
13 - notification.merge_mr(merge_request)  
14 - create_merge_event(merge_request) 12 + notification.merge_mr(merge_request, current_user)
  13 + create_merge_event(merge_request, current_user)
15 execute_project_hooks(merge_request) 14 execute_project_hooks(merge_request)
16 15
17 true 16 true
app/services/notification_service.rb
@@ -86,12 +86,12 @@ class NotificationService @@ -86,12 +86,12 @@ class NotificationService
86 # * merge_request assignee if their notification level is not Disabled 86 # * merge_request assignee if their notification level is not Disabled
87 # * project team members with notification level higher then Participating 87 # * project team members with notification level higher then Participating
88 # 88 #
89 - def merge_mr(merge_request) 89 + def merge_mr(merge_request, current_user)
90 recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project) 90 recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project)
91 recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq 91 recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq
92 92
93 recipients.each do |recipient| 93 recipients.each do |recipient|
94 - mailer.merged_merge_request_email(recipient.id, merge_request.id) 94 + mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user.id)
95 end 95 end
96 end 96 end
97 97
@@ -111,6 +111,7 @@ class NotificationService @@ -111,6 +111,7 @@ class NotificationService
111 111
112 # ignore gitlab service messages 112 # ignore gitlab service messages
113 return true if note.note =~ /\A_Status changed to closed_/ 113 return true if note.note =~ /\A_Status changed to closed_/
  114 + return true if note.note =~ /\A_mentioned in / && note.system == true
114 115
115 opts = { noteable_type: note.noteable_type, project_id: note.project_id } 116 opts = { noteable_type: note.noteable_type, project_id: note.project_id }
116 117
app/views/devise/sessions/_oauth_providers.html.haml
@@ -2,10 +2,12 @@ @@ -2,10 +2,12 @@
2 - if providers.present? 2 - if providers.present?
3 %hr 3 %hr
4 %div{:'data-no-turbolink' => 'data-no-turbolink'} 4 %div{:'data-no-turbolink' => 'data-no-turbolink'}
5 - %span Sign in with: &nbsp; 5 + %span Sign in with*: &nbsp;
6 - providers.each do |provider| 6 - providers.each do |provider|
7 %span 7 %span
8 - if default_providers.include?(provider) 8 - if default_providers.include?(provider)
9 = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) 9 = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
10 - else 10 - else
11 = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn" 11 = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn"
  12 + %br
  13 + %small * Make sure your email address is public
app/views/layouts/_head.html.haml
@@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
4 = "#{title} | " if defined?(title) 4 = "#{title} | " if defined?(title)
5 GitLab 5 GitLab
6 = favicon_link_tag 'favicon.ico' 6 = favicon_link_tag 'favicon.ico'
7 - = stylesheet_link_tag "application" 7 + = stylesheet_link_tag "application", :media => "all"
  8 + = stylesheet_link_tag "print", :media => "print"
8 = javascript_include_tag "application" 9 = javascript_include_tag "application"
9 = csrf_meta_tags 10 = csrf_meta_tags
10 = include_gon 11 = include_gon
app/views/layouts/_head_panel.html.haml
@@ -15,10 +15,6 @@ @@ -15,10 +15,6 @@
15 .navbar-collapse.collapse 15 .navbar-collapse.collapse
16 %ul.nav.navbar-nav 16 %ul.nav.navbar-nav
17 %li.hidden-sm.hidden-xs 17 %li.hidden-sm.hidden-xs
18 - %a  
19 - %div.hide.turbolink-spinner  
20 - %i.icon-refresh.icon-spin  
21 - %li.hidden-sm.hidden-xs  
22 = render "layouts/search" 18 = render "layouts/search"
23 %li.visible-sm.visible-xs 19 %li.visible-sm.visible-xs
24 = link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do 20 = link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do
app/views/layouts/_init_auto_complete.html.haml
1 :javascript 1 :javascript
2 - GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_project_path(@project)}"  
3 - GitLab.GfmAutoComplete.Emoji.assetBase = "#{Gitlab.config.gitlab.relative_url_root + '/assets/emoji'}" 2 + GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_project_path(@project, type: @noteable.class, type_id: params[:id])}"
4 GitLab.GfmAutoComplete.setup(); 3 GitLab.GfmAutoComplete.setup();
app/views/layouts/_public_head_panel.html.haml
@@ -8,11 +8,15 @@ @@ -8,11 +8,15 @@
8 %span.separator 8 %span.separator
9 %h1.title= title 9 %h1.title= title
10 10
11 - .pull-right 11 + %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
  12 + %span.sr-only Toggle navigation
  13 + %i.icon-reorder
  14 +
  15 + .pull-right.hidden-xs
12 = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in btn-new' 16 = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in btn-new'
13 17
14 - %ul.nav.navbar-nav  
15 - %li  
16 - %a  
17 - %div.hide.turbolink-spinner  
18 - %i.icon-refresh.icon-spin 18 + .navbar-collapse.collapse
  19 + %ul.nav.navbar-nav
  20 + %li.visible-xs
  21 + = link_to "Sign in", new_session_path(:user)
  22 +
app/views/layouts/public_projects.html.haml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 %body{class: "#{app_theme} application", :'data-page' => body_data_page} 4 %body{class: "#{app_theme} application", :'data-page' => body_data_page}
5 = render "layouts/broadcast" 5 = render "layouts/broadcast"
6 = render "layouts/public_head_panel", title: project_title(@project) 6 = render "layouts/public_head_panel", title: project_title(@project)
7 - %nav.main-nav 7 + %nav.main-nav.navbar-collapse.collapse
8 .container= render 'layouts/nav/project' 8 .container= render 'layouts/nav/project'
9 .container 9 .container
10 .content= yield 10 .content= yield
app/views/notify/repository_push_email.html.haml
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 %li 7 %li
8 #{commit.short_id} - #{commit.title} 8 #{commit.short_id} - #{commit.title}
9 9
10 -%h4 Diff: 10 +%h4 Changes:
11 - @diffs.each do |diff| 11 - @diffs.each do |diff|
12 %li 12 %li
13 %strong 13 %strong
@@ -23,6 +23,6 @@ @@ -23,6 +23,6 @@
23 %br 23 %br
24 24
25 - if @compare.timeout 25 - if @compare.timeout
26 - %h5 Huge diff. To prevent performance issues it was hidden 26 + %h5 To prevent performance issues changes are hidden
27 - elsif @compare.commits_over_limit? 27 - elsif @compare.commits_over_limit?
28 - %h5 Diff for big amount of commits is disabled 28 + %h5 Changes are not shown due to large amount of commits
app/views/notify/repository_push_email.text.haml
@@ -6,7 +6,7 @@ Commits: @@ -6,7 +6,7 @@ Commits:
6 #{commit.short_id} - #{truncate(commit.title, length: 40)} 6 #{commit.short_id} - #{truncate(commit.title, length: 40)}
7 \ 7 \
8 \ 8 \
9 -Diff: 9 +Changes:
10 - @diffs.each do |diff| 10 - @diffs.each do |diff|
11 \ 11 \
12 \===================================== 12 \=====================================
@@ -22,4 +22,4 @@ Diff: @@ -22,4 +22,4 @@ Diff:
22 - if @compare.timeout 22 - if @compare.timeout
23 Huge diff. To prevent performance issues it was hidden 23 Huge diff. To prevent performance issues it was hidden
24 - elsif @compare.commits_over_limit? 24 - elsif @compare.commits_over_limit?
25 - Diff for big amount of commits is disabled 25 + Changes are not shown due to large amount of commits
app/views/projects/commits/_parallel_view.html.haml
1 / Side-by-side diff view 1 / Side-by-side diff view
2 -- old_file = get_old_file(project, @commit, diff)  
3 -- deleted_lines = {}  
4 -- added_lines = {}  
5 -- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|  
6 - - if type == "old"  
7 - - deleted_lines[line_old] = { line_code: line_code, type: type, line: line }  
8 - - elsif type == "new"  
9 - - added_lines[line_new] = { line_code: line_code, type: type, line: line }  
10 -  
11 -- max_length = old_file.sloc + added_lines.length if old_file  
12 -- max_length ||= file.sloc  
13 -- offset1 = 0  
14 -- offset2 = 0 2 +- old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file)
  3 +- num_lines = old_lines.length
15 4
16 %div.text-file-parallel 5 %div.text-file-parallel
17 - %table{ style: "table-layout: fixed;" }  
18 - - max_length.times do |line_index|  
19 - - line_index1 = line_index - offset1  
20 - - line_index2 = line_index - offset2  
21 - - deleted_line = deleted_lines[line_index1 + 1]  
22 - - added_line = added_lines[line_index2 + 1]  
23 - - old_line = old_file.lines[line_index1] if old_file  
24 - - new_line = file.lines[line_index2] 6 + %div.diff-side.diff-side-left
  7 + %table
  8 + - old_lines.each do |line|
  9 +
  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=""
25 28
26 - - if deleted_line && added_line  
27 - - elsif deleted_line  
28 - - new_line = nil  
29 - - offset2 += 1  
30 - - elsif added_line  
31 - - old_line = nil  
32 - - offset1 += 1 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 33
34 - %tr.line_holder.parallel  
35 - - if line_index == 0 && diff.new_file  
36 - %td.line_content.parallel= "File was created"  
37 - %td.old_line= ""  
38 - - elsif deleted_line  
39 - %td.line_content{class: "parallel noteable_line old #{deleted_line[:line_code]}", "line_code" => deleted_line[:line_code] }= old_line  
40 - %td.old_line.old  
41 - = line_index1 + 1  
42 - - if @comments_allowed  
43 - =# render "projects/notes/diff_note_link", line_code: deleted_line[:line_code]  
44 - - elsif old_line  
45 - %td.line_content.parallel= old_line  
46 - %td.old_line= line_index1 + 1  
47 - - else  
48 - %td.line_content.parallel= ""  
49 - %td.old_line= "" 34 + %div.diff-side.diff-side-right
  35 + %table
  36 + - new_lines.each do |line|
50 37
51 - %td.diff_line= "" 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
52 45
53 - - if diff.deleted_file && line_index == 0  
54 - %td.new_line= ""  
55 - %td.line_content.parallel= "File was deleted"  
56 - - elsif added_line  
57 - %td.new_line.new  
58 - = line_index2 + 1  
59 - - if @comments_allowed  
60 - =# render "projects/notes/diff_note_link", line_code: added_line[:line_code]  
61 - %td.line_content{class: "parallel noteable_line new #{added_line[:line_code]}", "line_code" => added_line[:line_code] }= new_line  
62 - - elsif new_line  
63 - %td.new_line= line_index2 + 1  
64 - %td.line_content.parallel= new_line  
65 - - else  
66 - %td.new_line= ""  
67 - %td.line_content.parallel= "" 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 + });
68 51
69 - - if @reply_allowed  
70 - - comments1 = []  
71 - - comments2 = []  
72 - - comments1 = @line_notes.select { |n| n.line_code == deleted_line[:line_code] }.sort_by(&:created_at) if deleted_line  
73 - - comments2 = @line_notes.select { |n| n.line_code == added_line[:line_code] }.sort_by(&:created_at) if added_line  
74 - - unless comments1.empty? && comments2.empty?  
75 - = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2, line1: deleted_line, line2: added_line  
76 \ No newline at end of file 52 \ No newline at end of file
  53 + $('.diff-side-left').on('scroll', function(){
  54 + $('.diff-side-right, .diff-middle').scrollTop($(this).scrollTop()); // might never be relevant
  55 + $('.diff-side-right').scrollLeft($(this).scrollLeft());
  56 + });
app/views/projects/commits/_text_file.html.haml
1 - too_big = diff.diff.lines.count > 1000 1 - too_big = diff.diff.lines.count > 1000
2 - if too_big 2 - if too_big
3 - %a.supp_diff_link Diff suppressed. Click to show 3 + %a.supp_diff_link Changes suppressed. Click to show
4 4
5 %table.text-file{class: "#{'hide' if too_big}"} 5 %table.text-file{class: "#{'hide' if too_big}"}
6 - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line| 6 - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|
app/views/projects/compare/show.html.haml
@@ -18,17 +18,17 @@ @@ -18,17 +18,17 @@
18 - else 18 - else
19 %ul.well-list= render Commit.decorate(@commits), project: @project 19 %ul.well-list= render Commit.decorate(@commits), project: @project
20 20
21 - %h4 Diff 21 + %h4 Changes
22 - if @diffs.present? 22 - if @diffs.present?
23 = render "projects/commits/diffs", diffs: @diffs, project: @project 23 = render "projects/commits/diffs", diffs: @diffs, project: @project
24 - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE 24 - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
25 .bs-callout.bs-callout-danger 25 .bs-callout.bs-callout-danger
26 %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits. 26 %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
27 - %p To preserve performance the line diff is not shown. 27 + %p To preserve performance the line changes are not shown.
28 - elsif @timeout 28 - elsif @timeout
29 .bs-callout.bs-callout-danger 29 .bs-callout.bs-callout-danger
30 - %h4 Diff for this comparison is extremely large.  
31 - %p Use command line to browse diff for this comparison. 30 + %h4 Number of changed files for this comparison is extremely large.
  31 + %p Use command line to browse through changes for this comparison.
32 32
33 33
34 - else 34 - else
app/views/projects/deploy_keys/show.html.haml
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 Deploy key: 2 Deploy key:
3 = @key.title 3 = @key.title
4 %small 4 %small
5 - created at 5 + created on
6 = @key.created_at.stamp("Aug 21, 2011") 6 = @key.created_at.stamp("Aug 21, 2011")
7 .back-link 7 .back-link
8 = link_to project_deploy_keys_path(@project) do 8 = link_to project_deploy_keys_path(@project) do
app/views/projects/issues/_form.html.haml
1 %div.issue-form-holder 1 %div.issue-form-holder
2 %h3.page-title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.iid}" 2 %h3.page-title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.iid}"
3 %hr 3 %hr
4 - - if @repository.contribution_guide && !@issue.persisted? 4 + - if !@repository.empty? && @repository.contribution_guide && !@issue.persisted?
5 - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name)) 5 - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name))
6 .alert.alert-info.col-sm-10.col-sm-offset-2 6 .alert.alert-info.col-sm-10.col-sm-offset-2
7 ="Please review the <strong>#{link_to "guidelines for contribution", contribution_guide_url}</strong> to this repository.".html_safe 7 ="Please review the <strong>#{link_to "guidelines for contribution", contribution_guide_url}</strong> to this repository.".html_safe
app/views/projects/merge_requests/_form.html.haml
1 -- if @repository.contribution_guide && !@merge_request.persisted?  
2 - - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name))  
3 - .alert.alert-info.col-sm-10.col-sm-offset-2  
4 - ="Please review the <strong>#{link_to "guidelines for contribution", contribution_guide_url}</strong> to this repository.".html_safe  
5 = form_for [@project, @merge_request], html: { class: "merge-request-form form-horizontal" } do |f| 1 = form_for [@project, @merge_request], html: { class: "merge-request-form form-horizontal" } do |f|
6 - -if @merge_request.errors.any?  
7 - .alert.alert-danger  
8 - %ul  
9 - - @merge_request.errors.full_messages.each do |msg|  
10 - %li= msg 2 + .row
  3 + .col-sm-2
  4 + .col-sm-10
  5 + - if @repository.contribution_guide && !@merge_request.persisted?
  6 + - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name))
  7 + .alert.alert-info
  8 + Please review the
  9 + %strong #{link_to "guidelines for contribution", contribution_guide_url}
  10 + to this repository.
  11 +
  12 + -if @merge_request.errors.any?
  13 + .alert.alert-danger
  14 + - @merge_request.errors.full_messages.each do |msg|
  15 + %div= msg
11 16
12 .merge-request-branches 17 .merge-request-branches
13 .form-group 18 .form-group
@@ -47,24 +52,6 @@ @@ -47,24 +52,6 @@
47 = f.text_area :description, class: "form-control js-gfm-input", rows: 14 52 = f.text_area :description, class: "form-control js-gfm-input", rows: 14
48 %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. 53 %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
49 54
50 - %hr  
51 - .form-group  
52 - .merge-request-assignee  
53 - = f.label :assignee_id, class: 'control-label' do  
54 - %i.icon-user  
55 - Assign to  
56 - .col-sm-10  
57 - = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id)  
58 - &nbsp;  
59 - = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link'  
60 - .form-group  
61 - .merge-request-milestone  
62 - = f.label :milestone_id, class: 'control-label' do  
63 - %i.icon-time  
64 - Milestone  
65 - .col-sm-10= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'})  
66 -  
67 -  
68 .form-actions 55 .form-actions
69 - if @merge_request.new_record? 56 - if @merge_request.new_record?
70 = f.submit 'Submit merge request', class: "btn btn-create" 57 = f.submit 'Submit merge request', class: "btn btn-create"
@@ -96,7 +83,3 @@ @@ -96,7 +83,3 @@
96 target_branch.on("change", function() { 83 target_branch.on("change", function() {
97 $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() }); 84 $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() });
98 }); 85 });
99 - $('.assign-to-me-link').on('click', function(e){  
100 - $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");  
101 - e.preventDefault();  
102 - });  
app/views/projects/merge_requests/_show.html.haml
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 %li.diffs-tab{data: {action: 'diffs'}} 20 %li.diffs-tab{data: {action: 'diffs'}}
21 = link_to diffs_project_merge_request_path(@project, @merge_request) do 21 = link_to diffs_project_merge_request_path(@project, @merge_request) do
22 %i.icon-list-alt 22 %i.icon-list-alt
23 - Diff 23 + Changes
24 24
25 - content_for :note_actions do 25 - content_for :note_actions do
26 - if can?(current_user, :modify_merge_request, @merge_request) 26 - if can?(current_user, :modify_merge_request, @merge_request)
app/views/projects/merge_requests/branch_from.js.haml
@@ -3,5 +3,5 @@ @@ -3,5 +3,5 @@
3 var mrTitle = $('#merge_request_title'); 3 var mrTitle = $('#merge_request_title');
4 4
5 if(mrTitle.val().length == 0) { 5 if(mrTitle.val().length == 0) {
6 - mrTitle.val("#{params[:ref].titleize}"); 6 + mrTitle.val("#{params[:ref].humanize}");
7 } 7 }
app/views/projects/merge_requests/show/_diffs.html.haml
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 - else 5 - else
6 .bs-callout.bs-callout-warning 6 .bs-callout.bs-callout-warning
7 %h4 7 %h4
8 - Diff for this comparison is extremely large. 8 + Changes view for this comparison is extremely large.
9 %p 9 %p
10 You can 10 You can
11 = link_to "download it", project_merge_request_path(@merge_request.source_project, @merge_request, format: :diff), class: "vlink" 11 = link_to "download it", project_merge_request_path(@merge_request.source_project, @merge_request, format: :diff), class: "vlink"
app/views/projects/merge_requests/show/_mr_accept.html.haml
1 - unless @allowed_to_merge 1 - unless @allowed_to_merge
2 - .bs-callout  
3 - %strong You don't have permission to merge this MR 2 + - if @project.archived?
  3 + .bs-callout.bs-callout-warning
  4 + %strong Archived projects cannot be committed to!
  5 + - else
  6 + .bs-callout
  7 + .automerge_widget.cannot_be_merged.hide
  8 + %strong This can't be merged automatically, even if it could be merged you don't have the permission to do so.
  9 + .automerge_widget.can_be_merged.hide
  10 + %strong This can be merged automatically but you don't have the permission to do so.
4 11
5 12
6 - if @show_merge_controls 13 - if @show_merge_controls
app/views/projects/merge_requests/show/_mr_box.html.haml
@@ -29,13 +29,13 @@ @@ -29,13 +29,13 @@
29 %span 29 %span
30 %i.icon-remove 30 %i.icon-remove
31 Closed by #{link_to_member(@project, @merge_request.closed_event.author)} 31 Closed by #{link_to_member(@project, @merge_request.closed_event.author)}
32 - #{time_ago_with_tooltip(@merge_request.closed_event.created_at)}. 32 + #{time_ago_with_tooltip(@merge_request.closed_event.created_at)}
33 - if @merge_request.merged? 33 - if @merge_request.merged?
34 .alert.alert-info 34 .alert.alert-info
35 %span 35 %span
36 %i.icon-ok 36 %i.icon-ok
37 Merged by #{link_to_member(@project, @merge_request.merge_event.author)} 37 Merged by #{link_to_member(@project, @merge_request.merge_event.author)}
38 - #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}. 38 + #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}
39 - if !@closes_issues.empty? && @merge_request.open? 39 - if !@closes_issues.empty? && @merge_request.open?
40 .alert.alert-info.alert-info 40 .alert.alert-info.alert-info
41 %span 41 %span
app/views/projects/notes/_note.html.haml
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 %i.icon-thumbs-up 23 %i.icon-thumbs-up
24 \+1 24 \+1
25 - if note.downvote? 25 - if note.downvote?
26 - %span.vote.downvote.label.label-error 26 + %span.vote.downvote.label.label-danger
27 %i.icon-thumbs-down 27 %i.icon-thumbs-down
28 \-1 28 \-1
29 29
app/views/projects/show.html.haml
@@ -9,8 +9,8 @@ @@ -9,8 +9,8 @@
9 .col-md-3.project-side.hidden-sm 9 .col-md-3.project-side.hidden-sm
10 .clearfix 10 .clearfix
11 - if @project.archived? 11 - if @project.archived?
12 - .alert  
13 - %h5 12 + .alert.alert-warning
  13 + %h4
14 %i.icon-warning-sign 14 %i.icon-warning-sign
15 Archived project! 15 Archived project!
16 %p Repository is read-only 16 %p Repository is read-only
config/application.rb
@@ -19,7 +19,7 @@ module Gitlab @@ -19,7 +19,7 @@ module Gitlab
19 # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 19 # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
20 20
21 # Activate observers that should always be running. 21 # Activate observers that should always be running.
22 - config.active_record.observers = :activity_observer, 22 + config.active_record.observers = :milestone_observer,
23 :project_activity_cache_observer, 23 :project_activity_cache_observer,
24 :issue_observer, 24 :issue_observer,
25 :key_observer, 25 :key_observer,
config/environments/production.rb
@@ -33,6 +33,12 @@ Gitlab::Application.configure do @@ -33,6 +33,12 @@ Gitlab::Application.configure do
33 # See everything in the log (default is :info) 33 # See everything in the log (default is :info)
34 # config.log_level = :debug 34 # config.log_level = :debug
35 35
  36 + # Suppress 'Rendered template ...' messages in the log
  37 + # source: http://stackoverflow.com/a/16369363
  38 + %w{render_template render_partial render_collection}.each do |event|
  39 + ActiveSupport::Notifications.unsubscribe "#{event}.action_view"
  40 + end
  41 +
36 # Prepend all log lines with the following tags 42 # Prepend all log lines with the following tags
37 # config.log_tags = [ :subdomain, :uuid ] 43 # config.log_tags = [ :subdomain, :uuid ]
38 44
config/initializers/gemoji.rb
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -# Workaround for https://github.com/github/gemoji/pull/18  
2 -require 'gemoji'  
3 -Gitlab::Application.config.assets.paths << Emoji.images_path  
config/routes.rb
@@ -167,7 +167,7 @@ Gitlab::Application.routes.draw do @@ -167,7 +167,7 @@ Gitlab::Application.routes.draw do
167 167
168 resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create] 168 resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
169 169
170 - devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations } 170 + devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords}
171 171
172 # 172 #
173 # Project Area 173 # Project Area
config/unicorn_development.rb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +worker_processes 2
  2 +timeout 30
db/fixtures/development/11_keys.rb
@@ -2,7 +2,7 @@ Gitlab::Seeder.quiet do @@ -2,7 +2,7 @@ Gitlab::Seeder.quiet do
2 User.first(30).each_with_index do |user, i| 2 User.first(30).each_with_index do |user, i|
3 Key.seed(:id, [ 3 Key.seed(:id, [
4 { 4 {
5 - id: i, 5 + id: i + 1,
6 title: "Sample key #{i}", 6 title: "Sample key #{i}",
7 key: "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt#{i + 100}6k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", 7 key: "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt#{i + 100}6k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
8 user_id: user.id, 8 user_id: user.id,
doc/README.md 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +## The GitLab Documentation covers the following subjects
  2 +
  3 ++ [API](api/README.md)
  4 ++ [Development](development/README.md)
  5 ++ [Install](install/README.md)
  6 ++ [Integration](external-issue-tracker/README.md)
  7 ++ [Legal](legal/README.md)
  8 ++ [Markdown](markdown/markdown.md)
  9 ++ [Permissions](permissions/permissions.md)
  10 ++ [Public access](public_access/public_access.md)
  11 ++ [Raketasks](raketasks/README.md)
  12 ++ [Release](release/README.md)
  13 ++ [Security](security/README.md)
  14 ++ [System hooks](system_hooks/system_hooks.md)
  15 ++ [Update](update/README.md)
  16 ++ [Web hooks](web_hooks/web_hooks.md)
  17 ++ [Workflow](workflow/workflow.md)
doc/api/README.md
1 # GitLab API 1 # GitLab API
2 2
  3 +## End-points
  4 +
  5 ++ [Users](users.md)
  6 ++ [Session](session.md)
  7 ++ [Projects](projects.md)
  8 ++ [Project Snippets](project_snippets.md)
  9 ++ [Repositories](repositories.md)
  10 ++ [Repository Files](repository_files.md)
  11 ++ [Commits](commits.md)
  12 ++ [Merge Requests](merge_requests.md)
  13 ++ [Issues](issues.md)
  14 ++ [Milestones](milestones.md)
  15 ++ [Notes](notes.md)
  16 ++ [Deploy Keys](deploy_keys.md)
  17 ++ [System Hooks](system_hooks.md)
  18 ++ [Groups](groups.md)
  19 +
  20 +## Clients
  21 +
  22 ++ [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP
  23 ++ [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby
  24 ++ [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python
  25 ++ [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java
  26 +
  27 +## Introduction
  28 +
3 All API requests require authentication. You need to pass a `private_token` parameter by url or header. If passed as header, the header name must be "PRIVATE-TOKEN" (capital and with dash instead of underscore). You can find or reset your private token in your profile. 29 All API requests require authentication. You need to pass a `private_token` parameter by url or header. If passed as header, the header name must be "PRIVATE-TOKEN" (capital and with dash instead of underscore). You can find or reset your private token in your profile.
4 30
5 If no, or an invalid, `private_token` is provided then an error message will be returned with status code 401: 31 If no, or an invalid, `private_token` is provided then an error message will be returned with status code 401:
@@ -117,30 +143,3 @@ Issue @@ -117,30 +143,3 @@ Issue
117 143
118 So if you want to get issue with api you use `http://host/api/v3/.../issues/:id.json` 144 So if you want to get issue with api you use `http://host/api/v3/.../issues/:id.json`
119 But when you want to create a link to web page - use `http:://host/project/issues/:iid.json` 145 But when you want to create a link to web page - use `http:://host/project/issues/:iid.json`
120 -  
121 -  
122 -  
123 -## Contents  
124 -  
125 -+ [Users](users.md)  
126 -+ [Session](session.md)  
127 -+ [Projects](projects.md)  
128 -+ [Project Snippets](project_snippets.md)  
129 -+ [Repositories](repositories.md)  
130 -+ [Repository Files](repository_files.md)  
131 -+ [Commits](commits.md)  
132 -+ [Merge Requests](merge_requests.md)  
133 -+ [Issues](issues.md)  
134 -+ [Milestones](milestones.md)  
135 -+ [Notes](notes.md)  
136 -+ [Deploy Keys](deploy_keys.md)  
137 -+ [System Hooks](system_hooks.md)  
138 -+ [Groups](groups.md)  
139 -  
140 -  
141 -## Clients  
142 -  
143 -+ [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP  
144 -+ [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby  
145 -+ [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python  
146 -+ [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java  
doc/api/merge_requests.md
@@ -150,6 +150,7 @@ Parameters: @@ -150,6 +150,7 @@ Parameters:
150 + `target_branch` - The target branch 150 + `target_branch` - The target branch
151 + `assignee_id` - Assignee user ID 151 + `assignee_id` - Assignee user ID
152 + `title` - Title of MR 152 + `title` - Title of MR
  153 ++ `state_event` - New state (close|reopen|merge)
153 154
154 ```json 155 ```json
155 156
@@ -210,3 +211,44 @@ Parameters: @@ -210,3 +211,44 @@ Parameters:
210 "note":"text1" 211 "note":"text1"
211 } 212 }
212 ``` 213 ```
  214 +
  215 +
  216 +## Get the comments on a MR
  217 +
  218 +Gets all the comments associated with a merge request.
  219 +
  220 +```
  221 +GET /projects/:id/merge_request/:merge_request_id/comments
  222 +```
  223 +
  224 +Parameters:
  225 +
  226 ++ `id` (required) - The ID of a project
  227 ++ `merge_request_id` (required) - ID of merge request
  228 +
  229 +```json
  230 +[
  231 + {
  232 + "note":"this is the 1st comment on the 2merge merge request",
  233 + "author":{
  234 + "id":11,
  235 + "username":"admin",
  236 + "email":"admin@local.host",
  237 + "name":"Administrator",
  238 + "state":"active",
  239 + "created_at":"2014-03-06T08:17:35.000Z"
  240 + }
  241 + },
  242 + {
  243 + "note":"_Status changed to closed_",
  244 + "author":{
  245 + "id":11,
  246 + "username":"admin",
  247 + "email":"admin@local.host",
  248 + "name":"Administrator",
  249 + "state":"active",
  250 + "created_at":"2014-03-06T08:17:35.000Z"
  251 + }
  252 + }
  253 +]
  254 +```
doc/api/projects.md
@@ -621,3 +621,29 @@ Parameters: @@ -621,3 +621,29 @@ Parameters:
621 + query (required) - A string contained in the project name 621 + query (required) - A string contained in the project name
622 + per_page (optional) - number of projects to return per page 622 + per_page (optional) - number of projects to return per page
623 + page (optional) - the page to retrieve 623 + page (optional) - the page to retrieve
  624 +
  625 +
  626 +## Labels
  627 +
  628 +### List project labels
  629 +
  630 +Get a list of project labels.
  631 +
  632 +```
  633 +GET /projects/:id/labels
  634 +```
  635 +
  636 +Parameters:
  637 +
  638 ++ `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project
  639 +
  640 +```json
  641 +[
  642 + {
  643 + "name":"featute"
  644 + },
  645 + {
  646 + "name": "bug"
  647 + }
  648 +]
  649 +```
doc/api/system_hooks.md
1 -All methods require admin authorization.  
2 -  
3 -The url endpoint of the system hooks can be configured in [the admin area under hooks](/admin/hooks).  
4 -  
5 -## List system hooks  
6 -  
7 -Get list of system hooks  
8 -  
9 -```  
10 -GET /hooks  
11 -```  
12 -  
13 -Parameters:  
14 -  
15 -+ **none**  
16 -  
17 -```json  
18 -[  
19 - {  
20 - "id":3,  
21 - "url":"http://example.com/hook",  
22 - "created_at":"2013-10-02T10:15:31Z"  
23 - }  
24 -]  
25 -```  
26 -  
27 -## Add new system hook hook  
28 -  
29 -```  
30 -POST /hooks  
31 -```  
32 -  
33 -Parameters:  
34 -  
35 -+ `url` (required) - The hook URL  
36 -  
37 -  
38 -## Test system hook  
39 -  
40 -```  
41 -GET /hooks/:id  
42 -```  
43 -  
44 -Parameters:  
45 -  
46 -+ `id` (required) - The ID of hook  
47 -  
48 -```json  
49 -{  
50 - "event_name":"project_create",  
51 - "name":"Ruby",  
52 - "path":"ruby",  
53 - "project_id":1,  
54 - "owner_name":"Someone",  
55 - "owner_email":"example@gitlabhq.com"  
56 -}  
57 -```  
58 -  
59 -## Delete system hook  
60 -  
61 -Deletes a system hook. This is an idempotent API function and returns `200 Ok` even if the hook  
62 -is not available. If the hook is deleted it is also returned as JSON.  
63 -  
64 -```  
65 -DELETE /hooks/:id  
66 -```  
67 -  
68 -Parameters:  
69 -  
70 -+ `id` (required) - The ID of hook 1 +All methods require admin authorization.
  2 +
  3 +The url endpoint of the system hooks can be configured in [the admin area under hooks](/admin/hooks).
  4 +
  5 +## List system hooks
  6 +
  7 +Get list of system hooks
  8 +
  9 +```
  10 +GET /hooks
  11 +```
  12 +
  13 +Parameters:
  14 +
  15 ++ **none**
  16 +
  17 +```json
  18 +[
  19 + {
  20 + "id":3,
  21 + "url":"http://example.com/hook",
  22 + "created_at":"2013-10-02T10:15:31Z"
  23 + }
  24 +]
  25 +```
  26 +
  27 +## Add new system hook hook
  28 +
  29 +```
  30 +POST /hooks
  31 +```
  32 +
  33 +Parameters:
  34 +
  35 ++ `url` (required) - The hook URL
  36 +
  37 +
  38 +## Test system hook
  39 +
  40 +```
  41 +GET /hooks/:id
  42 +```
  43 +
  44 +Parameters:
  45 +
  46 ++ `id` (required) - The ID of hook
  47 +
  48 +```json
  49 +{
  50 + "event_name":"project_create",
  51 + "name":"Ruby",
  52 + "path":"ruby",
  53 + "project_id":1,
  54 + "owner_name":"Someone",
  55 + "owner_email":"example@gitlabhq.com"
  56 +}
  57 +```
  58 +
  59 +## Delete system hook
  60 +
  61 +Deletes a system hook. This is an idempotent API function and returns `200 Ok` even if the hook
  62 +is not available. If the hook is deleted it is also returned as JSON.
  63 +
  64 +```
  65 +DELETE /hooks/:id
  66 +```
  67 +
  68 +Parameters:
  69 +
  70 ++ `id` (required) - The ID of hook
doc/development/README.md 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 ++ [Architecture](architecture.md)
  2 ++ [Shell commands](shell_commands.md)
doc/development/architecture.md
@@ -18,7 +18,7 @@ New releases are generally around the same time as GitLab CE releases with excep @@ -18,7 +18,7 @@ New releases are generally around the same time as GitLab CE releases with excep
18 18
19 # System Layout 19 # System Layout
20 20
21 -When referring to ~git in the picures it means the home directory of the git user which is typically /home/git. 21 +When referring to ~git in the pictures it means the home directory of the git user which is typically /home/git.
22 22
23 GitLab is primarily installed within the `/home/git` user home directory as `git` user. 23 GitLab is primarily installed within the `/home/git` user home directory as `git` user.
24 Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable). 24 Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable).
@@ -28,7 +28,7 @@ To serve repositories over SSH there&#39;s an add-on application called gitlab-shell @@ -28,7 +28,7 @@ To serve repositories over SSH there&#39;s an add-on application called gitlab-shell
28 28
29 ## Components 29 ## Components
30 30
31 -![GitLab Diagram Overview](resources/gitlab_diagram_overview.png "GitLab Diagram Overview") 31 +![GitLab Diagram Overview](resources/gitlab_diagram_overview.png)
32 32
33 A typical install of GitLab will be on Ubuntu Linux or RHEL/CentOS. 33 A typical install of GitLab will be on Ubuntu Linux or RHEL/CentOS.
34 It uses Nginx or Apache as a web front end to proxypass the Unicorn web server. 34 It uses Nginx or Apache as a web front end to proxypass the Unicorn web server.
@@ -180,4 +180,4 @@ bundle exec rake gitlab:check RAILS_ENV=production @@ -180,4 +180,4 @@ bundle exec rake gitlab:check RAILS_ENV=production
180 ``` 180 ```
181 181
182 Note: It is recommended to log into the `git` user using `sudo -i -u git` or `sudo su - git`. 182 Note: It is recommended to log into the `git` user using `sudo -i -u git` or `sudo su - git`.
183 -While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL. 183 -While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL.
  184 +While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL.
184 \ No newline at end of file 185 \ No newline at end of file
doc/development/shell_commands.md
1 # Guidelines for shell commands in the GitLab codebase 1 # Guidelines for shell commands in the GitLab codebase
2 2
  3 +## References
  4 +
  5 +- [Google Ruby Security Reviewer's Guide](https://code.google.com/p/ruby-security/wiki/Guide)
  6 +- [OWASP Command Injection](https://www.owasp.org/index.php/Command_Injection)
  7 +- [Ruby on Rails Security Guide Command Line Injection](http://guides.rubyonrails.org/security.html#command-line-injection)
  8 +
3 ## Use File and FileUtils instead of shell commands 9 ## Use File and FileUtils instead of shell commands
4 10
5 Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it. 11 Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it.
doc/install/README.md 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 ++ [Installation](installation.md)
  2 ++ [Requirements](requirements.md)
  3 ++ [Structure](structure.md)
  4 ++ [Database MySQL](database_mysql.md)
doc/install/database_mysql.md
@@ -6,6 +6,9 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se @@ -6,6 +6,9 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
6 6
7 # Install the database packages 7 # Install the database packages
8 sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev 8 sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
  9 +
  10 + # Ensure you have MySQL version 5.5.14 or later
  11 + mysql --version
9 12
10 # Pick a database root password (can be anything), type it and press enter 13 # Pick a database root password (can be anything), type it and press enter
11 # Retype the database root password and press enter 14 # Retype the database root password and press enter
@@ -23,6 +26,10 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se @@ -23,6 +26,10 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
23 # change $password in the command below to a real password you pick 26 # change $password in the command below to a real password you pick
24 mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '$password'; 27 mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '$password';
25 28
  29 + # Ensure you can use the InnoDB engine which is necessary to support long indexes.
  30 + # If this fails, check your MySQL config files (e.g. `/etc/mysql/*.cnf`, `/etc/mysql/conf.d/*`) for the setting "innodb = off"
  31 + mysql> SET storage_engine=INNODB;
  32 +
26 # Create the GitLab production database 33 # Create the GitLab production database
27 mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; 34 mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
28 35
doc/install/installation.md
@@ -128,7 +128,7 @@ GitLab Shell is an ssh access and repository management software developed speci @@ -128,7 +128,7 @@ GitLab Shell is an ssh access and repository management software developed speci
128 cd /home/git 128 cd /home/git
129 129
130 # Clone gitlab shell 130 # Clone gitlab shell
131 - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.8.0 131 + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.9.1
132 132
133 cd gitlab-shell 133 cd gitlab-shell
134 134
@@ -173,7 +173,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da @@ -173,7 +173,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
173 ## Clone the Source 173 ## Clone the Source
174 174
175 # Clone GitLab repository 175 # Clone GitLab repository
176 - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-6-stable gitlab 176 + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-7-stable gitlab
177 177
178 # Go to gitlab dir 178 # Go to gitlab dir
179 cd /home/git/gitlab 179 cd /home/git/gitlab
doc/integration/external-issue-tracker.md
@@ -5,3 +5,5 @@ GitLab has a great issue tracker but you can also use an external issue tracker @@ -5,3 +5,5 @@ GitLab has a great issue tracker but you can also use an external issue tracker
5 - textual references to PROJECT-1234 in comments, commit messages get turned into HTML links to the corresponding JIRA issue. 5 - textual references to PROJECT-1234 in comments, commit messages get turned into HTML links to the corresponding JIRA issue.
6 6
7 ![jira screenshot](jira-intergration-points.png) 7 ![jira screenshot](jira-intergration-points.png)
  8 +
  9 +You can configure the integration in the gitlab.yml configuration file.
doc/legal/README.md 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 ++ [Corporate contributor license agreement](corporate_contributor_license_agreement.md)
  2 ++ [Individual contributor license agreement](individual_contributor_license_agreement.md)
doc/permissions/permissions.md
@@ -38,7 +38,7 @@ If a user is a GitLab administrator they receive all permissions. @@ -38,7 +38,7 @@ If a user is a GitLab administrator they receive all permissions.
38 |------|-----|--------|---------|------|-----| 38 |------|-----|--------|---------|------|-----|
39 |Browse group|✓|✓|✓|✓|✓| 39 |Browse group|✓|✓|✓|✓|✓|
40 |Edit group|||||✓| 40 |Edit group|||||✓|
41 -|create project in group|||||✓| 41 +|Create project in group|||||✓|
42 |Manage group members|||||✓| 42 |Manage group members|||||✓|
43 |Remove group|||||✓| 43 |Remove group|||||✓|
44 44
doc/raketasks/README.md 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 ++ [Backup restore](backup_restore.md)
  2 ++ [Cleanup](cleanup.md)
  3 ++ [Features](features.md)
  4 ++ [Maintenance](maintenance.md)
  5 ++ [User management](user_management.md)
  6 ++ [Web hooks](web_hooks.md)
doc/release/README.md 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 ++ [Monthly](monthly.md)
  2 ++ [Security](security.md)