diff --git a/app/controllers/blob_controller.rb b/app/controllers/blob_controller.rb
index 530b72fee7f66d634024f23cf545156df689f558..3547dfe23235c28d82dcdf7991448cbf65dd01a8 100644
--- a/app/controllers/blob_controller.rb
+++ b/app/controllers/blob_controller.rb
@@ -8,15 +8,6 @@ class BlobController < ProjectResourceController
   before_filter :require_non_empty_project
 
   def show
-    if @tree.is_blob?
-      send_data(
-        @tree.data,
-        type: @tree.mime_type,
-        disposition: 'inline',
-        filename: @tree.name
-      )
-    else
-      not_found!
-    end
+    @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
   end
 end
diff --git a/app/controllers/raw_controller.rb b/app/controllers/raw_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..18b401fe6112416fbcb82860c0fe7da2df6b0517
--- /dev/null
+++ b/app/controllers/raw_controller.rb
@@ -0,0 +1,25 @@
+# Controller for viewing a file's raw
+class RawController < ProjectResourceController
+  include ExtractsPath
+
+  # Authorize
+  before_filter :authorize_read_project!
+  before_filter :authorize_code_access!
+  before_filter :require_non_empty_project
+
+  def show
+    @blob = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, @path)
+
+    if @blob.exists?
+      send_data(
+        @blob.data,
+        type: @blob.mime_type,
+        disposition: 'inline',
+        filename: @blob.name
+      )
+    else
+      not_found!
+    end
+  end
+end
+
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index f21783d00059e6d95305e6ec6de1ba8e93bf5877..e7002f60b8a9b54585b43a399f0a5b9baf365a49 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -18,7 +18,7 @@ module TreeHelper
                render partial: 'tree/submodule_item', object: f
              else
                # Object is a Blob
-               render partial: 'tree/tree_item', object: f, locals: {type: 'file'}
+               render partial: 'tree/blob_item', object: f, locals: {type: 'file'}
              end
 
       tree += html if html.present?
diff --git a/app/views/tree/_blob_actions.html.haml b/app/views/blob/_actions.html.haml
similarity index 80%
rename from app/views/tree/_blob_actions.html.haml
rename to app/views/blob/_actions.html.haml
index 1d55a4ff2ef792ee2d624cbb5266db824f658d99..c3655bfb907c1ce981eaaded1e645645101e2929 100644
--- a/app/views/tree/_blob_actions.html.haml
+++ b/app/views/blob/_actions.html.haml
@@ -1,10 +1,10 @@
 .btn-group.tree-btn-group
   -# only show edit link for text files
-  - if @tree.text?
+  - if @blob.text?
     = link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-tiny", disabled: !allowed_tree_edit?
-  = link_to "raw", project_blob_path(@project, @id), class: "btn btn-tiny", target: "_blank"
+  = link_to "raw", project_raw_path(@project, @id), class: "btn btn-tiny", target: "_blank"
   -# only show normal/blame view links for text files
-  - if @tree.text?
+  - if @blob.text?
     - if current_page? project_blame_path(@project, @id)
       = link_to "normal view", project_tree_path(@project, @id), class: "btn btn-tiny"
     - else
diff --git a/app/views/blob/_blob.html.haml b/app/views/blob/_blob.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..d055d4857871644046af7e151c6e8ad948058079
--- /dev/null
+++ b/app/views/blob/_blob.html.haml
@@ -0,0 +1,27 @@
+%ul.breadcrumb
+  %li
+    %i.icon-angle-right
+    = link_to project_tree_path(@project, @ref) do
+      = @project.path
+  - tree_breadcrumbs(@tree, 6) do |title, path|
+    \/
+    %li
+      - if path
+        = link_to truncate(title, length: 40), project_tree_path(@project, path)
+      - else
+        = link_to title, '#'
+
+%div#tree-content-holder.tree-content-holder
+  .file_holder
+    .file_title
+      %i.icon-file
+      %span.file_name
+        = blob.name
+        %small= number_to_human_size blob.size
+      %span.options= render "actions"
+    - if blob.text?
+      = render "text", blob: blob
+    - elsif blob.image?
+      = render "image", blob: blob
+    - else
+      = render "download", blob: blob
diff --git a/app/views/tree/blob/_download.html.haml b/app/views/blob/_download.html.haml
similarity index 100%
rename from app/views/tree/blob/_download.html.haml
rename to app/views/blob/_download.html.haml
diff --git a/app/views/tree/blob/_image.html.haml b/app/views/blob/_image.html.haml
similarity index 100%
rename from app/views/tree/blob/_image.html.haml
rename to app/views/blob/_image.html.haml
diff --git a/app/views/tree/blob/_text.html.haml b/app/views/blob/_text.html.haml
similarity index 100%
rename from app/views/tree/blob/_text.html.haml
rename to app/views/blob/_text.html.haml
diff --git a/app/views/blob/show.html.haml b/app/views/blob/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..d1ca0e05e83bc74ea14a083bf32e57391e781f37
--- /dev/null
+++ b/app/views/blob/show.html.haml
@@ -0,0 +1,4 @@
+%div.tree-ref-holder
+  = render 'shared/ref_switcher', destination: 'tree', path: @path
+%div#tree-holder.tree-holder
+  = render 'blob', blob: @blob
diff --git a/app/views/blob/show.js.haml b/app/views/blob/show.js.haml
new file mode 100644
index 0000000000000000000000000000000000000000..804107f42fa37ba9d16b5ca55bb38767a2c9965e
--- /dev/null
+++ b/app/views/blob/show.js.haml
@@ -0,0 +1,10 @@
+:plain
+  // Load Files list
+  $("#tree-holder").html("#{escape_javascript(render(partial: "blob", locals: {blob: @blob}))}");
+  $("#tree-content-holder").show("slide", { direction: "right" }, 400);
+  $('.project-refs-form #path').val("#{@path}");
+
+  //  Load last commit log for each file in tree
+  $('#tree-slider').waitForImages(function() {
+    ajaxGet('#{@logs_path}');
+  });
diff --git a/app/views/tree/_blob.html.haml b/app/views/tree/_blob.html.haml
deleted file mode 100644
index ebf1ee2c6783367aeda88ba2d8445bb2bf2a63ab..0000000000000000000000000000000000000000
--- a/app/views/tree/_blob.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-.file_holder
-  .file_title
-    %i.icon-file
-    %span.file_name
-      = blob.name
-      %small= number_to_human_size blob.size
-    %span.options= render "tree/blob_actions"
-  - if blob.text?
-    = render "tree/blob/text", blob: blob
-  - elsif blob.image?
-    = render "tree/blob/image", blob: blob
-  - else
-    = render "tree/blob/download", blob: blob
diff --git a/app/views/tree/_blob_item.html.haml b/app/views/tree/_blob_item.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..ec15b608f8589d2d53afe42429cfda27f97a1982
--- /dev/null
+++ b/app/views/tree/_blob_item.html.haml
@@ -0,0 +1,9 @@
+%tr{ class: "tree-item #{tree_hex_class(blob_item)}" }
+  %td.tree-item-file-name
+    = tree_icon(type)
+    %strong= link_to truncate(blob_item.name, length: 40), project_blob_path(@project, tree_join(@id || @commit.id, blob_item.name))
+  %td.tree_time_ago.cgray
+    %span.log_loading.hide
+      Loading commit data...
+      = image_tag "ajax_loader_tree.gif", width: 14
+  %td.tree_commit{ colspan: 2 }
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index 7b1479515f9146f72303edec23016b98d9d41220..24c005fc7fe85e9df37b9bafaedde8fe5886f159 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -39,9 +39,8 @@
 
 %div.tree_progress
 
-- unless tree.is_blob?
-  :javascript
-    // Load last commit log for each file in tree
-    $(window).load(function(){
-      ajaxGet('#{@logs_path}');
-    });
+:javascript
+  // Load last commit log for each file in tree
+  $(window).load(function(){
+    ajaxGet('#{@logs_path}');
+  });
diff --git a/config/routes.rb b/config/routes.rb
index 61a604b954f773ae85d8287e7dee54f51df14a9a..b62d3fe2b0cfbba6f42289402570e574f4b231f2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -170,6 +170,7 @@ Gitlab::Application.routes.draw do
     end
 
     resources :blob,    only: [:show], constraints: {id: /.+/}
+    resources :raw,    only: [:show], constraints: {id: /.+/}
     resources :tree,    only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
     resources :edit_tree,    only: [:show, :update], constraints: {id: /.+/}, path: 'edit'
     resources :commit,  only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
index 405cbddad905e17e81296f4d378c26ad858daf79..57b89912f2d9a6eb6a5d967e43a2dfd817f7add6 100644
--- a/lib/gitlab/git/blob.rb
+++ b/lib/gitlab/git/blob.rb
@@ -23,7 +23,19 @@ module Gitlab
       end
 
       def exists?
-        @raw_blob
+        raw_blob
+      end
+
+      def empty?
+        data.blank?
+      end
+
+      def mode
+        raw_blob.mode
+      end
+
+      def size
+        raw_blob.size
       end
     end
   end