Rewrite and improve git backend logic. Fix project movind. Raise exception to prevent unexpected issues

This commit is contained in:
Dmitriy Zaporozhets 2012-11-27 09:31:15 +03:00
parent 70bf7f6e19
commit f5551efdfd
20 changed files with 146 additions and 99 deletions

View file

@ -22,6 +22,7 @@ class Admin::GroupsController < AdminController
def create def create
@group = Group.new(params[:group]) @group = Group.new(params[:group])
@group.path = @group.name.dup.parameterize if @group.name
@group.owner = current_user @group.owner = current_user
if @group.save if @group.save

View file

@ -34,12 +34,17 @@ class ProjectsController < ProjectResourceController
end end
def update def update
if params[:project].has_key?(:namespace_id)
namespace_id = params[:project].delete(:namespace_id) namespace_id = params[:project].delete(:namespace_id)
if namespace_id == Namespace.global_id and project.namespace.present?
if namespace_id.present? and namespace_id.to_i != project.namespace_id # Transfer to global namespace from anyone
project.transfer(nil)
elsif namespace_id.present? and namespace_id.to_i != project.namespace_id
# Transfer to someone namespace
namespace = Namespace.find(namespace_id) namespace = Namespace.find(namespace_id)
project.transfer(namespace) project.transfer(namespace)
end end
end
respond_to do |format| respond_to do |format|
if project.update_attributes(params[:project]) if project.update_attributes(params[:project])

View file

@ -84,6 +84,7 @@ module ApplicationHelper
end end
options = [ options = [
["Global", [['/', Namespace.global_id]] ],
["Groups", groups.map {|g| [g.human_name, g.id]} ], ["Groups", groups.map {|g| [g.human_name, g.id]} ],
[ "Users", users.map {|u| [u.human_name, u.id]} ] [ "Users", users.map {|u| [u.human_name, u.id]} ]
] ]

View file

@ -35,6 +35,10 @@ class Namespace < ActiveRecord::Base
where("name LIKE :query OR path LIKE :query", query: "%#{query}%") where("name LIKE :query OR path LIKE :query", query: "%#{query}%")
end end
def self.global_id
'GLN'
end
def to_param def to_param
path path
end end
@ -51,6 +55,9 @@ class Namespace < ActiveRecord::Base
def move_dir def move_dir
old_path = File.join(Gitlab.config.git_base_path, path_was) old_path = File.join(Gitlab.config.git_base_path, path_was)
new_path = File.join(Gitlab.config.git_base_path, path) new_path = File.join(Gitlab.config.git_base_path, path)
if File.exists?(new_path)
raise "Already exists"
end
system("mv #{old_path} #{new_path}") system("mv #{old_path} #{new_path}")
end end

View file

@ -111,6 +111,7 @@ class Project < ActiveRecord::Base
# Apply namespace if user has access to it # Apply namespace if user has access to it
# else fallback to user namespace # else fallback to user namespace
if namespace_id != Namespace.global_id
project.namespace_id = user.namespace_id project.namespace_id = user.namespace_id
if namespace_id if namespace_id
@ -119,6 +120,7 @@ class Project < ActiveRecord::Base
project.namespace_id = namespace_id project.namespace_id = namespace_id
end end
end end
end
project.save! project.save!
@ -254,12 +256,16 @@ class Project < ActiveRecord::Base
old_dir = old_namespace.try(:path) || '' old_dir = old_namespace.try(:path) || ''
new_dir = new_namespace.try(:path) || '' new_dir = new_namespace.try(:path) || ''
old_repo = File.join(old_dir, self.path) old_repo = if old_dir.present?
File.join(old_dir, self.path)
git_host.move_repository(old_repo, self.path_with_namespace, self) else
self.path
end
Gitlab::ProjectMover.new(self, old_dir, new_dir).execute Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
git_host.move_repository(old_repo, self.path_with_namespace, self)
save! save!
end end
end end

View file

@ -83,7 +83,7 @@ module Repository
end end
def path_to_repo def path_to_repo
File.join(Gitlab.config.git_base_path, namespace_dir, "#{path}.git") File.join(Gitlab.config.git_base_path, "#{path_with_namespace}.git")
end end
def namespace_dir def namespace_dir
@ -165,7 +165,7 @@ module Repository
# Build file path # Build file path
file_name = self.path + "-" + commit.id.to_s + ".tar.gz" file_name = self.path + "-" + commit.id.to_s + ".tar.gz"
storage_path = Rails.root.join("tmp", "repositories", self.path) storage_path = Rails.root.join("tmp", "repositories", self.path_with_namespace)
file_path = File.join(storage_path, file_name) file_path = File.join(storage_path, file_name)
# Put files into a directory before archiving # Put files into a directory before archiving

View file

@ -28,6 +28,8 @@
%h1= Project.count %h1= Project.count
%hr %hr
= link_to 'New Project', new_project_path, class: "btn small" = link_to 'New Project', new_project_path, class: "btn small"
&nbsp;
= link_to 'New Group', new_admin_group_path, class: "btn small"
.span4 .span4
.ui-box .ui-box
%h5 Users %h5 Users
@ -44,7 +46,7 @@
%hr %hr
- @projects.each do |project| - @projects.each do |project|
%p %p
= link_to project.name, [:admin, project] = link_to project.name_with_namespace, [:admin, project]
.span6 .span6
%h3 Latest users %h3 Latest users
%hr %hr

View file

@ -1,3 +1,21 @@
%h3.page_title New Group %h3.page_title New Group
%br %hr
= render 'form' = form_for [:admin, @group] do |f|
- if @group.errors.any?
.alert-message.block-message.error
%span= @group.errors.full_messages.first
.clearfix
= f.label :name do
Group name is
.input
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left"
&nbsp;
= f.submit 'Create group', class: "btn primary"
%hr
.padded
%ul
%li Group is kind of directory for several projects
%li All created groups are private
%li People within a group see only projects they have access to
%li All projects of group will be stored in group directory
%li You will be able to move existing projects into group

View file

@ -22,7 +22,7 @@
%b %b
Path: Path:
%td %td
= @group.path %span.monospace= File.join(Gitlab.config.git_base_path, @group.path)
%tr %tr
%td %td
%b %b
@ -43,10 +43,14 @@
= link_to 'Remove from group', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Are you sure?', method: :delete, class: "btn danger small" = link_to 'Remove from group', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Are you sure?', method: :delete, class: "btn danger small"
.clearfix .clearfix
%br
%h3 Add new project
%br
= form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do = form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do
= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' %fieldset
%legend Move projects to group
.clearfix
= label_tag :project_ids do
Projects
.input
= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
.form-actions .form-actions
= submit_tag 'Add', class: "btn primary" = submit_tag 'Add', class: "btn primary"

View file

@ -6,40 +6,61 @@
- @admin_user.errors.full_messages.each do |msg| - @admin_user.errors.full_messages.each do |msg|
%li= msg %li= msg
.row %fieldset
.span7 %legend Account
.ui-box
%br
.clearfix .clearfix
= f.label :name = f.label :name
.input .input
= f.text_field :name = f.text_field :name, required: true
%span.help-inline * required %span.help-inline * required
.clearfix .clearfix
= f.label :username = f.label :username
.input .input
= f.text_field :username = f.text_field :username, required: true
%span.help-inline * required %span.help-inline * required
.clearfix .clearfix
= f.label :email = f.label :email
.input .input
= f.text_field :email = f.text_field :email, required: true
%span.help-inline * required %span.help-inline * required
%hr
-if f.object.new_record?
.clearfix
= f.label :force_random_password do
%span Generate random password
.input= f.check_box :force_random_password, {}, true, nil
%div.password-fields %fieldset
%legend Password
.clearfix .clearfix
= f.label :password = f.label :password
.input= f.password_field :password, disabled: f.object.force_random_password .input= f.password_field :password, disabled: f.object.force_random_password
.clearfix .clearfix
= f.label :password_confirmation = f.label :password_confirmation
.input= f.password_field :password_confirmation, disabled: f.object.force_random_password .input= f.password_field :password_confirmation, disabled: f.object.force_random_password
%hr -if f.object.new_record?
.clearfix
= f.label :force_random_password do
%span Generate random password
.input= f.check_box :force_random_password, {}, true, nil
%fieldset
%legend Access
.row
.span8
.clearfix
= f.label :projects_limit
.input= f.number_field :projects_limit
.clearfix
= f.label :admin do
%strong.cred Administrator
.input= f.check_box :admin
.span4
- unless @admin_user.new_record?
.alert.alert-error
- if @admin_user.blocked
%p This user is blocked and is not able to login to GitLab
= link_to 'Unblock User', unblock_admin_user_path(@admin_user), method: :put, class: "btn small"
- else
%p Blocked users will be removed from all projects &amp; will not be able to login to GitLab.
= link_to 'Block User', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger"
%fieldset
%legend Profile
.clearfix .clearfix
= f.label :skype = f.label :skype
.input= f.text_field :skype .input= f.text_field :skype
@ -49,34 +70,7 @@
.clearfix .clearfix
= f.label :twitter = f.label :twitter
.input= f.text_field :twitter .input= f.text_field :twitter
.span5
.ui-box
%br
.clearfix
= f.label :projects_limit
.input= f.number_field :projects_limit
.clearfix
= f.label :admin do
%strong.cred Administrator
.input= f.check_box :admin
- unless @admin_user.new_record?
%hr
.padded.cred
- if @admin_user.blocked
%span
This user is blocked and is not able to login to GitLab
.clearfix
= link_to 'Unblock User', unblock_admin_user_path(@admin_user), method: :put, class: "btn small right"
- else
%span
Blocked users will be removed from all projects &amp; will not be able to login to GitLab.
.clearfix
= link_to 'Block User', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small right danger"
.row
.span6
.span6
.actions .actions
= f.submit 'Save', class: "btn save-btn" = f.submit 'Save', class: "btn save-btn"
- if @admin_user.new_record? - if @admin_user.new_record?

View file

@ -1,3 +1,6 @@
%h3.page_title #{@admin_user.name} &rarr; Edit user %h3.page_title
#{@admin_user.name} &rarr;
%i.icon-edit
Edit user
%hr %hr
= render 'form' = render 'form'

View file

@ -1,3 +1,5 @@
%h3.page_title New user %h3.page_title
%br %i.icon-plus
New user
%hr
= render 'form' = render 'form'

View file

@ -1,9 +1,9 @@
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@user.name} issues" xml.title "#{current_user.name} issues"
xml.link :href => dashboard_issues_url(:atom, :private_token => @user.private_token), :rel => "self", :type => "application/atom+xml" xml.link :href => dashboard_issues_url(:atom, :private_token => current_user.private_token), :rel => "self", :type => "application/atom+xml"
xml.link :href => dashboard_issues_url(:private_token => @user.private_token), :rel => "alternate", :type => "text/html" xml.link :href => dashboard_issues_url(:private_token => current_user.private_token), :rel => "alternate", :type => "text/html"
xml.id dashboard_issues_url(:private_token => @user.private_token) xml.id dashboard_issues_url(:private_token => current_user.private_token)
xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
@issues.each do |issue| @issues.each do |issue|

View file

@ -1,7 +1,7 @@
- if event.allowed? - if event.allowed?
%div.event-item %div.event-item
= event_image(event) = event_image(event)
= image_tag gravatar_icon(event.author_email), class: "avatar" = image_tag gravatar_icon(event.author_email), class: "avatar s24"
- if event.push? - if event.push?
= render "events/event/push", event: event = render "events/event/push", event: event

View file

@ -20,7 +20,7 @@
%td{style: "font-size: 0px;", width: "20"} %td{style: "font-size: 0px;", width: "20"}
\  \ 
%td{align: "left", style: "padding: 18px 0 10px;", width: "580"} %td{align: "left", style: "padding: 18px 0 10px;", width: "580"}
%h1{style: "color: #BBBBBB; font: normal 32px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 40px;"} %h1{style: "color: #BBBBBB; font: normal 22px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 32px;"}
GITLAB GITLAB
- if @project - if @project
| #{@project.name} | #{@project.name}

View file

@ -23,7 +23,7 @@
%tr %tr
%td %td
= link_to project do = link_to project do
%strong.term= project.name %strong.term= project.name_with_namespace
%small.cgray %small.cgray
last activity at last activity at
= project.last_activity_date.stamp("Aug 25, 2011") = project.last_activity_date.stamp("Aug 25, 2011")

View file

@ -1,3 +1,3 @@
- if current_user.require_ssh_key? - if current_user.require_ssh_key?
%p.error_message %p.error_message
You won't be able to pull or push project code until you #{link_to 'add an SSH key', new_key_path} to your profile You won't be able to pull or push project code via SSH until you #{link_to 'add an SSH key', new_key_path} to your profile

View file

@ -23,7 +23,7 @@ module Gitlab
end end
def update_repository project def update_repository project
config.update_project!(project.path, project) config.update_project!(project)
end end
def move_repository(old_repo, new_repo, project) def move_repository(old_repo, new_repo, project)

View file

@ -109,18 +109,18 @@ module Gitlab
end end
# update or create # update or create
def update_project(repo_name, project) def update_project(project)
repo = update_project_config(project, conf) repo = update_project_config(project, conf)
conf.add_repo(repo, true) conf.add_repo(repo, true)
end end
def update_project!(repo_name, project) def update_project!( project)
apply do |config| apply do |config|
config.update_project(repo_name, project) config.update_project(project)
end end
end end
# Updates many projects and uses project.path as the repo path # Updates many projects and uses project.path_with_namespace as the repo path
# An order of magnitude faster than update_project # An order of magnitude faster than update_project
def update_projects(projects) def update_projects(projects)
projects.each do |project| projects.each do |project|

View file

@ -21,6 +21,10 @@ module Gitlab
old_path = File.join(Gitlab.config.git_base_path, old_dir, "#{project.path}.git") old_path = File.join(Gitlab.config.git_base_path, old_dir, "#{project.path}.git")
new_path = File.join(new_dir_path, "#{project.path}.git") new_path = File.join(new_dir_path, "#{project.path}.git")
if File.exists? new_path
raise ProjectMoveError.new("Destination #{new_path} already exists")
end
if system("mv #{old_path} #{new_path}") if system("mv #{old_path} #{new_path}")
log_info "Project #{project.name} was moved from #{old_path} to #{new_path}" log_info "Project #{project.name} was moved from #{old_path} to #{new_path}"
true true