From 0678b8a426553110e63dde3c75aaf719e74771e1 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Tue, 29 Oct 2013 13:41:20 +0400 Subject: [PATCH 01/49] add 'Link' header for API response --- lib/api/helpers.rb | 20 ++++++++++++++++++-- spec/requests/api/issues_spec.rb | 6 ++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index edc662eaaa..227081d4c1 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -51,8 +51,12 @@ module API end end - def paginate(object) - object.page(params[:page]).per(params[:per_page].to_i) + def paginate(relation) + per_page = params[:per_page].to_i + paginated = relation.page(params[:page]).per(per_page) + add_pagination_headers(paginated, per_page) + + paginated end def authenticate! @@ -129,6 +133,18 @@ module API private + def add_pagination_headers(paginated, per_page) + request_url = request.url.split('?').first + + links = [] + links << %(<#{request_url}?page=#{paginated.current_page - 1}&per_page=#{per_page}>; rel="prev") unless paginated.first_page? + links << %(<#{request_url}?page=#{paginated.current_page + 1}&per_page=#{per_page}>; rel="next") unless paginated.last_page? + links << %(<#{request_url}?page=1&per_page=#{per_page}>; rel="first") + links << %(<#{request_url}?page=#{paginated.total_pages}&per_page=#{per_page}>; rel="last") + + header 'Link', links.join(', ') + end + def abilities @abilities ||= begin abilities = Six.new diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index c55025d72b..505e9597e1 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -25,6 +25,12 @@ describe API::API do json_response.should be_an Array json_response.first['title'].should == issue.title end + + it "should add pagination headers" do + get api("/issues?per_page=3", user) + response.headers['Link'].should == + '; rel="first", ; rel="last"' + end end end From 91e7692b66f8916f634af6cf1d2dc1a459699733 Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Thu, 30 Jan 2014 13:11:19 +0100 Subject: [PATCH 02/49] Fix searching by extern_uid for LDAP to be case-insensitive --- lib/gitlab/ldap/user.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index fd36dda7d2..4ba69525f8 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -83,8 +83,13 @@ module Gitlab private + def find_by_uid_and_provider + find_by_uid(uid) + end + def find_by_uid(uid) - model.where(provider: provider, extern_uid: uid).last + # LDAP distinguished name is case-insensitive + model.where("provider = ? and lower(extern_uid) = ?", provider, uid.downcase).last end def provider From 62b227b2f359c168447d24d1c099fa174329fcc9 Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Mon, 24 Feb 2014 16:37:36 +0900 Subject: [PATCH 03/49] Fix another instance of "created at" Replace it with "created on". Change-Id: Ibd26bf82d2e64f142a4f3be6da7701e5b035602f --- app/views/projects/deploy_keys/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/deploy_keys/show.html.haml b/app/views/projects/deploy_keys/show.html.haml index 67615e1781..c66e6bc69c 100644 --- a/app/views/projects/deploy_keys/show.html.haml +++ b/app/views/projects/deploy_keys/show.html.haml @@ -2,7 +2,7 @@ Deploy key: = @key.title %small - created at + created on = @key.created_at.stamp("Aug 21, 2011") .back-link = link_to project_deploy_keys_path(@project) do From 498a4e6b0c8b7cc9266f71dd3337669a9442934d Mon Sep 17 00:00:00 2001 From: esmail Date: Fri, 7 Mar 2014 19:57:05 -0500 Subject: [PATCH 04/49] Database doc changes to address #2412 and #6451. --- doc/install/database_mysql.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md index 4cf9b94c1a..bf8183729e 100644 --- a/doc/install/database_mysql.md +++ b/doc/install/database_mysql.md @@ -6,6 +6,9 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se # Install the database packages sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev + + # Ensure you have MySQL version 5.5.14 or later + mysql --version # Pick a database root password (can be anything), type it and press enter # 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 # change $password in the command below to a real password you pick mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '$password'; + # Ensure you can use the InnoDB engine which is necessary to support long indexes. + # If this fails, check your MySQL config files (e.g. `/etc/mysql/*.cnf`, `/etc/mysql/conf.d/*`) for the setting "innodb = off" + mysql> SET storage_engine=INNODB; + # Create the GitLab production database mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; From f03820ebf2f28ddb26e422322219a815d8cd3749 Mon Sep 17 00:00:00 2001 From: Franz-Robert Date: Tue, 18 Mar 2014 23:17:27 +0100 Subject: [PATCH 05/49] Update 6.0-to-6.5.md A lot of users get authentication errors after this upgrade. Reason being the change in 6.5 that secure cookies when using https. A link to this would be very handy for other upgraders! 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.5.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/update/6.0-to-6.5.md b/doc/update/6.0-to-6.5.md index e01cc589a8..4a23fbfdd9 100644 --- a/doc/update/6.0-to-6.5.md +++ b/doc/update/6.0-to-6.5.md @@ -125,3 +125,6 @@ Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the data cd /home/git/gitlab sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production ``` + +## Login issues after upgrade? +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) From 73a987ea6bedd569e24f37d323883a7dbeb3ae56 Mon Sep 17 00:00:00 2001 From: Nick Downs Date: Fri, 31 Jan 2014 21:14:05 -0800 Subject: [PATCH 06/49] Removed the backgrounding of the unicorn_rails webapp start call. --- lib/support/init.d/gitlab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index ff584e6905..701db3e7d5 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -167,7 +167,7 @@ start() { # Remove old socket if it exists rm -f "$socket_path"/gitlab.socket 2>/dev/null # Start the web server - RAILS_ENV=$RAILS_ENV script/web start & + RAILS_ENV=$RAILS_ENV script/web start fi # If sidekiq is already running, don't start it again. From 5bda665d74fe5fdb08980d3ab04822e578f6aa57 Mon Sep 17 00:00:00 2001 From: dosire Date: Tue, 25 Mar 2014 21:35:08 +0100 Subject: [PATCH 07/49] Nice trick for css class check mentioned by Dmitriy. --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d864df1486..b5fc2d59c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,6 +67,7 @@ If you can, please submit a merge request with the fix or improvements including 1. The MR title should describes the change you want to make 1. The MR description should give a motive for your change and the method you used to achieve it 1. If the MR changes the UI it should include before and after screenshots +1. If the MR changes CSS classes please include the list of affected pages `grep css-class ./app -R` 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 1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submittion 1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md). From 9422b451eb622196036ec3429bb61ac9a7078c2a Mon Sep 17 00:00:00 2001 From: Pawel Krzaczkowski Date: Thu, 19 Dec 2013 10:52:29 +0100 Subject: [PATCH 08/49] Init script - change start() stop() restart() reload() to xxxx_gitlab() --- lib/support/init.d/gitlab | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index ff584e6905..0308181b86 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -149,7 +149,7 @@ exit_if_not_running(){ } ## Starts Unicorn and Sidekiq if they're not running. -start() { +start_gitlab() { check_stale_pids if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then @@ -184,7 +184,7 @@ start() { } ## Asks the Unicorn and the Sidekiq if they would be so kind as to stop, if not kills them. -stop() { +stop_gitlab() { exit_if_not_running if [ "$web_status" = "0" -a "$sidekiq_status" = "0" ]; then @@ -246,7 +246,7 @@ print_status() { } ## Tells unicorn to reload it's config and Sidekiq to restart -reload(){ +reload_gitlab(){ exit_if_not_running if [ "$wpid" = "0" ];then echo "The GitLab Unicorn Web server is not running thus its configuration can't be reloaded." @@ -263,12 +263,12 @@ reload(){ } ## Restarts Sidekiq and Unicorn. -restart(){ +restart_gitlab(){ check_status if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then - stop + stop_gitlab fi - start + start_gitlab } @@ -276,16 +276,16 @@ restart(){ case "$1" in start) - start + start_gitlab ;; stop) - stop + stop_gitlab ;; restart) - restart + restart_gitlab ;; reload|force-reload) - reload + reload_gitlab ;; status) print_status From 961d87937b55535ff3ffd041dbc78af82d644daa Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Wed, 26 Mar 2014 12:44:00 +0100 Subject: [PATCH 09/49] Add the tests for user search. --- spec/models/user_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index fd8d7133ae..cb0bf9ba51 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -292,6 +292,18 @@ describe User do end end + describe 'search' do + let(:user1) { create(:user, username: 'James', email: 'james@testing.com') } + let(:user2) { create(:user, username: 'jameson', email: 'jameson@example.com') } + + it "should be case insensitive" do + User.search(user1.username.upcase).to_a.should == [user1] + User.search(user1.username.downcase).to_a.should == [user1] + User.search(user2.username.upcase).to_a.should == [user2] + User.search(user2.username.downcase).to_a.should == [user2] + end + end + describe 'by_username_or_id' do let(:user1) { create(:user, username: 'foo') } From 1aabfcb92d41f690e6756a7f057e85f17e30a0db Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Wed, 26 Mar 2014 12:45:39 +0100 Subject: [PATCH 10/49] Change the user search query to be case insensitive. --- CHANGELOG | 1 + app/models/user.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 0b295e4d75..06d19df7a3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ v 6.8.0 - Ability to at mention users that are participating in issue and merge req. discussion - Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu) + - Make user search case-insensitive (Christopher Arnold) v 6.7.2 - Fix upgrader script diff --git a/app/models/user.rb b/app/models/user.rb index d9f420759d..25c10a6faa 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -204,7 +204,7 @@ class User < ActiveRecord::Base end def search query - where("name LIKE :query OR email LIKE :query OR username LIKE :query", query: "%#{query}%") + where("lower(name) LIKE :query OR lower(email) LIKE :query OR lower(username) LIKE :query", query: "%#{query.downcase}%") end def by_username_or_id(name_or_id) From 466203eb0c386b4b64512dc44cf7efa6221718df Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Wed, 26 Mar 2014 12:56:25 +0100 Subject: [PATCH 11/49] Additional check in the test. --- spec/models/user_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index cb0bf9ba51..fef6314f23 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -301,6 +301,8 @@ describe User do User.search(user1.username.downcase).to_a.should == [user1] User.search(user2.username.upcase).to_a.should == [user2] User.search(user2.username.downcase).to_a.should == [user2] + User.search(user1.username.downcase).to_a.count.should == 2 + User.search(user2.username.downcase).to_a.count.should == 1 end end From 043c9f8640b558f2d46b9d64a498ab47f0c0700a Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Wed, 26 Mar 2014 13:51:28 +0100 Subject: [PATCH 12/49] Change Diff to Changes in views. --- app/views/notify/repository_push_email.html.haml | 6 +++--- app/views/notify/repository_push_email.text.haml | 4 ++-- app/views/projects/commits/_text_file.html.haml | 2 +- app/views/projects/compare/show.html.haml | 8 ++++---- app/views/projects/merge_requests/_show.html.haml | 2 +- app/views/projects/merge_requests/show/_diffs.html.haml | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml index ab0d6c653b..85a01a567f 100644 --- a/app/views/notify/repository_push_email.html.haml +++ b/app/views/notify/repository_push_email.html.haml @@ -7,7 +7,7 @@ %li #{commit.short_id} - #{commit.title} -%h4 Diff: +%h4 Changes: - @diffs.each do |diff| %li %strong @@ -23,6 +23,6 @@ %br - if @compare.timeout - %h5 Huge diff. To prevent performance issues it was hidden + %h5 To prevent performance issues changes are hidden - elsif @compare.commits_over_limit? - %h5 Diff for big amount of commits is disabled + %h5 Changes are not shown due to large amount of commits diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml index 93b344d2c8..b8d7fbeb04 100644 --- a/app/views/notify/repository_push_email.text.haml +++ b/app/views/notify/repository_push_email.text.haml @@ -6,7 +6,7 @@ Commits: #{commit.short_id} - #{truncate(commit.title, length: 40)} \ \ -Diff: +Changes: - @diffs.each do |diff| \ \===================================== @@ -22,4 +22,4 @@ Diff: - if @compare.timeout Huge diff. To prevent performance issues it was hidden - elsif @compare.commits_over_limit? - Diff for big amount of commits is disabled + Changes are not shown due to large amount of commits diff --git a/app/views/projects/commits/_text_file.html.haml b/app/views/projects/commits/_text_file.html.haml index c827d96d85..ba83d2e5a0 100644 --- a/app/views/projects/commits/_text_file.html.haml +++ b/app/views/projects/commits/_text_file.html.haml @@ -1,6 +1,6 @@ - too_big = diff.diff.lines.count > 1000 - if too_big - %a.supp_diff_link Diff suppressed. Click to show + %a.supp_diff_link Changes suppressed. Click to show %table.text-file{class: "#{'hide' if too_big}"} - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line| diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml index 9bd4985536..57331bff31 100644 --- a/app/views/projects/compare/show.html.haml +++ b/app/views/projects/compare/show.html.haml @@ -18,17 +18,17 @@ - else %ul.well-list= render Commit.decorate(@commits), project: @project - %h4 Diff + %h4 Changes - if @diffs.present? = render "projects/commits/diffs", diffs: @diffs, project: @project - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE .bs-callout.bs-callout-danger %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits. - %p To preserve performance the line diff is not shown. + %p To preserve performance the line changes are not shown. - elsif @timeout .bs-callout.bs-callout-danger - %h4 Diff for this comparison is extremely large. - %p Use command line to browse diff for this comparison. + %h4 Number of changed files for this comparison is extremely large. + %p Use command line to browse through changes for this comparison. - else diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 809b01918c..7a21c0dd06 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -20,7 +20,7 @@ %li.diffs-tab{data: {action: 'diffs'}} = link_to diffs_project_merge_request_path(@project, @merge_request) do %i.icon-list-alt - Diff + Changes - content_for :note_actions do - if can?(current_user, :modify_merge_request, @merge_request) diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml index 7c4f43d2d8..3d48514f98 100644 --- a/app/views/projects/merge_requests/show/_diffs.html.haml +++ b/app/views/projects/merge_requests/show/_diffs.html.haml @@ -5,7 +5,7 @@ - else .bs-callout.bs-callout-warning %h4 - Diff for this comparison is extremely large. + Changes view for this comparison is extremely large. %p You can = link_to "download it", project_merge_request_path(@merge_request.source_project, @merge_request, format: :diff), class: "vlink" From 7bf92b368fae70c835c729515f9dac1fb766c185 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Wed, 26 Mar 2014 15:38:14 +0100 Subject: [PATCH 13/49] Ldap check recognize ldap user filter. --- lib/tasks/gitlab/check.rake | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 071760c0c3..3b9b2531bf 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -677,7 +677,20 @@ namespace :gitlab do end def filter - Net::LDAP::Filter.present?(ldap_config.uid) + uid_filter = Net::LDAP::Filter.present?(ldap_config.uid) + if user_filter + Net::LDAP::Filter.join(uid_filter, user_filter) + else + uid_filter + end + end + + def user_filter + if ldap_config['user_filter'] && ldap_config.user_filter.present? + Net::LDAP::Filter.construct(ldap_config.user_filter) + else + nil + end end def ldap From 83f811fff5f6b2188c82f187f747122d2f7cd936 Mon Sep 17 00:00:00 2001 From: George Dewar Date: Fri, 21 Mar 2014 17:05:46 +1300 Subject: [PATCH 14/49] Refactor Parallel Diff feature and add scrollbars Also now removed lines relating to unused comments feature --- app/assets/stylesheets/sections/diff.scss | 25 +++- app/helpers/commits_helper.rb | 76 +++++++++++- app/models/diff_line.rb | 3 + .../projects/commits/_parallel_view.html.haml | 114 ++++++++---------- 4 files changed, 147 insertions(+), 71 deletions(-) create mode 100644 app/models/diff_line.rb diff --git a/app/assets/stylesheets/sections/diff.scss b/app/assets/stylesheets/sections/diff.scss index 813566c4de..eb272f20f4 100644 --- a/app/assets/stylesheets/sections/diff.scss +++ b/app/assets/stylesheets/sections/diff.scss @@ -62,6 +62,29 @@ font-size: 12px; } } + + .text-file-parallel div { + display: inline-block; + padding-bottom: 16px; + } + .diff-side { + overflow-x: scroll; + width: 508px; + height: 700px; + } + .diff-side.diff-side-left{ + overflow-y:hidden; + } + .diff-side table, td.diff-middle table { + height: 700px; + } + .diff-middle { + width: 114px; + vertical-align: top; + height: 700px; + overflow: hidden + } + .old_line, .new_line, .diff_line { margin: 0px; padding: 0px; @@ -125,8 +148,6 @@ } &.parallel { display: table-cell; - overflow: hidden; - width: 50%; } } } diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 5e5f3f77a2..c6e4f574b6 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -105,8 +105,80 @@ module CommitsHelper branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe end - def get_old_file(project, commit, diff) - project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id + def parallel_diff_lines(project, commit, diff, file) + old_file = project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id + deleted_lines = {} + added_lines = {} + each_diff_line(diff, 0) do |line, type, line_code, line_new, line_old| + if type == "old" + deleted_lines[line_old] = { line_code: line_code, type: type, line: line } + elsif type == "new" + added_lines[line_new] = { line_code: line_code, type: type, line: line } + end + end + max_length = old_file ? old_file.sloc + added_lines.length : file.sloc + + offset1 = 0 + offset2 = 0 + old_lines = [] + new_lines = [] + + max_length.times do |line_index| + line_index1 = line_index - offset1 + line_index2 = line_index - offset2 + deleted_line = deleted_lines[line_index1 + 1] + added_line = added_lines[line_index2 + 1] + old_line = old_file.lines[line_index1] if old_file + new_line = file.lines[line_index2] + + if deleted_line && added_line + elsif deleted_line + new_line = nil + offset2 += 1 + elsif added_line + old_line = nil + offset1 += 1 + end + + old_lines[line_index] = DiffLine.new + new_lines[line_index] = DiffLine.new + + # old + if line_index == 0 && diff.new_file + old_lines[line_index].type = :file_created + old_lines[line_index].content = 'File was created' + elsif deleted_line + old_lines[line_index].type = :deleted + old_lines[line_index].content = old_line + old_lines[line_index].num = line_index1 + 1 + old_lines[line_index].code = deleted_line[:line_code] + elsif old_line + old_lines[line_index].type = :no_change + old_lines[line_index].content = old_line + old_lines[line_index].num = line_index1 + 1 + else + old_lines[line_index].type = :added + end + + # new + if line_index == 0 && diff.deleted_file + new_lines[line_index].type = :file_deleted + new_lines[line_index].content = "File was deleted" + elsif added_line + new_lines[line_index].type = :added + new_lines[line_index].num = line_index2 + 1 + new_lines[line_index].content = new_line + new_lines[line_index].code = added_line[:line_code] + elsif new_line + new_lines[line_index].type = :no_change + new_lines[line_index].num = line_index2 + 1 + new_lines[line_index].content = new_line + else + new_lines[line_index].type = :deleted + end + end + + return old_lines, new_lines end protected diff --git a/app/models/diff_line.rb b/app/models/diff_line.rb new file mode 100644 index 0000000000..ad37945874 --- /dev/null +++ b/app/models/diff_line.rb @@ -0,0 +1,3 @@ +class DiffLine + attr_accessor :type, :content, :num, :code +end diff --git a/app/views/projects/commits/_parallel_view.html.haml b/app/views/projects/commits/_parallel_view.html.haml index 3234e9da0a..5b60ab80ba 100644 --- a/app/views/projects/commits/_parallel_view.html.haml +++ b/app/views/projects/commits/_parallel_view.html.haml @@ -1,75 +1,55 @@ / Side-by-side diff view -- old_file = get_old_file(project, @commit, diff) -- deleted_lines = {} -- added_lines = {} -- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line| - - if type == "old" - - deleted_lines[line_old] = { line_code: line_code, type: type, line: line } - - elsif type == "new" - - added_lines[line_new] = { line_code: line_code, type: type, line: line } - -- max_length = old_file.sloc + added_lines.length if old_file -- max_length ||= file.sloc -- offset1 = 0 -- offset2 = 0 +- old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file) +- num_lines = old_lines.length %div.text-file-parallel - %table{ style: "table-layout: fixed;" } - - max_length.times do |line_index| - - line_index1 = line_index - offset1 - - line_index2 = line_index - offset2 - - deleted_line = deleted_lines[line_index1 + 1] - - added_line = added_lines[line_index2 + 1] - - old_line = old_file.lines[line_index1] if old_file - - new_line = file.lines[line_index2] + %div.diff-side.diff-side-left + %table + - old_lines.each do |line| - - if deleted_line && added_line - - elsif deleted_line - - new_line = nil - - offset2 += 1 - - elsif added_line - - old_line = nil - - offset1 += 1 + %tr.line_holder.parallel + - if line.type == :file_created + %td.line_content.parallel= "File was created" + - elsif line.type == :deleted + %td.line_content{class: "parallel noteable_line old #{line.code}", "line_code" => line.code }= line.content + - else line.type == :no_change + %td.line_content.parallel= line.content - %tr.line_holder.parallel - - if line_index == 0 && diff.new_file - %td.line_content.parallel= "File was created" - %td.old_line= "" - - elsif deleted_line - %td.line_content{class: "parallel noteable_line old #{deleted_line[:line_code]}", "line_code" => deleted_line[:line_code] }= old_line - %td.old_line.old - = line_index1 + 1 - - if @comments_allowed - =# render "projects/notes/diff_note_link", line_code: deleted_line[:line_code] - - elsif old_line - %td.line_content.parallel= old_line - %td.old_line= line_index1 + 1 - - else - %td.line_content.parallel= "" - %td.old_line= "" + %div.diff-middle + %table + - num_lines.times do |index| + %tr + - if old_lines[index].type == :deleted + %td.old_line.old= old_lines[index].num + - else + %td.old_line= old_lines[index].num - %td.diff_line= "" + %td.diff_line="" - - if diff.deleted_file && line_index == 0 - %td.new_line= "" - %td.line_content.parallel= "File was deleted" - - elsif added_line - %td.new_line.new - = line_index2 + 1 - - if @comments_allowed - =# render "projects/notes/diff_note_link", line_code: added_line[:line_code] - %td.line_content{class: "parallel noteable_line new #{added_line[:line_code]}", "line_code" => added_line[:line_code] }= new_line - - elsif new_line - %td.new_line= line_index2 + 1 - %td.line_content.parallel= new_line - - else - %td.new_line= "" - %td.line_content.parallel= "" + - if new_lines[index].type == :added + %td.new_line.new= new_lines[index].num + - else + %td.new_line= new_lines[index].num - - if @reply_allowed - - comments1 = [] - - comments2 = [] - - comments1 = @line_notes.select { |n| n.line_code == deleted_line[:line_code] }.sort_by(&:created_at) if deleted_line - - comments2 = @line_notes.select { |n| n.line_code == added_line[:line_code] }.sort_by(&:created_at) if added_line - - unless comments1.empty? && comments2.empty? - = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2, line1: deleted_line, line2: added_line \ No newline at end of file + %div.diff-side.diff-side-right + %table + - new_lines.each do |line| + + %tr.line_holder.parallel + - if line.type == :file_deleted + %td.line_content.parallel= "File was deleted" + - elsif line.type == :added + %td.line_content{class: "parallel noteable_line new #{line.code}", "line_code" => line.code }= line.content + - else line.type == :no_change + %td.line_content.parallel= line.content + +:javascript + $('.diff-side-right').on('scroll', function(){ + $('.diff-side-left, .diff-middle').scrollTop($(this).scrollTop()); + $('.diff-side-left').scrollLeft($(this).scrollLeft()); + }); + + $('.diff-side-left').on('scroll', function(){ + $('.diff-side-right, .diff-middle').scrollTop($(this).scrollTop()); // might never be relevant + $('.diff-side-right').scrollLeft($(this).scrollLeft()); + }); From 682cafdce627d5965a1f9e8d8053a2c6faf59219 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Thu, 27 Mar 2014 15:43:16 +1000 Subject: [PATCH 15/49] Update permissions.md --- doc/permissions/permissions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md index 73e1728a55..ac4bdefddd 100644 --- a/doc/permissions/permissions.md +++ b/doc/permissions/permissions.md @@ -38,7 +38,7 @@ If a user is a GitLab administrator they receive all permissions. |------|-----|--------|---------|------|-----| |Browse group|✓|✓|✓|✓|✓| |Edit group|||||✓| -|create project in group|||||✓| +|Create project in group|||||✓| |Manage group members|||||✓| |Remove group|||||✓| From b04c343311dfd5f12815936384762a9f1412fe34 Mon Sep 17 00:00:00 2001 From: dosire Date: Thu, 27 Mar 2014 10:53:26 +0100 Subject: [PATCH 16/49] Put important information at the top of the readme. --- doc/api/README.md | 53 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/doc/api/README.md b/doc/api/README.md index 850666953a..fa5b12af14 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -1,5 +1,31 @@ # GitLab API +## End-points + ++ [Users](users.md) ++ [Session](session.md) ++ [Projects](projects.md) ++ [Project Snippets](project_snippets.md) ++ [Repositories](repositories.md) ++ [Repository Files](repository_files.md) ++ [Commits](commits.md) ++ [Merge Requests](merge_requests.md) ++ [Issues](issues.md) ++ [Milestones](milestones.md) ++ [Notes](notes.md) ++ [Deploy Keys](deploy_keys.md) ++ [System Hooks](system_hooks.md) ++ [Groups](groups.md) + +## Clients + ++ [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP ++ [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby ++ [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python ++ [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java + +## Introduction + 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. 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 So if you want to get issue with api you use `http://host/api/v3/.../issues/:id.json` But when you want to create a link to web page - use `http:://host/project/issues/:iid.json` - - - -## Contents - -+ [Users](users.md) -+ [Session](session.md) -+ [Projects](projects.md) -+ [Project Snippets](project_snippets.md) -+ [Repositories](repositories.md) -+ [Repository Files](repository_files.md) -+ [Commits](commits.md) -+ [Merge Requests](merge_requests.md) -+ [Issues](issues.md) -+ [Milestones](milestones.md) -+ [Notes](notes.md) -+ [Deploy Keys](deploy_keys.md) -+ [System Hooks](system_hooks.md) -+ [Groups](groups.md) - - -## Clients - -+ [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP -+ [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby -+ [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python -+ [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java From 8a90db9e33b2dbb46655c0c3044da382b66c4d36 Mon Sep 17 00:00:00 2001 From: dosire Date: Thu, 27 Mar 2014 10:56:30 +0100 Subject: [PATCH 17/49] Test the new doc index. --- doc/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/README.md diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000000..39880b55fa --- /dev/null +++ b/doc/README.md @@ -0,0 +1,7 @@ +## The GitLab Documentation covers the following subjects + ++ [API](api/README.md) ++ [API](api/) ++ [API](api) ++ [API](/api/) ++ [API](/api) From 417c0cb2d33e76e271c89e99b323f2443e942107 Mon Sep 17 00:00:00 2001 From: dosire Date: Thu, 27 Mar 2014 12:17:27 +0100 Subject: [PATCH 18/49] New doc site needs indexes. --- doc/README.md | 18 ++++++++++++++---- doc/development/README.md | 2 ++ doc/install/README.md | 4 ++++ doc/legal/README.md | 2 ++ doc/raketasks/README.md | 6 ++++++ doc/release/README.md | 2 ++ doc/security/README.md | 2 ++ doc/update/README.md | 5 +++++ 8 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 doc/development/README.md create mode 100644 doc/install/README.md create mode 100644 doc/legal/README.md create mode 100644 doc/raketasks/README.md create mode 100644 doc/release/README.md create mode 100644 doc/security/README.md create mode 100644 doc/update/README.md diff --git a/doc/README.md b/doc/README.md index 39880b55fa..865806f297 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,7 +1,17 @@ ## The GitLab Documentation covers the following subjects + [API](api/README.md) -+ [API](api/) -+ [API](api) -+ [API](/api/) -+ [API](/api) ++ [Development](development/README.md) ++ [Install](install/README.md) ++ [Integration](external-issue-tracker/README.md) ++ [Legal](legal/README.md) ++ [Markdown](markdown/markdown.md) ++ [Permissions](permissions/permissions.md) ++ [Public access](public_access/public_access.md) ++ [Raketasks](raketasks/README.md) ++ [Release](release/README.md) ++ [Security](security/README.md) ++ [System hooks](system_hooks/system_hooks.md) ++ [Update](update/README.md) ++ [Web hooks](web_hooks/web_hooks.md) ++ [Workflow](workflow/workflow.md) diff --git a/doc/development/README.md b/doc/development/README.md new file mode 100644 index 0000000000..aa59eb2c3e --- /dev/null +++ b/doc/development/README.md @@ -0,0 +1,2 @@ ++ [Architecture](architecture.md) ++ [Shell commands](shell_commands.md) diff --git a/doc/install/README.md b/doc/install/README.md new file mode 100644 index 0000000000..ec80e3cd62 --- /dev/null +++ b/doc/install/README.md @@ -0,0 +1,4 @@ ++ [Installation](installation.md) ++ [Requirements](requirements.md) ++ [Structure](structure.md) ++ [Database MySQL](database_mysql.md) diff --git a/doc/legal/README.md b/doc/legal/README.md new file mode 100644 index 0000000000..ebfdad1354 --- /dev/null +++ b/doc/legal/README.md @@ -0,0 +1,2 @@ ++ [Corporate contributor license agreement](corporate_contributor_license_agreement.md) ++ [Individual contributor license agreement](individual_contributor_license_agreement.md) diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md new file mode 100644 index 0000000000..9aa80af12c --- /dev/null +++ b/doc/raketasks/README.md @@ -0,0 +1,6 @@ ++ [Backup restore](backup_restore.md) ++ [Cleanup](cleanup.md) ++ [Features](features.md) ++ [Maintenance](maintenance.md) ++ [User management](user_management.md) ++ [Web hooks](web_hooks.md) diff --git a/doc/release/README.md b/doc/release/README.md new file mode 100644 index 0000000000..22510be3f1 --- /dev/null +++ b/doc/release/README.md @@ -0,0 +1,2 @@ ++ [Monthly](monthly.md) ++ [Security](security.md) diff --git a/doc/security/README.md b/doc/security/README.md new file mode 100644 index 0000000000..f8dd1291b9 --- /dev/null +++ b/doc/security/README.md @@ -0,0 +1,2 @@ ++ [Password length limits](password_length_limits.md) ++ [Rack attack](rack_attack.md) diff --git a/doc/update/README.md b/doc/update/README.md new file mode 100644 index 0000000000..97afd71bbe --- /dev/null +++ b/doc/update/README.md @@ -0,0 +1,5 @@ ++ [The indivual upgrade guides](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update) ++ [Uprader](upgrader.md) ++ [Ruby](ruby.md) ++ [Patch versions](patch_versions.md) ++ [MySQL to Postgress](mysql_to_postgress.md) From 762c7b4f2b272f56d185f09f061a8811c751a50e Mon Sep 17 00:00:00 2001 From: Kyle Fazzari Date: Thu, 27 Mar 2014 08:20:43 -0400 Subject: [PATCH 19/49] Fixed 500 error when creating issue for project with no commits. The form was updated to check that the repository wasn't empty before trying to load the contribution guide. This fixes #153. --- app/views/projects/issues/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml index dd091302c8..05cae80e50 100644 --- a/app/views/projects/issues/_form.html.haml +++ b/app/views/projects/issues/_form.html.haml @@ -1,7 +1,7 @@ %div.issue-form-holder %h3.page-title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.iid}" %hr - - if @repository.contribution_guide && !@issue.persisted? + - if !@repository.empty? && @repository.contribution_guide && !@issue.persisted? - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name)) .alert.alert-info.col-sm-10.col-sm-offset-2 ="Please review the #{link_to "guidelines for contribution", contribution_guide_url} to this repository.".html_safe From 592dce18b549cd29933603f53f1ab8fb9f33840e Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Thu, 27 Mar 2014 14:32:32 +0100 Subject: [PATCH 20/49] Always show merge status Always show the merge status of a merge request, even if the user has no permission to do the actual merging. Fixes http://feedback.gitlab.com/forums/176466-general/suggestions/5673321-everyone-should-be-able-to-see-a-mr-status --- app/views/projects/merge_requests/show/_mr_accept.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index 4b1857ccb6..bd7c8435f4 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -4,7 +4,10 @@ %strong Archived projects cannot be committed to! - else .bs-callout - %strong You don't have permission to merge this MR + .automerge_widget.cannot_be_merged.hide + %strong This can't be merged automatically, even if it could be merged you don't have the permission to do so. + .automerge_widget.can_be_merged.hide + %strong This can be merged automatically but you don't have the permission to do so. - if @show_merge_controls From 3b3186d58be54c0c720564939cebc0419a5751c1 Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Thu, 27 Mar 2014 14:34:55 +0000 Subject: [PATCH 21/49] fix image not displaying in GitLab due to faulty markdown --- doc/development/architecture.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/development/architecture.md b/doc/development/architecture.md index 805e115047..6f832614d7 100644 --- a/doc/development/architecture.md +++ b/doc/development/architecture.md @@ -28,7 +28,7 @@ To serve repositories over SSH there's an add-on application called gitlab-shell ## Components -![GitLab Diagram Overview](resources/gitlab_diagram_overview.png "GitLab Diagram Overview") +![GitLab Diagram Overview](resources/gitlab_diagram_overview.png) A typical install of GitLab will be on Ubuntu Linux or RHEL/CentOS. 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 ``` Note: It is recommended to log into the `git` user using `sudo -i -u git` or `sudo su - git`. -While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL. +While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL. \ No newline at end of file From 9ec08daa90162ea4d63db518fca0312f5bd5328d Mon Sep 17 00:00:00 2001 From: dosire Date: Thu, 27 Mar 2014 16:08:02 +0100 Subject: [PATCH 22/49] Move help to the website. --- README.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/README.md b/README.md index 7818d40ac5..2668ed8bac 100644 --- a/README.md +++ b/README.md @@ -129,22 +129,4 @@ or start each component separately ### Getting help -* [Maintenance policy](MAINTENANCE.md) specifies what versions are supported. - -* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) contains solutions to common problems. - -* [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. - -* [Feature request forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab. - -* [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. - -* [Support subscription](http://www.gitlab.com/subscription/) connects you to the knowledge of GitLab experts that will resolve your issues and answer your questions. - -* [Consultancy](http://www.gitlab.com/consultancy/) from the GitLab experts for installations, upgrades and customizations. - -* [#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). - -* [Book](http://www.packtpub.com/gitlab-repository-management/book) written by GitLab enthusiast Jonathan M. Hethey is unofficial but it offers a good overview. - -* [Gitter chat room](https://gitter.im/gitlabhq/gitlabhq#) here you can ask questions when you need help. +Please see [Getting help for GitLab](https://www.gitlab.com/getting-help/) on our website for the many options to get help. From 4fc57b5872feddb3521478659bee6f9b9da838ef Mon Sep 17 00:00:00 2001 From: Kyle Fazzari Date: Thu, 27 Mar 2014 11:23:05 -0400 Subject: [PATCH 23/49] Updated contribution guidelines to specify MRs should be to master. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b5fc2d59c9..bdf5e09831 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,7 +63,7 @@ If you can, please submit a merge request with the fix or improvements including 1. Add your changes to the [CHANGELOG](CHANGELOG) 1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) 1. Push the commit to your fork -1. Submit a merge request (MR) +1. Submit a merge request (MR) to the master branch 1. The MR title should describes the change you want to make 1. The MR description should give a motive for your change and the method you used to achieve it 1. If the MR changes the UI it should include before and after screenshots From b7225bead8ecf8664c898029648925556be8553d Mon Sep 17 00:00:00 2001 From: Tom de Bruijn Date: Thu, 20 Mar 2014 13:23:07 +0100 Subject: [PATCH 24/49] Clearfix on well-lists. Pages affected: Pages affected: - admin/groups#show - admin/projets#index - admin/users#index - dashboard/issues#index (on small screens) --- app/assets/stylesheets/generic/lists.scss | 6 ++++++ app/assets/stylesheets/sections/dashboard.scss | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/generic/lists.scss b/app/assets/stylesheets/generic/lists.scss index de70e47333..8a6d7f6817 100644 --- a/app/assets/stylesheets/generic/lists.scss +++ b/app/assets/stylesheets/generic/lists.scss @@ -13,6 +13,12 @@ border-bottom: 1px solid #eee; border-bottom: 1px solid rgba(0, 0, 0, 0.05); + &:after { + content: " "; + display: table; + clear: both; + } + &.disabled { color: #888; } diff --git a/app/assets/stylesheets/sections/dashboard.scss b/app/assets/stylesheets/sections/dashboard.scss index e088ef8220..e70757e040 100644 --- a/app/assets/stylesheets/sections/dashboard.scss +++ b/app/assets/stylesheets/sections/dashboard.scss @@ -113,6 +113,5 @@ float: left; margin-right: 3px; color: #999; - margin-bottom: 10px; width: 16px; } From ce857b7cc983172e35dca36f950864d693cfdf2b Mon Sep 17 00:00:00 2001 From: Tom de Bruijn Date: Wed, 26 Mar 2014 08:25:02 +0100 Subject: [PATCH 25/49] Improve alignment of labels in .well-list items --- app/assets/stylesheets/generic/lists.scss | 6 ++++++ app/views/admin/groups/show.html.haml | 5 +++-- app/views/admin/hooks/index.html.haml | 6 ++++-- app/views/admin/projects/index.html.haml | 7 ++++--- app/views/admin/projects/show.html.haml | 5 +++-- app/views/admin/users/index.html.haml | 19 ++++++++++--------- app/views/admin/users/show.html.haml | 3 ++- app/views/groups/edit.html.haml | 5 +++-- app/views/users_groups/_users_group.html.haml | 13 +++++++------ 9 files changed, 42 insertions(+), 27 deletions(-) diff --git a/app/assets/stylesheets/generic/lists.scss b/app/assets/stylesheets/generic/lists.scss index 8a6d7f6817..963768044d 100644 --- a/app/assets/stylesheets/generic/lists.scss +++ b/app/assets/stylesheets/generic/lists.scss @@ -52,6 +52,12 @@ .author { color: #999; } + .list-item-name { + float: left; + position: relative; + top: 3px; + } + p { padding-top: 1px; margin: 0; diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 252111875f..6055865b4c 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -70,8 +70,9 @@ - @group.users_groups.order('group_access DESC').each do |member| - user = member.user %li{class: dom_class(user)} - %strong - = link_to user.name, admin_user_path(user) + .list-item-name + %strong + = link_to user.name, admin_user_path(user) %span.pull-right.light = member.human_access = link_to group_users_group_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml index ff90d513ca..60773c2009 100644 --- a/app/views/admin/hooks/index.html.haml +++ b/app/views/admin/hooks/index.html.haml @@ -28,8 +28,10 @@ %ul.well-list - @hooks.each do |hook| %li + .list-item-name + = link_to admin_hook_path(hook) do + %strong= hook.url + .pull-right = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-small" = link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-small" - = link_to admin_hook_path(hook) do - %strong= hook.url diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index 5f19d21f10..296094ab29 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -44,9 +44,10 @@ %ul.well-list - @projects.each do |project| %li - %span{ class: visibility_level_color(project.visibility_level) } - = visibility_level_icon(project.visibility_level) - = link_to project.name_with_namespace, [:admin, project] + .list-item-name + %span{ class: visibility_level_color(project.visibility_level) } + = visibility_level_icon(project.visibility_level) + = link_to project.name_with_namespace, [:admin, project] .pull-right %span.label.label-gray = repository_size(project) diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 34a91cce16..11f07743ac 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -116,8 +116,9 @@ - @project.users_projects.each do |users_project| - user = users_project.user %li.users_project - %strong - = link_to user.name, admin_user_path(user) + .list-item-name + %strong + = link_to user.name, admin_user_path(user) .pull-right - if users_project.owner? %span.light Owner diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 0b3934a712..f42ae7c6a0 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -36,15 +36,16 @@ %ul.well-list - @users.each do |user| %li - - if user.blocked? - %i.icon-lock.cred - - else - %i.icon-user.cgreen - = link_to user.name, [:admin, user] - - if user.admin? - %strong.cred (Admin) - - if user == current_user - %span.cred It's you! + .list-item-name + - if user.blocked? + %i.icon-lock.cred + - else + %i.icon-user.cgreen + = link_to user.name, [:admin, user] + - if user.admin? + %strong.cred (Admin) + - if user == current_user + %span.cred It's you! .pull-right %span.light %i.icon-envelope diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index d66119e271..764b34499a 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -124,7 +124,8 @@ - @user.users_groups.each do |user_group| - group = user_group.group %li.users_group - %strong= link_to group.name, admin_group_path(group) + %span{class: ("list-item-name" unless user_group.owner?)} + %strong= link_to group.name, admin_group_path(group) .pull-right %span.light= user_group.human_access - unless user_group.owner? diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 9308bd8124..500c37ab71 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -73,8 +73,9 @@ %ul.well-list - @group.projects.each do |project| %li - = visibility_level_icon(project.visibility_level) - = link_to project.name_with_namespace, project + .list-item-name + = visibility_level_icon(project.visibility_level) + = link_to project.name_with_namespace, project .pull-right = link_to 'Members', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" diff --git a/app/views/users_groups/_users_group.html.haml b/app/views/users_groups/_users_group.html.haml index 1784dab35b..ad363eaba2 100644 --- a/app/views/users_groups/_users_group.html.haml +++ b/app/views/users_groups/_users_group.html.haml @@ -2,11 +2,12 @@ - return unless user - show_roles = true if show_roles.nil? %li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)} - = image_tag avatar_icon(user.email, 16), class: "avatar s16" - %strong= user.name - %span.cgray= user.username - - if user == current_user - %span.label.label-success It's you + %span{class: ("list-item-name" if show_controls)} + = image_tag avatar_icon(user.email, 16), class: "avatar s16" + %strong= user.name + %span.cgray= user.username + - if user == current_user + %span.label.label-success It's you - if show_roles %span.pull-right @@ -22,7 +23,7 @@ - else = link_to group_users_group_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do %i.icon-minus.icon-white - + .edit-member.hide.js-toggle-content = form_for [@group, member], remote: true do |f| .alert.prepend-top-20 From f48fc3c6cbcc0cbcb34cefa2025434c09cf57e04 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 28 Mar 2014 13:37:09 +0100 Subject: [PATCH 26/49] Add a rake task that drops all tables --- lib/tasks/gitlab/db/drop_all_tables.rake | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 lib/tasks/gitlab/db/drop_all_tables.rake diff --git a/lib/tasks/gitlab/db/drop_all_tables.rake b/lib/tasks/gitlab/db/drop_all_tables.rake new file mode 100644 index 0000000000..a66030ab93 --- /dev/null +++ b/lib/tasks/gitlab/db/drop_all_tables.rake @@ -0,0 +1,10 @@ +namespace :gitlab do + namespace :db do + task drop_all_tables: :environment do + connection = ActiveRecord::Base.connection + connection.tables.each do |table| + connection.drop_table(table) + end + end + end +end From 77b57c114be6b1fa02538c35066ccc363bfe68e6 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 28 Mar 2014 13:38:36 +0100 Subject: [PATCH 27/49] Drop all tables before restoring a PostgreSQL DB Invoking 'db:schema:load' turned out to be a bad idea: when downgrading an existing GitLab installation, the schema of the newer version would be preserved when trying to import the old version. --- CHANGELOG | 1 + lib/backup/database.rb | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 06d19df7a3..dc8031c75a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ v 6.8.0 - Ability to at mention users that are participating in issue and merge req. discussion - Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu) - Make user search case-insensitive (Christopher Arnold) + - Drop all tables before restoring a Postgres backup v 6.7.2 - Fix upgrader script diff --git a/lib/backup/database.rb b/lib/backup/database.rb index 6552f45ff0..7b6908ccad 100644 --- a/lib/backup/database.rb +++ b/lib/backup/database.rb @@ -29,9 +29,10 @@ module Backup print "Restoring MySQL database #{config['database']} ... " system('mysql', *mysql_args, config['database'], in: db_file_name) when "postgresql" then - puts "Destructively rebuilding database schema for RAILS_ENV #{Rails.env}" - Rake::Task["db:schema:load"].invoke print "Restoring PostgreSQL database #{config['database']} ... " + # Drop all tables because PostgreSQL DB dumps do not contain DROP TABLE + # statements like MySQL. + Rake::Task["gitlab:db:drop_all_tables"].invoke pg_env system('psql', config['database'], '-f', db_file_name) end From 2e6b537018062b8407411e7bd51327f797f2fe1f Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 28 Mar 2014 13:54:38 +0100 Subject: [PATCH 28/49] Use omniauth nickname as the username for LDAP Before there was a bug in omniauth-ldap which prevented samaccountname showing up as a possible username for new LDAP users. Thanks to upstream fixes, we no longer need to work around this bug. --- CHANGELOG | 1 + lib/gitlab/ldap/user.rb | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 06d19df7a3..0224d95028 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ v 6.8.0 - Ability to at mention users that are participating in issue and merge req. discussion - Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu) - Make user search case-insensitive (Christopher Arnold) + - Remove omniauth-ldap nickname bug workaround v 6.7.2 - Fix upgrader script diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index 456a61b9e4..6bc587df3c 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -86,11 +86,7 @@ module Gitlab end def username - (auth.info.nickname || samaccountname).to_s.force_encoding("utf-8") - end - - def samaccountname - (auth.extra[:raw_info][:samaccountname] || []).first + auth.info.nickname.to_s.force_encoding("utf-8") end def provider From c34186f88258aadd03c7e692606ff2499d221d2b Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 28 Mar 2014 16:43:28 +0100 Subject: [PATCH 29/49] Refactor project watchers collecting. --- app/services/notification_service.rb | 42 ++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 6fda9868aa..d85398809c 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -178,21 +178,41 @@ class NotificationService # Get project users with WATCH notification level def project_watchers(project) - project_watchers = [] - member_methods = { project => :users_projects } - member_methods.merge!(project.group => :users_groups) if project.group + # Gather all user ids that have WATCH notification setting for project + project_notification_uids = project_notification_list(project, Notification::N_WATCH) - member_methods.each do |object, member_method| - # Get project notification settings since it has higher priority - user_ids = object.send(member_method).where(notification_level: Notification::N_WATCH).pluck(:user_id) - project_watchers += User.where(id: user_ids) + # Gather all user ids that have WATCH notification setting for group + group_notification_uids = group_notification_list(project, Notification::N_WATCH) - # next collect users who use global settings with watch state - user_ids = object.send(member_method).where(notification_level: Notification::N_GLOBAL).pluck(:user_id) - project_watchers += User.where(id: user_ids, notification_level: Notification::N_WATCH) + # Gather all user ids that have GLOBAL setting + global_notification_uids = global_notification_list(project) + + project_and_group_uids = [project_notification_uids, group_notification_uids].flatten.uniq + group_and_project_watchers = User.where(id: project_and_group_uids) + + # Find all users that have WATCH as their GLOBAL setting + global_watchers = User.where(id: global_notification_uids, notification_level: Notification::N_WATCH) + + [group_and_project_watchers, global_watchers].flatten.uniq + end + + def project_notification_list(project, notification_level) + project.users_projects.where(notification_level: notification_level).pluck(:user_id) + end + + def group_notification_list(project, notification_level) + if project.group + project.group.users_groups.where(notification_level: notification_level).pluck(:user_id) + else + [] end + end - project_watchers.uniq + def global_notification_list(project) + [ + project_notification_list(project, Notification::N_GLOBAL), + group_notification_list(project, Notification::N_GLOBAL) + ].flatten end # Remove users with disabled notifications from array From f43a6339d783f689355ac9dbfaa280083817243c Mon Sep 17 00:00:00 2001 From: dosire Date: Sun, 30 Mar 2014 17:36:32 +0200 Subject: [PATCH 30/49] Different filename. --- doc/update/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/update/README.md b/doc/update/README.md index 97afd71bbe..06e3764616 100644 --- a/doc/update/README.md +++ b/doc/update/README.md @@ -2,4 +2,4 @@ + [Uprader](upgrader.md) + [Ruby](ruby.md) + [Patch versions](patch_versions.md) -+ [MySQL to Postgress](mysql_to_postgress.md) ++ [MySQL to PostgreSQL](mysql_to_postgresql.md) From 3055331965ee4eb1724a2abf91ac2a66a0856b82 Mon Sep 17 00:00:00 2001 From: Robert Boloc Date: Mon, 31 Mar 2014 12:05:41 +0200 Subject: [PATCH 31/49] Grammar correction: "View in Gitlab" Changed to "View on Gitlab" --- app/views/layouts/notify.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 09d84a3eb9..cf6c72a146 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -23,4 +23,4 @@ - if @project You're receiving this notification because you are a member of the #{link_to @project.name_with_namespace, project_url(@project)} project team. - if @target_url - #{link_to "View in GitLab", @target_url} + #{link_to "View on GitLab", @target_url} From 200eeea2587d36a90f8308425887e953c48eecbc Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 28 Mar 2014 13:09:25 +0100 Subject: [PATCH 32/49] Make the repository downloads path configurable --- CHANGELOG | 1 + app/controllers/projects/repositories_controller.rb | 2 +- config/gitlab.yml.example | 4 ++++ config/initializers/1_settings.rb | 1 + lib/api/repositories.rb | 2 +- 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1921991578..e3ab6a5e92 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ v 6.8.0 - Make user search case-insensitive (Christopher Arnold) - Remove omniauth-ldap nickname bug workaround - Drop all tables before restoring a Postgres backup + - Make the repository downloads path configurable v 6.7.2 - Fix upgrader script diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index f686db70bd..d1a6fecba2 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -14,7 +14,7 @@ class Projects::RepositoriesController < Projects::ApplicationController render_404 and return end - storage_path = Rails.root.join("tmp", "repositories") + storage_path = Gitlab.config.gitlab.repository_downloads_path file_path = @repository.archive_repo(params[:ref], storage_path, params[:format].downcase) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 9364181eaa..cb4b8c73a4 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -76,6 +76,10 @@ production: &base snippets: false visibility_level: "private" # can be "private" | "internal" | "public" + ## Repository downloads directory + # When a user clicks e.g. 'Download zip' on a project, a temporary zip file is created in the following directory. + # repository_downloads_path: tmp/repositories + ## External issues trackers issues_tracker: # redmine: diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index cf6c79bb50..70ba26cea7 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -97,6 +97,7 @@ Settings.gitlab.default_projects_features['wiki'] = true if Settings.g Settings.gitlab.default_projects_features['wall'] = false if Settings.gitlab.default_projects_features['wall'].nil? Settings.gitlab.default_projects_features['snippets'] = false if Settings.gitlab.default_projects_features['snippets'].nil? Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) +Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root) # # Gravatar diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index ba53bf9baa..53482c3b7f 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -161,7 +161,7 @@ module API repo = user_project.repository ref = params[:sha] format = params[:format] - storage_path = Rails.root.join("tmp", "repositories") + storage_path = Gitlab.config.gitlab.repository_downloads_path file_path = repo.archive_repo(ref, storage_path, format) if file_path && File.exists?(file_path) From eeeaaa4bc136c30db7d276cdcba4739937157663 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 28 Mar 2014 13:48:00 +0100 Subject: [PATCH 33/49] Explain the default repository_downloads_path --- config/gitlab.yml.example | 1 + 1 file changed, 1 insertion(+) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index cb4b8c73a4..d9ac1c02ef 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -78,6 +78,7 @@ production: &base ## Repository downloads directory # When a user clicks e.g. 'Download zip' on a project, a temporary zip file is created in the following directory. + # The default is 'tmp/repositories' relative to the root of the Rails app. # repository_downloads_path: tmp/repositories ## External issues trackers From dd32c9f0ed73eeebc32fbbed38de5c467839b665 Mon Sep 17 00:00:00 2001 From: Robert Boloc Date: Mon, 31 Mar 2014 12:24:55 +0200 Subject: [PATCH 34/49] Updated notification message --- app/views/layouts/notify.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index cf6c72a146..3e8dae0b23 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -23,4 +23,4 @@ - if @project You're receiving this notification because you are a member of the #{link_to @project.name_with_namespace, project_url(@project)} project team. - if @target_url - #{link_to "View on GitLab", @target_url} + #{link_to "View it on GitLab", @target_url} From 24f64e65a63fa5c1a6dd562d5855fe8b67b1cd2b Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 31 Mar 2014 13:16:52 +0200 Subject: [PATCH 35/49] Add documentation for https://github.com/gitlabhq/gitlabhq/pull/5469 --- doc/api/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/README.md b/doc/api/README.md index fa5b12af14..dd14188159 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -129,6 +129,10 @@ When listing resources you can pass the following parameters: + `page` (default: `1`) - page number + `per_page` (default: `20`, max: `100`) - number of items to list per page +[Link headers](http://www.w3.org/wiki/LinkHeader) are send back with each response. +These have `rel` prev/next/first/last and contain the relevant url. +Please use these instead of generating your own urls. + ## id vs iid When you work with API you may notice two similar fields in api entites: id and iid. From 8da35fe26ecda1a984fbf2c1a5ab8bf4c1d25bee Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Mon, 31 Mar 2014 14:49:57 +0200 Subject: [PATCH 36/49] Fix link to isue tracker integration page --- doc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/README.md b/doc/README.md index 865806f297..3cd0196347 100644 --- a/doc/README.md +++ b/doc/README.md @@ -3,7 +3,7 @@ + [API](api/README.md) + [Development](development/README.md) + [Install](install/README.md) -+ [Integration](external-issue-tracker/README.md) ++ [Integration](integration/external-issue-tracker.md) + [Legal](legal/README.md) + [Markdown](markdown/markdown.md) + [Permissions](permissions/permissions.md) From 9b276f0003d19599e6426eb5f58028a81ede4a30 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 31 Mar 2014 16:31:53 +0300 Subject: [PATCH 37/49] Move branches api to separate class Signed-off-by: Dmitriy Zaporozhets --- lib/api/api.rb | 1 + lib/api/branches.rb | 70 +++++++++++++++++++ lib/api/commits.rb | 11 +-- lib/api/repositories.rb | 60 ---------------- spec/requests/api/branches_spec.rb | 95 ++++++++++++++++++++++++++ spec/requests/api/repositories_spec.rb | 80 ---------------------- 6 files changed, 167 insertions(+), 150 deletions(-) create mode 100644 lib/api/branches.rb create mode 100644 spec/requests/api/branches_spec.rb diff --git a/lib/api/api.rb b/lib/api/api.rb index 7c4cdad7f0..ce4cc8b34f 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -45,5 +45,6 @@ module API mount Files mount Commits mount Namespaces + mount Branches end end diff --git a/lib/api/branches.rb b/lib/api/branches.rb new file mode 100644 index 0000000000..6339094bd9 --- /dev/null +++ b/lib/api/branches.rb @@ -0,0 +1,70 @@ +require 'mime/types' + +module API + # Projects API + class Branches < Grape::API + before { authenticate! } + before { authorize! :download_code, user_project } + + resource :projects do + # Get a project repository branches + # + # Parameters: + # id (required) - The ID of a project + # Example Request: + # GET /projects/:id/repository/branches + get ":id/repository/branches" do + present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project + end + + # Get a single branch + # + # Parameters: + # id (required) - The ID of a project + # branch (required) - The name of the branch + # Example Request: + # GET /projects/:id/repository/branches/:branch + get ":id/repository/branches/:branch" do + @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } + not_found!("Branch does not exist") if @branch.nil? + present @branch, with: Entities::RepoObject, project: user_project + end + + # Protect a single branch + # + # Parameters: + # id (required) - The ID of a project + # branch (required) - The name of the branch + # Example Request: + # PUT /projects/:id/repository/branches/:branch/protect + put ":id/repository/branches/:branch/protect" do + authorize_admin_project + + @branch = user_project.repository.find_branch(params[:branch]) + not_found! unless @branch + protected_branch = user_project.protected_branches.find_by(name: @branch.name) + user_project.protected_branches.create(name: @branch.name) unless protected_branch + + present @branch, with: Entities::RepoObject, project: user_project + end + + # Unprotect a single branch + # + # Parameters: + # id (required) - The ID of a project + # branch (required) - The name of the branch + # Example Request: + # PUT /projects/:id/repository/branches/:branch/unprotect + put ":id/repository/branches/:branch/unprotect" do + authorize_admin_project + + @branch = user_project.repository.find_branch(params[:branch]) + not_found! unless @branch + protected_branch = user_project.protected_branches.find_by(name: @branch.name) + protected_branch.destroy if protected_branch + + present @branch, with: Entities::RepoObject, project: user_project + end + end + end +end diff --git a/lib/api/commits.rb b/lib/api/commits.rb index 33b8b3d224..4a67313430 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -1,21 +1,12 @@ require 'mime/types' module API - # Projects API + # Projects commits API class Commits < Grape::API before { authenticate! } before { authorize! :download_code, user_project } resource :projects do - helpers do - def handle_project_member_errors(errors) - if errors[:project_access].any? - error!(errors[:project_access], 422) - end - not_found! - end - end - # Get a project repository commits # # Parameters: diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 53482c3b7f..076a9ceeb7 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -15,66 +15,6 @@ module API not_found! end end - - # Get a project repository branches - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/repository/branches - get ":id/repository/branches" do - present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project - end - - # Get a single branch - # - # Parameters: - # id (required) - The ID of a project - # branch (required) - The name of the branch - # Example Request: - # GET /projects/:id/repository/branches/:branch - get ":id/repository/branches/:branch" do - @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } - not_found!("Branch does not exist") if @branch.nil? - present @branch, with: Entities::RepoObject, project: user_project - end - - # Protect a single branch - # - # Parameters: - # id (required) - The ID of a project - # branch (required) - The name of the branch - # Example Request: - # PUT /projects/:id/repository/branches/:branch/protect - put ":id/repository/branches/:branch/protect" do - authorize_admin_project - - @branch = user_project.repository.find_branch(params[:branch]) - not_found! unless @branch - protected_branch = user_project.protected_branches.find_by(name: @branch.name) - user_project.protected_branches.create(name: @branch.name) unless protected_branch - - present @branch, with: Entities::RepoObject, project: user_project - end - - # Unprotect a single branch - # - # Parameters: - # id (required) - The ID of a project - # branch (required) - The name of the branch - # Example Request: - # PUT /projects/:id/repository/branches/:branch/unprotect - put ":id/repository/branches/:branch/unprotect" do - authorize_admin_project - - @branch = user_project.repository.find_branch(params[:branch]) - not_found! unless @branch - protected_branch = user_project.protected_branches.find_by(name: @branch.name) - protected_branch.destroy if protected_branch - - present @branch, with: Entities::RepoObject, project: user_project - end - # Get a project repository tags # # Parameters: diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb new file mode 100644 index 0000000000..47c0ba94a4 --- /dev/null +++ b/spec/requests/api/branches_spec.rb @@ -0,0 +1,95 @@ +require 'spec_helper' +require 'mime/types' + +describe API::API do + include ApiHelpers + before(:each) { enable_observers } + after(:each) {disable_observers} + + let(:user) { create(:user) } + let(:user2) { create(:user) } + let!(:project) { create(:project, creator_id: user.id) } + let!(:master) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } + let!(:guest) { create(:users_project, user: user2, project: project, project_access: UsersProject::GUEST) } + + describe "GET /projects/:id/repository/branches" do + it "should return an array of project branches" do + get api("/projects/#{project.id}/repository/branches", user) + response.status.should == 200 + json_response.should be_an Array + json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name + end + end + + describe "GET /projects/:id/repository/branches/:branch" do + it "should return the branch information for a single branch" do + get api("/projects/#{project.id}/repository/branches/new_design", user) + response.status.should == 200 + + json_response['name'].should == 'new_design' + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' + json_response['protected'].should == false + end + + it "should return a 403 error if guest" do + get api("/projects/#{project.id}/repository/branches", user2) + response.status.should == 403 + end + + it "should return a 404 error if branch is not available" do + get api("/projects/#{project.id}/repository/branches/unknown", user) + response.status.should == 404 + end + end + + describe "PUT /projects/:id/repository/branches/:branch/protect" do + it "should protect a single branch" do + put api("/projects/#{project.id}/repository/branches/new_design/protect", user) + response.status.should == 200 + + json_response['name'].should == 'new_design' + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' + json_response['protected'].should == true + end + + it "should return a 404 error if branch not found" do + put api("/projects/#{project.id}/repository/branches/unknown/protect", user) + response.status.should == 404 + end + + it "should return a 403 error if guest" do + put api("/projects/#{project.id}/repository/branches/new_design/protect", user2) + response.status.should == 403 + end + + it "should return success when protect branch again" do + put api("/projects/#{project.id}/repository/branches/new_design/protect", user) + put api("/projects/#{project.id}/repository/branches/new_design/protect", user) + response.status.should == 200 + end + end + + describe "PUT /projects/:id/repository/branches/:branch/unprotect" do + it "should unprotect a single branch" do + put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) + response.status.should == 200 + + json_response['name'].should == 'new_design' + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' + json_response['protected'].should == false + end + + it "should return success when unprotect branch" do + put api("/projects/#{project.id}/repository/branches/unknown/unprotect", user) + response.status.should == 404 + end + + it "should return success when unprotect branch again" do + put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) + put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) + response.status.should == 200 + end + end + + +end diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index 99d966edc3..44c561eab5 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -14,86 +14,6 @@ describe API::API do before { project.team << [user, :reporter] } - - describe "GET /projects/:id/repository/branches" do - it "should return an array of project branches" do - get api("/projects/#{project.id}/repository/branches", user) - response.status.should == 200 - json_response.should be_an Array - json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name - end - end - - describe "GET /projects/:id/repository/branches/:branch" do - it "should return the branch information for a single branch" do - get api("/projects/#{project.id}/repository/branches/new_design", user) - response.status.should == 200 - - json_response['name'].should == 'new_design' - json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' - json_response['protected'].should == false - end - - it "should return a 403 error if guest" do - get api("/projects/#{project.id}/repository/branches", user2) - response.status.should == 403 - end - - it "should return a 404 error if branch is not available" do - get api("/projects/#{project.id}/repository/branches/unknown", user) - response.status.should == 404 - end - end - - describe "PUT /projects/:id/repository/branches/:branch/protect" do - it "should protect a single branch" do - put api("/projects/#{project.id}/repository/branches/new_design/protect", user) - response.status.should == 200 - - json_response['name'].should == 'new_design' - json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' - json_response['protected'].should == true - end - - it "should return a 404 error if branch not found" do - put api("/projects/#{project.id}/repository/branches/unknown/protect", user) - response.status.should == 404 - end - - it "should return a 403 error if guest" do - put api("/projects/#{project.id}/repository/branches/new_design/protect", user2) - response.status.should == 403 - end - - it "should return success when protect branch again" do - put api("/projects/#{project.id}/repository/branches/new_design/protect", user) - put api("/projects/#{project.id}/repository/branches/new_design/protect", user) - response.status.should == 200 - end - end - - describe "PUT /projects/:id/repository/branches/:branch/unprotect" do - it "should unprotect a single branch" do - put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) - response.status.should == 200 - - json_response['name'].should == 'new_design' - json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' - json_response['protected'].should == false - end - - it "should return success when unprotect branch" do - put api("/projects/#{project.id}/repository/branches/unknown/unprotect", user) - response.status.should == 404 - end - - it "should return success when unprotect branch again" do - put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) - put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) - response.status.should == 200 - end - end - describe "GET /projects/:id/repository/tags" do it "should return an array of project tags" do get api("/projects/#{project.id}/repository/tags", user) From 8f3701eff005aeedcebff8ce02074f5056a369b3 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 31 Mar 2014 16:43:45 +0300 Subject: [PATCH 38/49] Move branches API docs to separate file Signed-off-by: Dmitriy Zaporozhets --- doc/api/README.md | 1 + doc/api/branches.md | 167 ++++++++++++++++++++++++++++++++++++++++ doc/api/repositories.md | 167 ---------------------------------------- 3 files changed, 168 insertions(+), 167 deletions(-) create mode 100644 doc/api/branches.md diff --git a/doc/api/README.md b/doc/api/README.md index fa5b12af14..b2edf47fe5 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -9,6 +9,7 @@ + [Repositories](repositories.md) + [Repository Files](repository_files.md) + [Commits](commits.md) ++ [Branches](branches.md) + [Merge Requests](merge_requests.md) + [Issues](issues.md) + [Milestones](milestones.md) diff --git a/doc/api/branches.md b/doc/api/branches.md new file mode 100644 index 0000000000..a62f9e38a9 --- /dev/null +++ b/doc/api/branches.md @@ -0,0 +1,167 @@ +# Branches + +## List repository branches + +Get a list of repository branches from a project, sorted by name alphabetically. + +``` +GET /projects/:id/repository/branches +``` + +Parameters: + ++ `id` (required) - The ID of a project + +```json +[ + { + "name": "master", + "commit": { + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", + "parents": [ + { + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" + } + ], + "tree": "46e82de44b1061621357f24c05515327f2795a95", + "message": "add projects API", + "author": { + "name": "John Smith", + "email": "john@example.com" + }, + "committer": { + "name": "John Smith", + "email": "john@example.com" + }, + "authored_date": "2012-06-27T05:51:39-07:00", + "committed_date": "2012-06-28T03:44:20-07:00" + }, + "protected": true + } +] +``` + + +## Get single repository branch + +Get a single project repository branch. + +``` +GET /projects/:id/repository/branches/:branch +``` + +Parameters: + ++ `id` (required) - The ID of a project ++ `branch` (required) - The name of the branch + +```json +{ + "name": "master", + "commit": { + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", + "parents": [ + { + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" + } + ], + "tree": "46e82de44b1061621357f24c05515327f2795a95", + "message": "add projects API", + "author": { + "name": "John Smith", + "email": "john@example.com" + }, + "committer": { + "name": "John Smith", + "email": "john@example.com" + }, + "authored_date": "2012-06-27T05:51:39-07:00", + "committed_date": "2012-06-28T03:44:20-07:00" + }, + "protected": true +} +``` + + +## Protect repository branch + +Protects a single project repository branch. This is an idempotent function, protecting an already +protected repository branch still returns a `200 Ok` status code. + +``` +PUT /projects/:id/repository/branches/:branch/protect +``` + +Parameters: + ++ `id` (required) - The ID of a project ++ `branch` (required) - The name of the branch + +```json +{ + "name": "master", + "commit": { + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", + "parents": [ + { + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" + } + ], + "tree": "46e82de44b1061621357f24c05515327f2795a95", + "message": "add projects API", + "author": { + "name": "John Smith", + "email": "john@example.com" + }, + "committer": { + "name": "John Smith", + "email": "john@example.com" + }, + "authored_date": "2012-06-27T05:51:39-07:00", + "committed_date": "2012-06-28T03:44:20-07:00" + }, + "protected": true +} +``` + + +## Unprotect repository branch + +Unprotects a single project repository branch. This is an idempotent function, unprotecting an already +unprotected repository branch still returns a `200 Ok` status code. + +``` +PUT /projects/:id/repository/branches/:branch/unprotect +``` + +Parameters: + ++ `id` (required) - The ID of a project ++ `branch` (required) - The name of the branch + +```json +{ + "name": "master", + "commit": { + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", + "parents": [ + { + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" + } + ], + "tree": "46e82de44b1061621357f24c05515327f2795a95", + "message": "add projects API", + "author": { + "name": "John Smith", + "email": "john@example.com" + }, + "committer": { + "name": "John Smith", + "email": "john@example.com" + }, + "authored_date": "2012-06-27T05:51:39-07:00", + "committed_date": "2012-06-28T03:44:20-07:00" + }, + "protected": false +} +``` diff --git a/doc/api/repositories.md b/doc/api/repositories.md index 65ea361535..3b042e14e7 100644 --- a/doc/api/repositories.md +++ b/doc/api/repositories.md @@ -1,170 +1,3 @@ -## List repository branches - -Get a list of repository branches from a project, sorted by name alphabetically. - -``` -GET /projects/:id/repository/branches -``` - -Parameters: - -+ `id` (required) - The ID of a project - -```json -[ - { - "name": "master", - "commit": { - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "parents": [ - { - "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - } - ], - "tree": "46e82de44b1061621357f24c05515327f2795a95", - "message": "add projects API", - "author": { - "name": "John Smith", - "email": "john@example.com" - }, - "committer": { - "name": "John Smith", - "email": "john@example.com" - }, - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00" - }, - "protected": true - } -] -``` - - -## Get single repository branch - -Get a single project repository branch. - -``` -GET /projects/:id/repository/branches/:branch -``` - -Parameters: - -+ `id` (required) - The ID of a project -+ `branch` (required) - The name of the branch - -```json -{ - "name": "master", - "commit": { - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "parents": [ - { - "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - } - ], - "tree": "46e82de44b1061621357f24c05515327f2795a95", - "message": "add projects API", - "author": { - "name": "John Smith", - "email": "john@example.com" - }, - "committer": { - "name": "John Smith", - "email": "john@example.com" - }, - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00" - }, - "protected": true -} -``` - - -## Protect repository branch - -Protects a single project repository branch. This is an idempotent function, protecting an already -protected repository branch still returns a `200 Ok` status code. - -``` -PUT /projects/:id/repository/branches/:branch/protect -``` - -Parameters: - -+ `id` (required) - The ID of a project -+ `branch` (required) - The name of the branch - -```json -{ - "name": "master", - "commit": { - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "parents": [ - { - "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - } - ], - "tree": "46e82de44b1061621357f24c05515327f2795a95", - "message": "add projects API", - "author": { - "name": "John Smith", - "email": "john@example.com" - }, - "committer": { - "name": "John Smith", - "email": "john@example.com" - }, - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00" - }, - "protected": true -} -``` - - -## Unprotect repository branch - -Unprotects a single project repository branch. This is an idempotent function, unprotecting an already -unprotected repository branch still returns a `200 Ok` status code. - -``` -PUT /projects/:id/repository/branches/:branch/unprotect -``` - -Parameters: - -+ `id` (required) - The ID of a project -+ `branch` (required) - The name of the branch - -```json -{ - "name": "master", - "commit": { - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "parents": [ - { - "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - } - ], - "tree": "46e82de44b1061621357f24c05515327f2795a95", - "message": "add projects API", - "author": { - "name": "John Smith", - "email": "john@example.com" - }, - "committer": { - "name": "John Smith", - "email": "john@example.com" - }, - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00" - }, - "protected": false -} -``` - - ## List project repository tags Get a list of repository tags from a project, sorted by name in reverse alphabetical order. From 2496f85d464c599d83bd95bde11b1cb6895693bd Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Mon, 31 Mar 2014 18:10:20 +0200 Subject: [PATCH 39/49] Fix rendering for enumeration for doc page --- doc/workflow/workflow.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/workflow/workflow.md b/doc/workflow/workflow.md index 1c238f7495..bb232e9d5c 100644 --- a/doc/workflow/workflow.md +++ b/doc/workflow/workflow.md @@ -3,24 +3,25 @@ ```bash git clone git@example.com:project-name.git ``` + 2. Create branch with your feature ```bash git checkout -b $feature_name ``` -3. Write code. Comit changes +3. Write code. Commit changes ```bash git commit -am "My feature is ready" ``` 4. Push your branch to GitLab - + ```bash git push origin $feature_name ``` -5. Review your code on Commits page +5. Review your code on commits page 6. Create a merge request 7. Your team lead will review the code & merge it to the main branch From f6189a9f07607628d02c3660496d50c57dcc226b Mon Sep 17 00:00:00 2001 From: dosire Date: Mon, 31 Mar 2014 18:23:10 +0200 Subject: [PATCH 40/49] Use underscores in doc filename like elsewhere. --- doc/update/{mysql-to-postgresql.md => mysql_to_postgresql.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/update/{mysql-to-postgresql.md => mysql_to_postgresql.md} (100%) diff --git a/doc/update/mysql-to-postgresql.md b/doc/update/mysql_to_postgresql.md similarity index 100% rename from doc/update/mysql-to-postgresql.md rename to doc/update/mysql_to_postgresql.md From 230335650d2328bf00e8e2c987887d7d670387da Mon Sep 17 00:00:00 2001 From: dosire Date: Tue, 1 Apr 2014 09:19:37 +0200 Subject: [PATCH 41/49] Link to doc site from the readme. --- README.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2668ed8bac..fcc40f1b91 100644 --- a/README.md +++ b/README.md @@ -113,19 +113,9 @@ or start each component separately Single Spinach test: bundle exec spinach features/project/issues/milestones.feature -### GitLab interfaces +### Documentation -* [GitLab API doc](doc/api/README.md) or see the [GitLab API website](http://api.gitlab.org/) - -* [Rake tasks](doc/raketasks) including a [backup and restore procedure](doc/raketasks/backup_restore.md) - -* [Directory structure](doc/install/structure.md) - -* [Database installation](doc/install/databases.md) - -* [Markdown specification](doc/markdown/markdown.md) - -* [Security guide](doc/security/rack_attack.md) to throttle abusive requests +All documentation can be found on [doc.gitlab.com/ce/](http://doc.gitlab.com/ce/). ### Getting help From 95b84e2c5aa92a5a8effc108fdbdf596dff4818c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 1 Apr 2014 10:33:23 +0300 Subject: [PATCH 42/49] Move branch creation logic in service Signed-off-by: Dmitriy Zaporozhets --- app/controllers/projects/branches_controller.rb | 6 +----- app/services/create_branch_service.rb | 13 +++++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 app/services/create_branch_service.rb diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index aa6914414c..6a6cbe4818 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -16,11 +16,7 @@ class Projects::BranchesController < Projects::ApplicationController end def create - @repository.add_branch(params[:branch_name], params[:ref]) - - if new_branch = @repository.find_branch(params[:branch_name]) - Event.create_ref_event(@project, current_user, new_branch, 'add') - end + CreateBranchService.new.execute(project, params[:branch_name], params[:ref], current_user) redirect_to project_branches_path(@project) end diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb new file mode 100644 index 0000000000..98beeee835 --- /dev/null +++ b/app/services/create_branch_service.rb @@ -0,0 +1,13 @@ +class CreateBranchService + def execute(project, branch_name, ref, current_user) + repository = project.repository + repository.add_branch(branch_name, ref) + new_branch = repository.find_branch(branch_name) + + if new_branch + Event.create_ref_event(project, current_user, new_branch, 'add') + end + + new_branch + end +end From 33a00ceeeacfc52272d25cef914a027b9bf13a2a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 1 Apr 2014 10:39:53 +0300 Subject: [PATCH 43/49] Create branch via API Signed-off-by: Dmitriy Zaporozhets --- lib/api/branches.rb | 15 +++++++++++++++ lib/api/helpers.rb | 4 ++++ spec/requests/api/branches_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/lib/api/branches.rb b/lib/api/branches.rb index 6339094bd9..953c6100f8 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -65,6 +65,21 @@ module API present @branch, with: Entities::RepoObject, project: user_project end + + # Create branch + # + # Parameters: + # id (required) - The ID of a project + # branch_name (required) - The name of the branch + # ref (required) - Create branch from commit sha or existing branch + # Example Request: + # POST /projects/:id/repository/branches + post ":id/repository/branches" do + authorize_push_project + @branch = CreateBranchService.new.execute(user_project, params[:branch_name], params[:ref], current_user) + + present @branch, with: Entities::RepoObject, project: user_project + end end end end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 03a2968fcc..7ee4b9d138 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -78,6 +78,10 @@ module API end end + def authorize_push_project + authorize! :push_code, user_project + end + def authorize_admin_project authorize! :admin_project, user_project end diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb index 47c0ba94a4..f792c618e6 100644 --- a/spec/requests/api/branches_spec.rb +++ b/spec/requests/api/branches_spec.rb @@ -92,4 +92,24 @@ describe API::API do end + describe "POST /projects/:id/repository/branches" do + it "should create a new branch" do + post api("/projects/#{project.id}/repository/branches", user), + branch_name: 'new_design', + ref: '621491c677087aa243f165eab467bfdfbee00be1' + + response.status.should == 201 + + json_response['name'].should == 'new_design' + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' + end + + it "should deny for user without push access" do + post api("/projects/#{project.id}/repository/branches", user2), + branch_name: 'new_design', + ref: '621491c677087aa243f165eab467bfdfbee00be1' + + response.status.should == 403 + end + end end From d7afdab7a5fcb1aa686955f6d13e024737e89a94 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 1 Apr 2014 10:44:58 +0300 Subject: [PATCH 44/49] Add docs for create branch via api Signed-off-by: Dmitriy Zaporozhets --- doc/api/branches.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/api/branches.md b/doc/api/branches.md index a62f9e38a9..3417a69507 100644 --- a/doc/api/branches.md +++ b/doc/api/branches.md @@ -165,3 +165,34 @@ Parameters: "protected": false } ``` + +## Create repository branch + + +``` +POST /projects/:id/repository/branches +``` + +Parameters: + ++ `id` (required) - The ID of a project ++ `branch_name` (required) - The name of the branch ++ `ref` (required) - Create branch from commit sha or existing branch + +```json +{ + "name": "my-new-branch", + "commit": { + "id": "8848c0e90327a0b70f1865b843fb2fbfb9345e57", + "message": "Merge pull request #54 from brightbox/use_fog_brightbox_module\n\nUpdate to use fog-brightbox module", + "parent_ids": ["fff449e0bf453576f16c91d6544f00a2664009d8", "f93a93626fec20fd659f4ed3ab2e64019b6169ae"], + "authored_date": "2014-02-20T19:54:55+02:00", + "author_name": "john smith", + "author_email": "john@example.com", + "committed_date": "2014-02-20T19:54:55+02:00", + "committer_name": "john smith", + "committer_email": "john@example.com" + }, + "protected": false +} +``` From a88225b7689ab87b49908db23e1bebf1c7ea09d3 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 1 Apr 2014 10:45:10 +0300 Subject: [PATCH 45/49] Update changelog with new feature Signed-off-by: Dmitriy Zaporozhets --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index e3ab6a5e92..d936986a77 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ v 6.8.0 - Remove omniauth-ldap nickname bug workaround - Drop all tables before restoring a Postgres backup - Make the repository downloads path configurable + - Create branches via API (sponsored by O'Reilly Media) v 6.7.2 - Fix upgrader script From 799361a389f890620bd11d75f2fae5a6aa4fc9e6 Mon Sep 17 00:00:00 2001 From: dosire Date: Tue, 1 Apr 2014 10:28:55 +0200 Subject: [PATCH 46/49] SSH section was missing in doc and corrected the deploy key section. --- doc/README.md | 1 + doc/ssh/README.md | 2 ++ doc/ssh/deploy_keys.md | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 doc/ssh/README.md diff --git a/doc/README.md b/doc/README.md index 865806f297..99a0d678cd 100644 --- a/doc/README.md +++ b/doc/README.md @@ -11,6 +11,7 @@ + [Raketasks](raketasks/README.md) + [Release](release/README.md) + [Security](security/README.md) ++ [SSH](ssh/README.md) + [System hooks](system_hooks/system_hooks.md) + [Update](update/README.md) + [Web hooks](web_hooks/web_hooks.md) diff --git a/doc/ssh/README.md b/doc/ssh/README.md new file mode 100644 index 0000000000..76d9e8bb07 --- /dev/null +++ b/doc/ssh/README.md @@ -0,0 +1,2 @@ ++ [Deploy keys](deploy_keys.md) ++ [SSH](ssh.md) diff --git a/doc/ssh/deploy_keys.md b/doc/ssh/deploy_keys.md index 56fe98bb10..c7125b7949 100644 --- a/doc/ssh/deploy_keys.md +++ b/doc/ssh/deploy_keys.md @@ -9,4 +9,4 @@ After this the machine that uses the corresponding private key has read-only acc You can't add the same deploy key twice with the 'New Deploy Key' option. If you want to add the same key to another project please enable it in the list that says 'Deploy keys from projects available to you'. -You need to be the owner of the deploy key to see it in this list. +All the deploy keys of all the projects you have access to are available. This project access can happen through being a direct member of the project or through a group. See `def accessible_deploy_keys` in `app/models/user.rb` for more information. From 9ae11007fee229f39c6edc072597d1b457c8f982 Mon Sep 17 00:00:00 2001 From: dosire Date: Tue, 1 Apr 2014 10:41:57 +0200 Subject: [PATCH 47/49] Mention search options. --- doc/api/users.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/users.md b/doc/api/users.md index 4098da72b3..1b9eecf215 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -51,6 +51,10 @@ GET /users ] ``` +You can search for a users by email or username with: +`/users?search=John` + +Also see `def search query` in `app/models/user.rb`. ## Single user From 24ea884fab740ea9c666179a61c53d5768a8db89 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 1 Apr 2014 12:30:07 +0300 Subject: [PATCH 48/49] add spring to guard Signed-off-by: Dmitriy Zaporozhets --- Guardfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Guardfile b/Guardfile index e682f0b6cf..b6a9a0545e 100644 --- a/Guardfile +++ b/Guardfile @@ -1,7 +1,7 @@ # A sample Guardfile # More info at https://github.com/guard/guard#readme -guard 'rspec', :version => 2, :all_on_start => false, :all_after_pass => false do +guard 'rspec', cmd:"spring rspec", :version => 2, :all_on_start => false, :all_after_pass => false do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch(%r{^lib/api/(.+)\.rb$}) { |m| "spec/requests/api/#{m[1]}_spec.rb" } From 3b0510a7c124a8511966ad4785757bd4d78998ac Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 1 Apr 2014 13:08:16 +0300 Subject: [PATCH 49/49] Use ruby 1.9 hash syntax in Guardfile Signed-off-by: Dmitriy Zaporozhets --- Guardfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Guardfile b/Guardfile index b6a9a0545e..e19a312377 100644 --- a/Guardfile +++ b/Guardfile @@ -1,7 +1,7 @@ # A sample Guardfile # More info at https://github.com/guard/guard#readme -guard 'rspec', cmd:"spring rspec", :version => 2, :all_on_start => false, :all_after_pass => false do +guard 'rspec', cmd: "spring rspec", version: 2, all_on_start: false, all_after_pass: false do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch(%r{^lib/api/(.+)\.rb$}) { |m| "spec/requests/api/#{m[1]}_spec.rb" }