summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2012-05-17 19:11:45 +0300
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2012-05-17 19:11:45 +0300
commit9cd8f7b08296d73532c66f06581ff47dab9720a3 (patch)
tree1671523db0c0c2b806c750e31217ae3ee4c35cfa
parent2e54ac17c5815814f288a1a9a1b30ba79977699c (diff)
downloadgitlab-ce-9cd8f7b08296d73532c66f06581ff47dab9720a3.tar.gz
New Feature: Git Blame for file
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap.scss7
-rw-r--r--app/assets/stylesheets/tree.scss29
-rw-r--r--app/controllers/refs_controller.rb6
-rw-r--r--app/views/refs/_head.html.haml10
-rw-r--r--app/views/refs/_tree_file.html.haml8
-rw-r--r--app/views/refs/blame.html.haml46
-rw-r--r--app/views/refs/tree.html.haml11
-rw-r--r--config/routes.rb8
-rw-r--r--spec/requests/file_blame_spec.rb25
9 files changed, 135 insertions, 15 deletions
diff --git a/app/assets/stylesheets/gitlab_bootstrap.scss b/app/assets/stylesheets/gitlab_bootstrap.scss
index ea23c906973..b520c3bccf5 100644
--- a/app/assets/stylesheets/gitlab_bootstrap.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap.scss
@@ -268,6 +268,13 @@ img.avatar {
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
+
+ &.s16 {
+ width:16px;
+ }
+ &.s24 {
+ width:24px;
+ }
}
img.lil_av {
diff --git a/app/assets/stylesheets/tree.scss b/app/assets/stylesheets/tree.scss
index a5a7f8bc21e..d3146f6a476 100644
--- a/app/assets/stylesheets/tree.scss
+++ b/app/assets/stylesheets/tree.scss
@@ -53,6 +53,11 @@
padding: 9px 10px;
height:18px;
+ .options {
+ float:right;
+ margin-top: -5px;
+ }
+
.file_name {
color:$style_color;
font-size:14px;
@@ -220,3 +225,27 @@
margin:0;
}
}
+
+.blame_file {
+ .view_file_content {
+ tr {
+ border-bottom: 1px solid #eee;
+ }
+ td {
+ padding:5px;
+ }
+ .author,
+ .commit {
+ background:#f5f5f5;
+ vertical-align:top;
+ }
+ .lines {
+ pre {
+ padding:0;
+ margin:0;
+ background:none;
+ border:none;
+ }
+ }
+ }
+}
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index b8ab1bce219..e4e5b4edd42 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -8,7 +8,7 @@ class RefsController < ApplicationController
before_filter :require_non_empty_project
before_filter :ref
- before_filter :define_tree_vars, :only => [:tree, :blob]
+ before_filter :define_tree_vars, :only => [:tree, :blob, :blame]
before_filter :render_full_content
layout "project"
@@ -62,6 +62,10 @@ class RefsController < ApplicationController
return render_404
end
+ def blame
+ @blame = Grit::Blob.blame(@repo, @commit.id, params[:path])
+ end
+
protected
def define_tree_vars
diff --git a/app/views/refs/_head.html.haml b/app/views/refs/_head.html.haml
new file mode 100644
index 00000000000..d76a4aca026
--- /dev/null
+++ b/app/views/refs/_head.html.haml
@@ -0,0 +1,10 @@
+%ul.nav.nav-tabs
+ %li
+ = form_tag switch_project_refs_path(@project), :method => :get, :class => "project-refs-form", :remote => true do
+ = select_tag "ref", grouped_options_refs, :onchange => "$(this.form).trigger('submit');", :class => "project-refs-select"
+ = hidden_field_tag :destination, "tree"
+ = hidden_field_tag :path, params[:path]
+ %li{:class => "#{'active' if (controller.controller_name == "refs") }"}
+ = link_to tree_project_ref_path(@project, @ref) do
+ Code
+
diff --git a/app/views/refs/_tree_file.html.haml b/app/views/refs/_tree_file.html.haml
index c0a11e72113..768ff5a0446 100644
--- a/app/views/refs/_tree_file.html.haml
+++ b/app/views/refs/_tree_file.html.haml
@@ -1,13 +1,13 @@
-:css
.view_file
.view_file_header
%i.icon-file
%span.file_name
= name
%small #{file.mode}
- %span.right
- = link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path]), :class => "right", :target => "_blank"
- = link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref), :class => "right", :style => "margin-right:10px;"
+ %span.options
+ = link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small", :target => "_blank"
+ = link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref), :class => "btn very_small"
+ = link_to "blame", blame_file_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small"
- if file.text?
- if name =~ /\.(md|markdown)$/i
#tree-readme-holder
diff --git a/app/views/refs/blame.html.haml b/app/views/refs/blame.html.haml
new file mode 100644
index 00000000000..7307d557a30
--- /dev/null
+++ b/app/views/refs/blame.html.haml
@@ -0,0 +1,46 @@
+= render "head"
+
+#tree-holder
+ %ul.breadcrumb
+ %li
+ %span.arrow
+ = link_to tree_project_ref_path(@project, @ref, :path => nil) do
+ = @project.name
+ - @tree.breadcrumbs(6) do |link|
+ \/
+ %li= link
+ .clear
+
+ .view_file.blame_file
+ .view_file_header
+ %i.icon-file
+ %span.file_name
+ = @tree.name
+ %small blame
+ %span.options
+ = link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small", :target => "_blank"
+ = link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref), :class => "btn very_small"
+ = link_to "source", tree_file_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small"
+ .view_file_content
+ %table
+ - @blame.each do |commit, lines|
+ - commit = Commit.new(commit)
+ %tr
+ %td.author
+ = image_tag gravatar_icon(commit.author_email, 16)
+ = commit.author_name
+ %td.commit
+ &nbsp;
+ = link_to project_commit_path(@project, :id => commit.id) do
+ %code= commit.id.to_s[0..10]
+ %span.row_title= truncate(commit.safe_message, :length => 30) rescue "--broken encoding"
+ %td.lines
+ = preserve do
+ %pre
+ - lines.each do |line|
+ = line
+
+:javascript
+ $(function(){
+ $('.project-refs-select').chosen();
+ });
diff --git a/app/views/refs/tree.html.haml b/app/views/refs/tree.html.haml
index 165d7788fa5..7d19280b820 100644
--- a/app/views/refs/tree.html.haml
+++ b/app/views/refs/tree.html.haml
@@ -1,13 +1,4 @@
-%ul.nav.nav-tabs
- %li
- = form_tag switch_project_refs_path(@project), :method => :get, :class => "project-refs-form", :remote => true do
- = select_tag "ref", grouped_options_refs, :onchange => "$(this.form).trigger('submit');", :class => "project-refs-select"
- = hidden_field_tag :destination, "tree"
- = hidden_field_tag :path, params[:path]
- %li{:class => "#{'active' if (controller.controller_name == "refs") }"}
- = link_to tree_project_ref_path(@project, @ref) do
- Code
-
+= render "head"
#tree-holder= render :partial => "tree", :locals => {:repo => @repo, :commit => @commit, :tree => @tree}
:javascript
diff --git a/config/routes.rb b/config/routes.rb
index 1b8f6d3c077..e137ff717e1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -94,6 +94,14 @@ Gitlab::Application.routes.draw do
:id => /[a-zA-Z.0-9\/_\-]+/,
:path => /.*/
}
+
+ # blame
+ get "blame/:path" => "refs#blame",
+ :as => :blame_file,
+ :constraints => {
+ :id => /[a-zA-Z.0-9\/_\-]+/,
+ :path => /.*/
+ }
end
end
diff --git a/spec/requests/file_blame_spec.rb b/spec/requests/file_blame_spec.rb
new file mode 100644
index 00000000000..511f340c1c8
--- /dev/null
+++ b/spec/requests/file_blame_spec.rb
@@ -0,0 +1,25 @@
+require 'spec_helper'
+
+describe "Blame file" do
+ before { login_as :user }
+
+ describe "GET /:projectname/:commit/blob/Gemfile" do
+ before do
+ @project = Factory :project
+ @project.add_access(@user, :read)
+
+ visit tree_project_ref_path(@project, @project.root_ref, :path => "Gemfile")
+ click_link "blame"
+ end
+
+ it "should be correct path" do
+ current_path.should == blame_file_project_ref_path(@project, @project.root_ref, :path => "Gemfile")
+ end
+
+ it "should contain file view" do
+ page.should have_content("rubygems.org")
+ page.should have_content("Dmitriy Zaporozhets")
+ page.should have_content("bc3735004cb Moving to rails 3.2")
+ end
+ end
+end