Commit ba37f84067039454b709906803f9f2f873c0c5f0

Authored by Job van der Voort
2 parents db7f0738 172ad962

Merge branch 'master' into monthly-revision

Conflicts:
	doc/release/monthly.md
Showing 69 changed files with 705 additions and 300 deletions   Show diff stats
CHANGELOG
  1 +v 6.9.0
  2 + - Store Rails cache data in the Redis `cache:gitlab` namespace
  3 + - Adjust MySQL limits for existing installations
  4 + - Add db index on project_id+iid column. This prevents duplicate on iid (During migration duplicates will be removed)
  5 + - Markdown preview or diff during editing via web editor (Evgeniy Sokovikov)
  6 + - Give the Rails cache its own Redis namespace
  7 + - Add ability to set different ssh host, if different from http/https
  8 + - Fix syntax highlighting for code comments blocks
  9 + - Improve comments loading logic
  10 + - Stop refreshing comments when the tab is hidden
  11 +
1 12 v 6.8.0
2 13 - Ability to at mention users that are participating in issue and merge req. discussion
3 14 - 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)
... ... @@ -17,7 +28,6 @@ v 6.8.0
17 28 - Fix download link for huge MR diffs
18 29 - Expose event and mergerequest timestamps in API
19 30 - Fix emails on push service when only one commit is pushed
20   - - Store Rails cache data in the Redis `cache:gitlab` namespace
21 31  
22 32 v 6.7.3
23 33 - Fix the merge notification email not being sent (Pierre de La Morinerie)
... ...
Gemfile
... ... @@ -71,6 +71,7 @@ gem "carrierwave"
71 71  
72 72 # for aws storage
73 73 gem "fog", "~> 1.14", group: :aws
  74 +gem "unf", group: :aws
74 75  
75 76 # Authorization
76 77 gem "six"
... ... @@ -82,6 +83,9 @@ gem "seed-fu"
82 83 gem "redcarpet", "~> 2.2.2"
83 84 gem "github-markup"
84 85  
  86 +# Diffs
  87 +gem 'diffy', '~> 3.0.3'
  88 +
85 89 # Asciidoc to HTML
86 90 gem "asciidoctor"
87 91  
... ... @@ -157,8 +161,8 @@ gem 'jquery-turbolinks'
157 161  
158 162 gem 'select2-rails'
159 163 gem 'jquery-atwho-rails', "~> 0.3.3"
160   -gem "jquery-rails", "2.1.3"
161   -gem "jquery-ui-rails", "2.0.2"
  164 +gem "jquery-rails"
  165 +gem "jquery-ui-rails"
162 166 gem "raphael-rails", "~> 2.1.2"
163 167 gem 'bootstrap-sass', '~> 3.0'
164 168 gem "font-awesome-rails", '~> 3.2'
... ... @@ -232,4 +236,4 @@ end
232 236  
233 237 group :production do
234 238 gem "gitlab_meta", '6.0'
235   -end
236 239 \ No newline at end of file
  240 +end
... ...
Gemfile.lock
... ... @@ -34,7 +34,6 @@ GEM
34 34 rake (>= 0.8.7)
35 35 arel (4.0.2)
36 36 asciidoctor (0.1.4)
37   - atomic (1.1.16)
38 37 awesome_print (1.2.0)
39 38 axiom-types (0.0.5)
40 39 descendants_tracker (~> 0.0.1)
... ... @@ -101,6 +100,7 @@ GEM
101 100 devise-async (0.8.0)
102 101 devise (>= 2.2, < 3.2)
103 102 diff-lcs (1.2.5)
  103 + diffy (3.0.3)
104 104 docile (1.1.1)
105 105 dotenv (0.9.0)
106 106 email_spec (1.5.0)
... ... @@ -247,15 +247,14 @@ GEM
247 247 rake
248 248 jasmine-core (2.0.0.rc5)
249 249 jquery-atwho-rails (0.3.3)
250   - jquery-rails (2.1.3)
251   - railties (>= 3.1.0, < 5.0)
252   - thor (~> 0.14)
  250 + jquery-rails (3.1.0)
  251 + railties (>= 3.0, < 5.0)
  252 + thor (>= 0.14, < 2.0)
253 253 jquery-turbolinks (2.0.1)
254 254 railties (>= 3.1.0)
255 255 turbolinks
256   - jquery-ui-rails (2.0.2)
257   - jquery-rails
258   - railties (>= 3.1.0)
  256 + jquery-ui-rails (4.2.1)
  257 + railties (>= 3.2.16)
259 258 json (1.8.1)
260 259 jwt (0.1.8)
261 260 multi_json (>= 1.5)
... ... @@ -280,7 +279,7 @@ GEM
280 279 mime-types (1.25.1)
281 280 mini_portile (0.5.3)
282 281 minitest (4.7.5)
283   - multi_json (1.9.2)
  282 + multi_json (1.9.3)
284 283 multi_xml (0.5.5)
285 284 multipart-post (1.2.0)
286 285 mysql2 (0.3.11)
... ... @@ -375,7 +374,7 @@ GEM
375 374 rake (>= 0.8.7)
376 375 thor (>= 0.18.1, < 2.0)
377 376 raindrops (0.12.0)
378   - rake (10.1.1)
  377 + rake (10.3.1)
379 378 raphael-rails (2.1.2)
380 379 rb-fsevent (0.9.3)
381 380 rb-inotify (0.9.2)
... ... @@ -502,9 +501,8 @@ GEM
502 501 daemons (>= 1.0.9)
503 502 eventmachine (>= 1.0.0)
504 503 rack (>= 1.0.0)
505   - thor (0.18.1)
506   - thread_safe (0.3.1)
507   - atomic (>= 1.1.7, < 2)
  504 + thor (0.19.1)
  505 + thread_safe (0.3.3)
508 506 tilt (1.4.1)
509 507 timers (1.1.0)
510 508 tinder (1.9.3)
... ... @@ -531,6 +529,9 @@ GEM
531 529 execjs (>= 0.3.0)
532 530 json (>= 1.8.0)
533 531 underscore-rails (1.4.4)
  532 + unf (0.1.4)
  533 + unf_ext
  534 + unf_ext (0.0.6)
534 535 unicorn (4.6.3)
535 536 kgio (~> 2.6)
536 537 rack
... ... @@ -574,6 +575,7 @@ DEPENDENCIES
574 575 default_value_for (~> 3.0.0)
575 576 devise (= 3.0.4)
576 577 devise-async (= 0.8.0)
  578 + diffy (~> 3.0.3)
577 579 email_spec
578 580 email_validator (~> 1.4.0)
579 581 enumerize
... ... @@ -603,9 +605,9 @@ DEPENDENCIES
603 605 httparty
604 606 jasmine (= 2.0.0.rc5)
605 607 jquery-atwho-rails (~> 0.3.3)
606   - jquery-rails (= 2.1.3)
  608 + jquery-rails
607 609 jquery-turbolinks
608   - jquery-ui-rails (= 2.0.2)
  610 + jquery-ui-rails
609 611 kaminari (~> 0.15.1)
610 612 launchy
611 613 letter_opener
... ... @@ -659,6 +661,7 @@ DEPENDENCIES
659 661 turbolinks
660 662 uglifier
661 663 underscore-rails (~> 1.4.4)
  664 + unf
662 665 unicorn (~> 4.6.3)
663 666 unicorn-worker-killer
664 667 version_sorter
... ...
README.md
... ... @@ -29,11 +29,11 @@
29 29  
30 30 * [GitLab.com](https://www.gitlab.com/) includes information about [subscriptions](https://www.gitlab.com/subscription/), [consultancy](https://www.gitlab.com/consultancy/), the [community](https://www.gitlab.com/community/) and the [hosted GitLab Cloud](https://www.gitlab.com/cloud/).
31 31  
32   -* [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ce/) offers additional features that are useful for larger organizations (100+ users).
  32 +* [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ee/) offers additional features aimed at larger organizations.
33 33  
34 34 * [GitLab CI](https://www.gitlab.com/gitlab-ci/) is a continuous integration (CI) server that is easy to integrate with GitLab.
35 35  
36   -* Unofficial third-party [iPhone app](http://gitlabcontrol.com/) and [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en) for GitLab
  36 +* Unofficial third-party [iPhone app](http://gitlabcontrol.com/)m [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en) and [command line client](https://github.com/drewblessing/gitlab-cli) for GitLab.
37 37  
38 38 ### Requirements
39 39  
... ...
app/assets/images/ui-icons_222222_256x240.png

4.09 KB

app/assets/images/ui-icons_454545_256x240.png

4.09 KB

app/assets/javascripts/dispatcher.js.coffee
... ... @@ -59,7 +59,7 @@ class Dispatcher
59 59  
60 60 initHighlight: ->
61 61 $('.highlight pre code').each (i, e) ->
62   - hljs.highlightBlock(e)
63 62 $(e).html($.map($(e).html().split("\n"), (line, i) ->
64   - "<div class='line' id='LC" + (i + 1) + "'>" + line + "</div>"
  63 + "<span class='line' id='LC" + (i + 1) + "'>" + line + "</span>"
65 64 ).join("\n"))
  65 + hljs.highlightBlock(e)
... ...
app/assets/javascripts/notes.js.coffee
1 1 class Notes
2 2 @interval: null
3 3  
4   - constructor: (notes_url, note_ids) ->
  4 + constructor: (notes_url, note_ids, last_fetched_at) ->
5 5 @notes_url = notes_url
6 6 @notes_url = gon.relative_url_root + @notes_url if gon.relative_url_root?
7 7 @note_ids = note_ids
  8 + @last_fetched_at = last_fetched_at
8 9 @initRefresh()
9 10 @setupMainTargetNoteForm()
10 11 @cleanBinding()
... ... @@ -49,6 +50,9 @@ class Notes
49 50 # hide diff note form
50 51 $(document).on "click", ".js-close-discussion-note-form", @cancelDiscussionForm
51 52  
  53 + # fetch notes when tab becomes visible
  54 + $(document).on "visibilitychange", @visibilityChange
  55 +
52 56 cleanBinding: ->
53 57 $(document).off "ajax:success", ".js-main-target-form"
54 58 $(document).off "ajax:success", ".js-discussion-note-form"
... ... @@ -62,6 +66,7 @@ class Notes
62 66 $(document).off "click", ".js-choose-note-attachment-button"
63 67 $(document).off "click", ".js-discussion-reply-button"
64 68 $(document).off "click", ".js-add-diff-note-button"
  69 + $(document).off "visibilitychange"
65 70  
66 71  
67 72 initRefresh: ->
... ... @@ -71,14 +76,16 @@ class Notes
71 76 , 15000
72 77  
73 78 refresh: ->
74   - @getContent()
  79 + @getContent() unless document.hidden
75 80  
76 81 getContent: ->
77 82 $.ajax
78 83 url: @notes_url
  84 + data: "last_fetched_at=" + @last_fetched_at
79 85 dataType: "json"
80 86 success: (data) =>
81 87 notes = data.notes
  88 + @last_fetched_at = data.last_fetched_at
82 89 $.each notes, (i, note) =>
83 90 @renderNote(note)
84 91  
... ... @@ -450,4 +457,10 @@ class Notes
450 457 filename = $(this).val().replace(/^.*[\\\/]/, "")
451 458 form.find(".js-attachment-filename").text filename
452 459  
  460 + ###
  461 + Called when the tab visibility changes
  462 + ###
  463 + visibilityChange: =>
  464 + @refresh()
  465 +
453 466 @Notes = Notes
... ...
app/assets/stylesheets/generic/files.scss
... ... @@ -26,6 +26,10 @@
26 26 margin-top: -5px;
27 27 }
28 28  
  29 + .left-options {
  30 + margin-top: -3px;
  31 + }
  32 +
29 33 .file_name {
30 34 color: $style_color;
31 35 font-size: 14px;
... ...
app/controllers/admin/projects_controller.rb
... ... @@ -12,6 +12,7 @@ class Admin::ProjectsController &lt; Admin::ApplicationController
12 12 @projects = @projects.with_push if params[:with_push].present?
13 13 @projects = @projects.abandoned if params[:abandoned].present?
14 14 @projects = @projects.search(params[:name]) if params[:name].present?
  15 + @projects = @projects.sort(@sort = params[:sort])
15 16 @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
16 17 end
17 18  
... ...
app/controllers/projects/edit_tree_controller.rb
... ... @@ -26,6 +26,18 @@ class Projects::EditTreeController &lt; Projects::BaseTreeController
26 26 end
27 27 end
28 28  
  29 + def preview
  30 + @content = params[:content]
  31 + #FIXME workaround https://github.com/gitlabhq/gitlabhq/issues/5936
  32 + @content += "\n" if @blob.data.end_with?("\n")
  33 +
  34 + diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
  35 + include_diff_info: true)
  36 + @diff = Gitlab::DiffParser.new(diffy.diff.scan(/.*\n/))
  37 +
  38 + render layout: false
  39 + end
  40 +
29 41 private
30 42  
31 43 def blob
... ...
app/controllers/projects/notes_controller.rb
... ... @@ -5,9 +5,10 @@ class Projects::NotesController &lt; Projects::ApplicationController
5 5 before_filter :authorize_admin_note!, only: [:update, :destroy]
6 6  
7 7 def index
  8 + current_fetched_at = Time.now.to_i
8 9 @notes = NotesFinder.new.execute(project, current_user, params)
9 10  
10   - notes_json = { notes: [] }
  11 + notes_json = { notes: [], last_fetched_at: current_fetched_at }
11 12  
12 13 @notes.each do |note|
13 14 notes_json[:notes] << {
... ...
app/finders/notes_finder.rb
1 1 class NotesFinder
  2 + FETCH_OVERLAP = 5.seconds
  3 +
2 4 def execute(project, current_user, params)
3 5 target_type = params[:target_type]
4 6 target_id = params[:target_id]
  7 + # Default to 0 to remain compatible with old clients
  8 + last_fetched_at = Time.at(params.fetch(:last_fetched_at, 0).to_i)
5 9  
6   - case target_type
  10 + notes = case target_type
7 11 when "commit"
8 12 project.notes.for_commit_id(target_id).not_inline.fresh
9 13 when "issue"
... ... @@ -12,6 +16,11 @@ class NotesFinder
12 16 project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
13 17 when "snippet"
14 18 project.snippets.find(target_id).notes.fresh
  19 + else
  20 + raise 'invalid target_type'
15 21 end
  22 +
  23 + # Use overlapping intervals to avoid worrying about race conditions
  24 + notes.where('updated_at > ?', last_fetched_at - FETCH_OVERLAP)
16 25 end
17 26 end
... ...
app/helpers/commits_helper.rb
... ... @@ -16,9 +16,10 @@ module CommitsHelper
16 16 end
17 17  
18 18 def each_diff_line(diff, index)
19   - Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
20   - yield(full_line, type, line_code, line_new, line_old)
21   - end
  19 + Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
  20 + .each do |full_line, type, line_code, line_new, line_old|
  21 + yield(full_line, type, line_code, line_new, line_old)
  22 + end
22 23 end
23 24  
24 25 def each_diff_line_near(diff, index, expected_line_code)
... ...
app/helpers/projects_helper.rb
... ... @@ -163,7 +163,7 @@ module ProjectsHelper
163 163 end
164 164  
165 165 def repository_size(project = nil)
166   - "#{(project || @project).repository.size} MB"
  166 + "#{(project || @project).repository_size} MB"
167 167 rescue
168 168 # In order to prevent 500 error
169 169 # when application cannot allocate memory
... ...
app/helpers/tree_helper.rb
... ... @@ -91,4 +91,12 @@ module TreeHelper
91 91 def leave_edit_message
92 92 "Leave edit mode?\nAll unsaved changes will be lost."
93 93 end
  94 +
  95 + def editing_preview_title(filename)
  96 + if gitlab_markdown?(filename) || markup?(filename)
  97 + 'Preview'
  98 + else
  99 + 'Diff'
  100 + end
  101 + end
94 102 end
... ...
app/models/milestone.rb
... ... @@ -25,6 +25,7 @@ class Milestone &lt; ActiveRecord::Base
25 25  
26 26 scope :active, -> { with_state(:active) }
27 27 scope :closed, -> { with_state(:closed) }
  28 + scope :of_projects, ->(ids) { where(project_id: ids) }
28 29  
29 30 validates :title, presence: true
30 31 validates :project, presence: true
... ...
app/models/note.rb
... ... @@ -184,9 +184,10 @@ class Note &lt; ActiveRecord::Base
184 184 return @diff_line if @diff_line
185 185  
186 186 if diff
187   - Gitlab::DiffParser.new(diff).each do |full_line, type, line_code, line_new, line_old|
188   - @diff_line = full_line if line_code == self.line_code
189   - end
  187 + Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
  188 + .each do |full_line, type, line_code, line_new, line_old|
  189 + @diff_line = full_line if line_code == self.line_code
  190 + end
190 191 end
191 192  
192 193 @diff_line
... ...
app/models/project.rb
... ... @@ -203,6 +203,7 @@ class Project &lt; ActiveRecord::Base
203 203 when 'oldest' then reorder('projects.created_at ASC')
204 204 when 'recently_updated' then reorder('projects.updated_at DESC')
205 205 when 'last_updated' then reorder('projects.updated_at ASC')
  206 + when 'largest_repository' then reorder('projects.repository_size DESC')
206 207 else reorder("namespaces.path, projects.name ASC")
207 208 end
208 209 end
... ... @@ -562,4 +563,8 @@ class Project &lt; ActiveRecord::Base
562 563 def forked_from?(project)
563 564 forked? && project == forked_from_project
564 565 end
  566 +
  567 + def update_repository_size
  568 + update_attribute(:repository_size, repository.size)
  569 + end
565 570 end
... ...
app/services/git_push_service.rb
... ... @@ -25,6 +25,7 @@ class GitPushService
25 25  
26 26 project.ensure_satellite_exists
27 27 project.repository.expire_cache
  28 + project.update_repository_size
28 29  
29 30 if push_to_existing_branch?(ref, oldrev)
30 31 project.update_merge_requests(oldrev, newrev, ref, @user)
... ...
app/views/admin/broadcast_messages/index.html.haml
... ... @@ -22,12 +22,12 @@
22 22 = f.label :color, "Background Color", class: 'control-label'
23 23 .col-sm-10
24 24 = f.text_field :color, placeholder: "#AA33EE", class: "form-control"
25   - .light Hex values as 3 double digit numbers, starting with a # sign.
  25 + .light 6 character hex values starting with a # sign.
26 26 .form-group.js-toggle-colors-container.hide
27 27 = f.label :font, "Font Color", class: 'control-label'
28 28 .col-sm-10
29 29 = f.text_field :font, placeholder: "#224466", class: "form-control"
30   - .light Hex values as 3 double digit numbers, starting with a # sign.
  30 + .light 6 character hex values starting with a # sign.
31 31 .form-group
32 32 = f.label :starts_at, class: 'control-label'
33 33 .col-sm-10.datetime-controls
... ...
app/views/admin/projects/index.html.haml
... ... @@ -32,6 +32,7 @@
32 32 = visibility_level_icon(level)
33 33 = label
34 34 .form-actions
  35 + = hidden_field_tag :sort, params[:sort]
35 36 = submit_tag "Search", class: "btn submit btn-primary"
36 37 = link_to "Reset", admin_projects_path, class: "btn"
37 38  
... ... @@ -40,6 +41,28 @@
40 41 .title
41 42 Projects (#{@projects.total_count})
42 43 .pull-right
  44 + .dropdown.inline
  45 + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
  46 + %span.light sort:
  47 + - if @sort.present?
  48 + = @sort.humanize
  49 + - else
  50 + Name
  51 + %b.caret
  52 + %ul.dropdown-menu
  53 + %li
  54 + = link_to admin_projects_path(sort: nil) do
  55 + Name
  56 + = link_to admin_projects_path(sort: 'newest') do
  57 + Newest
  58 + = link_to admin_projects_path(sort: 'oldest') do
  59 + Oldest
  60 + = link_to admin_projects_path(sort: 'recently_updated') do
  61 + Recently updated
  62 + = link_to admin_projects_path(sort: 'last_updated') do
  63 + Last updated
  64 + = link_to admin_projects_path(sort: 'largest_repository') do
  65 + Largest repository
43 66 = link_to 'New Project', new_project_path, class: "btn btn-new"
44 67 %ul.well-list
45 68 - @projects.each do |project|
... ...
app/views/layouts/_head_panel.html.haml
... ... @@ -20,6 +20,10 @@
20 20 = link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do
21 21 %i.icon-search
22 22 %li
  23 + = link_to help_path, title: 'Help', class: 'has_bottom_tooltip',
  24 + 'data-original-title' => 'Help' do
  25 + %i.icon-question-sign
  26 + %li
23 27 = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do
24 28 %i.icon-globe
25 29 %li
... ...
app/views/layouts/devise.html.haml
... ... @@ -10,7 +10,7 @@
10 10 %p.light
11 11 GitLab is open source software to collaborate on code.
12 12 %br
13   - #{link_to "Sign in", new_user_session_path} or browse for #{link_to "public projects", public_projects_path}.
  13 + Sign in or browse for #{link_to "public projects", public_projects_path}.
14 14 %hr
15 15 .container
16 16 .content
... ...
app/views/notify/repository_push_email.text.haml
... ... @@ -17,7 +17,7 @@ Changes:
17 17 - else
18 18 = diff.new_path || diff.old_path
19 19 \=====================================
20   - = diff.diff
  20 + != diff.diff
21 21 \
22 22 - if @compare.timeout
23 23 Huge diff. To prevent performance issues it was hidden
... ...
app/views/projects/edit_tree/_diff.html.haml 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +%table.text-file
  2 + - each_diff_line(diff, 1) do |line, type, line_code, line_new, line_old, raw_line|
  3 + %tr.line_holder{ id: line_code, class: "#{type}" }
  4 + - if type == "match"
  5 + %td.old_line= "..."
  6 + %td.new_line= "..."
  7 + %td.line_content.matched= line
  8 + - else
  9 + %td.old_line
  10 + = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
  11 + %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
  12 + %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
  13 +
... ...
app/views/projects/edit_tree/preview.html.haml 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +.diff-file
  2 + .diff-content
  3 + - if gitlab_markdown?(@blob.name)
  4 + .file-content.wiki
  5 + = preserve do
  6 + = markdown(@content)
  7 + - elsif markup?(@blob.name)
  8 + .file-content.wiki
  9 + = raw GitHub::Markup.render(@blob.name, @content)
  10 + - else
  11 + .file-content.code
  12 + - unless @diff.empty?
  13 + %table.text-file
  14 + - @diff.each do |line, type, line_code, line_new, line_old, raw_line|
  15 + %tr.line_holder{ id: line_code, class: "#{type}" }
  16 + - if type == "match"
  17 + %td.old_line= "..."
  18 + %td.new_line= "..."
  19 + %td.line_content.matched= line
  20 + - else
  21 + %td.old_line
  22 + = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
  23 + %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
  24 + %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
  25 + - else
  26 + %p.nothing_here_message No changes.
... ...
app/views/projects/edit_tree/show.html.haml
1 1 %h3.page-title Edit mode
2 2 .file-editor
3 3 = form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do
4   - .file-holder
  4 + .file-holder.file
5 5 .file-title
  6 + .btn-group.js-edit-mode.left-options
  7 + = link_to 'Edit', '#editor', class: 'active hover btn btn-tiny'
  8 + = link_to editing_preview_title(@blob.name), '#preview', class: 'btn btn-tiny', 'data-preview-url' => preview_project_edit_tree_path(@project, @id)
6 9 %i.icon-file
7 10 %span.file_name
8 11 = @path
... ... @@ -13,7 +16,8 @@
13 16 .btn-group.tree-btn-group
14 17 = link_to "Cancel", @after_edit_path, class: "btn btn-tiny btn-cancel", data: { confirm: leave_edit_message }
15 18 .file-content.code
16   - %pre#editor= @blob.data
  19 + %pre.js-edit-mode-pane#editor= @blob.data
  20 + .js-edit-mode-pane#preview.hide
17 21  
18 22 .form-group.commit_message-group
19 23 = label_tag 'commit_message', class: "control-label" do
... ... @@ -45,3 +49,28 @@
45 49 $("#file-content").val(editor.getValue());
46 50 $(".file-editor form").submit();
47 51 });
  52 +
  53 + var editModePanes = $('.js-edit-mode-pane'),
  54 + editModeLinks = $('.js-edit-mode a');
  55 +
  56 + editModeLinks.click(function(event) {
  57 + event.preventDefault();
  58 +
  59 + var currentLink = $(this),
  60 + paneId = currentLink.attr('href'),
  61 + currentPane = editModePanes.filter(paneId);
  62 +
  63 + editModeLinks.removeClass('active hover');
  64 + currentLink.addClass('active hover');
  65 + editModePanes.hide();
  66 +
  67 + if (paneId == '#preview') {
  68 + $.post(currentLink.data('preview-url'), { content: editor.getValue() }, function(response) {
  69 + currentPane.empty().append(response);
  70 + currentPane.fadeIn(200);
  71 + })
  72 + } else {
  73 + currentPane.fadeIn(200);
  74 + editor.focus()
  75 + }
  76 + })
... ...
app/views/projects/merge_requests/show/_mr_ci.html.haml
... ... @@ -26,4 +26,4 @@
26 26  
27 27 .ci_widget.ci-error{style: "display:none"}
28 28 %i.icon-remove
29   - %strong Cannot connect to CI server. Please check your setting
  29 + %strong Cannot connect to the CI server. Please check your settings and try again.
... ...
app/views/projects/notes/_notes_with_form.html.haml
... ... @@ -7,4 +7,4 @@
7 7 = render "projects/notes/form"
8 8  
9 9 :javascript
10   - new Notes("#{project_notes_path(target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json})
  10 + new Notes("#{project_notes_path(target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json}, #{Time.now.to_i})
... ...
config/gitlab.yml.example
... ... @@ -107,7 +107,7 @@ production: &amp;base
107 107 # ## :id - Issue id (from commit messages)
108 108 # issues_url: "http://redmine.sample/issues/:id"
109 109 #
110   - # ## If not nil, linkis to creating new issues will be replaced with this
  110 + # ## If not nil, links to creating new issues will be replaced with this
111 111 # ## Use placeholders:
112 112 # ## :project_id - GitLab project identifier
113 113 # ## :issues_tracker_id - Project Name or Id in external issue tracker
... ...
config/initializers/carrierwave.rb
... ... @@ -18,4 +18,16 @@ if File.exists?(aws_file)
18 18 config.fog_authenticated_url_expiration = 1 << 29 # optional time (in seconds) that authenticated urls will be valid.
19 19 # when fog_public is false and provider is AWS or Google, defaults to 600
20 20 end
  21 +
  22 + # Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders
  23 + if Rails.env.test?
  24 + Fog.mock!
  25 + connection = ::Fog::Storage.new(
  26 + :aws_access_key_id => AWS_CONFIG['access_key_id'],
  27 + :aws_secret_access_key => AWS_CONFIG['secret_access_key'],
  28 + :provider => 'AWS',
  29 + :region => AWS_CONFIG['region']
  30 + )
  31 + connection.directories.create(:key => AWS_CONFIG['bucket'])
  32 + end
21 33 end
... ...
config/routes.rb
... ... @@ -187,7 +187,9 @@ Gitlab::Application.routes.draw do
187 187 resources :blob, only: [:show, :destroy], constraints: {id: /.+/}
188 188 resources :raw, only: [:show], constraints: {id: /.+/}
189 189 resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
190   - resources :edit_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'edit'
  190 + resources :edit_tree, only: [:show, :update], constraints: { id: /.+/ }, path: 'edit' do
  191 + post :preview, on: :member
  192 + end
191 193 resources :new_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'new'
192 194 resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
193 195 resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
... ...
db/migrate/20140415124820_limits_to_mysql.rb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +require_relative 'limits_to_mysql'
... ...
db/migrate/20140416074002_add_index_on_iid.rb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +class AddIndexOnIid < ActiveRecord::Migration
  2 + def change
  3 + RemoveDuplicateIid.clean(Issue)
  4 + RemoveDuplicateIid.clean(MergeRequest, 'target_project_id')
  5 + RemoveDuplicateIid.clean(Milestone)
  6 +
  7 + add_index :issues, [:project_id, :iid], unique: true
  8 + add_index :merge_requests, [:target_project_id, :iid], unique: true
  9 + add_index :milestones, [:project_id, :iid], unique: true
  10 + end
  11 +end
  12 +
  13 +class RemoveDuplicateIid
  14 + def self.clean(klass, project_field = 'project_id')
  15 + duplicates = klass.find_by_sql("SELECT iid, #{project_field} FROM #{klass.table_name} GROUP BY #{project_field}, iid HAVING COUNT(*) > 1")
  16 +
  17 + duplicates.each do |duplicate|
  18 + project_id = duplicate.send(project_field)
  19 + iid = duplicate.iid
  20 + items = klass.of_projects(project_id).where(iid: iid)
  21 +
  22 + if items.size > 1
  23 + puts "Remove #{klass.name} duplicates for iid: #{iid} and project_id: #{project_id}"
  24 + items.shift
  25 + items.each do |item|
  26 + item.destroy
  27 + puts '.'
  28 + end
  29 + end
  30 + end
  31 + end
  32 +end
... ...
db/migrate/20140428105831_add_notes_index_updated_at.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class AddNotesIndexUpdatedAt < ActiveRecord::Migration
  2 + def change
  3 + add_index :notes, :updated_at
  4 + end
  5 +end
... ...
db/migrate/20140502115131_add_repo_size_to_db.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class AddRepoSizeToDb < ActiveRecord::Migration
  2 + def change
  3 + add_column :projects, :repository_size, :float, default: 0
  4 + end
  5 +end
... ...
db/migrate/20140502125220_migrate_repo_size.rb 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +class MigrateRepoSize < ActiveRecord::Migration
  2 + def up
  3 + Project.reset_column_information
  4 + Project.find_each(batch_size: 500) do |project|
  5 + begin
  6 + if project.empty_repo?
  7 + print '-'
  8 + else
  9 + project.update_repository_size
  10 + print '.'
  11 + end
  12 + rescue
  13 + print 'F'
  14 + end
  15 + end
  16 + puts 'Done'
  17 + end
  18 +
  19 + def down
  20 + end
  21 +end
... ...
db/migrate/limits_to_mysql.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +class LimitsToMysql < ActiveRecord::Migration
  2 + def up
  3 + return unless ActiveRecord::Base.configurations[Rails.env]['adapter'] =~ /^mysql/
  4 +
  5 + change_column :merge_request_diffs, :st_commits, :text, limit: 2147483647
  6 + change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647
  7 + change_column :snippets, :content, :text, limit: 2147483647
  8 + change_column :notes, :st_diff, :text, limit: 2147483647
  9 + end
  10 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 12 # It's strongly recommended that you check this file into your version control system.
13 13  
14   -ActiveRecord::Schema.define(version: 20140416185734) do
  14 +ActiveRecord::Schema.define(version: 20140502125220) do
15 15  
16 16 # These are extensions that must be enabled in order to support this database
17 17 enable_extension "plpgsql"
... ... @@ -93,6 +93,7 @@ ActiveRecord::Schema.define(version: 20140416185734) do
93 93 add_index "issues", ["author_id"], name: "index_issues_on_author_id", using: :btree
94 94 add_index "issues", ["created_at"], name: "index_issues_on_created_at", using: :btree
95 95 add_index "issues", ["milestone_id"], name: "index_issues_on_milestone_id", using: :btree
  96 + add_index "issues", ["project_id", "iid"], name: "index_issues_on_project_id_and_iid", unique: true, using: :btree
96 97 add_index "issues", ["project_id"], name: "index_issues_on_project_id", using: :btree
97 98 add_index "issues", ["title"], name: "index_issues_on_title", using: :btree
98 99  
... ... @@ -143,6 +144,7 @@ ActiveRecord::Schema.define(version: 20140416185734) do
143 144 add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree
144 145 add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_source_project_id", using: :btree
145 146 add_index "merge_requests", ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree
  147 + add_index "merge_requests", ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid", unique: true, using: :btree
146 148 add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree
147 149  
148 150 create_table "milestones", force: true do |t|
... ... @@ -157,6 +159,7 @@ ActiveRecord::Schema.define(version: 20140416185734) do
157 159 end
158 160  
159 161 add_index "milestones", ["due_date"], name: "index_milestones_on_due_date", using: :btree
  162 + add_index "milestones", ["project_id", "iid"], name: "index_milestones_on_project_id_and_iid", unique: true, using: :btree
160 163 add_index "milestones", ["project_id"], name: "index_milestones_on_project_id", using: :btree
161 164  
162 165 create_table "namespaces", force: true do |t|
... ... @@ -197,6 +200,7 @@ ActiveRecord::Schema.define(version: 20140416185734) do
197 200 add_index "notes", ["noteable_type"], name: "index_notes_on_noteable_type", using: :btree
198 201 add_index "notes", ["project_id", "noteable_type"], name: "index_notes_on_project_id_and_noteable_type", using: :btree
199 202 add_index "notes", ["project_id"], name: "index_notes_on_project_id", using: :btree
  203 + add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree
200 204  
201 205 create_table "projects", force: true do |t|
202 206 t.string "name"
... ... @@ -218,6 +222,7 @@ ActiveRecord::Schema.define(version: 20140416185734) do
218 222 t.integer "visibility_level", default: 0, null: false
219 223 t.boolean "archived", default: false, null: false
220 224 t.string "import_status"
  225 + t.float "repository_size", default: 0.0
221 226 end
222 227  
223 228 add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree
... ... @@ -319,7 +324,6 @@ ActiveRecord::Schema.define(version: 20140416185734) do
319 324 t.integer "notification_level", default: 1, null: false
320 325 t.datetime "password_expires_at"
321 326 t.integer "created_by_id"
322   - t.datetime "last_credential_check_at"
323 327 t.string "avatar"
324 328 t.string "confirmation_token"
325 329 t.datetime "confirmed_at"
... ... @@ -327,6 +331,7 @@ ActiveRecord::Schema.define(version: 20140416185734) do
327 331 t.string "unconfirmed_email"
328 332 t.boolean "hide_no_ssh_key", default: false
329 333 t.string "website_url", default: "", null: false
  334 + t.datetime "last_credential_check_at"
330 335 end
331 336  
332 337 add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
... ...
doc/api/README.md
... ... @@ -13,7 +13,7 @@
13 13 + [Merge Requests](merge_requests.md)
14 14 + [Issues](issues.md)
15 15 + [Milestones](milestones.md)
16   -+ [Notes](notes.md)
  16 ++ [Notes](notes.md) (comments)
17 17 + [Deploy Keys](deploy_keys.md)
18 18 + [System Hooks](system_hooks.md)
19 19 + [Groups](groups.md)
... ... @@ -24,6 +24,7 @@
24 24 + [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby
25 25 + [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python
26 26 + [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java
  27 ++ [node-gitlab](https://github.com/moul/node-gitlab) - Node.js
27 28  
28 29 ## Introduction
29 30  
... ...
doc/api/issues.md
... ... @@ -193,3 +193,7 @@ Parameters:
193 193  
194 194 + `id` (required) - The project ID
195 195 + `issue_id` (required) - The ID of the issue
  196 +
  197 +## Comments on issues
  198 +
  199 +Comments are done via the notes resource.
... ...
doc/api/merge_requests.md
... ... @@ -258,3 +258,7 @@ Parameters:
258 258 }
259 259 ]
260 260 ```
  261 +
  262 +## Comments on issues
  263 +
  264 +Comments are done via the notes resource.
... ...
doc/api/notes.md
  1 +Notes can be wall notes or comments on snippets, issues or merge requests.
  2 +
1 3 ## Wall
2 4  
3 5 ### List project wall notes
... ...
doc/development/README.md
1   -+ [Architecture](architecture.md)
2   -+ [Shell commands](shell_commands.md)
  1 +## Development
  2 +
  3 ++ [Architecture](architecture.md) of GitLab
  4 ++ [Shell commands](shell_commands.md) in the GitLab codebase
  5 ++ [Rake tasks](rake_tasks.md) for development
... ...
doc/development/rake_tasks.md 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +# Rake tasks for developers
  2 +
  3 +## Setup db with developer seeds:
  4 +
  5 +Note that if your db user does not have advanced privilegies you must create db manually before run this command
  6 +
  7 +```
  8 +bundle exec rake setup
  9 +```
  10 +
  11 +## Run tests
  12 +
  13 +This runs all test suite present in GitLab
  14 +
  15 +```
  16 +bundle exec rake test
  17 +```
  18 +
  19 +## Generate searchable docs for source code
  20 +
  21 +You can find results under `doc/code` directory
  22 +
  23 +```
  24 +bundle exec rake gitlab:generate_docs
  25 +```
... ...
doc/install/installation.md
... ... @@ -27,10 +27,9 @@ The GitLab installation consists of setting up the following components:
27 27 1. Packages / Dependencies
28 28 2. Ruby
29 29 3. System Users
30   -4. GitLab shell
31   -5. Database
32   -6. GitLab
33   -7. Nginx
  30 +4. Database
  31 +5. GitLab
  32 +6. Nginx
34 33  
35 34  
36 35 # 1. Packages / Dependencies
... ... @@ -119,30 +118,7 @@ Create a `git` user for Gitlab:
119 118  
120 119 sudo adduser --disabled-login --gecos 'GitLab' git
121 120  
122   -
123   -# 4. GitLab shell
124   -
125   -GitLab Shell is an ssh access and repository management software developed specially for GitLab.
126   -
127   - # Go to home directory
128   - cd /home/git
129   -
130   - # Clone gitlab shell
131   - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.9.3
132   -
133   - cd gitlab-shell
134   -
135   - sudo -u git -H cp config.yml.example config.yml
136   -
137   - # Edit config and replace gitlab_url
138   - # with something like 'http://domain.com/'
139   - sudo -u git -H editor config.yml
140   -
141   - # Do setup
142   - sudo -u git -H ./bin/install
143   -
144   -
145   -# 5. Database
  121 +# 4. Database
146 122  
147 123 We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](database_mysql.md).
148 124  
... ... @@ -165,7 +141,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
165 141 sudo -u git -H psql -d gitlabhq_production
166 142  
167 143  
168   -# 6. GitLab
  144 +# 5. GitLab
169 145  
170 146 # We'll install GitLab into home directory of the user "git"
171 147 cd /home/git
... ... @@ -276,6 +252,18 @@ that were [fixed](https://github.com/bundler/bundler/pull/2817) in 1.5.2.
276 252  
277 253 # When done you see 'Administrator account created:'
278 254  
  255 +## Install GitLab shell
  256 +
  257 +GitLab Shell is an ssh access and repository management software developed specially for GitLab.
  258 +
  259 + # Go to the Gitlab installation folder:
  260 + cd /home/git/gitlab
  261 +
  262 + # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
  263 + sudo -u git -H bundle exec rake gitlab:shell:install[v1.9.3] REDIS_URL=redis://localhost:6379
  264 +
  265 + # By default, the gitlab-shell config is generated from your main gitlab config. You can review (and modify) it as follows:
  266 + sudo -u git -H editor /home/git/gitlab-shell/config.yml
279 267  
280 268 ## Install Init Script
281 269  
... ... @@ -313,7 +301,13 @@ Check if GitLab and its environment are configured correctly:
313 301 # or
314 302 sudo /etc/init.d/gitlab restart
315 303  
316   -# 7. Nginx
  304 +
  305 +## Compile assets
  306 +
  307 + sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
  308 +
  309 +
  310 +# 6. Nginx
317 311  
318 312 **Note:**
319 313 Nginx is the officially supported web server for GitLab. If you cannot or do not want to use Nginx as your web server, have a look at the
... ...
doc/integration/README.md
... ... @@ -6,3 +6,4 @@ See the documentation below for details on how to configure these services.
6 6 + [External issue tracker](external-issue-tracker.md) Redmine, JIRA, etc.
7 7 + [LDAP](ldap.md) Set up sign in via LDAP
8 8 + [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, and Google via OAuth.
  9 ++ [Slack](slack.md) Integrate with the Slack chat service
... ...
doc/permissions/permissions.md
... ... @@ -27,7 +27,7 @@ If a user is a GitLab administrator they receive all permissions.
27 27 |Remove protected branches| |||✓|✓|
28 28 |Edit project| |||✓|✓|
29 29 |Add Deploy Keys to project| |||✓|✓|
30   -|Confiure Project Hooks| |||✓|✓|
  30 +|Configure Project Hooks| |||✓|✓|
31 31 |Switch visibility level| ||||✓|
32 32 |Transfer project to another namespace| ||||✓|
33 33 |Remove project| ||||✓|
... ...
doc/raketasks/README.md
1 1 + [Backup restore](backup_restore.md)
2 2 + [Cleanup](cleanup.md)
3 3 + [Features](features.md)
4   -+ [Maintenance](maintenance.md)
  4 ++ [Maintenance](maintenance.md) and self-checks
5 5 + [User management](user_management.md)
6 6 + [Web hooks](web_hooks.md)
  7 ++ [Import](import.md) of git repositories in bulk
... ...
doc/raketasks/import.md 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +### Import bare repositories into GitLab project instance
  2 +
  3 +Notes:
  4 +
  5 +* project owner will be a first admin
  6 +* groups will be created as needed
  7 +* group owner will be the first admin
  8 +* existing projects will be skipped
  9 +
  10 +How to use:
  11 +
  12 +1. copy your bare repos under git repos_path (see `config/gitlab.yml` gitlab_shell -> repos_path)
  13 +2. run the command below
  14 +
  15 +```
  16 +bundle exec rake gitlab:import:repos RAILS_ENV=production
  17 +```
  18 +
  19 +Example output:
  20 +
  21 +```
  22 +Processing abcd.git
  23 + * Created abcd (abcd.git)
  24 +Processing group/xyz.git
  25 + * Created Group group (2)
  26 + * Created xyz (group/xyz.git)
  27 +[...]
  28 +```
... ...
doc/raketasks/maintenance.md
... ... @@ -110,32 +110,3 @@ If necessary, remove the `tmp/repo_satellites` directory and rerun the command b
110 110 ```
111 111 bundle exec rake gitlab:satellites:create RAILS_ENV=production
112 112 ```
113   -
114   -### Import bare repositories into GitLab project instance
115   -
116   -Notes:
117   -
118   -* project owner will be a first admin
119   -* groups will be created as needed
120   -* group owner will be the first admin
121   -* existing projects will be skipped
122   -
123   -How to use:
124   -
125   -1. copy your bare repos under git repos_path (see `config/gitlab.yml` gitlab_shell -> repos_path)
126   -2. run the command below
127   -
128   -```
129   -bundle exec rake gitlab:import:repos RAILS_ENV=production
130   -```
131   -
132   -Example output:
133   -
134   -```
135   -Processing abcd.git
136   - * Created abcd (abcd.git)
137   -Processing group/xyz.git
138   - * Created Group group (2)
139   - * Created xyz (group/xyz.git)
140   -[...]
141   -```
... ...
doc/release/monthly.md
... ... @@ -122,7 +122,6 @@ It is important to do this as soon as possible, so we can catch any errors befor
122 122  
123 123 After making the release branch new commits are cherry-picked from master. When the release gets closer we get more selective what is cherry-picked. The days of the month are approximately as follows:
124 124  
125   -
126 125 ### **1. Create x-x-stable branch and push to the repositories**
127 126  
128 127 ```
... ...
doc/update/6.0-to-6.7.md
... ... @@ -1,148 +0,0 @@
1   -# From 6.0 to 6.7
2   -
3   -# In 6.1 we remove a lot of deprecated code.
4   -# You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run.
5   -
6   -### Deprecations
7   -
8   -#### Global issue numbers
9   -
10   -As of 6.1 issue numbers are project specific. This means all issues are renumbered and get a new number in their url. If you use an old issue number url and the issue number does not exist yet you are redirected to the new one. This conversion does not trigger if the old number already exists for this project, this is unlikely but will happen with old issues and large projects.
11   -
12   -### 0. Backup
13   -
14   -It's useful to make a backup just in case things go south:
15   -(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
16   -
17   -```bash
18   -cd /home/git/gitlab
19   -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
20   -```
21   -
22   -### 1. Stop server
23   -
24   - sudo service gitlab stop
25   -
26   -### 2. Get latest code
27   -
28   -```bash
29   -cd /home/git/gitlab
30   -sudo -u git -H git fetch --all
31   -```
32   -
33   -For Gitlab Community Edition:
34   -
35   -```bash
36   -sudo -u git -H git checkout 6-7-stable
37   -```
38   -
39   -OR
40   -
41   -For GitLab Enterprise Edition:
42   -
43   -```bash
44   -sudo -u git -H git checkout 6-7-stable-ee
45   -```
46   -
47   -
48   -### 3. Install additional packages
49   -
50   -```bash
51   -# Add support for lograte for better log file handling
52   -sudo apt-get install logrotate
53   -```
54   -
55   -### 4. Update gitlab-shell
56   -
57   -```bash
58   -cd /home/git/gitlab-shell
59   -sudo -u git -H git fetch
60   -sudo -u git -H git checkout v1.9.1 # Addresses multiple critical security vulnerabilities
61   -```
62   -
63   -### 5. Install libs, migrations, etc.
64   -
65   -```bash
66   -cd /home/git/gitlab
67   -
68   -# MySQL installations (note: the line below states '--without ... postgres')
69   -sudo -u git -H bundle install --without development test postgres --deployment
70   -
71   -# PostgreSQL installations (note: the line below states '--without ... mysql')
72   -sudo -u git -H bundle install --without development test mysql --deployment
73   -
74   -
75   -# Run database migrations
76   -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
77   -
78   -# Enable internal issue IDs (introduced in GitLab 6.1)
79   -sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production
80   -
81   -# Clean up assets and cache
82   -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
83   -
84   -# Close access to gitlab-satellites for others
85   -sudo chmod u+rwx,g+rx,o-rwx /home/git/gitlab-satellites
86   -```
87   -
88   -### 6. Update config files
89   -
90   -TIP: to see what changed in gitlab.yml.example in this release use next command:
91   -
92   -```
93   -git diff 6-0-stable:config/gitlab.yml.example 6-7-stable:config/gitlab.yml.example
94   -```
95   -
96   -* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/gitlab.yml.example but with your settings.
97   -* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/unicorn.rb.example but with your settings.
98   -* Copy rack attack middleware config
99   -
100   -```bash
101   -sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb
102   -```
103   -
104   -* Set up logrotate
105   -
106   -```bash
107   -sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
108   -```
109   -
110   -### 7. Update Init script
111   -
112   -```bash
113   -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
114   -```
115   -
116   -### 8. Start application
117   -
118   - sudo service gitlab start
119   - sudo service nginx restart
120   -
121   -### 9. Check application status
122   -
123   -Check if GitLab and its environment are configured correctly:
124   -
125   - cd /home/git/gitlab
126   - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
127   -
128   -To make sure you didn't miss anything run a more thorough check with:
129   -
130   - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
131   -
132   -If all items are green, then congratulations upgrade complete!
133   -
134   -## Things went south? Revert to previous version (6.0)
135   -
136   -### 1. Revert the code to the previous version
137   -Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the database migration
138   -(The backup is already migrated to the previous version)
139   -
140   -### 2. Restore from the backup:
141   -
142   -```bash
143   -cd /home/git/gitlab
144   -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
145   -```
146   -
147   -## Login issues after upgrade?
148   -If running in https mode, be sure to read [Can't Verify csrf token authenticity](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide#cant-verify-csrf-token-authenticitycant-get-past-login-pageredirected-to-login-page)
doc/update/6.0-to-6.8.md 0 → 100644
... ... @@ -0,0 +1,149 @@
  1 +# From 6.0 to 6.8
  2 +
  3 +# In 6.1 we remove a lot of deprecated code.
  4 +# You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run.
  5 +
  6 +### Deprecations
  7 +
  8 +#### Global issue numbers
  9 +
  10 +As of 6.1 issue numbers are project specific. This means all issues are renumbered and get a new number in their url. If you use an old issue number url and the issue number does not exist yet you are redirected to the new one. This conversion does not trigger if the old number already exists for this project, this is unlikely but will happen with old issues and large projects.
  11 +
  12 +### 0. Backup
  13 +
  14 +It's useful to make a backup just in case things go south:
  15 +(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
  16 +
  17 +```bash
  18 +cd /home/git/gitlab
  19 +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
  20 +```
  21 +
  22 +### 1. Stop server
  23 +
  24 + sudo service gitlab stop
  25 +
  26 +### 2. Get latest code
  27 +
  28 +```bash
  29 +cd /home/git/gitlab
  30 +sudo -u git -H git fetch --all
  31 +```
  32 +
  33 +For Gitlab Community Edition:
  34 +
  35 +```bash
  36 +sudo -u git -H git checkout 6-8-stable
  37 +```
  38 +
  39 +OR
  40 +
  41 +For GitLab Enterprise Edition:
  42 +
  43 +```bash
  44 +sudo -u git -H git checkout 6-8-stable-ee
  45 +```
  46 +
  47 +
  48 +### 3. Install additional packages
  49 +
  50 +```bash
  51 +# Add support for lograte for better log file handling
  52 +sudo apt-get install logrotate
  53 +```
  54 +
  55 +### 4. Update gitlab-shell
  56 +
  57 +```bash
  58 +cd /home/git/gitlab-shell
  59 +sudo -u git -H git fetch
  60 +sudo -u git -H git checkout v1.9.3 # Addresses multiple critical security vulnerabilities
  61 +```
  62 +
  63 +### 5. Install libs, migrations, etc.
  64 +
  65 +```bash
  66 +cd /home/git/gitlab
  67 +
  68 +# MySQL installations (note: the line below states '--without ... postgres')
  69 +sudo -u git -H bundle install --without development test postgres --deployment
  70 +
  71 +# PostgreSQL installations (note: the line below states '--without ... mysql')
  72 +sudo -u git -H bundle install --without development test mysql --deployment
  73 +
  74 +
  75 +# Run database migrations
  76 +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
  77 +
  78 +# Enable internal issue IDs (introduced in GitLab 6.1)
  79 +sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production
  80 +
  81 +# Clean up assets and cache
  82 +sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
  83 +
  84 +# Close access to gitlab-satellites for others
  85 +sudo chmod u+rwx,g+rx,o-rwx /home/git/gitlab-satellites
  86 +```
  87 +
  88 +### 6. Update config files
  89 +
  90 +TIP: to see what changed in gitlab.yml.example in this release use next command:
  91 +
  92 +```
  93 +git diff 6-0-stable:config/gitlab.yml.example 6-8-stable:config/gitlab.yml.example
  94 +```
  95 +
  96 +* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-8-stable/config/gitlab.yml.example but with your settings.
  97 +* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-8-stable/config/unicorn.rb.example but with your settings.
  98 +* Make `/etc/nginx/sites-available/nginx` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-8-stable/lib/support/nginx/gitlab but with your settings.
  99 +* Copy rack attack middleware config
  100 +
  101 +```bash
  102 +sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb
  103 +```
  104 +
  105 +* Set up logrotate
  106 +
  107 +```bash
  108 +sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
  109 +```
  110 +
  111 +### 7. Update Init script
  112 +
  113 +```bash
  114 +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
  115 +```
  116 +
  117 +### 8. Start application
  118 +
  119 + sudo service gitlab start
  120 + sudo service nginx restart
  121 +
  122 +### 9. Check application status
  123 +
  124 +Check if GitLab and its environment are configured correctly:
  125 +
  126 + cd /home/git/gitlab
  127 + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
  128 +
  129 +To make sure you didn't miss anything run a more thorough check with:
  130 +
  131 + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
  132 +
  133 +If all items are green, then congratulations upgrade complete!
  134 +
  135 +## Things went south? Revert to previous version (6.0)
  136 +
  137 +### 1. Revert the code to the previous version
  138 +Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the database migration
  139 +(The backup is already migrated to the previous version)
  140 +
  141 +### 2. Restore from the backup:
  142 +
  143 +```bash
  144 +cd /home/git/gitlab
  145 +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
  146 +```
  147 +
  148 +## Login issues after upgrade?
  149 +If running in https mode, be sure to read [Can't Verify csrf token authenticity](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide#cant-verify-csrf-token-authenticitycant-get-past-login-pageredirected-to-login-page)
... ...
doc/update/6.7-to-6.8.md
... ... @@ -62,6 +62,7 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS
62 62  
63 63 # Update init.d script
64 64 sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
  65 +sudo chmod +x /etc/init.d/gitlab
65 66  
66 67 # Update the logrotate configuration (keep logs for 90 days instead of 52 weeks)
67 68 sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
... ... @@ -92,19 +93,12 @@ If you are using HTTPS, disable gzip as in [this commit](https://gitlab.com/gitl
92 93  
93 94 To improve performance, enable gzip asset compression as seen [in this commit](https://gitlab.com/gitlab-org/gitlab-ce/commit/8af94ed75505f0253823b9b2d44320fecea5b5fb).
94 95  
95   -### 6. Update Init script
96   -
97   -```bash
98   -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
99   -sudo chmod +x /etc/init.d/gitlab
100   -```
101   -
102   -### 7. Start application
  96 +### 6. Start application
103 97  
104 98 sudo service gitlab start
105 99 sudo service nginx restart
106 100  
107   -### 8. Check application status
  101 +### 7. Check application status
108 102  
109 103 Check if GitLab and its environment are configured correctly:
110 104  
... ...
doc/web_hooks/web_hooks.md
... ... @@ -2,16 +2,16 @@ Project web hooks allow you to trigger an URL if new code is pushed or a new iss
2 2  
3 3 ---
4 4  
5   -You can configure web hook to listen for specific events like pushes, issues, merge requests.
6   -GitLab will send POST request with data to web hook URL.
7   -Web Hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.
  5 +You can configure web hooks to listen for specific events like pushes, issues or merge requests.
  6 +GitLab will send a POST request with data to the web hook URL.
  7 +Web hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.
8 8 If you send a web hook to an SSL endpoint [the certificate will not be verified](https://gitlab.com/gitlab-org/gitlab-ce/blob/ccd617e58ea71c42b6b073e692447d0fe3c00be6/app/models/web_hook.rb#L35) since many people use self-signed certificates.
9 9  
10 10 ---
11 11  
12 12 #### Push events
13 13  
14   -Triggered when you push to the repository except pushing tags.
  14 +Triggered when you push to the repository except when pushing tags.
15 15  
16 16 **Request body:**
17 17  
... ... @@ -84,7 +84,7 @@ Triggered when a new issue is created or an existing issue was updated/closed/re
84 84  
85 85 #### Merge request events
86 86  
87   -Triggered when a new merge request is created or an existing merge request was updated/merges/closed.
  87 +Triggered when a new merge request is created or an existing merge request was updated/merged/closed.
88 88  
89 89 **Request body:**
90 90  
... ...
features/project/source/browse_files.feature
... ... @@ -29,3 +29,13 @@ Feature: Project Browse files
29 29 Given I click on "Gemfile.lock" file in repo
30 30 And I click button "edit"
31 31 Then I can edit code
  32 +
  33 + @javascript
  34 + Scenario: I can see editing preview
  35 + Given I click on "Gemfile.lock" file in repo
  36 + And I click button "edit"
  37 + And I edit code
  38 + And I click link "Diff"
  39 + Then I see diff
  40 +
  41 +
... ...
features/steps/project/browse_files.rb
... ... @@ -41,6 +41,18 @@ class ProjectBrowseFiles &lt; Spinach::FeatureSteps
41 41 page.evaluate_script('editor.getValue()').should == "GitlabFileEditor"
42 42 end
43 43  
  44 + step 'I edit code' do
  45 + page.execute_script('editor.setValue("GitlabFileEditor")')
  46 + end
  47 +
  48 + step 'I click link "Diff"' do
  49 + click_link 'Diff'
  50 + end
  51 +
  52 + step 'I see diff' do
  53 + page.should have_css '.line_holder.new'
  54 + end
  55 +
44 56 step 'I click on "new file" link in repo' do
45 57 click_link 'new-file-link'
46 58 end
... ...
lib/gitlab/diff_parser.rb
... ... @@ -4,9 +4,9 @@ module Gitlab
4 4  
5 5 attr_reader :lines, :new_path
6 6  
7   - def initialize(diff)
8   - @lines = diff.diff.lines.to_a
9   - @new_path = diff.new_path
  7 + def initialize(lines, new_path = '')
  8 + @lines = lines
  9 + @new_path = new_path
10 10 end
11 11  
12 12 def each
... ... @@ -18,10 +18,7 @@ module Gitlab
18 18 lines_arr.each do |line|
19 19 raw_line = line.dup
20 20  
21   - next if line.match(/^\-\-\- \/dev\/null/)
22   - next if line.match(/^\+\+\+ \/dev\/null/)
23   - next if line.match(/^\-\-\- a/)
24   - next if line.match(/^\+\+\+ b/)
  21 + next if filename?(line)
25 22  
26 23 full_line = html_escape(line.gsub(/\n/, ''))
27 24 full_line = ::Gitlab::InlineDiff.replace_markers full_line
... ... @@ -53,8 +50,17 @@ module Gitlab
53 50 end
54 51 end
55 52  
  53 + def empty?
  54 + @lines.empty?
  55 + end
  56 +
56 57 private
57 58  
  59 + def filename?(line)
  60 + line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b',
  61 + '--- /tmp/diffy', '+++ /tmp/diffy')
  62 + end
  63 +
58 64 def identification_type(line)
59 65 if line[0] == "+"
60 66 "new"
... ...
lib/gitlab/ldap/adapter.rb
... ... @@ -44,7 +44,8 @@ module Gitlab
44 44 def users(field, value)
45 45 if field.to_sym == :dn
46 46 options = {
47   - base: value
  47 + base: value,
  48 + scope: Net::LDAP::SearchScope_BaseObject
48 49 }
49 50 else
50 51 options = {
... ...
lib/tasks/gitlab/setup.rake
... ... @@ -15,14 +15,7 @@ namespace :gitlab do
15 15 end
16 16  
17 17 Rake::Task["db:setup"].invoke
18   -
19   - config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
20   - success = case config["adapter"]
21   - when /^mysql/ then
22   - Rake::Task["add_limits_mysql"].invoke
23   - when "postgresql" then
24   - end
25   -
  18 + Rake::Task["add_limits_mysql"].invoke
26 19 Rake::Task["db:seed_fu"].invoke
27 20 rescue Gitlab::TaskAbortedByUserError
28 21 puts "Quitting...".red
... ...
lib/tasks/gitlab/shell.rake
1 1 namespace :gitlab do
2 2 namespace :shell do
  3 + desc "GITLAB | Install or upgrade gitlab-shell"
  4 + task :install, [:tag, :repo] => :environment do |t, args|
  5 + warn_user_is_not_gitlab
  6 +
  7 + args.with_defaults(tag: "v1.9.3", repo: "https://gitlab.com/gitlab-org/gitlab-shell.git")
  8 +
  9 + user = Settings.gitlab.user
  10 + home_dir = Settings.gitlab.user_home
  11 + gitlab_url = Settings.gitlab.url
  12 + # gitlab-shell requires a / at the end of the url
  13 + gitlab_url += "/" unless gitlab_url.match(/\/$/)
  14 + repos_path = Gitlab.config.gitlab_shell.repos_path
  15 + target_dir = Gitlab.config.gitlab_shell.path
  16 +
  17 + # Clone if needed
  18 + unless File.directory?(target_dir)
  19 + sh "git clone '#{args.repo}' '#{target_dir}'"
  20 + end
  21 +
  22 + # Make sure we're on the right tag
  23 + Dir.chdir(target_dir) do
  24 + sh "git fetch origin && git reset --hard $(git describe #{args.tag} || git describe origin/#{args.tag})"
  25 +
  26 + redis_url = URI.parse(ENV['REDIS_URL'] || "redis://localhost:6379")
  27 +
  28 + config = {
  29 + user: user,
  30 + gitlab_url: gitlab_url,
  31 + http_settings: {self_signed_cert: false}.stringify_keys,
  32 + repos_path: repos_path,
  33 + auth_file: File.join(home_dir, ".ssh", "authorized_keys"),
  34 + redis: {
  35 + bin: %x{which redis-cli}.chomp,
  36 + host: redis_url.host,
  37 + port: redis_url.port,
  38 + namespace: "resque:gitlab"
  39 + }.stringify_keys,
  40 + log_level: "INFO",
  41 + audit_usernames: false
  42 + }.stringify_keys
  43 +
  44 + # Generate config.yml based on existing gitlab settings
  45 + File.open("config.yml", "w+") {|f| f.puts config.to_yaml}
  46 +
  47 + # Launch installation process
  48 + sh "bin/install"
  49 + end
  50 +
  51 + # Required for debian packaging with PKGR: Setup .ssh/environment with
  52 + # the current PATH, so that the correct ruby version gets loaded
  53 + # Requires to set "PermitUserEnvironment yes" in sshd config (should not
  54 + # be an issue since it is more than likely that there are no "normal"
  55 + # user accounts on a gitlab server). The alternative is for the admin to
  56 + # install a ruby (1.9.3+) in the global path.
  57 + File.open(File.join(home_dir, ".ssh", "environment"), "w+") do |f|
  58 + f.puts "PATH=#{ENV['PATH']}"
  59 + end
  60 + end
  61 +
3 62 desc "GITLAB | Setup gitlab-shell"
4 63 task setup: :environment do
5 64 setup
... ...
lib/tasks/migrate/add_limits_mysql.rake
  1 +require Rails.root.join('db/migrate/limits_to_mysql')
  2 +
1 3 desc "GITLAB | Add limits to strings in mysql database"
2 4 task add_limits_mysql: :environment do
3 5 puts "Adding limits to schema.rb for mysql"
4 6 LimitsToMysql.new.up
5 7 end
6   -
7   -class LimitsToMysql < ActiveRecord::Migration
8   - def up
9   - change_column :merge_request_diffs, :st_commits, :text, limit: 2147483647
10   - change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647
11   - change_column :snippets, :content, :text, limit: 2147483647
12   - change_column :notes, :st_diff, :text, limit: 2147483647
13   - end
14   -end
... ...
lib/tasks/setup.rake 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +desc "GITLAB | Setup gitlab db"
  2 +task :setup do
  3 + Rake::Task["gitlab:setup"].invoke
  4 +end
... ...
public/apple-touch-icon-precomposed.png 0 → 100644

11.7 KB

public/static.css
... ... @@ -2,7 +2,6 @@ body {
2 2 color: #666;
3 3 text-align: center;
4 4 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
5   - sans-serif;
6 5 margin:0;
7 6 width: 800px;
8 7 margin: auto;
... ...
spec/finders/notes_finder_spec.rb 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +require 'spec_helper'
  2 +
  3 +describe NotesFinder do
  4 + let(:user) { create :user }
  5 + let(:project) { create :project }
  6 + let(:note1) { create :note_on_commit, project: project }
  7 + let(:note2) { create :note_on_commit, project: project }
  8 + let(:commit) { note1.noteable }
  9 +
  10 + before do
  11 + project.team << [user, :master]
  12 + end
  13 +
  14 + describe :execute do
  15 + let(:params) { { target_id: commit.id, target_type: 'commit', last_fetched_at: 1.hour.ago.to_i } }
  16 +
  17 + before do
  18 + note1
  19 + note2
  20 + end
  21 +
  22 + it 'should find all notes' do
  23 + notes = NotesFinder.new.execute(project, user, params)
  24 + notes.size.should eq(2)
  25 + end
  26 +
  27 + it 'should raise an exception for an invalid target_type' do
  28 + params.merge!(target_type: 'invalid')
  29 + expect { NotesFinder.new.execute(project, user, params) }.to raise_error('invalid target_type')
  30 + end
  31 +
  32 + it 'filters out old notes' do
  33 + note2.update_attribute(:updated_at, 2.hours.ago)
  34 + notes = NotesFinder.new.execute(project, user, params)
  35 + notes.should eq([note1])
  36 + end
  37 + end
  38 +end
... ...
spec/helpers/application_helper_spec.rb
... ... @@ -46,7 +46,7 @@ describe ApplicationHelper do
46 46 group = create(:group)
47 47 group.avatar = File.open(avatar_file_path)
48 48 group.save!
49   - group_icon(group.path).to_s.should == "/uploads/group/avatar/#{ group.id }/gitlab_logo.png"
  49 + group_icon(group.path).to_s.should match("/uploads/group/avatar/#{ group.id }/gitlab_logo.png")
50 50 end
51 51  
52 52 it "should give default avatar_icon when no avatar is present" do
... ... @@ -63,7 +63,7 @@ describe ApplicationHelper do
63 63 user = create(:user)
64 64 user.avatar = File.open(avatar_file_path)
65 65 user.save!
66   - avatar_icon(user.email).to_s.should == "/uploads/user/avatar/#{ user.id }/gitlab_logo.png"
  66 + avatar_icon(user.email).to_s.should match("/uploads/user/avatar/#{ user.id }/gitlab_logo.png")
67 67 end
68 68  
69 69 it "should call gravatar_icon when no avatar is present" do
... ...