merging upstream changes
This commit is contained in:
commit
35d0de8f36
49 changed files with 512 additions and 169 deletions
|
@ -11,6 +11,7 @@
|
|||
//= require jquery.tagify
|
||||
//= require jquery.cookie
|
||||
//= require jquery.endless-scroll
|
||||
//= require jquery.highlight
|
||||
//= require bootstrap-modal
|
||||
//= require modernizr
|
||||
//= require chosen
|
||||
|
|
|
@ -11,7 +11,7 @@ var MergeRequest = {
|
|||
|
||||
$(".tabs a.merge-notes-tab").live("click", function(e) {
|
||||
$(".merge-request-diffs").hide();
|
||||
$(".merge-request-notes").show();
|
||||
$(".merge_request_notes").show();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
@ -19,7 +19,7 @@ var MergeRequest = {
|
|||
if(!MergeRequest.diffs_loaded) {
|
||||
MergeRequest.loadDiff();
|
||||
}
|
||||
$(".merge-request-notes").hide();
|
||||
$(".merge_request_notes").hide();
|
||||
$(".merge-request-diffs").show();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
@ -33,7 +33,7 @@ var MergeRequest = {
|
|||
url: $(".merge-diffs-tab").attr("data-url"),
|
||||
complete: function(){
|
||||
MergeRequest.diffs_loaded = true;
|
||||
$(".merge-request-notes").hide();
|
||||
$(".merge_request_notes").hide();
|
||||
$(".dashboard-loader").hide()},
|
||||
dataType: "script"});
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ a {
|
|||
color: $link_color;
|
||||
&:hover {
|
||||
text-decoration:none;
|
||||
color: $style_color;
|
||||
color: $blue_link;
|
||||
}
|
||||
|
||||
&.btn {
|
||||
|
@ -11,6 +11,18 @@ a {
|
|||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f1f1f1), color-stop(25%, #f1f1f1), to(#e6e6e6));
|
||||
background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
|
||||
background-image: -moz-linear-gradient(top, #f1f1f1, #f1f1f1 25%, #e6e6e6);
|
||||
background-image: -ms-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
|
||||
background-image: -o-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
|
||||
background-image: linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
|
||||
|
||||
&:hover {
|
||||
}
|
||||
}
|
||||
|
||||
a:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
@ -29,6 +41,29 @@ a:focus {
|
|||
|
||||
.label {
|
||||
background-color: #474D57;
|
||||
|
||||
&.pushed {
|
||||
background-color: $link_color;
|
||||
}
|
||||
}
|
||||
|
||||
.pretty_label {
|
||||
@include round-borders-all(4px);
|
||||
padding:2px 4px;
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
|
||||
background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
|
||||
background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
|
||||
background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
|
||||
color: #777;
|
||||
border: 1px solid #DEDFE1;
|
||||
|
||||
&.branch {
|
||||
border:none;
|
||||
font-size:13px;
|
||||
background: #474D57;
|
||||
color:#fff;
|
||||
font-family: monospace;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs > li > a, .pills > li > a {
|
||||
|
@ -807,12 +842,19 @@ p.time {
|
|||
width:840px;
|
||||
margin:auto;
|
||||
|
||||
.wll {
|
||||
padding:5px;
|
||||
margin-top:5px;
|
||||
.dash_project_item {
|
||||
margin-bottom:10px;
|
||||
border:none;
|
||||
&:hover {
|
||||
background:none;
|
||||
|
||||
h4 {
|
||||
color:#2FA0BB;
|
||||
.arrow {
|
||||
background:#2FA0BB;
|
||||
color:#fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
|
@ -887,7 +929,7 @@ p.time {
|
|||
}
|
||||
a:last-child h4 { border:none; }
|
||||
|
||||
a.active {
|
||||
a:hover {
|
||||
h4 {
|
||||
color:#111;
|
||||
border-right:4px solid $styled_border_color;
|
||||
|
@ -974,3 +1016,32 @@ p.time {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.highlight_word {
|
||||
background:#EEDC94;
|
||||
}
|
||||
|
||||
.status_info {
|
||||
font-size:14px;
|
||||
padding:5px 15px;
|
||||
line-height:24px;
|
||||
width:60px;
|
||||
text-align:center;
|
||||
float:left;
|
||||
margin-right:20px;
|
||||
}
|
||||
|
||||
.merge_request_status_holder {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.arrow{
|
||||
float: right;
|
||||
background: #E3E5EA;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
text-shadow: none;
|
||||
color: #999;
|
||||
line-height: 16px;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ $app_padding:20px;
|
|||
$bg_color: #FFF;
|
||||
$styled_border_color: #2FA0BB;
|
||||
$color: "#4BB8D2";
|
||||
$blue_link: "#2fa0bb";
|
||||
$blue_link: #2fa0bb;
|
||||
|
||||
|
||||
/** Style colors **/
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
color: $link_color;
|
||||
&:hover {
|
||||
text-decoration:none;
|
||||
color: $style_color;
|
||||
color: $blue_link;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class DashboardController < ApplicationController
|
|||
# Get authored or assigned open merge requests
|
||||
def merge_requests
|
||||
@projects = current_user.projects.all
|
||||
@merge_requests = MergeRequest.where("author_id = :id or assignee_id = :id", :id => current_user.id).opened.order("created_at DESC").limit(40)
|
||||
@merge_requests = current_user.cared_merge_requests.order("created_at DESC").limit(40)
|
||||
end
|
||||
|
||||
# Get only assigned issues
|
||||
|
|
|
@ -41,13 +41,9 @@ class MergeRequestsController < ApplicationController
|
|||
|
||||
@note = @project.notes.new(:noteable => @merge_request)
|
||||
|
||||
@commits = @project.repo.
|
||||
commits_between(@merge_request.target_branch, @merge_request.source_branch).
|
||||
map {|c| Commit.new(c)}.
|
||||
sort_by(&:created_at).
|
||||
reverse
|
||||
|
||||
render_full_content
|
||||
# Get commits from repository
|
||||
# or from cache if already merged
|
||||
@commits = @merge_request.commits
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
@ -76,6 +72,7 @@ class MergeRequestsController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
if @merge_request.save
|
||||
@merge_request.reload_code
|
||||
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.' }
|
||||
format.json { render json: @merge_request, status: :created, location: @merge_request }
|
||||
else
|
||||
|
@ -88,6 +85,7 @@ class MergeRequestsController < ApplicationController
|
|||
def update
|
||||
respond_to do |format|
|
||||
if @merge_request.update_attributes(params[:merge_request].merge(:author_id_of_changes => current_user.id))
|
||||
@merge_request.reload_code
|
||||
format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.' }
|
||||
format.json { head :ok }
|
||||
else
|
||||
|
|
|
@ -13,6 +13,7 @@ class ProjectsController < ApplicationController
|
|||
def index
|
||||
@projects = current_user.projects
|
||||
@projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse
|
||||
@events = Event.where(:project_id => @projects.map(&:id)).recent.limit(40)
|
||||
end
|
||||
|
||||
def new
|
||||
|
@ -78,7 +79,6 @@ class ProjectsController < ApplicationController
|
|||
render "projects/empty"
|
||||
end
|
||||
end
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
|
|
12
app/controllers/search_controller.rb
Normal file
12
app/controllers/search_controller.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
class SearchController < ApplicationController
|
||||
def show
|
||||
query = params[:search]
|
||||
if query.blank?
|
||||
@projects = []
|
||||
@merge_requests = []
|
||||
else
|
||||
@projects = Project.search(query).limit(10)
|
||||
@merge_requests = MergeRequest.search(query).limit(10)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,7 @@ class Event < ActiveRecord::Base
|
|||
Reopened = 4
|
||||
Pushed = 5
|
||||
Commented = 6
|
||||
Merged = 7
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :target, :polymorphic => true
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
require File.join(Rails.root, "app/models/commit")
|
||||
|
||||
class MergeRequest < ActiveRecord::Base
|
||||
belongs_to :project
|
||||
belongs_to :author, :class_name => "User"
|
||||
belongs_to :assignee, :class_name => "User"
|
||||
has_many :notes, :as => :noteable, :dependent => :destroy
|
||||
|
||||
serialize :st_commits
|
||||
serialize :st_diffs
|
||||
|
||||
attr_protected :author, :author_id, :project, :project_id
|
||||
attr_accessor :author_id_of_changes
|
||||
|
||||
|
@ -32,6 +37,13 @@ class MergeRequest < ActiveRecord::Base
|
|||
scope :closed, where(:closed => true)
|
||||
scope :assigned, lambda { |u| where(:assignee_id => u.id)}
|
||||
|
||||
def self.search query
|
||||
where("title like :query", :query => "%#{query}%")
|
||||
end
|
||||
|
||||
def self.find_all_by_branch(branch_name)
|
||||
where("source_branch like :branch or target_branch like :branch", :branch => branch_name)
|
||||
end
|
||||
|
||||
def validate_branches
|
||||
if target_branch == source_branch
|
||||
|
@ -39,23 +51,99 @@ class MergeRequest < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def reload_code
|
||||
self.reloaded_commits
|
||||
self.reloaded_diffs
|
||||
end
|
||||
|
||||
def new?
|
||||
today? && created_at == updated_at
|
||||
end
|
||||
|
||||
def diffs
|
||||
st_diffs || []
|
||||
end
|
||||
|
||||
def reloaded_diffs
|
||||
if open? && unmerged_diffs.any?
|
||||
self.st_diffs = unmerged_diffs
|
||||
save
|
||||
end
|
||||
diffs
|
||||
end
|
||||
|
||||
def unmerged_diffs
|
||||
commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)}
|
||||
diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue []
|
||||
end
|
||||
|
||||
def last_commit
|
||||
project.commit(source_branch)
|
||||
commits.first
|
||||
end
|
||||
|
||||
def merged?
|
||||
merged && merge_event
|
||||
end
|
||||
|
||||
def merge_event
|
||||
self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Merged).last
|
||||
end
|
||||
|
||||
def closed_event
|
||||
self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Closed).last
|
||||
end
|
||||
|
||||
|
||||
# Return the number of +1 comments (upvotes)
|
||||
def upvotes
|
||||
notes.select(&:upvote?).size
|
||||
end
|
||||
|
||||
def commits
|
||||
st_commits || []
|
||||
end
|
||||
|
||||
def probably_merged?
|
||||
unmerged_commits.empty? &&
|
||||
commits.any? && open?
|
||||
end
|
||||
|
||||
def open?
|
||||
!closed
|
||||
end
|
||||
|
||||
def mark_as_merged!
|
||||
self.merged = true
|
||||
self.closed = true
|
||||
save
|
||||
end
|
||||
|
||||
def reloaded_commits
|
||||
if open? && unmerged_commits.any?
|
||||
self.st_commits = unmerged_commits
|
||||
save
|
||||
end
|
||||
commits
|
||||
end
|
||||
|
||||
def unmerged_commits
|
||||
self.project.repo.
|
||||
commits_between(self.target_branch, self.source_branch).
|
||||
map {|c| Commit.new(c)}.
|
||||
sort_by(&:created_at).
|
||||
reverse
|
||||
end
|
||||
|
||||
def merge!(user_id)
|
||||
self.mark_as_merged!
|
||||
Event.create(
|
||||
:project => self.project,
|
||||
:action => Event::Merged,
|
||||
:target_id => self.id,
|
||||
:target_type => "MergeRequest",
|
||||
:author_id => user_id
|
||||
)
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
|
|
|
@ -54,6 +54,10 @@ class Project < ActiveRecord::Base
|
|||
UsersProject.access_roles
|
||||
end
|
||||
|
||||
def self.search query
|
||||
where("name like :query or code like :query or path like :query", :query => "%#{query}%")
|
||||
end
|
||||
|
||||
def to_param
|
||||
code
|
||||
end
|
||||
|
@ -73,6 +77,24 @@ class Project < ActiveRecord::Base
|
|||
)
|
||||
end
|
||||
|
||||
def update_merge_requests(oldrev, newrev, ref, author_key_id)
|
||||
return true unless ref =~ /heads/
|
||||
branch_name = ref.gsub("refs/heads/", "")
|
||||
user = Key.find_by_identifier(author_key_id).user
|
||||
c_ids = self.commits_between(oldrev, newrev).map(&:id)
|
||||
|
||||
# Update code for merge requests
|
||||
mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
|
||||
mrs.each { |merge_request| merge_request.reload_code }
|
||||
|
||||
# Close merge requests
|
||||
mrs = self.merge_requests.opened.where(:target_branch => branch_name).all
|
||||
mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
|
||||
mrs.each { |merge_request| merge_request.merge!(user.id) }
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def execute_web_hooks(oldrev, newrev, ref, author_key_id)
|
||||
ref_parts = ref.split('/')
|
||||
|
||||
|
|
|
@ -86,6 +86,10 @@ class User < ActiveRecord::Base
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
def cared_merge_requests
|
||||
MergeRequest.where("author_id = :id or assignee_id = :id", :id => self.id).opened
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
= @commit.committer_name
|
||||
%small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm")
|
||||
|
||||
%hr
|
||||
%pre.commit_message
|
||||
%br
|
||||
%pre.commit_message.prettyprint
|
||||
= commit_msg_with_link_to_issues(@project, @commit.safe_message)
|
||||
.clear
|
||||
%br
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
= render @events
|
||||
|
|
@ -3,8 +3,10 @@
|
|||
= link_to [issue.project, issue] do
|
||||
%p
|
||||
%strong
|
||||
%span.label= issue.project.name
|
||||
%span.pretty_label= issue.project.name
|
||||
–
|
||||
Issue #
|
||||
= issue.id
|
||||
= truncate issue.title, :length => 50
|
||||
%span.right.cgray
|
||||
= issue.updated_at.stamp("Aug 21, 2011")
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
= link_to [merge_request.project, merge_request] do
|
||||
%p
|
||||
%strong
|
||||
%span.label= merge_request.project.name
|
||||
%span.pretty_label= merge_request.project.name
|
||||
–
|
||||
Merge Request #
|
||||
= merge_request.id
|
||||
Merge Request ##{merge_request.id}
|
||||
= truncate merge_request.title, :length => 50
|
||||
%span.right.cgray
|
||||
= merge_request.updated_at.stamp("Aug 21, 2011")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- @active_projects.first(5).each do |project|
|
||||
.wll
|
||||
- projects.first(5).each do |project|
|
||||
%div.dash_project_item
|
||||
= link_to project do
|
||||
%h4
|
||||
%span.ico.project
|
||||
|
@ -7,3 +7,5 @@
|
|||
%small
|
||||
last activity at
|
||||
= project.last_activity_date.stamp("Aug 25, 2011")
|
||||
%span.right.arrow
|
||||
→
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
.row
|
||||
.dashboard_block
|
||||
.row
|
||||
.span10= render "dashboard/projects_feed"
|
||||
.span10= render "dashboard/projects_feed", :projects => @active_projects
|
||||
.span4.right
|
||||
- if current_user.can_create_project?
|
||||
.alert-message.block-message.warning
|
||||
|
@ -65,4 +65,4 @@
|
|||
|
||||
%hr
|
||||
.row
|
||||
.dashboard_block= render "dashboard/events_feed"
|
||||
.dashboard_block= render @events
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
- if event.closed?
|
||||
closed
|
||||
- else
|
||||
reopened
|
||||
issue
|
||||
%span.label.important
|
||||
- if event.closed?
|
||||
closed
|
||||
- else
|
||||
reopened
|
||||
issue
|
||||
= link_to project_issue_path(event.project, event.issue) do
|
||||
%strong= truncate event.issue_title
|
||||
at
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
- if event.closed?
|
||||
closed
|
||||
- else
|
||||
reopened
|
||||
merge request
|
||||
%span.label.important
|
||||
- if event.closed?
|
||||
closed
|
||||
- else
|
||||
reopened
|
||||
merge request
|
||||
= link_to project_merge_request_path(event.project, event.merge_request) do
|
||||
%strong= truncate event.merge_request_title
|
||||
at
|
||||
|
@ -12,7 +13,6 @@ at
|
|||
%span.cgray
|
||||
= time_ago_in_words(event.created_at)
|
||||
ago.
|
||||
%br
|
||||
%span.label= event.merge_request.source_branch
|
||||
→
|
||||
%span.label= event.merge_request.target_branch
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
created new issue
|
||||
%span.label.success created
|
||||
new issue
|
||||
= link_to project_issue_path(event.project, event.issue) do
|
||||
%strong= truncate event.issue_title
|
||||
at
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
requested merge
|
||||
%span.label.success requested
|
||||
merge
|
||||
= link_to project_merge_request_path(event.project, event.merge_request) do
|
||||
%strong= truncate event.merge_request_title
|
||||
at
|
||||
|
@ -8,7 +9,6 @@ at
|
|||
%span.cgray
|
||||
= time_ago_in_words(event.created_at)
|
||||
ago.
|
||||
%br
|
||||
%span.label= event.merge_request.source_branch
|
||||
→
|
||||
%span.label= event.merge_request.target_branch
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
- if event.new_branch? || event.new_tag?
|
||||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
pushed new
|
||||
%span.label.pushed pushed
|
||||
new
|
||||
- if event.new_tag?
|
||||
tag
|
||||
= link_to project_commits_path(event.project, :ref => event.tag_name) do
|
||||
|
@ -18,7 +19,8 @@
|
|||
- else
|
||||
= image_tag gravatar_icon(event.author_email), :class => "avatar"
|
||||
%strong #{event.author_name}
|
||||
pushed to
|
||||
%span.label.pushed pushed
|
||||
to
|
||||
= link_to project_commits_path(event.project, :ref => event.branch_name) do
|
||||
%strong= event.branch_name
|
||||
at
|
||||
|
@ -30,10 +32,10 @@
|
|||
= link_to compare_project_commits_path(event.project, :from => event.commits.first.prev_commit_id, :to => event.commits.last.id) do
|
||||
Compare #{event.commits.first.commit.id[0..8]}...#{event.commits.last.id[0..8]}
|
||||
- @project = event.project
|
||||
%ul.unstyled
|
||||
- if event.commits.size > 4
|
||||
= render event.commits[0..2]
|
||||
%li ... and #{event.commits.size - 3} more commits
|
||||
%ul.unstyled.event_commits
|
||||
- if event.commits.size > 3
|
||||
= render event.commits[0...2]
|
||||
%li ... and #{event.commits.size - 2} more commits
|
||||
- else
|
||||
= render event.commits
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
%nav.main_menu
|
||||
= render "layouts/const_menu_links"
|
||||
= link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}"
|
||||
= link_to "Issues", dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide"
|
||||
= link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide"
|
||||
= link_to dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" do
|
||||
Issues
|
||||
%span.count= current_user.assigned_issues.opened.count
|
||||
= link_to dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" do
|
||||
Requests
|
||||
%span.count= current_user.cared_merge_requests.count
|
||||
= link_to "Search", search_path, :class => "#{"current" if current_page?(search_path)}"
|
||||
= link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}"
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
%h1
|
||||
GITLAB
|
||||
%h1.project_name= title
|
||||
.search= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input"
|
||||
.search
|
||||
= form_tag search_path, :method => :get do |f|
|
||||
= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input"
|
||||
- if current_user.is_admin?
|
||||
= link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do
|
||||
= image_tag "admin.PNG", :width => 16
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
.ui-box
|
||||
%h5 Commits
|
||||
.merge-request-commits
|
||||
%ul.unstyled= render @commits
|
||||
%ul.unstyled
|
||||
- @commits.each do |commit|
|
||||
= render "commits/commit", :commit => commit
|
||||
|
||||
- else
|
||||
%h5
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
:javascript
|
||||
$(function(){
|
||||
var modal = $('#modal_merge_info').modal({modal: true});
|
||||
$('.info_link').bind("click", function(){
|
||||
$('.how_to_merge_link').bind("click", function(){
|
||||
modal.show();
|
||||
});
|
||||
$('.modal-header .close').bind("click", function(){
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
= time_ago_in_words(merge_request.created_at)
|
||||
ago
|
||||
- if merge_request.notes.any?
|
||||
%span.label= pluralize merge_request.notes.count, 'note'
|
||||
%span.pretty_label= pluralize merge_request.notes.count, 'note'
|
||||
- if merge_request.upvotes > 0
|
||||
%span.label.success= "+#{merge_request.upvotes}"
|
||||
.right
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
%h3
|
||||
= "Merge Request ##{@merge_request.id}:"
|
||||
|
||||
%span.label= @merge_request.source_branch
|
||||
%span.pretty_label.branch= @merge_request.source_branch
|
||||
→
|
||||
%span.label= @merge_request.target_branch
|
||||
%span.pretty_label.branch= @merge_request.target_branch
|
||||
|
||||
%small
|
||||
created at
|
||||
|
@ -11,12 +11,10 @@
|
|||
|
||||
%span.right
|
||||
- if can?(current_user, :modify_merge_request, @merge_request)
|
||||
- if @merge_request.closed
|
||||
= link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "btn"
|
||||
- else
|
||||
- if @merge_request.open?
|
||||
= link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "btn", :title => "Close merge request"
|
||||
= link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn" do
|
||||
Edit
|
||||
= link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn" do
|
||||
Edit
|
||||
|
||||
%br
|
||||
- if @merge_request.upvotes > 0
|
||||
|
@ -28,17 +26,27 @@
|
|||
|
||||
|
||||
%hr
|
||||
- if @merge_request.closed
|
||||
.alert-message.error Closed
|
||||
- else
|
||||
.alert-message.success
|
||||
= link_to "#", :class => "info_link", :title => "How To Merge" do
|
||||
= image_tag "Info-UI.PNG"
|
||||
Open
|
||||
.merge_request_status_holder
|
||||
- if @merge_request.closed
|
||||
%h5
|
||||
.alert-message.error.status_info Closed
|
||||
- if @merge_request.merged?
|
||||
%span
|
||||
Merged by #{@merge_request.merge_event.author_name}
|
||||
%small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago.
|
||||
- elsif @merge_request.closed_event
|
||||
%span
|
||||
Closed by #{@merge_request.closed_event.author_name}
|
||||
%small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago.
|
||||
%br
|
||||
- else
|
||||
%h5
|
||||
.alert-message.success.status_info Open
|
||||
= link_to "How to merge", "#", :class => "vlink how_to_merge_link", :title => "How To Merge"
|
||||
|
||||
= render "merge_requests/how_to_merge"
|
||||
|
||||
%div.well
|
||||
%div.well.prettyprint
|
||||
%div
|
||||
%cite.cgray Created by
|
||||
= image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av"
|
||||
|
|
|
@ -1,42 +1,46 @@
|
|||
%h3 Password
|
||||
%hr
|
||||
= form_for @user, :url => profile_password_path, :method => :put do |f|
|
||||
.data
|
||||
.alert-message.block-message.warning
|
||||
%p After successfull password update you will be redirected to login page where you should login with new password
|
||||
-if @user.errors.any?
|
||||
.alert-message.block-message.error
|
||||
%ul
|
||||
- @user.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
= f.label :password
|
||||
.input= f.password_field :password
|
||||
.clearfix
|
||||
= f.label :password_confirmation
|
||||
.input= f.password_field :password_confirmation
|
||||
.actions
|
||||
= f.submit 'Save', :class => "btn"
|
||||
|
||||
%h3
|
||||
Private token
|
||||
%span.cred.right
|
||||
keep it in secret!
|
||||
%hr
|
||||
= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
|
||||
.data
|
||||
%p Private token used to access application resources without authentication.
|
||||
%p For example its required to access commits feed.
|
||||
.row
|
||||
.span8
|
||||
%h3 Password
|
||||
%hr
|
||||
%p.cgray
|
||||
- if current_user.private_token
|
||||
= text_field_tag "token", current_user.private_token
|
||||
- else
|
||||
You don`t have one yet. Click generate to fix it.
|
||||
.actions
|
||||
- if current_user.private_token
|
||||
= f.submit 'Reset', :confirm => "Are you sure?", :class => "btn"
|
||||
- else
|
||||
= f.submit 'Generate', :class => "btn"
|
||||
= form_for @user, :url => profile_password_path, :method => :put do |f|
|
||||
.data
|
||||
.alert-message.block-message.warning
|
||||
%p After successfull password update you will be redirected to login page where you should login with new password
|
||||
-if @user.errors.any?
|
||||
.alert-message.block-message.error
|
||||
%ul
|
||||
- @user.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
= f.label :password
|
||||
.input= f.password_field :password
|
||||
.clearfix
|
||||
= f.label :password_confirmation
|
||||
.input= f.password_field :password_confirmation
|
||||
.actions
|
||||
= f.submit 'Save', :class => "btn"
|
||||
|
||||
.span7.right
|
||||
%h3
|
||||
Private token
|
||||
%span.cred.right
|
||||
keep it in secret!
|
||||
%hr
|
||||
= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
|
||||
.data
|
||||
.alert-message.block-message.warning
|
||||
%p Private token used to access application resources without authentication.
|
||||
%hr
|
||||
%p * required for rss feed
|
||||
%p.cgray
|
||||
- if current_user.private_token
|
||||
= text_field_tag "token", current_user.private_token
|
||||
- else
|
||||
You don`t have one yet. Click generate to fix it.
|
||||
.actions
|
||||
- if current_user.private_token
|
||||
= f.submit 'Reset', :confirm => "Are you sure?", :class => "btn"
|
||||
- else
|
||||
= f.submit 'Generate', :class => "btn"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%h4.title
|
||||
%h5.title
|
||||
= @project.name
|
||||
%br
|
||||
%div
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
%li Visit profile → keys and add public key of every machine you want to use for work with gitlabhq.
|
||||
|
||||
.alert-message.block-message.error
|
||||
%ul.alert_holder
|
||||
%ul.unstyled.alert_holder
|
||||
%li You should push repository to proceed.
|
||||
%li After push you will be able to browse code, commits etc.
|
||||
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
- if @projects.any?
|
||||
.row
|
||||
.span4
|
||||
.span11
|
||||
= render @events
|
||||
.span5.right
|
||||
%div.leftbar.ui-box
|
||||
%h5
|
||||
Projects
|
||||
%small
|
||||
(#{@projects.count})
|
||||
- if current_user.can_create_project?
|
||||
%span.right
|
||||
= link_to new_project_path, :class => "btn very_small info" do
|
||||
New Project
|
||||
.content_list
|
||||
- @projects.each do |project|
|
||||
= link_to project_path(project), :remote => true, :class => dom_class(project) do
|
||||
= link_to project_path(project), :class => dom_class(project) do
|
||||
%h4
|
||||
%span.ico.project
|
||||
= truncate(project.name, :length => 22)
|
||||
.span12.right
|
||||
.show_holder.ui-box.padded
|
||||
.loading
|
||||
= truncate(project.name, :length => 25)
|
||||
%span.right
|
||||
→
|
||||
|
||||
- else
|
||||
%h3 Nothing here
|
||||
|
@ -31,20 +34,3 @@
|
|||
New Project »
|
||||
- else
|
||||
If you will be added to project - it will be displayed here
|
||||
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
$("a.project").live("ajax:before", function() {
|
||||
$(".show_holder").html("<div class='loading'>");
|
||||
$('a.project').removeClass("active");
|
||||
$(this).addClass("active");
|
||||
});
|
||||
$('a.project:first-child').trigger("click");
|
||||
});
|
||||
|
||||
- if @projects.count == @limit
|
||||
:javascript
|
||||
$(function(){
|
||||
Pager.init(#{@limit});
|
||||
});
|
||||
|
|
|
@ -21,9 +21,13 @@
|
|||
= text_field_tag :project_clone, @project.url_to_repo, :class => "xlarge one_click_select git_clone_url"
|
||||
|
||||
- if @project.description.present?
|
||||
= markdown @project.description
|
||||
.prettyprint= markdown @project.description
|
||||
- unless @events.blank?
|
||||
%h5.cgray Recent Activity
|
||||
%br
|
||||
%h5.cgray
|
||||
%span.ico.activities
|
||||
Recent Activity
|
||||
%hr
|
||||
.content_list= render @events
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
- if @project.repo_exists? && @project.has_commits?
|
||||
:plain
|
||||
$(".show_holder").html("#{escape_javascript(render(:partial => 'projects/show'))}");
|
||||
- else
|
||||
:plain
|
||||
$(".show_holder").html("#{escape_javascript(render(:template => 'projects/empty'))}");
|
||||
|
1
app/views/search/_result.html.haml
Normal file
1
app/views/search/_result.html.haml
Normal file
|
@ -0,0 +1 @@
|
|||
|
41
app/views/search/show.html.haml
Normal file
41
app/views/search/show.html.haml
Normal file
|
@ -0,0 +1,41 @@
|
|||
= form_tag search_path, :method => :get do |f|
|
||||
.padded
|
||||
= label_tag :search, "Looking for"
|
||||
.input
|
||||
= text_field_tag :search, params[:search],:placeholder => "issue 143", :class => "xxlarge"
|
||||
= submit_tag 'Search', :class => "btn primary"
|
||||
- if params[:search].present?
|
||||
%br
|
||||
%h3 Search results
|
||||
%hr
|
||||
.search_results
|
||||
- if @projects.empty? && @merge_requests.empty?
|
||||
%h3
|
||||
%small Nothing here
|
||||
- else
|
||||
- if @projects.any?
|
||||
- @projects.each do |project|
|
||||
= link_to project do
|
||||
%h4
|
||||
%span.ico.project
|
||||
= project.name
|
||||
%small
|
||||
last activity at
|
||||
= project.last_activity_date.stamp("Aug 25, 2011")
|
||||
- if @merge_requests.any?
|
||||
- @merge_requests.each do |merge_request|
|
||||
= link_to [merge_request.project, merge_request] do
|
||||
%h5
|
||||
Merge Request #
|
||||
= merge_request.id
|
||||
–
|
||||
= truncate merge_request.title, :length => 50
|
||||
%small
|
||||
updated at
|
||||
= merge_request.updated_at.stamp("Aug 25, 2011")
|
||||
%strong
|
||||
%span.label= merge_request.project.name
|
||||
:javascript
|
||||
$(function() {
|
||||
$(".search_results").highlight("#{params[:search]}");
|
||||
})
|
|
@ -8,7 +8,13 @@ class PostReceive
|
|||
# Ignore push from non-gitlab users
|
||||
return false unless Key.find_by_identifier(author_key_id)
|
||||
|
||||
# Create push event
|
||||
project.observe_push(oldrev, newrev, ref, author_key_id)
|
||||
|
||||
# Close merged MR
|
||||
project.update_merge_requests(oldrev, newrev, ref, author_key_id)
|
||||
|
||||
# Execute web hooks
|
||||
project.execute_web_hooks(oldrev, newrev, ref, author_key_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Gitlab::Application.routes.draw do
|
||||
|
||||
get 'search' => "search#show"
|
||||
|
||||
# Optionally, enable Resque here
|
||||
require 'resque/server'
|
||||
|
@ -40,6 +40,7 @@ Gitlab::Application.routes.draw do
|
|||
get "dashboard", :to => "dashboard#index"
|
||||
get "dashboard/issues", :to => "dashboard#issues"
|
||||
get "dashboard/merge_requests", :to => "dashboard#merge_requests"
|
||||
get "dashboard/activities", :to => "dashboard#activities"
|
||||
|
||||
#get "profile/:id", :to => "profile#show"
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
class AddCommitsDiffStoreToMergeRequest < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :merge_requests, :st_commits, :text, :null => true
|
||||
add_column :merge_requests, :st_diffs, :text, :null => true
|
||||
end
|
||||
end
|
5
db/migrate/20120315132931_add_merged_to_merge_request.rb
Normal file
5
db/migrate/20120315132931_add_merged_to_merge_request.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddMergedToMergeRequest < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :merge_requests, :merged, :boolean, :null => false, :default => false
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20120307095918) do
|
||||
ActiveRecord::Schema.define(:version => 20120315132931) do
|
||||
|
||||
create_table "events", :force => true do |t|
|
||||
t.string "target_type"
|
||||
|
@ -61,6 +61,9 @@ ActiveRecord::Schema.define(:version => 20120307095918) do
|
|||
t.boolean "closed", :default => false, :null => false
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.text "st_commits"
|
||||
t.text "st_diffs"
|
||||
t.boolean "merged", :default => false, :null => false
|
||||
end
|
||||
|
||||
add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id"
|
||||
|
|
|
@ -209,7 +209,7 @@ Application can be started with next command:
|
|||
|
||||
cd /home/gitlab/gitlab
|
||||
sudo -u gitlab cp config/unicorn.rb.orig config/unicorn.rb
|
||||
sudo -u gitlab unicorn_rails -c config/unicorn.rb -E production -D
|
||||
sudo -u gitlab bundle exec unicorn_rails -c config/unicorn.rb -E production -D
|
||||
|
||||
Edit /etc/nginx/nginx.conf. Add next code to **http** section:
|
||||
|
||||
|
@ -256,33 +256,38 @@ Create init script in /etc/init.d/gitlab:
|
|||
NAME=unicorn
|
||||
DESC="Gitlab service"
|
||||
PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid
|
||||
RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
CD_TO_APP_DIR="cd /home/gitlab/gitlab"
|
||||
START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS"
|
||||
START_RESQUE_PROCESS="./resque.sh"
|
||||
|
||||
echo -n "Starting $DESC: "
|
||||
if [ `whoami` = root ]; then
|
||||
sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS"
|
||||
sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS"
|
||||
else
|
||||
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS
|
||||
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS
|
||||
fi
|
||||
echo "$NAME."
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $DESC: "
|
||||
kill -QUIT `cat $PID`
|
||||
kill -QUIT `cat $RESQUE_PID`
|
||||
echo "$NAME."
|
||||
;;
|
||||
restart)
|
||||
echo -n "Restarting $DESC: "
|
||||
kill -USR2 `cat $PID`
|
||||
kill -USR2 `cat $RESQUE_PID`
|
||||
echo "$NAME."
|
||||
;;
|
||||
reload)
|
||||
echo -n "Reloading $DESC configuration: "
|
||||
kill -HUP `cat $PID`
|
||||
kill -HUP `cat $RESQUE_PID`
|
||||
echo "$NAME."
|
||||
;;
|
||||
*)
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
mkdir tmp/pids
|
||||
nohup bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production PIDFILE=tmp/pids/resque_worker_QUEUE.pid & >> log/resque_worker_QUEUE.log 2>&1
|
||||
nohup bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production PIDFILE=tmp/pids/resque_worker.pid & >> log/resque_worker.log 2>&1
|
||||
|
|
|
@ -160,6 +160,34 @@ describe Project do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :update_merge_requests do
|
||||
let(:project) { Factory :project }
|
||||
|
||||
before do
|
||||
@merge_request = Factory :merge_request,
|
||||
:project => project,
|
||||
:merged => false,
|
||||
:closed => false
|
||||
@key = Factory :key, :user_id => project.owner.id
|
||||
end
|
||||
|
||||
it "should close merge request if last commit from source branch was pushed to target branch" do
|
||||
@merge_request.reloaded_commits
|
||||
@merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
|
||||
project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/stable", @key.identifier)
|
||||
@merge_request.reload
|
||||
@merge_request.merged.should be_true
|
||||
@merge_request.closed.should be_true
|
||||
end
|
||||
|
||||
it "should update merge request commits with new one if pushed to source branch" do
|
||||
@merge_request.last_commit.should == nil
|
||||
project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/master", @key.identifier)
|
||||
@merge_request.reload
|
||||
@merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
|
||||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
require 'spec_helper'
|
||||
__END__
|
||||
# Disabled for now
|
||||
describe "Dashboard" do
|
||||
before do
|
||||
@project = Factory :project
|
||||
|
@ -22,19 +20,7 @@ describe "Dashboard" do
|
|||
end
|
||||
|
||||
it "should have projects panel" do
|
||||
within ".project-list" do
|
||||
page.should have_content(@project.name)
|
||||
end
|
||||
page.should have_content(@project.name)
|
||||
end
|
||||
|
||||
# Temporary disabled cause of travis
|
||||
# TODO: fix or rewrite
|
||||
#it "should have news feed" do
|
||||
#within "#news-feed" do
|
||||
#page.should have_content("commit")
|
||||
#page.should have_content(@project.commit.author.name)
|
||||
#page.should have_content(@project.commit.safe_message)
|
||||
#end
|
||||
#end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,7 +42,7 @@ describe "MergeRequests" do
|
|||
|
||||
it { should have_content(@merge_request.title[0..10]) }
|
||||
it "Show page should inform user that merge request closed" do
|
||||
page.should have_content "Reopen"
|
||||
page.should have_content "Closed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
53
vendor/assets/javascripts/jquery.highlight.js
vendored
Normal file
53
vendor/assets/javascripts/jquery.highlight.js
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
|
||||
highlight v3
|
||||
|
||||
Highlights arbitrary terms.
|
||||
|
||||
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
|
||||
|
||||
MIT license.
|
||||
|
||||
Johann Burkard
|
||||
<http://johannburkard.de>
|
||||
<mailto:jb@eaio.com>
|
||||
|
||||
*/
|
||||
|
||||
jQuery.fn.highlight = function(pat) {
|
||||
function innerHighlight(node, pat) {
|
||||
var skip = 0;
|
||||
if (node.nodeType == 3) {
|
||||
var pos = node.data.toUpperCase().indexOf(pat);
|
||||
if (pos >= 0) {
|
||||
var spannode = document.createElement('span');
|
||||
spannode.className = 'highlight_word';
|
||||
var middlebit = node.splitText(pos);
|
||||
var endbit = middlebit.splitText(pat.length);
|
||||
var middleclone = middlebit.cloneNode(true);
|
||||
spannode.appendChild(middleclone);
|
||||
middlebit.parentNode.replaceChild(spannode, middlebit);
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
|
||||
for (var i = 0; i < node.childNodes.length; ++i) {
|
||||
i += innerHighlight(node.childNodes[i], pat);
|
||||
}
|
||||
}
|
||||
return skip;
|
||||
}
|
||||
return this.each(function() {
|
||||
innerHighlight(this, pat.toUpperCase());
|
||||
});
|
||||
};
|
||||
|
||||
jQuery.fn.removeHighlight = function() {
|
||||
return this.find("span.highlight").each(function() {
|
||||
this.parentNode.firstChild.nodeName;
|
||||
with (this.parentNode) {
|
||||
replaceChild(this.firstChild, this);
|
||||
normalize();
|
||||
}
|
||||
}).end();
|
||||
};
|
Loading…
Add table
Reference in a new issue