diff --git a/app/assets/javascripts/pull_requests.js.coffee b/app/assets/javascripts/pull_requests.js.coffee
new file mode 100644
index 000000000..761567942
--- /dev/null
+++ b/app/assets/javascripts/pull_requests.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/app/assets/stylesheets/pull_requests.css.scss b/app/assets/stylesheets/pull_requests.css.scss
new file mode 100644
index 000000000..f69ac413b
--- /dev/null
+++ b/app/assets/stylesheets/pull_requests.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the pull_requests controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb
new file mode 100644
index 000000000..7db6e592e
--- /dev/null
+++ b/app/controllers/pull_requests_controller.rb
@@ -0,0 +1,135 @@
+
+class PullRequestsController < ApplicationController
+ before_filter :find_project_and_repository
+ before_filter :connect_gitlab, :only => [:index, :show, :create, :accept_pull_request, :pull_request_commits, :pull_request_changes, :new]
+ layout "base_projects"
+ include PullRequestsHelper
+ include ApplicationHelper
+
+ # 返回json格式
+ def index
+ type = params[:type]
+ case type
+ when nil, "1"
+ @requests = @g.merge_requests(@project.gpid).select{|request| request.state == "opened" || request.state == "reopened"}
+ when "2"
+ @requests = @g.merge_requests(@project.gpid).select{|request| request.state == "merged"}
+ end
+ @requests_opened_count = @requests.count
+ @requests_merged_count = params[:type] ? @requests.count : @g.merge_requests(@project.gpid).select{|request| request.state == "merged"}.count
+ respond_to do |format|
+ format.html
+ format.js
+ end
+ end
+
+ # 主要取源项目和目标项目分支及标识(用户名/版本库名)
+ def new
+ identifier = get_rep_identifier_by_project @project
+ @source_project_name = "#{get_user_name(@project.user_id)}/#{identifier}"
+ @source_rev = @g.branches(@project.gpid).map{|b| b.name}
+
+ # 获取forked源项目信息
+ if @project.forked_from_project_id
+ @forked_project = Project.find(@project.forked_from_project_id)
+ identifier = get_rep_identifier_by_project @forked_project
+ @forked_project_name = "#{get_user_name(@forked_project.user_id)}/#{identifier}"
+ @forked_rev = @g.branches(@forked_project.gpid).map{|b| b.name}
+ end
+ end
+
+ # Creates a merge request.
+ # If the operation is successful, 200 and the newly created merge request is returned. If an error occurs, an error number and a message explaining the reason is returned.
+ #
+ # @example
+ # Gitlab.create_merge_request(5, 'New merge request',
+ # :source_branch => 'source_branch', :target_branch => 'target_branch')
+ # Gitlab.create_merge_request(5, 'New merge request',
+ # :source_branch => 'source_branch', :target_branch => 'target_branch', :assignee_id => 42)
+ #
+ # @param [Integer] project The ID of a project.
+ # @param [String] title The title of a merge request.
+ # @param [Hash] options A customizable set of options.
+ # @option options [String] :source_branch (required) The source branch name.
+ # @option options [String] :target_branch (required) The target branch name.
+ # @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request.
+ # @return [Gitlab::ObjectifiedHash] Information about created merge request.
+ def create
+ title = params[:title]
+ description = params[:description]
+ source_branch = params[:source_branch]
+ target_branch = params[:target_branch]
+ begin
+ # 如果传送了目标项目ID,则PR请求发至目标项目
+ if params[:forked_project_id] && params[:source_project] == "forked_project_name"
+ target_project_id = params[:forked_project_id].to_i
+ request = @g.create_merge_request(@project.gpid, title, User.current.gid, :description => description, :source_branch => source_branch, :target_branch => target_branch, :target_project_id => target_project_id)
+ @fork_project_name = Project.find(@project.forked_from_project_id).try(:name)
+ @fork_pr_message = true if @fork_project_name
+ else
+ request = @g.create_merge_request(@project.gpid, title, User.current.gid, :description => description, :source_branch => source_branch, :target_branch => target_branch)
+ respond_to do |format|
+ format.js{redirect_to project_pull_request_path(request.id, :project_id => @project.id)}
+ end
+ end
+ rescue Exception => e
+ @message = e.message
+ end
+ end
+
+ def show
+ @type = params[:type]
+ @request = @g.merge_request(@project.gpid, params[:id])
+ @commits = @g.merge_request_commits(@project.gpid, params[:id].to_i)
+ @commits_count = @commits.count
+ @changes = @g.merge_request_changes(@project.gpid, params[:id]).try(:changes)
+ @changes_count = @changes.count
+ end
+
+ # Accept a merge request.
+ # If merge success you get 200 OK.
+ # Accept a merge request.
+ #
+ # @example
+ # Gitlab.accept_pull_rquest(5, 1)
+ #
+ # @param [Integer] project The ID of a project.
+ # @param [Integer] id The ID of a merge request.
+ # @return [Gitlab::ObjectifiedHash]
+ def accept_pull_request
+ begin
+ status = @g.accept_merge_rquest(@project.gpid, params[:id])
+ respond_to do |format|
+ format.js{redirect_to project_pull_request_path(status.id, :project_id => @project.id)}
+ end
+ rescue Exception => e
+ @message = e.message
+ end
+ end
+
+ # 获取某次请求的提交次数
+ def pull_request_commits
+ @type = parms[:type]
+ @commits = @g.merge_request_commits(@project.gpid, params[:id].to_i)
+ end
+
+ # 获取某次请求的改动
+ def pull_request_changes
+ @changes = @g.merge_request_changes(@project.gpid, params[:id]).try(:changes)
+ @changes_count = @changes.count
+ end
+
+ private
+ def connect_gitlab
+ @g = Gitlab.client
+ end
+
+ def find_project_and_repository
+ @project = Project.find(params[:project_id])
+ render_404 if @project.gpid.blank?
+ @repository = Repository.where(:project_id => @project.id, :type => "Repository::Gitlab")
+ rescue ActiveRecord::RecordNotFound
+ render_404
+ end
+
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index d64d95223..69da2657b 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -43,6 +43,12 @@ module ApplicationHelper
user.nil? ? User.find(2) : user
end
+ # 通过系统外部用户名查找用户,如果用户不存在则用邮箱替换
+ def get_user_by_login_and login
+ user = User.find_by_login(login)
+ user.nil? ? User.find(2) : user
+ end
+
# 历史数据(老版本库数据)处理完则可以修改该放放
def get_rep_identifier_by_project project
identifier = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first.try(:identifier)
@@ -814,6 +820,18 @@ module ApplicationHelper
return @result
end
+ # 必须是项目成,项目必须提交过代码
+ def allow_pull_request project
+ return false if project.gpid.nil?
+ g = Gitlab.client
+ count = g.user_static(project.gpid, :rev => "master").count
+ if User.current.member_of?(project) && count > 0
+ true
+ else
+ false
+ end
+ end
+
# 判断版本库是否初始为gitlab
def rep_is_gitlab?(project)
rep = project.repositories.where("type =?", "Repository::Gitlab")
diff --git a/app/helpers/pull_requests_helper.rb b/app/helpers/pull_requests_helper.rb
new file mode 100644
index 000000000..82d4edc0f
--- /dev/null
+++ b/app/helpers/pull_requests_helper.rb
@@ -0,0 +1,17 @@
+module PullRequestsHelper
+
+ # 获取diff内容行号
+ def diff_line_num content
+ content.scan(/@@ -(\d+),\d+ \+\d+,\d+ @@/).first.nil? ? "" : content.scan(/@@ -(\d+),\d+ \+\d+,\d+ @@/).first.join("").to_i
+ end
+
+ # 处理内容
+ def diff_content content
+ content.gsub!(/.*@@ -\d+,\d+ \+\d+,\d+ @@\n/m,'')
+ end
+
+ def get_user_name user_id
+ User.find(user_id).try(:login)
+ end
+
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index 86f670f33..0751c902f 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1236,8 +1236,7 @@ class Project < ActiveRecord::Base
# 创建项目后在项目下同步创建一个讨论区
def create_board_sync
@board = self.boards.build
- self.name=" #{l(:label_borad_project) }"
- @board.name = self.name
+ @board.name = " #{l(:label_borad_project) }"
@board.description = self.name.to_s
if @board.save
logger.debug "[Project Model] ===> #{@board.to_json}"
diff --git a/app/views/projects/_development_group.html.erb b/app/views/projects/_development_group.html.erb
index 2c7d36fb5..273fcf56a 100644
--- a/app/views/projects/_development_group.html.erb
+++ b/app/views/projects/_development_group.html.erb
@@ -39,6 +39,14 @@
<% end %>
<% end %>
+
+<% if allow_pull_request(@project) %>
+
+ <%= link_to "Pull Requests", project_pull_requests_path(@project), :class => "f14 c_blue02" %>
+ <%= link_to "+新建请求", new_project_pull_request_path(:project_id => @project.id), :class => "subnav_green" %>
+
+<% end %>
+
<%# --版本库被设置成私有、module中设置不显示、没有创建版本库 三种情况不显示-- %>
<% if visible_repository?(@project) %>
<%= render 'projects/tools_expand' %>
diff --git a/app/views/pull_requests/_error_message.html.erb b/app/views/pull_requests/_error_message.html.erb
new file mode 100644
index 000000000..9d0dd5a21
--- /dev/null
+++ b/app/views/pull_requests/_error_message.html.erb
@@ -0,0 +1,7 @@
+<% if @message %>
+ <%= @message %>
+<% end %>
+
+<% if @fork_pr_message %>
+ 您的Pull Request请求已成功发送至源项目:<%= @fork_project_name %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/pull_requests/_form.html.erb b/app/views/pull_requests/_form.html.erb
new file mode 100644
index 000000000..52e3ed20a
--- /dev/null
+++ b/app/views/pull_requests/_form.html.erb
@@ -0,0 +1,67 @@
+<%= form_tag(url_for(:controller => 'pull_requests', :action => 'create', :project_id => @project.id, :forked_project_id => @forked_project.try(:gpid)), :id => 'pull_request_form', :method => "post", :remote => true) do %>
+
+
* 标题
+
标题不能为空
+
+
描述
+
+
+
+
+
源分支
+ <%= select_tag :branch, options_for_select(@source_rev), :name => "source_branch", :value => "source_branch", :class => "ml30 fontGrey3 fb fl", :style => "padding:5px 0 5px 5px;" %>
+
+
目标分支
+ <% if @forked_project.nil? %>
+ <%= select_tag :branch, options_for_select(@source_rev), :name => "target_branch", :value => "target_branch",:class => "ml30 fontGrey3 fb fl", :style => "padding:5px 0 5px 5px;", :id => "targetBranch" %>
+ <% else %>
+
+ <%= @source_project_name %>
+ <%= @forked_project_name %>
+
+
+ <% @source_rev.each do |rev| %>
+ <%= rev %>
+ <% end %>
+
+ <% end %>
+
+
+
+
提交请求
+ <%= link_to "返回", project_pull_requests_path(:project_id => @project.id), :class => "fr linkGrey2 mt5 mr10" %>
+
+
+<% end %>
+
+
\ No newline at end of file
diff --git a/app/views/pull_requests/_new.html.erb b/app/views/pull_requests/_new.html.erb
new file mode 100644
index 000000000..54c7434b0
--- /dev/null
+++ b/app/views/pull_requests/_new.html.erb
@@ -0,0 +1,30 @@
+
+
+
\ No newline at end of file
diff --git a/app/views/pull_requests/_pull_request_changes.html.erb b/app/views/pull_requests/_pull_request_changes.html.erb
new file mode 100644
index 000000000..f8c423504
--- /dev/null
+++ b/app/views/pull_requests/_pull_request_changes.html.erb
@@ -0,0 +1,33 @@
+<% unless @changes.blank? %>
+ <% @changes.each do |cd| %>
+
+
+ <% end %>
+<% end %>
+
diff --git a/app/views/pull_requests/_pull_request_commits.html.erb b/app/views/pull_requests/_pull_request_commits.html.erb
new file mode 100644
index 000000000..a7f6b5aa7
--- /dev/null
+++ b/app/views/pull_requests/_pull_request_commits.html.erb
@@ -0,0 +1,19 @@
+<% @commits.each do |commit| %>
+
+
+
<%= format_date(commit.created_at) %>
+
+
<%= link_to commit.author_name, user_path(get_user_by_mail(commit.author_email)), :class => "link-blue" %>创建于<%= time_tag(commit.created_at) %>前
+
+
+ <%= commit.title %>
+
+
+
+
+ <%= link_to truncate(commit.short_id, :length => 20), {:controller => 'repositories', :action => 'commit_diff', :id => @project.id, :changeset => commit.id}, :target => "_blank" %>
+
+
+
+
+<% end %>
diff --git a/app/views/pull_requests/_pull_request_container.html.erb b/app/views/pull_requests/_pull_request_container.html.erb
new file mode 100644
index 000000000..451be228f
--- /dev/null
+++ b/app/views/pull_requests/_pull_request_container.html.erb
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/app/views/pull_requests/_pull_requests_list.html.erb b/app/views/pull_requests/_pull_requests_list.html.erb
new file mode 100644
index 000000000..db9059710
--- /dev/null
+++ b/app/views/pull_requests/_pull_requests_list.html.erb
@@ -0,0 +1,15 @@
+<% if @requests.blank? %>
+ 没有可显示的请求
+<% else %>
+ <% @requests.each do |request| %>
+
+ <% request %>
+ <%=link_to request.title, project_pull_request_path(request.id, :project_id => @project.id), :class => "linkGrey3 fb fl"%>
+
+
+ 由 <%= link_to request.author.try(:username), user_path(get_user_by_login_and(request.author.try(:username))), :class => "link-blue" %> 创建于<%= time_tag(request.created_at) %>
+ <%= time_tag(request.updated_at) %>更新
+
+
+ <% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/pull_requests/_show.html.erb b/app/views/pull_requests/_show.html.erb
new file mode 100644
index 000000000..b3d6dd314
--- /dev/null
+++ b/app/views/pull_requests/_show.html.erb
@@ -0,0 +1,60 @@
+
+ <%= render :partial => "pull_requests/error_message" %>
+
+
+
+
+
<%= @request.state == "merged" ? "已合并" : "待处理" %> 合并请求 由<%= link_to @request.author.try(:username), user_path(get_user_by_login_and(@request.author.try(:username))), :class => "link-blue" %>于<%= time_tag(@request.created_at) %>提交 · 最后编辑时间<%= time_tag(@request.updated_at) %>
+
+
+
+
<%= @request.title %> <%= @request.description %>
+
+ 请求将
<%= @request.source_branch %> 合并至
<%= @request.target_branch %>
+
+<% if @commits_count == 0 && @changes_count == 0 %>
+
<%= @request.source_branch %>没有新内容可以合并至<%= @request.target_branch %>
+
请将新改动提交至源分支或者切换到其它目标分支
+<% else %>
+ <% if @request.state == "merged" %>
+
Hjqreturn 于两小时前合并
+
改动已合并至<%= @request.target_branch %>
+ <% else %>
+ <%= link_to "接受请求", accept_pull_request_project_pull_request_path(@request.id, :project_id => @project.id), :class => "BlueCirBtn", :remote => true %>
+ <% end %>
+
+
+
+ <%= link_to "提交#{@commits_count} ".html_safe, pull_request_commits_project_pull_request_path(@request.id, :project_id => @project.id, :type => 1), :remote => true, :class => "active" %>
+ <%= link_to "改动#{@changes_count} ".html_safe, pull_request_changes_project_pull_request_path(@request.id, :project_id => @project.id, :type => 2), :remote => true %>
+
+
根据最近提交时间排列
+
+ <%= render :partial => "pull_requests/pull_request_commits" %>
+
+
+ <%= render :partial => "pull_requests/pull_request_changes" %>
+
+ <% end %>
+
+
+
+
\ No newline at end of file
diff --git a/app/views/pull_requests/accept_pull_request.js.erb b/app/views/pull_requests/accept_pull_request.js.erb
new file mode 100644
index 000000000..b9007d7a3
--- /dev/null
+++ b/app/views/pull_requests/accept_pull_request.js.erb
@@ -0,0 +1,2 @@
+$("#create_pull_request_error").html('<%= escape_javascript(render :partial => "pull_requests/error_message") %>');
+
diff --git a/app/views/pull_requests/create.html.erb b/app/views/pull_requests/create.html.erb
new file mode 100644
index 000000000..034f30163
--- /dev/null
+++ b/app/views/pull_requests/create.html.erb
@@ -0,0 +1,3 @@
+<%= render :partial => "pull_requests/pull_request_container" %>
+<%= render :partial => "pull_requests/new" %>
+
diff --git a/app/views/pull_requests/create.js.erb b/app/views/pull_requests/create.js.erb
new file mode 100644
index 000000000..ce5f50ac0
--- /dev/null
+++ b/app/views/pull_requests/create.js.erb
@@ -0,0 +1 @@
+$("#create_pull_request_error").html('<%= escape_javascript(render :partial => "pull_requests/error_message") %>');
diff --git a/app/views/pull_requests/index.html.erb b/app/views/pull_requests/index.html.erb
new file mode 100644
index 000000000..f9f7fe4db
--- /dev/null
+++ b/app/views/pull_requests/index.html.erb
@@ -0,0 +1,22 @@
+<%= render :partial => "pull_requests/pull_request_container" %>
+
+ <%= link_to "待处理#{@requests_opened_count} ".html_safe, project_pull_requests_path(:type => "1"), :remote => true %>
+ <%= link_to "已处理#{@requests_merged_count} ".html_safe, project_pull_requests_path(:type => "2"), :remote => true %>
+
+ <%= link_to "创建Pull Request", new_project_pull_request_path, :class => "BlueCirBtn fr ml10 mt10", :style => "width:110px;" %>
+
+
+
+
+
+ <%= render "pull_requests/pull_requests_list" %>
+
+
+
\ No newline at end of file
diff --git a/app/views/pull_requests/index.js.erb b/app/views/pull_requests/index.js.erb
new file mode 100644
index 000000000..bcf218cb3
--- /dev/null
+++ b/app/views/pull_requests/index.js.erb
@@ -0,0 +1 @@
+$("#pull_requests_list").html('<%= escape_javascript( render :partial => "pull_requests/pull_requests_list", :locals => {:type => @type} ) %>');
\ No newline at end of file
diff --git a/app/views/pull_requests/new.html.erb b/app/views/pull_requests/new.html.erb
new file mode 100644
index 000000000..e7494708c
--- /dev/null
+++ b/app/views/pull_requests/new.html.erb
@@ -0,0 +1,3 @@
+<%= render :partial => "pull_requests/pull_request_container" %>
+<%= render :partial => "pull_requests/new" %>
+
diff --git a/app/views/pull_requests/pull_request_changes.js.erb b/app/views/pull_requests/pull_request_changes.js.erb
new file mode 100644
index 000000000..2b3d77537
--- /dev/null
+++ b/app/views/pull_requests/pull_request_changes.js.erb
@@ -0,0 +1 @@
+$("#merge_record_1").html('<%= escape_javascript( render :partial => "pull_requests/pull_request_changes", :locals => {:type => @type} ) %>');
\ No newline at end of file
diff --git a/app/views/pull_requests/pull_request_commits.js.erb b/app/views/pull_requests/pull_request_commits.js.erb
new file mode 100644
index 000000000..0833b1e8a
--- /dev/null
+++ b/app/views/pull_requests/pull_request_commits.js.erb
@@ -0,0 +1 @@
+$("#merge_record_0").html('<%= escape_javascript( render :partial => "pull_requests/pull_request_commits", :locals => {:type => @type} ) %>');
\ No newline at end of file
diff --git a/app/views/pull_requests/show.html.erb b/app/views/pull_requests/show.html.erb
new file mode 100644
index 000000000..cf344d32c
--- /dev/null
+++ b/app/views/pull_requests/show.html.erb
@@ -0,0 +1,2 @@
+<%= render :partial => "pull_requests/pull_request_container" %>
+<%= render :partial => "pull_requests/show" %>
diff --git a/app/views/pull_requests/show.js.erb b/app/views/pull_requests/show.js.erb
new file mode 100644
index 000000000..0a64c51a8
--- /dev/null
+++ b/app/views/pull_requests/show.js.erb
@@ -0,0 +1,3 @@
+<%# 详情页面和新建页面都会跳入,所以用两种局部刷新 %>
+$("#pull_request_new_form").html('<%= escape_javascript(render :partial => "pull_requests/show") %>');
+$("#pull_request_show").html('<%= escape_javascript(render :partial => "pull_requests/show") %>');
\ No newline at end of file
diff --git a/app/views/repositories/_commit_details.html.erb b/app/views/repositories/_commit_details.html.erb
index ef8faecd7..1845da61b 100644
--- a/app/views/repositories/_commit_details.html.erb
+++ b/app/views/repositories/_commit_details.html.erb
@@ -1,7 +1,7 @@
<% if !user_commit_rep(changeset.author_email).nil? %>
- <%= image_tag(url_to_avatar(user_commit_rep(changeset.author_email)), :width => "20", :height => "20", :class => "fl portraitRadius mt2 ml4 mr5") %>
+ <%= image_tag(url_to_avatar(user_commit_rep(changeset.author_email)), :width => "20", :height => "20", :class => "fl portraitRadius mt2 ml4 mr5") %>
<%= link_to user_commit_rep(changeset.author_email), user_path(user_commit_rep(changeset.author_email)), :length => 30 %> 提交于
<%= time_tag(changeset.created_at) %>前
diff --git a/config/routes.rb b/config/routes.rb
index b7a743591..f68745fd8 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -805,6 +805,16 @@ RedmineApp::Application.routes.draw do
end
end
+ resources :pull_requests do
+ collection do
+ end
+ member do
+ get 'accept_pull_request'
+ get 'pull_request_commits'
+ get 'pull_request_changes'
+ end
+ end
+
resources :quality_analysis, :only => [:index, :create, :edit, :update, :delete] do
collection do
end
diff --git a/lib/gitlab-cli/lib/gitlab/client/merge_requests.rb b/lib/gitlab-cli/lib/gitlab/client/merge_requests.rb
index 1ccc25081..17b12cdaa 100644
--- a/lib/gitlab-cli/lib/gitlab/client/merge_requests.rb
+++ b/lib/gitlab-cli/lib/gitlab/client/merge_requests.rb
@@ -43,11 +43,11 @@ class Gitlab::Client
# @option options [String] :target_branch (required) The target branch name.
# @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request.
# @return [Gitlab::ObjectifiedHash] Information about created merge request.
- def create_merge_request(project, title, options={})
+ def create_merge_request(project, title, gid, options={})
check_attributes!(options, [:source_branch, :target_branch])
body = {:title => title}.merge(options)
- post("/projects/#{project}/merge_requests", :body => body)
+ post("/projects/#{project}/merge_requests?user_id=#{gid}", :body => body)
end
# Updates a merge request.
@@ -82,6 +82,22 @@ class Gitlab::Client
post("/projects/#{project}/merge_request/#{id}/comments", :body => {:note => note})
end
+ # Get a list of merge request commits.
+ # Parameters:
+ # id (required) - The ID of a project
+ # merge_request_id (required) - The ID of MR
+ def merge_request_commits(project, id)
+ get("/projects/#{project}/merge_request/#{id}/commits")
+ end
+
+ # Shows information about the merge request including its files and changes. With GitLab 8.2 the return fields upvotes and downvotes are deprecated and always return 0.
+ # Parameters:
+ # id (required) - The ID of a project
+ # merge_request_id (required) - The ID of MR
+ def merge_request_changes(project, id)
+ get("/projects/#{project}/merge_request/#{id}/changes")
+ end
+
# Gets the comments on a merge request.
#
# @example
@@ -94,6 +110,18 @@ class Gitlab::Client
get("/projects/#{project}/merge_request/#{id}/comments")
end
+ # Accept a merge request.
+ #
+ # @example
+ # Gitlab.accept_pull_rquest(5, 1)
+ #
+ # @param [Integer] project The ID of a project.
+ # @param [Integer] id The ID of a merge request.
+ # @return [Gitlab::ObjectifiedHash]
+ def accept_merge_rquest(project, id)
+ put("/projects/#{project}/merge_request/#{id}/merge")
+ end
+
private
def check_attributes!(options, attrs)
diff --git a/public/javascripts/project.js b/public/javascripts/project.js
index fa5648ffa..13ed76aa4 100644
--- a/public/javascripts/project.js
+++ b/public/javascripts/project.js
@@ -658,3 +658,23 @@ function search_tag_attachment(url,tag_name,q,course_id,sort)
}
}
+
+
+function choice_branch(name, branch, source_rev, forked_rev) {
+ switch (name) {
+ case "source_project_name" :
+ var branchOptions = source_rev;
+ break;
+ case "forked_project_name" :
+ var branchOptions = forked_rev;
+ break;
+ default:
+ var branchOptions = source_rev;
+ break;
+ }
+
+ branch.options.length = 0;
+ for (var i = 0; i < branchOptions.length; i++) {
+ branch.options[i] = new Option(branchOptions[i]);
+ }
+}
\ No newline at end of file
diff --git a/public/stylesheets/css/common.css b/public/stylesheets/css/common.css
index 7db3c4370..cfbf83394 100644
--- a/public/stylesheets/css/common.css
+++ b/public/stylesheets/css/common.css
@@ -94,9 +94,6 @@ h4{ font-size:14px;}/*color:#3b3b3b;*/
.flow_hidden{ width:300px;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
.white_space{white-space:nowrap;}
.pr {position:relative;}
-.fontGrey3 {color:#484848;}
-a.linkGrey6 {color:#484848 !important;}
-a.linkGrey6:hover {color:#ffffff !important;}
.markPopup {width:290px; height:auto; padding:5px 0px 15px 15px; background-color:#ffffff; z-index:1000;}
.markInput { outline:none; border:1px solid #e6e6e6; height:30px; width:50px; color:#3d3c3c; margin-bottom:10px; text-align:center; margin-right:5px; padding-left:0;}
.markPercentage {margin:10px 0; border:1px solid #e6e6e6; width:70px; height:30px; outline:none; font-size:12px; color:#3d3c3c;}
@@ -545,6 +542,10 @@ a:hover.BlueCirBtnMini{ background:#269ac9; color:#fff;}
.borderRadius {border-radius:5px;}
a.Blue-btn{ display:block; margin-right:15px;width:65px; height:22px; background-color:#ffffff; line-height:24px; vertical-align:middle; text-align:center; border:1px solid #3598db; color:#3598db; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;}
a:hover.Blue-btn{ background:#3598db; color:#fff;}
+a.BlueCirBtn{ display:block;width:75px; height:28px; background-color:#fff; line-height:28px; vertical-align:middle; text-align:center; border:1px solid #3598db; color:#3598db; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;}
+a:hover.BlueCirBtn{ background:#3598db; color:#fff;}
+a.BlueCirBtnMini{ display:block;width:40px; height:22px; background-color:#ffffff; line-height:24px; vertical-align:middle; text-align:center; border:1px solid #3598db; color:#3598db; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;}
+a:hover.BlueCirBtnMini{ background:#3598db; color:#fff;}
/*20160725 项目申请按钮*/
a.sy_btn_grey{
diff --git a/public/stylesheets/css/courses.css b/public/stylesheets/css/courses.css
index 7a1a0dabb..163f33338 100644
--- a/public/stylesheets/css/courses.css
+++ b/public/stylesheets/css/courses.css
@@ -8,14 +8,10 @@
.HomeWork {width:718px; background-color:#ffffff; padding:15px; border:1px solid #dddddd; float:right;}
.RightBanner {font-size:16px; width:733px; color:#4b4b4b; padding:10px 0 0 15px; margin-bottom:10px; background:#fff; border:1px solid #dddddd;height:34px;}
select.InputBox,input.InputBox,textarea.InputBox{ border:1px solid #d9d9d9; color:#888888; height:28px; line-height:28px; padding-left:5px; font-size:14px;}
-a.BlueCirBtn{ display:block;width:75px; height:28px; background-color:#fff; line-height:28px; vertical-align:middle; text-align:center; border:1px solid #3598db; color:#3598db; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;}
-a:hover.BlueCirBtn{ background:#3598db; color:#fff;}
/*a.AnnexBtn{ background: url(../images/homepage_icon.png) 0px -343px no-repeat; width:70px; height:20px; display:block; padding-left:20px; color:#888888;}*/
/*a:hover.AnnexBtn{background: url(../images/homepage_icon.png) -90px -343px no-repeat; color:#3598db;}*/
a.FilesBtn{ background: url(../images/homepage_icon.png) 0px -373px no-repeat; width:38px; height:20px; display:block; padding-left:20px; color:#888888;}
a:hover.FilesBtn{background: url(../images/homepage_icon.png) -89px -372px no-repeat; color:#3598db;}
-a.BlueCirBtnMini{ display:block;width:40px; height:22px; background-color:#ffffff; line-height:24px; vertical-align:middle; text-align:center; border:1px solid #3598db; color:#3598db; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;}
-a:hover.BlueCirBtnMini{ background:#3598db; color:#fff;}
a.ProBtn{background: url(../images/homepage_icon.png) -86px -396px no-repeat; width:30px; height:20px; display:block; padding-left:20px; color:#888888;}
a:hover.ProBtn{background: url(../images/homepage_icon.png) -86px -426px no-repeat; color:#3598db;}
diff --git a/public/stylesheets/css/project.css b/public/stylesheets/css/project.css
index 350141150..4c4019593 100644
--- a/public/stylesheets/css/project.css
+++ b/public/stylesheets/css/project.css
@@ -513,4 +513,31 @@ a:hover.upload_btn_grey{background:#8a8a8a;}
.analysis-result-loc {width:60px; text-align:right;}
.analysis-result-debt {width:160px; text-align:right;}
.analysis-result-time {width:150px; text-align:right;}
-.analysis-name-icon {background:url(/images/code-analysis-icon.png) -2px -148px no-repeat; width:16px; height:16px; display:inline-block; vertical-align:middle;}
\ No newline at end of file
+.analysis-name-icon {background:url(/images/code-analysis-icon.png) -2px -148px no-repeat; width:16px; height:16px; display:inline-block; vertical-align:middle;}
+
+
+/*20160801项目合并*/
+.project-merge-banner {margin:-10px -10px 0 -10px; padding:0 10px; border-bottom:1px solid #ddd;}
+.project-merge-banner li {float:left;}
+.project-merge-banner .active {border-bottom:2px solid #3b94d6;}
+.project-merge-banner li a {padding:14px; font-size:14px; color:#555; display:inline-block;}
+.project-number-dot {display:inline-block; min-width:10px; padding:3px 5px; font-size:12px; color:#888; line-height:1; vertical-align:middle; white-space:nowrap; text-align:center; background-color:#eee; border-radius:10px; margin-left:5px;}
+.project-merge-content {}
+.project-merge-content li {padding:10px; margin:0 -10px; background-color:#f9f9f9; border-bottom:1px solid #e5e5e5;}
+.no-merge-content {padding:10px 15px; color:#888;}
+.new-merge-request {border-bottom:1px solid #ddd; padding-bottom:10px;}
+.new-merge-wrap {font-size:13px; color:#484848; border-bottom:1px solid #ddd; padding:10px 0;}
+.new-merge-row {font-size:13px; color:#484848; border-bottom:1px solid #ddd; margin:0 -10px; padding:10px;}
+.merge-option-name {width:70px; text-align:right; }
+.merge-title-input {width:610px; height:16px; padding:8px 5px; border-radius:2px;}
+.merge-description-input {width:610px; height:90px; line-height:18px; padding:8px 5px;}
+.merge-record {font-size:13px; color:#484848; border-bottom:1px solid #ddd; margin:0 -10px; text-align:center;}
+.merge-record li {display:inline-block;}
+.merge-record li a {display:inline-block; padding:10px;}
+.merge-record .active {border-bottom:2px solid #3b94d6;}
+.merge-commit-time {width:200px; float:left;}
+.merge-commit-detail {width:380px; float:left;}
+.merge-commit-code {width:150px; float:left; text-align:right;}
+.merge-show {margin:-10px -10px 0 -10px; padding:10px; line-height:36px; border-bottom:1px solid #ddd;}
+.open-status {color:#fff; padding:0 16px; background-color:#3b94d6; border-radius:2px; display:inline-block;}
+.merge-commit-option {padding:12px; border:1px solid #ddd; background-color:#f9f9f9; border-radius:2px;}
\ No newline at end of file
diff --git a/public/stylesheets/css/public.css b/public/stylesheets/css/public.css
index cc27955d5..6712d5ef0 100644
--- a/public/stylesheets/css/public.css
+++ b/public/stylesheets/css/public.css
@@ -148,7 +148,6 @@ a.opnionButton:hover{background: #297fb8; }
.hiddent{ overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
-.break_word_firefox{white-space: pre-wrap;word-break: break-all;}
.font_bold{font-weight: bold;}
@@ -443,7 +442,7 @@ a.sortArrowActiveU {background:url(../images/post_image_list.png) -17px -20px no
.postDetailWrap {width:655px; float:left;}
.postDetailTitle {width:570px; max-width:570px; margin-bottom:5px;}
.postDetailDes {width:580px; max-width:580px; margin-bottom:6px; color:#888888;display:block;overflow:hidden;word-break:keep-all;text-overflow:ellipsis;}
-.postDetailDes p,div,em{word-break: break-all;word-wrap: break-word;}
+/*.postDetailDes p,div,em{word-break: break-all;word-wrap: break-word;}*/
.postDetailDes ol li{list-style-type: decimal;margin-left: 40px;}
.postDetailDes ul li{list-style-type: disc;margin-left: 40px;}
.postDetailDes td,.postDetailDes tr {border: 1px solid; border-color: inherit;}
diff --git a/spec/controllers/pull_requests_controller_spec.rb b/spec/controllers/pull_requests_controller_spec.rb
new file mode 100644
index 000000000..1e6838c53
--- /dev/null
+++ b/spec/controllers/pull_requests_controller_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe PullRequestsController, :type => :controller do
+
+end