Merge pull request #109 from warpc/18-commit_comments
18 commit comments
This commit is contained in:
commit
4ba268dd67
|
@ -1,7 +1,7 @@
|
|||
class CommentsController < ApplicationController
|
||||
before_filter :authenticate_user!
|
||||
before_filter :set_commentable, :only => [:index, :edit, :create]
|
||||
before_filter :find_project, :only => [:index]
|
||||
before_filter :set_commentable, :only => [:index, :edit, :create, :update, :destroy]
|
||||
#before_filter :find_project, :only => [:index, :edit]
|
||||
before_filter :find_comment, :only => [:edit, :update, :destroy]
|
||||
|
||||
authorize_resource :only => [:show, :edit, :update, :destroy]
|
||||
|
@ -12,11 +12,12 @@ class CommentsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@comment = @commentable.comments.build(params[:comment])
|
||||
@comment = @commentable.comments.build(params[:comment]) if @commentable.class == Issue
|
||||
@comment = Comment.new(params[:comment].merge(:commentable_id => @commentable.id, :commentable_type => @commentable.class.name)) if @commentable.class == Grit::Commit
|
||||
@comment.user = current_user
|
||||
if @comment.save
|
||||
flash[:notice] = I18n.t("flash.comment.saved")
|
||||
redirect_to [@commentable.project, @commentable]
|
||||
redirect_to commentable_path
|
||||
else
|
||||
flash[:error] = I18n.t("flash.comment.save_error")
|
||||
render :action => 'new'
|
||||
|
@ -24,15 +25,19 @@ class CommentsController < ApplicationController
|
|||
end
|
||||
|
||||
def edit
|
||||
@issue = @commentable
|
||||
@project = @issue.project
|
||||
@update_url = case @commentable.class.name
|
||||
when "Issue"
|
||||
project_issue_comment_path(@project, @commentable, @comment)
|
||||
when "Grit::Commit"
|
||||
project_commit_comment_path(@project, @commentable, @comment)
|
||||
end
|
||||
@commentable_path = commentable_path
|
||||
end
|
||||
|
||||
def update
|
||||
if @comment.update_attributes(params[:comment])
|
||||
flash[:notice] = I18n.t("flash.comment.saved")
|
||||
#redirect_to :back
|
||||
redirect_to [@comment.commentable.project, @comment.commentable]
|
||||
redirect_to commentable_path
|
||||
else
|
||||
flash[:error] = I18n.t("flash.comment.save_error")
|
||||
render :action => 'new'
|
||||
|
@ -43,7 +48,7 @@ class CommentsController < ApplicationController
|
|||
@comment.destroy
|
||||
|
||||
flash[:notice] = t("flash.comment.destroyed")
|
||||
redirect_to :back
|
||||
redirect_to commentable_path
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -55,18 +60,31 @@ class CommentsController < ApplicationController
|
|||
# end
|
||||
#end
|
||||
#nil
|
||||
return Issue.find_by_serial_id_and_project_id(params[:issue_id], params[:project_id])
|
||||
if params[:issue_id].present?
|
||||
return Issue.find_by_serial_id_and_project_id(params[:issue_id], params[:project_id])
|
||||
elsif params[:commit_id].present?
|
||||
return @project.git_repository.commit(params[:commit_id])
|
||||
end
|
||||
end
|
||||
|
||||
def set_commentable
|
||||
find_project
|
||||
@commentable = find_commentable
|
||||
end
|
||||
|
||||
def find_comment
|
||||
@comment = Comment.find(params[:id])
|
||||
@comment.project = @project if @comment.commentable_type == 'Grit::Commit'
|
||||
end
|
||||
|
||||
def find_project
|
||||
@project = @comment.commentable.project
|
||||
@project = Project.find(params[:project_id])
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def commentable_path
|
||||
@commentable.class == Issue ? [@project, @commentable] : commit_path(@project, @commentable.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -23,4 +23,4 @@ class Git::CommitsController < Git::BaseController
|
|||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# If rules goes one by one CanCan joins them by 'OR' sql operator
|
||||
# If rule has multiple conditions CanCan joins them by 'AND' sql operator
|
||||
# WARNING:
|
||||
# WARNING:
|
||||
# - put cannot rules _after_ can rules and not before!
|
||||
# - beware inner joins. Use sub queries against them!
|
||||
# - beware inner joins. Use sub queries against them!
|
||||
|
||||
class Ability
|
||||
include CanCan::Ability
|
||||
|
@ -91,9 +91,10 @@ class Ability
|
|||
can([:update, :destroy], Issue) {|issue| issue.user_id == user.id or local_admin?(issue.project)}
|
||||
cannot :manage, Issue, :project => {:has_issues => false} # switch off issues
|
||||
|
||||
can(:create, Comment) {|comment| can? :read, comment.commentable.project}
|
||||
can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.commentable.project)}
|
||||
cannot :manage, Comment, :commentable => {:project => {:has_issues => false}} # switch off issues
|
||||
can(:create, Comment) {|comment| can? :read, comment.project || comment.commentable.project}
|
||||
can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)}
|
||||
#cannot :manage, Comment, :commentable => {:project => {:has_issues => false}} # switch off issues
|
||||
cannot(:manage, Comment) {|comment| comment.commentable_type == 'Issue' && !comment.commentable.project.has_issues} # switch off issues
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
class Comment < ActiveRecord::Base
|
||||
belongs_to :commentable, :polymorphic => true
|
||||
belongs_to :user
|
||||
attr_accessor :project
|
||||
|
||||
validates :body, :user_id, :commentable_id, :commentable_type, :presence => true
|
||||
|
||||
after_create :subscribe_on_reply
|
||||
after_create :deliver_new_comment_notification
|
||||
# FIXME
|
||||
after_create :subscribe_on_reply, :unless => "commentable_type == 'Grit::Commit'"
|
||||
after_create :deliver_new_comment_notification, :unless => "commentable_type == 'Grit::Commit'"
|
||||
|
||||
protected
|
||||
|
||||
|
|
|
@ -4,7 +4,13 @@ class Issue < ActiveRecord::Base
|
|||
belongs_to :project
|
||||
belongs_to :user
|
||||
|
||||
has_many :comments, :as => :commentable
|
||||
has_many :comments, :as => :commentable,
|
||||
:finder_sql => proc { "comments.commentable_id = '#{self.id}' " +
|
||||
" AND comments.commentable_type = '#{self.class.name}'"}
|
||||
#'SELECT comments.* FROM comments ' +
|
||||
#'WHERE comments.commentable_id = \'#{self.id}\' ' +
|
||||
#' AND comments.commentable_type = \'#{self.class.name}\' ' +
|
||||
#'ORDER BY comments.created_at'
|
||||
has_many :subscribes, :as => :subscribeable
|
||||
|
||||
validates :title, :body, :project_id, :presence => true
|
||||
|
|
|
@ -66,7 +66,7 @@ class Project < ActiveRecord::Base
|
|||
res = tags.select{|tag| tag.name =~ /^v\./}
|
||||
return res if res and res.size > 0
|
||||
tags
|
||||
end
|
||||
end
|
||||
def collected_project_versions
|
||||
project_versions.collect{|tag| tag.name.gsub(/^\w+\./, "")}
|
||||
end
|
||||
|
@ -118,7 +118,7 @@ class Project < ActiveRecord::Base
|
|||
return true
|
||||
else
|
||||
raise "Failed to create project #{name} (repo #{repository.name}) inside platform #{repository.platform.name} in path #{path} with code #{result}."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def xml_rpc_destroy(repository)
|
||||
|
@ -134,6 +134,13 @@ class Project < ActiveRecord::Base
|
|||
@platforms ||= repositories.map(&:platform).uniq
|
||||
end
|
||||
|
||||
class << self
|
||||
def commit_comments(commit, project)
|
||||
comments = Comment.where(:commentable_id => commit.id, :commentable_type => 'Grit::Commit').order(:created_at)
|
||||
comments.each {|x| x.project = project}
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def build_path(dir)
|
||||
|
|
|
@ -48,7 +48,7 @@ class Repository < ActiveRecord::Base
|
|||
return true
|
||||
else
|
||||
raise "Failed to create repository #{name} inside platform #{platform.name} with code #{result}."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def xml_rpc_destroy
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
= image_tag("web-app-theme/icons/tick.png", :alt => t("layout.save"))
|
||||
= t("layout.save")
|
||||
%span.text_button_padding= t("layout.or")
|
||||
= link_to t("layout.cancel"), [@issue.project, @issue], :class => "text_button_padding link_button"
|
||||
= link_to t("layout.cancel"), @commentable_path , :class => "text_button_padding link_button"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
%a{ :name => "comments" }
|
||||
.block#block-list
|
||||
.content
|
||||
%h2.title
|
||||
= t("layout.issues.comments_header")
|
||||
.inner
|
||||
%ul.list
|
||||
- list.each do |comment|
|
||||
%li
|
||||
.left
|
||||
= link_to comment.user.uname, user_path(comment.user.uname)
|
||||
.item
|
||||
= comment.body
|
||||
%br
|
||||
%br
|
||||
- if commentable.class == Issue
|
||||
- edit_path = edit_project_issue_comment_path(project, commentable, comment)
|
||||
- delete_path = project_issue_comment_path(project, commentable, comment)
|
||||
- elsif commentable.class == Grit::Commit
|
||||
- edit_path = edit_project_commit_comment_path(project, commentable, comment)
|
||||
- delete_path = project_commit_comment_path(project, commentable, comment)
|
||||
= link_to t("layout.edit"), edit_path if can? :update, comment
|
||||
= link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), delete_path, :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment
|
||||
|
||||
.block
|
||||
.content
|
||||
%h2.title
|
||||
= t("layout.comments.new_header")
|
||||
.inner
|
||||
- new_path = project_issue_comments_path(project, commentable) if commentable.class == Issue
|
||||
- new_path = project_commit_comments_path(project, commentable) if commentable.class == Grit::Commit
|
||||
= form_for :comment, :url => new_path, :method => :post, :html => { :class => :form } do |f|
|
||||
= render :partial => "comments/form", :locals => {:f => f}
|
|
@ -1,10 +1,10 @@
|
|||
.block
|
||||
.secondary-navigation
|
||||
%ul.wat-cf
|
||||
%li.first= link_to t("layout.issues.list"), project_issue_path(@project, @issue)
|
||||
%li.first= link_to t(@comment.commentable_type == 'Grit::Commit' ? "layout.git.repositories.commits" : "layout.issues.list"), @commentable_path
|
||||
.content
|
||||
%h2.title
|
||||
= t("layout.issues.edit_header")
|
||||
= t("layout.#{@comment.commentable_type == 'Grit::Commit' ? 'comments' : 'issues'}.edit_header")
|
||||
.inner
|
||||
= form_for @comment, :url => project_issue_comment_path(@project, @issue, @comment), :html => { :class => :form } do |f|
|
||||
= form_for @comment, :url => @update_url, :html => { :class => :form } do |f|
|
||||
= render :partial => "form", :locals => {:f => f}
|
||||
|
|
|
@ -31,4 +31,4 @@
|
|||
:plain
|
||||
<pre>#{render_blob(@blob)}</pre>
|
||||
|
||||
- content_for :sidebar, render(:partial => 'git/shared/sidebar')
|
||||
- content_for :sidebar, render(:partial => 'git/shared/sidebar')
|
||||
|
|
|
@ -26,3 +26,5 @@
|
|||
%p= t 'layout.git.repositories.commit_diff_too_big'
|
||||
|
||||
- content_for :sidebar, render(:partial => 'git/shared/sidebar')
|
||||
|
||||
= render :partial => "comments/list", :locals => {:list => Project.commit_comments(@commit, @project), :project => @project, :commentable => @commit}
|
||||
|
|
|
@ -29,28 +29,4 @@
|
|||
- else
|
||||
= link_to t('layout.issues.subscribe_btn'), project_issue_subscribes_path(@project, @issue), :method => :post
|
||||
|
||||
%a{ :name => "comments" }
|
||||
.block#block-list
|
||||
.content
|
||||
%h2.title
|
||||
= t("layout.issues.comments_header")
|
||||
.inner
|
||||
%ul.list
|
||||
- @issue.comments.order(:created_at).each do |comment|
|
||||
%li
|
||||
.left
|
||||
= link_to comment.user.uname, user_path(comment.user.uname)
|
||||
.item
|
||||
= comment.body
|
||||
%br
|
||||
%br
|
||||
= link_to t("layout.edit"), edit_project_issue_comment_path(@project, @issue, comment) if can? :update, comment
|
||||
= link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_issue_comment_path(@project, @issue, comment), :method => "delete", :class => "button", :confirm => t("layout.comments.confirm_delete") if can? :delete, comment
|
||||
|
||||
.block
|
||||
.content
|
||||
%h2.title
|
||||
= t("layout.comments.new_header")
|
||||
.inner
|
||||
= form_for :comment, :url => project_issue_comments_path(@project, @issue), :method => :post, :html => { :class => :form } do |f|
|
||||
= render :partial => "comments/form", :locals => {:f => f}
|
||||
= render :partial => "comments/list", :locals => {:list => @issue.comments.order(:created_at), :project => @project, :commentable => @issue}
|
||||
|
|
|
@ -129,6 +129,7 @@ ru:
|
|||
comments:
|
||||
confirm_delete: Вы уверены, что хотите удалить комментарий?
|
||||
new_header: Новый комментарий
|
||||
edit_header: Редактирование комментария
|
||||
|
||||
platforms:
|
||||
admin_id: Владелец
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Rosa::Application.routes.draw do
|
||||
# XML RPC
|
||||
match 'api/xmlrpc' => 'rpc#xe_index'
|
||||
|
||||
|
||||
devise_for :users, :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'} do
|
||||
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
|
||||
end
|
||||
|
||||
|
||||
resources :users do
|
||||
resources :groups, :only => [:new, :create, :index]
|
||||
get :autocomplete_user_uname, :on => :collection
|
||||
|
@ -146,20 +146,24 @@ Rosa::Application.routes.draw do
|
|||
|
||||
# Tree
|
||||
match '/projects/:project_id/git/tree/:treeish(/*path)', :controller => "git/trees", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :tree
|
||||
|
||||
|
||||
# Commits
|
||||
match '/projects/:project_id/git/commits/:treeish(/*path)', :controller => "git/commits", :action => :index, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :commits
|
||||
match '/projects/:project_id/git/commit/:id(.:format)', :controller => "git/commits", :action => :show, :defaults => { :format => :html }, :as => :commit
|
||||
|
||||
# Commit Comments
|
||||
match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :edit, :as => :edit_project_commit_comment, :via => :get
|
||||
match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :update, :as => :project_commit_comment, :via => :put
|
||||
match '/projects/:project_id/git/commit/:commit_id/comments/:id(.:format)', :controller => "comments", :action => :destroy, :via => :delete
|
||||
match '/projects/:project_id/git/commit/:commit_id/comments(.:format)', :controller => "comments", :action => :create, :as => :project_commit_comments, :via => :post
|
||||
# Blobs
|
||||
match '/projects/:project_id/git/blob/:treeish/*path', :controller => "git/blobs", :action => :show, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blob
|
||||
match '/projects/:project_id/git/commit/blob/:commit_hash/*path', :controller => "git/blobs", :action => :show, :project_name => /[0-9a-zA-Z_.\-]*/, :as => :blob_commit
|
||||
|
||||
|
||||
# Blame
|
||||
match '/projects/:project_id/git/blame/:treeish/*path', :controller => "git/blobs", :action => :blame, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :blame
|
||||
match '/projects/:project_id/git/commit/blame/:commit_hash/*path', :controller => "git/blobs", :action => :blame, :as => :blame_commit
|
||||
|
||||
# Raw
|
||||
|
||||
# Raw
|
||||
match '/projects/:project_id/git/raw/:treeish/*path', :controller => "git/blobs", :action => :raw, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :raw
|
||||
match '/projects/:project_id/git/commit/raw/:commit_hash/*path', :controller => "git/blobs", :action => :raw, :as => :raw_commit
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
class ChangeCommentableId < ActiveRecord::Migration
|
||||
def self.up
|
||||
change_column :comments, :commentable_id, :string
|
||||
end
|
||||
|
||||
def self.down
|
||||
change_column :comments, :commentable_id, :integer
|
||||
end
|
||||
end
|
17
db/schema.rb
17
db/schema.rb
|
@ -89,7 +89,7 @@ ActiveRecord::Schema.define(:version => 20120117110723) do
|
|||
end
|
||||
|
||||
create_table "comments", :force => true do |t|
|
||||
t.integer "commentable_id"
|
||||
t.string "commentable_id"
|
||||
t.string "commentable_type"
|
||||
t.integer "user_id"
|
||||
t.text "body"
|
||||
|
@ -167,6 +167,13 @@ ActiveRecord::Schema.define(:version => 20120117110723) do
|
|||
|
||||
add_index "issues", ["project_id", "serial_id"], :name => "index_issues_on_project_id_and_serial_id", :unique => true
|
||||
|
||||
create_table "permissions", :force => true do |t|
|
||||
t.integer "right_id"
|
||||
t.integer "role_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "platforms", :force => true do |t|
|
||||
t.string "description"
|
||||
t.string "name"
|
||||
|
@ -263,6 +270,14 @@ ActiveRecord::Schema.define(:version => 20120117110723) do
|
|||
t.string "owner_type"
|
||||
end
|
||||
|
||||
create_table "rights", :force => true do |t|
|
||||
t.string "name", :null => false
|
||||
t.string "controller", :null => false
|
||||
t.string "action", :null => false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "rpms", :force => true do |t|
|
||||
t.string "name", :null => false
|
||||
t.integer "arch_id", :null => false
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
require 'spec_helper'
|
||||
|
||||
shared_examples_for 'user with create comment rights for commits' do
|
||||
it 'should be able to perform create action' do
|
||||
post :create, @create_params
|
||||
response.should redirect_to(commit_path(@project, @commit.id))
|
||||
end
|
||||
|
||||
it 'should create subscribe object into db' do
|
||||
lambda{ post :create, @create_params }.should change{ Comment.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'user with update own comment rights for commits' do
|
||||
it 'should be able to perform update action' do
|
||||
put :update, {:id => @own_comment.id}.merge(@update_params)
|
||||
response.should redirect_to(commit_path(@project, @commit.id))
|
||||
end
|
||||
|
||||
it 'should update subscribe body' do
|
||||
put :update, {:id => @own_comment.id}.merge(@update_params)
|
||||
@own_comment.reload.body.should == 'updated'
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'user with update stranger comment rights for commits' do
|
||||
it 'should be able to perform update action' do
|
||||
put :update, {:id => @comment.id}.merge(@update_params)
|
||||
response.should redirect_to(commit_path(@project, @commit.id))
|
||||
end
|
||||
|
||||
it 'should update comment title' do
|
||||
put :update, {:id => @comment.id}.merge(@update_params)
|
||||
@comment.reload.body.should == 'updated'
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'user without update stranger comment rights for commits' do
|
||||
it 'should not be able to perform update action' do
|
||||
put :update, {:id => @comment.id}.merge(@update_params)
|
||||
response.should redirect_to(forbidden_path)
|
||||
end
|
||||
|
||||
it 'should not update comment title' do
|
||||
put :update, {:id => @comment.id}.merge(@update_params)
|
||||
@comment.reload.body.should_not == 'updated'
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'user without destroy comment rights for commits' do
|
||||
it 'should not be able to perform destroy action' do
|
||||
delete :destroy, :id => @comment.id, :commit_id => @commit.id, :project_id => @project.id
|
||||
response.should redirect_to(forbidden_path)
|
||||
end
|
||||
|
||||
it 'should not reduce comments count' do
|
||||
lambda{ delete :destroy, :id => @comment.id, :commit_id => @commit.id, :project_id => @project.id }.should change{ Comment.count }.by(0)
|
||||
end
|
||||
end
|
||||
|
||||
#shared_examples_for 'user with destroy rights' do
|
||||
# it 'should be able to perform destroy action' do
|
||||
# delete :destroy, :id => @comment.id, :issue_id => @issue.serial_id, :project_id => @project.id
|
||||
# response.should redirect_to([@project, @issue])
|
||||
# end
|
||||
#
|
||||
# it 'should reduce comments count' do
|
||||
# lambda{ delete :destroy, :id => @comment.id, :issue_id => @issue.serial_id, :project_id => @project.id }.should change{ Comment.count }.by(-1)
|
||||
# end
|
||||
#end
|
||||
|
||||
describe CommentsController do
|
||||
before(:each) do
|
||||
stub_rsync_methods
|
||||
|
||||
@project = Factory(:project)
|
||||
%x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ?
|
||||
@commit = @project.git_repository.commits.first
|
||||
|
||||
@comment = Factory(:comment)
|
||||
@comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id)
|
||||
@create_params = {:comment => {:body => 'I am a comment!'}, :project_id => @project.id, :commit_id => @commit.id}
|
||||
@update_params = {:comment => {:body => 'updated'}, :project_id => @project.id, :commit_id => @commit.id}
|
||||
|
||||
any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
|
||||
|
||||
@request.env['HTTP_REFERER'] = commit_path(@project, @commit.id)
|
||||
end
|
||||
|
||||
context 'for project admin user' do
|
||||
before(:each) do
|
||||
@user = Factory(:user)
|
||||
set_session_for(@user)
|
||||
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin')
|
||||
@own_comment = Factory(:comment, :user => @user)
|
||||
@own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id)
|
||||
end
|
||||
|
||||
it_should_behave_like 'user with create comment rights for commits'
|
||||
it_should_behave_like 'user with update stranger comment rights for commits'
|
||||
it_should_behave_like 'user with update own comment rights for commits'
|
||||
it_should_behave_like 'user without destroy comment rights for commits'
|
||||
end
|
||||
|
||||
context 'for project owner user' do
|
||||
before(:each) do
|
||||
@user = @project.owner
|
||||
set_session_for(@user)
|
||||
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin')
|
||||
|
||||
@own_comment = Factory(:comment, :user => @user)
|
||||
@own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id)
|
||||
end
|
||||
|
||||
it_should_behave_like 'user with create comment rights for commits'
|
||||
it_should_behave_like 'user with update stranger comment rights for commits'
|
||||
it_should_behave_like 'user with update own comment rights for commits'
|
||||
it_should_behave_like 'user without destroy comment rights for commits'
|
||||
end
|
||||
|
||||
context 'for project reader user' do
|
||||
before(:each) do
|
||||
@user = Factory(:user)
|
||||
set_session_for(@user)
|
||||
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'reader')
|
||||
|
||||
@own_comment = Factory(:comment, :user => @user)
|
||||
@own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id)
|
||||
end
|
||||
|
||||
it_should_behave_like 'user with create comment rights for commits'
|
||||
it_should_behave_like 'user without update stranger comment rights for commits'
|
||||
it_should_behave_like 'user with update own comment rights for commits'
|
||||
it_should_behave_like 'user without destroy comment rights for commits'
|
||||
end
|
||||
|
||||
context 'for project writer user' do
|
||||
before(:each) do
|
||||
@user = Factory(:user)
|
||||
set_session_for(@user)
|
||||
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'writer')
|
||||
|
||||
@own_comment = Factory(:comment, :user => @user)
|
||||
@own_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id)
|
||||
end
|
||||
|
||||
it_should_behave_like 'user with create comment rights for commits'
|
||||
it_should_behave_like 'user without update stranger comment rights for commits'
|
||||
it_should_behave_like 'user with update own comment rights for commits'
|
||||
it_should_behave_like 'user without destroy comment rights for commits'
|
||||
end
|
||||
end
|
|
@ -49,12 +49,12 @@ end
|
|||
|
||||
shared_examples_for 'user without destroy comment rights' do
|
||||
it 'should not be able to perform destroy action' do
|
||||
delete :destroy, :id => @comment.id, :issue_id => @issue.id, :project_id => @project.id
|
||||
delete :destroy, :id => @comment.id, :issue_id => @issue.serial_id, :project_id => @project.id
|
||||
response.should redirect_to(forbidden_path)
|
||||
end
|
||||
|
||||
it 'should not reduce comments count' do
|
||||
lambda{ delete :destroy, :id => @comment.id, :issue_id => @issue.id, :project_id => @project.id }.should change{ Issue.count }.by(0)
|
||||
lambda{ delete :destroy, :id => @comment.id, :issue_id => @issue.serial_id, :project_id => @project.id }.should change{ Issue.count }.by(0)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
require 'spec_helper'
|
||||
require "cancan/matchers"
|
||||
|
||||
def set_comments_data_for_commit
|
||||
@ability = Ability.new(@user)
|
||||
|
||||
@project = Factory(:project)
|
||||
%x(cp -Rf #{Rails.root}/spec/tests.git/* #{@project.git_repository.path}) # maybe FIXME ?
|
||||
@commit = @project.git_repository.commits.first
|
||||
|
||||
@comment = Factory(:comment, :user => @user)
|
||||
@comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id)
|
||||
|
||||
@stranger_comment = Factory(:comment, :user => @stranger)
|
||||
@stranger_comment.update_attributes(:commentable_type => @commit.class.name, :commentable_id => @commit.id, :project => @project)
|
||||
|
||||
@create_params = {:commentable_type => @commit.class.name, :commentable_id => @commit.id, :user => @user, :project => @project}
|
||||
|
||||
any_instance_of(Project, :versions => ['v1.0', 'v2.0'])
|
||||
end
|
||||
|
||||
describe Comment do
|
||||
context 'for global admin user' do
|
||||
before(:each) do
|
||||
@user = Factory(:admin)
|
||||
@stranger = Factory(:user)
|
||||
|
||||
set_comments_data_for_commit
|
||||
end
|
||||
|
||||
it 'should create comment' do
|
||||
@ability.should be_able_to(:create, Comment.new(@create_params))
|
||||
end
|
||||
|
||||
pending "sends an e-mail" do
|
||||
ActionMailer::Base.deliveries.last.to.include?(@stranger.email).should == true
|
||||
end
|
||||
|
||||
it 'should update comment' do
|
||||
@ability.should be_able_to(:update, @comment)
|
||||
end
|
||||
|
||||
it 'should update stranger comment' do
|
||||
@ability.should be_able_to(:update, @stranger_comment)
|
||||
end
|
||||
|
||||
it 'should destroy own comment' do
|
||||
@ability.should be_able_to(:destroy, @comment)
|
||||
end
|
||||
|
||||
it 'should destroy stranger comment' do
|
||||
@ability.should be_able_to(:destroy, @stranger_comment)
|
||||
end
|
||||
end
|
||||
|
||||
context 'for project admin user' do
|
||||
before(:each) do
|
||||
@user = Factory(:user)
|
||||
@stranger = Factory(:user)
|
||||
|
||||
set_comments_data_for_commit
|
||||
|
||||
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin')
|
||||
end
|
||||
|
||||
it 'should create comment' do
|
||||
@ability.should be_able_to(:create, Comment.new(@create_params))
|
||||
end
|
||||
|
||||
it 'should update comment' do
|
||||
@ability.should be_able_to(:update, @comment)
|
||||
end
|
||||
|
||||
it 'should update stranger comment' do
|
||||
@ability.should be_able_to(:update, @stranger_comment)
|
||||
end
|
||||
|
||||
it 'should not destroy comment' do
|
||||
@ability.should_not be_able_to(:destroy, @comment)
|
||||
end
|
||||
end
|
||||
|
||||
context 'for project owner user' do
|
||||
before(:each) do
|
||||
@user = Factory(:user)
|
||||
@stranger = Factory(:user)
|
||||
|
||||
set_comments_data_for_commit
|
||||
|
||||
@project.update_attribute(:owner, @user)
|
||||
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'admin')
|
||||
end
|
||||
|
||||
it 'should create comment' do
|
||||
@ability.should be_able_to(:create, Comment.new(@create_params))
|
||||
end
|
||||
|
||||
it 'should update comment' do
|
||||
@ability.should be_able_to(:update, @comment)
|
||||
end
|
||||
|
||||
it 'should update stranger comment' do
|
||||
@ability.should be_able_to(:update, @stranger_comment)
|
||||
end
|
||||
|
||||
it 'should not destroy comment' do
|
||||
@ability.should_not be_able_to(:destroy, @comment)
|
||||
end
|
||||
end
|
||||
|
||||
context 'for simple user' do
|
||||
before(:each) do
|
||||
@user = Factory(:user)
|
||||
@stranger = Factory(:user)
|
||||
|
||||
set_comments_data_for_commit
|
||||
end
|
||||
|
||||
it 'should create comment' do
|
||||
@ability.should be_able_to(:create, Comment.new(@create_params))
|
||||
end
|
||||
|
||||
it 'should update comment' do
|
||||
@ability.should be_able_to(:update, @comment)
|
||||
end
|
||||
|
||||
it 'should not update stranger comment' do
|
||||
@ability.should_not be_able_to(:update, @stranger_comment)
|
||||
end
|
||||
|
||||
it 'should not destroy comment' do
|
||||
@ability.should_not be_able_to(:destroy, @comment)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
bdc8b580b5b583aeb43efb19aac2ab8ce5566dff
|
|
@ -0,0 +1,11 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
[remote "origin"]
|
||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
||||
url = git://github.com/tpope/vim-ragtag.git
|
||||
[branch "master"]
|
||||
remote = origin
|
||||
merge = refs/heads/master
|
|
@ -0,0 +1 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message taken by
|
||||
# applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit. The hook is
|
||||
# allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "applypatch-msg".
|
||||
|
||||
. git-sh-setup
|
||||
test -x "$GIT_DIR/hooks/commit-msg" &&
|
||||
exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
|
||||
:
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message.
|
||||
# Called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero
|
||||
# status after issuing an appropriate message if it wants to stop the
|
||||
# commit. The hook is allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "commit-msg".
|
||||
|
||||
# Uncomment the below to add a Signed-off-by line to the message.
|
||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||
# hook is more suited to it.
|
||||
#
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||
|
||||
# This example catches duplicate Signed-off-by lines.
|
||||
|
||||
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||
echo >&2 Duplicate Signed-off-by lines.
|
||||
exit 1
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script that is called after a successful
|
||||
# commit is made.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-commit".
|
||||
|
||||
: Nothing
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script for the "post-receive" event.
|
||||
#
|
||||
# The "post-receive" script is run after receive-pack has accepted a pack
|
||||
# and the repository has been updated. It is passed arguments in through
|
||||
# stdin in the form
|
||||
# <oldrev> <newrev> <refname>
|
||||
# For example:
|
||||
# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
|
||||
#
|
||||
# see contrib/hooks/ for a sample, or uncomment the next line and
|
||||
# rename the file to "post-receive".
|
||||
|
||||
#. /usr/share/doc/git-core/contrib/hooks/post-receive-email
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare a packed repository for use over
|
||||
# dumb transports.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-update".
|
||||
|
||||
exec git update-server-info
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed
|
||||
# by applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-applypatch".
|
||||
|
||||
. git-sh-setup
|
||||
test -x "$GIT_DIR/hooks/pre-commit" &&
|
||||
exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
|
||||
:
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
# Initial commit: diff against an empty tree object
|
||||
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
||||
fi
|
||||
|
||||
# If you want to allow non-ascii filenames set this variable to true.
|
||||
allownonascii=$(git config hooks.allownonascii)
|
||||
|
||||
# Cross platform projects tend to avoid non-ascii filenames; prevent
|
||||
# them from being added to the repository. We exploit the fact that the
|
||||
# printable range starts at the space character and ends with tilde.
|
||||
if [ "$allownonascii" != "true" ] &&
|
||||
# Note that the use of brackets around a tr range is ok here, (it's
|
||||
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||
# the square bracket bytes happen to fall in the designated range.
|
||||
test "$(git diff --cached --name-only --diff-filter=A -z $against |
|
||||
LC_ALL=C tr -d '[ -~]\0')"
|
||||
then
|
||||
echo "Error: Attempt to add a non-ascii file name."
|
||||
echo
|
||||
echo "This can cause problems if you want to work"
|
||||
echo "with people on other platforms."
|
||||
echo
|
||||
echo "To be portable it is advisable to rename the file ..."
|
||||
echo
|
||||
echo "If you know what you are doing you can disable this"
|
||||
echo "check using:"
|
||||
echo
|
||||
echo " git config hooks.allownonascii true"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec git diff-index --check --cached $against --
|
|
@ -0,0 +1,172 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||
#
|
||||
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||
# its job, and can prevent the command from running by exiting with
|
||||
# non-zero status.
|
||||
#
|
||||
# The hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- the upstream the series was forked from.
|
||||
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||
#
|
||||
# This sample shows how to prevent topic branches that are already
|
||||
# merged to 'next' branch from getting rebased, because allowing it
|
||||
# would result in rebasing already published history.
|
||||
|
||||
publish=next
|
||||
basebranch="$1"
|
||||
if test "$#" = 2
|
||||
then
|
||||
topic="refs/heads/$2"
|
||||
else
|
||||
topic=`git symbolic-ref HEAD` ||
|
||||
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||
fi
|
||||
|
||||
case "$topic" in
|
||||
refs/heads/??/*)
|
||||
;;
|
||||
*)
|
||||
exit 0 ;# we do not interrupt others.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Now we are dealing with a topic branch being rebased
|
||||
# on top of master. Is it OK to rebase it?
|
||||
|
||||
# Does the topic really exist?
|
||||
git show-ref -q "$topic" || {
|
||||
echo >&2 "No such branch $topic"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is topic fully merged to master?
|
||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||
if test -z "$not_in_master"
|
||||
then
|
||||
echo >&2 "$topic is fully merged to master; better remove it."
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
fi
|
||||
|
||||
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||
if test "$only_next_1" = "$only_next_2"
|
||||
then
|
||||
not_in_topic=`git rev-list "^$topic" master`
|
||||
if test -z "$not_in_topic"
|
||||
then
|
||||
echo >&2 "$topic is already up-to-date with master"
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||
/usr/bin/perl -e '
|
||||
my $topic = $ARGV[0];
|
||||
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||
my (%not_in_next) = map {
|
||||
/^([0-9a-f]+) /;
|
||||
($1 => 1);
|
||||
} split(/\n/, $ARGV[1]);
|
||||
for my $elem (map {
|
||||
/^([0-9a-f]+) (.*)$/;
|
||||
[$1 => $2];
|
||||
} split(/\n/, $ARGV[2])) {
|
||||
if (!exists $not_in_next{$elem->[0]}) {
|
||||
if ($msg) {
|
||||
print STDERR $msg;
|
||||
undef $msg;
|
||||
}
|
||||
print STDERR " $elem->[1]\n";
|
||||
}
|
||||
}
|
||||
' "$topic" "$not_in_next" "$not_in_master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
<<\DOC_END
|
||||
################################################################
|
||||
|
||||
This sample hook safeguards topic branches that have been
|
||||
published from being rewound.
|
||||
|
||||
The workflow assumed here is:
|
||||
|
||||
* Once a topic branch forks from "master", "master" is never
|
||||
merged into it again (either directly or indirectly).
|
||||
|
||||
* Once a topic branch is fully cooked and merged into "master",
|
||||
it is deleted. If you need to build on top of it to correct
|
||||
earlier mistakes, a new topic branch is created by forking at
|
||||
the tip of the "master". This is not strictly necessary, but
|
||||
it makes it easier to keep your history simple.
|
||||
|
||||
* Whenever you need to test or publish your changes to topic
|
||||
branches, merge them into "next" branch.
|
||||
|
||||
The script, being an example, hardcodes the publish branch name
|
||||
to be "next", but it is trivial to make it configurable via
|
||||
$GIT_DIR/config mechanism.
|
||||
|
||||
With this workflow, you would want to know:
|
||||
|
||||
(1) ... if a topic branch has ever been merged to "next". Young
|
||||
topic branches can have stupid mistakes you would rather
|
||||
clean up before publishing, and things that have not been
|
||||
merged into other branches can be easily rebased without
|
||||
affecting other people. But once it is published, you would
|
||||
not want to rewind it.
|
||||
|
||||
(2) ... if a topic branch has been fully merged to "master".
|
||||
Then you can delete it. More importantly, you should not
|
||||
build on top of it -- other people may already want to
|
||||
change things related to the topic as patches against your
|
||||
"master", so if you need further changes, it is better to
|
||||
fork the topic (perhaps with the same name) afresh from the
|
||||
tip of "master".
|
||||
|
||||
Let's look at this example:
|
||||
|
||||
o---o---o---o---o---o---o---o---o---o "next"
|
||||
/ / / /
|
||||
/ a---a---b A / /
|
||||
/ / / /
|
||||
/ / c---c---c---c B /
|
||||
/ / / \ /
|
||||
/ / / b---b C \ /
|
||||
/ / / / \ /
|
||||
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||
|
||||
|
||||
A, B and C are topic branches.
|
||||
|
||||
* A has one fix since it was merged up to "next".
|
||||
|
||||
* B has finished. It has been fully merged up to "master" and "next",
|
||||
and is ready to be deleted.
|
||||
|
||||
* C has not merged to "next" at all.
|
||||
|
||||
We would want to allow C to be rebased, refuse A, and encourage
|
||||
B to be deleted.
|
||||
|
||||
To compute (1):
|
||||
|
||||
git rev-list ^master ^topic next
|
||||
git rev-list ^master next
|
||||
|
||||
if these match, topic has not merged in next at all.
|
||||
|
||||
To compute (2):
|
||||
|
||||
git rev-list master..topic
|
||||
|
||||
if this is empty, it is fully merged to "master".
|
||||
|
||||
DOC_END
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare the commit log message.
|
||||
# Called by "git commit" with the name of the file that has the
|
||||
# commit message, followed by the description of the commit
|
||||
# message's source. The hook's purpose is to edit the commit
|
||||
# message file. If the hook fails with a non-zero status,
|
||||
# the commit is aborted.
|
||||
#
|
||||
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||
|
||||
# This hook includes three examples. The first comments out the
|
||||
# "Conflicts:" part of a merge commit.
|
||||
#
|
||||
# The second includes the output of "git diff --name-status -r"
|
||||
# into the message, just before the "git status" output. It is
|
||||
# commented because it doesn't cope with --amend or with squashed
|
||||
# commits.
|
||||
#
|
||||
# The third example adds a Signed-off-by line to the message, that can
|
||||
# still be edited. This is rarely a good idea.
|
||||
|
||||
case "$2,$3" in
|
||||
merge,)
|
||||
/usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
|
||||
|
||||
# ,|template,)
|
||||
# /usr/bin/perl -i.bak -pe '
|
||||
# print "\n" . `git diff --cached --name-status -r`
|
||||
# if /^#/ && $first++ == 0' "$1" ;;
|
||||
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
|
@ -0,0 +1,128 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to blocks unannotated tags from entering.
|
||||
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
||||
#
|
||||
# To enable this hook, rename this file to "update".
|
||||
#
|
||||
# Config
|
||||
# ------
|
||||
# hooks.allowunannotated
|
||||
# This boolean sets whether unannotated tags will be allowed into the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowdeletetag
|
||||
# This boolean sets whether deleting tags will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowmodifytag
|
||||
# This boolean sets whether a tag may be modified after creation. By default
|
||||
# it won't be.
|
||||
# hooks.allowdeletebranch
|
||||
# This boolean sets whether deleting branches will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.denycreatebranch
|
||||
# This boolean sets whether remotely creating branches will be denied
|
||||
# in the repository. By default this is allowed.
|
||||
#
|
||||
|
||||
# --- Command line
|
||||
refname="$1"
|
||||
oldrev="$2"
|
||||
newrev="$3"
|
||||
|
||||
# --- Safety check
|
||||
if [ -z "$GIT_DIR" ]; then
|
||||
echo "Don't run this script from the command line." >&2
|
||||
echo " (if you want, you could supply GIT_DIR then run" >&2
|
||||
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
||||
echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Config
|
||||
allowunannotated=$(git config --bool hooks.allowunannotated)
|
||||
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
|
||||
denycreatebranch=$(git config --bool hooks.denycreatebranch)
|
||||
allowdeletetag=$(git config --bool hooks.allowdeletetag)
|
||||
allowmodifytag=$(git config --bool hooks.allowmodifytag)
|
||||
|
||||
# check for no description
|
||||
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
||||
case "$projectdesc" in
|
||||
"Unnamed repository"* | "")
|
||||
echo "*** Project description file hasn't been set" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Check types
|
||||
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
||||
zero="0000000000000000000000000000000000000000"
|
||||
if [ "$newrev" = "$zero" ]; then
|
||||
newrev_type=delete
|
||||
else
|
||||
newrev_type=$(git cat-file -t $newrev)
|
||||
fi
|
||||
|
||||
case "$refname","$newrev_type" in
|
||||
refs/tags/*,commit)
|
||||
# un-annotated tag
|
||||
short_refname=${refname##refs/tags/}
|
||||
if [ "$allowunannotated" != "true" ]; then
|
||||
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
||||
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,delete)
|
||||
# delete tag
|
||||
if [ "$allowdeletetag" != "true" ]; then
|
||||
echo "*** Deleting a tag is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,tag)
|
||||
# annotated tag
|
||||
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
||||
then
|
||||
echo "*** Tag '$refname' already exists." >&2
|
||||
echo "*** Modifying a tag is not allowed in this repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,commit)
|
||||
# branch
|
||||
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
||||
echo "*** Creating a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,delete)
|
||||
# delete branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/remotes/*,commit)
|
||||
# tracking branch
|
||||
;;
|
||||
refs/remotes/*,delete)
|
||||
# delete tracking branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# Anything else (is there anything else?)
|
||||
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Finished
|
||||
exit 0
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
|
@ -0,0 +1,2 @@
|
|||
0000000000000000000000000000000000000000 bdc8b580b5b583aeb43efb19aac2ab8ce5566dff Alexander <avm@avm-work.(none)> 1325695134 +0600 clone: from git://github.com/tpope/vim-ragtag.git
|
||||
bdc8b580b5b583aeb43efb19aac2ab8ce5566dff bdc8b580b5b583aeb43efb19aac2ab8ce5566dff Alexander <avm@avm-work.(none)> 1325695134 +0600 checkout: moving from master to bdc8b580b5b583aeb43efb19aac2ab8ce5566dff
|
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 bdc8b580b5b583aeb43efb19aac2ab8ce5566dff Alexander <avm@avm-work.(none)> 1325695134 +0600 clone: from git://github.com/tpope/vim-ragtag.git
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
# pack-refs with: peeled
|
||||
30aefeac002db3ec08ff278bd76290645469611e refs/tags/v2.0
|
||||
^644c62ad7bc7d9a4a5f19f5e8c41ef910782178b
|
||||
235e4467107467feacc50553bbeda15e9bf99f57 refs/tags/v1.11
|
||||
bdc8b580b5b583aeb43efb19aac2ab8ce5566dff refs/remotes/origin/master
|
|
@ -0,0 +1 @@
|
|||
bdc8b580b5b583aeb43efb19aac2ab8ce5566dff
|
|
@ -0,0 +1 @@
|
|||
ref: refs/remotes/origin/master
|
Loading…
Reference in New Issue