diff --git a/Gemfile b/Gemfile index d950f43b20522ca0f6948479424c85e7afeba0cf..c80705af3168a0418362f0df7c0a87307f80822c 100644 --- a/Gemfile +++ b/Gemfile @@ -23,7 +23,7 @@ gem 'omniauth-github' # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '2.1.0' +gem "gitlab_git", '2.1.1' # Ruby/Rack Git Smart-HTTP Server Handler gem 'gitlab-grack', '~> 1.0.1', require: 'grack' diff --git a/Gemfile.lock b/Gemfile.lock index abec9243bcedfc36842ab7ade23ad2103f43face..e345c40f4450a69365c282ec520cfeb4c52c2992 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -186,7 +186,7 @@ GEM gitlab-pygments.rb (0.3.2) posix-spawn (~> 0.3.6) yajl-ruby (~> 1.1.0) - gitlab_git (2.1.0) + gitlab_git (2.1.1) activesupport (~> 3.2.13) github-linguist (~> 2.3.4) gitlab-grit (~> 2.6.0) @@ -576,7 +576,7 @@ DEPENDENCIES gitlab-gollum-lib (~> 1.0.1) gitlab-grack (~> 1.0.1) gitlab-pygments.rb (~> 0.3.2) - gitlab_git (= 2.1.0) + gitlab_git (= 2.1.1) gitlab_meta (= 6.0) gitlab_omniauth-ldap (= 1.0.3) gon diff --git a/VERSION b/VERSION index 09b254e90c61ed28bb68a54752cf04f6a736a7d3..9b9a244206f6ab79c1155fa07c154d15d4ac54ab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.0 +6.0.2 diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 1190dd40b73c0c3c387292132ad5ab23deacfefe..60fc3f6b551fb416f3944c3778f6b69ef182f1b1 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -87,7 +87,6 @@ class GroupsController < ApplicationController end def destroy - @group.truncate_teams @group.destroy redirect_to root_path, notice: 'Group was removed.' diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb index 0d35f373e9c7511e10b12c69b1705019f7ff97fd..0c23d411f4c5040bbec86bb4ef73bcce69344e7d 100644 --- a/app/controllers/projects/raw_controller.rb +++ b/app/controllers/projects/raw_controller.rb @@ -11,9 +11,17 @@ class Projects::RawController < Projects::ApplicationController @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path) if @blob.exists? + type = if @blob.mime_type =~ /html|javascript/ + 'text/plain; charset=utf-8' + else + @blob.mime_type + end + + headers['X-Content-Type-Options'] = 'nosniff' + send_data( @blob.data, - type: @blob.mime_type, + type: type, disposition: 'inline', filename: @blob.name ) diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index f22070f85043f97b6eef5b10c4884eb8698c969e..67ad02e8048d6d1e5b35bb2aec5f1db8959e2e4e 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -15,7 +15,7 @@ module Mentionable matches.each do |match| identifier = match.delete "@" if has_project - id = project.users_projects.joins(:user).where(users: { username: identifier }).pluck(:user_id).first + id = project.team.members.find { |u| u.username == identifier }.try(:id) else id = User.where(username: identifier).pluck(:id).first end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index b7df2e40a164ddf7c898cc007b31f5e427e6857a..d525ad17537bcdcc1ba6655d318597bbe5b7c37d 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -250,6 +250,10 @@ class MergeRequest < ActiveRecord::Base (source_project.root_ref? source_branch) || for_fork? end + def project + target_project + end + private def dump_commits(commits) diff --git a/app/models/user.rb b/app/models/user.rb index a149b3a0322785d2e0a4c67f5b5b6416ffeb233b..53e60747df80724809ee3a17bc104ecfbdff7bdf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -319,7 +319,7 @@ class User < ActiveRecord::Base end def several_namespaces? - namespaces.many? + namespaces.many? || owned_groups.any? end def namespace_id diff --git a/db/migrate/20130419190306_allow_merges_for_forks.rb b/db/migrate/20130419190306_allow_merges_for_forks.rb index 691293a1c3ec31e05688ff5970609b8bccd566d8..56ce58a846dba43d724635aaaeb7b16d7a0ee2a4 100644 --- a/db/migrate/20130419190306_allow_merges_for_forks.rb +++ b/db/migrate/20130419190306_allow_merges_for_forks.rb @@ -1,7 +1,8 @@ class AllowMergesForForks < ActiveRecord::Migration def self.up - add_column :merge_requests, :target_project_id, :integer, :null => false + add_column :merge_requests, :target_project_id, :integer, :null => true MergeRequest.update_all("target_project_id = project_id") + change_column :merge_requests, :target_project_id, :integer, :null => false rename_column :merge_requests, :project_id, :source_project_id end diff --git a/doc/install/databases.md b/doc/install/databases.md index 5ec1d0c6524e41c76ce7f752e7e8fe0cab2068a4..6477e1c967c1531485e94fa3fe88f2e14122ddf8 100644 --- a/doc/install/databases.md +++ b/doc/install/databases.md @@ -14,6 +14,9 @@ GitLab supports the following databases: # Pick a database root password (can be anything), type it and press enter # Retype the database root password and press enter + # Secure your installation. + sudo mysql_secure_installation + # Login to MySQL mysql -u root -p diff --git a/doc/install/installation.md b/doc/install/installation.md index 8ec0998e5bdc9aae80f9d5b1246b3a1f1c3767ac..dd696f954aa8d20dfd601f790c2a09511304f4f7 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -122,7 +122,7 @@ GitLab Shell is a ssh access and repository management software developed specia cd gitlab-shell # switch to right version - sudo -u git -H git checkout v1.7.0 + sudo -u git -H git checkout v1.7.1 sudo -u git -H cp config.yml.example config.yml @@ -153,10 +153,10 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install cd /home/git/gitlab # Checkout to stable release - sudo -u git -H git checkout 5-4-stable + sudo -u git -H git checkout 6-0-stable **Note:** -You can change `5-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! +You can change `6-0-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! ## Configure it @@ -232,10 +232,10 @@ Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup. sudo gem install charlock_holmes --version '0.6.9.4' # For MySQL (note, the option says "without ... postgres") - sudo -u git -H bundle install --deployment --without development test postgres unicorn aws + sudo -u git -H bundle install --deployment --without development test postgres aws # Or for PostgreSQL (note, the option says "without ... mysql") - sudo -u git -H bundle install --deployment --without development test mysql unicorn aws + sudo -u git -H bundle install --deployment --without development test mysql aws ## Initialize Database and Activate Advanced Features diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md index 947998525496970200e94525bb6b59fa39050c53..3d58bee2bef13b7b230efb07f0a6987af51d65ab 100644 --- a/doc/update/5.4-to-6.0.md +++ b/doc/update/5.4-to-6.0.md @@ -4,7 +4,7 @@ #### Global projects -We deprecated root(global) namespace for projects. +We deprecated root(global) namespace for projects. So you need to move all your global projects under group/users manually before update or they will be automatically moved to the owner namespace during the update. #### Teams @@ -36,17 +36,25 @@ sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create ```bash cd /home/git/gitlab sudo -u git -H git fetch -sudo -u git -H git checkout 6-0-dev +sudo -u git -H git checkout 6-0-stable ``` -### 3. Install additional packages +### 3. Update gitlab-shell + +```bash +cd /home/git/gitlab-shell +sudo -u git -H git fetch +sudo -u git -H git checkout v1.7.0 +``` + +### 4. Install additional packages ```bash # For reStructuredText markup language support install required package: sudo apt-get install python-docutils ``` -### 4. Install libs, migrations, etc. +### 5. Install libs, migrations, etc. ```bash cd /home/git/gitlab @@ -54,7 +62,7 @@ cd /home/git/gitlab # MySQL sudo -u git -H bundle install --without development test postgres --deployment -#PostgreSQL +# PostgreSQL sudo -u git -H bundle install --without development test mysql --deployment sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production @@ -63,29 +71,35 @@ sudo -u git -H bundle exec rake migrate_global_projects RAILS_ENV=production sudo -u git -H bundle exec rake migrate_keys RAILS_ENV=production sudo -u git -H bundle exec rake migrate_inline_notes RAILS_ENV=production +# Clear redis cache +sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production + +# Clear and precompile assets +sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production +sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ``` -### 5. Update config files +### 6. Update config files Note: We switched from Puma in GitLab 5.4 to unicorn in GitLab 6.0. * Make `/home/git/gitlab/config/gitlab.yml` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/gitlab.yml.example but with your settings. * Make `/home/git/gitlab/config/unicorn.rb` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/unicorn.rb.example but with your settings. -### 6. Update Init script +### 7. Update Init script ```bash sudo rm /etc/init.d/gitlab -sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/master/lib/support/init.d/gitlab +sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/6-0-stable/lib/support/init.d/gitlab sudo chmod +x /etc/init.d/gitlab ``` -### 7. Start application +### 8. Start application sudo service gitlab start sudo service nginx restart -### 8. Check application status +### 9. Check application status Check if GitLab and its environment are configured correctly: diff --git a/lib/gitlab/inline_diff.rb b/lib/gitlab/inline_diff.rb index 44cf49b40473a359a2c7c41fbf95705996ad8d91..89c8e0680c30b1c70353290a323a30911e45c694 100644 --- a/lib/gitlab/inline_diff.rb +++ b/lib/gitlab/inline_diff.rb @@ -13,6 +13,9 @@ module Gitlab second_line = diff_arr[index+2] max_length = [first_line.size, second_line.size].max + # Skip inline diff if empty line was replaced with content + next if first_line == "-\n" + first_the_same_symbols = 0 (0..max_length + 1).each do |i| first_the_same_symbols = i - 1 @@ -20,10 +23,19 @@ module Gitlab break end end + first_token = first_line[0..first_the_same_symbols][1..-1] start = first_token + START - diff_arr[index+1].sub!(first_token, first_token => start) - diff_arr[index+2].sub!(first_token, first_token => start) + + if first_token.empty? + # In case if we remove string of spaces in commit + diff_arr[index+1].sub!("-", "-" => "-#{START}") + diff_arr[index+2].sub!("+", "+" => "+#{START}") + else + diff_arr[index+1].sub!(first_token, first_token => start) + diff_arr[index+2].sub!(first_token, first_token => start) + end + last_the_same_symbols = 0 (1..max_length + 1).each do |i| last_the_same_symbols = -i diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index 29c9d98965d016209174ad8582c07a5734b7b6d7..b4870d25954c7b7bd731f5be9cf002d0733a1981 100644 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -1,7 +1,8 @@ -#! /bin/bash +#! /bin/sh # GITLAB # Maintainer: @randx +# Authors: rovanion.luckey@gmail.com, @randx # App Version: 6.0 ### BEGIN INIT INFO @@ -14,102 +15,227 @@ # Description: GitLab git repository management ### END INIT INFO +### Environment variables +RAILS_ENV="production" -APP_ROOT="/home/git/gitlab" -APP_USER="git" -DAEMON_OPTS="-c $APP_ROOT/config/unicorn.rb -E production" -PID_PATH="$APP_ROOT/tmp/pids" -SOCKET_PATH="$APP_ROOT/tmp/sockets" -WEB_SERVER_PID="$PID_PATH/unicorn.pid" -SIDEKIQ_PID="$PID_PATH/sidekiq.pid" -STOP_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:stop" -START_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:start" -NAME="gitlab" -DESC="GitLab service" - -check_pid(){ - if [ -f $WEB_SERVER_PID ]; then - PID=`cat $WEB_SERVER_PID` - SPID=`cat $SIDEKIQ_PID` - STATUS=`ps aux | grep $PID | grep -v grep | wc -l` +# Script variable names should be lower-case not to conflict with internal +# /bin/sh variables such as PATH, EDITOR or SHELL. +app_root="/home/git/gitlab" +app_user="git" +unicorn_conf="$app_root/config/unicorn.rb" +pid_path="$app_root/tmp/pids" +socket_path="$app_root/tmp/sockets" +web_server_pid_path="$pid_path/unicorn.pid" +sidekiq_pid_path="$pid_path/sidekiq.pid" + + + +### Here ends user configuration ### + + +# Switch to the app_user if it is not he/she who is running the script. +if [ "$USER" != "$app_user" ]; then + sudo -u "$app_user" -H -i $0 "$@"; exit; +fi + +# Switch to the gitlab path, if it fails exit with an error. +if ! cd "$app_root" ; then + echo "Failed to cd into $app_root, exiting!"; exit 1 +fi + +### Init Script functions + +check_pids(){ + if ! mkdir -p "$pid_path"; then + echo "Could not create the path $pid_path needed to store the pids." + exit 1 + fi + # If there exists a file which should hold the value of the Unicorn pid: read it. + if [ -f "$web_server_pid_path" ]; then + wpid=$(cat "$web_server_pid_path") else - STATUS=0 - PID=0 + wpid=0 + fi + if [ -f "$sidekiq_pid_path" ]; then + spid=$(cat "$sidekiq_pid_path") + else + spid=0 fi } -execute() { - sudo -u $APP_USER -H bash -l -c "$1" -} +# We use the pids in so many parts of the script it makes sense to always check them. +# Only after start() is run should the pids change. Sidekiq sets it's own pid. +check_pids -start() { - cd $APP_ROOT - check_pid - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then - # Program is running, exit with error code 1. - echo "Error! $DESC $NAME is currently running!" - exit 1 + +# Checks whether the different parts of the service are already running or not. +check_status(){ + check_pids + # If the web server is running kill -0 $wpid returns true, or rather 0. + # Checks of *_status should only check for == 0 or != 0, never anything else. + if [ $wpid -ne 0 ]; then + kill -0 "$wpid" 2>/dev/null + web_status="$?" else - if [ `whoami` = root ]; then - execute "rm -f $SOCKET_PATH/gitlab.socket" - execute "RAILS_ENV=production bundle exec unicorn_rails $DAEMON_OPTS > /dev/null 2>&1 &" - execute "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &" - echo "$DESC started" + web_status="-1" + fi + if [ $spid -ne 0 ]; then + kill -0 "$spid" 2>/dev/null + sidekiq_status="$?" + else + sidekiq_status="-1" + fi +} + +# Check for stale pids and remove them if necessary +check_stale_pids(){ + check_status + # If there is a pid it is something else than 0, the service is running if + # *_status is == 0. + if [ "$wpid" != "0" -a "$web_status" != "0" ]; then + echo "Removing stale Unicorn web server pid. This is most likely caused by the web server crashing the last time it ran." + if ! rm "$web_server_pid_path"; then + echo "Unable to remove stale pid, exiting" + exit 1 + fi + fi + if [ "$spid" != "0" -a "$sidekiq_status" != "0" ]; then + echo "Removing stale Sidekiq web server pid. This is most likely caused by the Sidekiq crashing the last time it ran." + if ! rm "$sidekiq_pid_path"; then + echo "Unable to remove stale pid, exiting" + exit 1 fi fi } -stop() { - cd $APP_ROOT - check_pid - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then - ## Program is running, stop it. - kill -QUIT `cat $WEB_SERVER_PID` - execute "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &" - rm "$WEB_SERVER_PID" >> /dev/null - echo "$DESC stopped" +# If no parts of the service is running, bail out. +exit_if_not_running(){ + check_stale_pids + if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then + echo "GitLab is not running." + exit + fi +} + +# Starts Unicorn and Sidekiq. +start() { + check_stale_pids + + # Then check if the service is running. If it is: don't start again. + if [ "$web_status" = "0" ]; then + echo "The Unicorn web server already running with pid $wpid, not restarting." else - ## Program is not running, exit with error. - echo "Error! $DESC not started!" - exit 1 + echo "Starting the GitLab Unicorn web server..." + # Remove old socket if it exists + rm -f "$socket_path"/gitlab.socket 2>/dev/null + # Start the webserver + bundle exec unicorn_rails -D -c "$unicorn_conf" -E "$RAILS_ENV" + fi + + # If sidekiq is already running, don't start it again. + if [ "$sidekiq_status" = "0" ]; then + echo "The Sidekiq job dispatcher is already running with pid $spid, not restarting" + else + echo "Starting the GitLab Sidekiq event dispatcher..." + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:start + # We are sleeping a bit here because sidekiq is slow at writing it's pid + sleep 2 fi + + # Finally check the status to tell wether or not GitLab is running + status } -restart() { - cd $APP_ROOT - check_pid - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then - echo "Restarting $DESC..." - kill -USR2 `cat $WEB_SERVER_PID` - execute "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &" - if [ `whoami` = root ]; then - execute "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &" - fi - echo "$DESC restarted." +# Asks the Unicorn and the Sidekiq if they would be so kind as to stop, if not kills them. +stop() { + exit_if_not_running + # If the Unicorn web server is running, tell it to stop; + if [ "$web_status" = "0" ]; then + kill -QUIT "$wpid" & + echo "Stopping the GitLab Unicorn web server..." + stopping=true else - echo "Error, $NAME not running!" - exit 1 + echo "The Unicorn web was not running, doing nothing." + fi + # And do the same thing for the Sidekiq. + if [ "$sidekiq_status" = "0" ]; then + printf "Stopping Sidekiq job dispatcher." + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:stop & + stopping=true + else + echo "The Sidekiq was not running, must have run out of breath." fi + + + # If something needs to be stopped, lets wait for it to stop. Never use SIGKILL in a script. + while [ "$stopping" = "true" ]; do + sleep 1 + check_status + if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then + printf "." + else + printf "\n" + break + fi + done + sleep 1 + # Cleaning up unused pids + rm "$web_server_pid_path" 2>/dev/null + # rm "$sidekiq_pid_path" # Sidekiq seems to be cleaning up it's own pid. + + status } +# Returns the status of GitLab and it's components status() { - cd $APP_ROOT - check_pid - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then - echo "$DESC / Unicorn with PID $PID is running." - echo "$DESC / Sidekiq with PID $SPID is running." + check_status + if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then + echo "GitLab is not running." + return + fi + if [ "$web_status" = "0" ]; then + echo "The GitLab Unicorn webserver with pid $wpid is running." else - echo "$DESC is not running." - exit 1 + printf "The GitLab Unicorn webserver is \033[31mnot running\033[0m.\n" + fi + if [ "$sidekiq_status" = "0" ]; then + echo "The GitLab Sidekiq job dispatcher with pid $spid is running." + else + printf "The GitLab Sidekiq job dispatcher is \033[31mnot running\033[0m.\n" + fi + if [ "$web_status" = "0" -a "$sidekiq_status" = "0" ]; then + printf "GitLab and all it's components are \033[32mup and running\033[0m.\n" fi } -## Check to see if we are running as root first. -## Found at http://www.cyberciti.biz/tips/shell-root-user-check-script.html -if [ "$(id -u)" != "0" ]; then - echo "This script must be run as root" +reload(){ + exit_if_not_running + if [ "$wpid" = "0" ];then + echo "The GitLab Unicorn Web server is not running thus its configuration can't be reloaded." exit 1 -fi + fi + printf "Reloading GitLab Unicorn configuration... " + kill -USR2 "$wpid" + echo "Done." + echo "Restarting GitLab Sidekiq since it isn't capable of reloading its config..." + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:stop + echo "Starting Sidekiq..." + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:start + # Waiting 2 seconds for sidekiq to write it. + sleep 2 + status +} + +restart(){ + check_status + if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then + stop + fi + start +} + + +## Finally the input handling. case "$1" in start) @@ -122,17 +248,15 @@ case "$1" in restart ;; reload|force-reload) - echo -n "Reloading $NAME configuration: " - kill -HUP `cat $PID` - echo "done." + reload ;; status) status ;; *) - echo "Usage: sudo service gitlab {start|stop|restart|reload}" >&2 + echo "Usage: service gitlab {start|stop|restart|reload|status}" exit 1 ;; esac -exit 0 +exit diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 3e929c52990de1633104b0448a5cee5e189efb3a..d4f14c911c4c0d33fe5e6058689548f1415c2b84 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -1,6 +1,6 @@ # GITLAB # Maintainer: @randx -# App Version: 5.0 +# App Version: 6.0 upstream gitlab { server unix:/home/git/gitlab/tmp/sockets/gitlab.socket; diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index eb8ffa5aafee8d009e276e75ffafbe5186841331..45208a9486af6b98bb8bfd3a843480120f8eba8d 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -139,6 +139,19 @@ describe User do it { @user.owned_groups.should == [@group] } end + describe 'group multiple owners' do + before do + ActiveRecord::Base.observers.enable(:user_observer) + @user = create :user + @user2 = create :user + @group = create :group, owner: @user + + @group.add_users([@user2.id], UsersGroup::OWNER) + end + + it { @user2.several_namespaces?.should be_true } + end + describe 'namespaced' do before do ActiveRecord::Base.observers.enable(:user_observer)