diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index c67912b97a6c2717ff67b06b1621f3203d442010..e116bc358c9c749d7a83e580317b0c5af9b2bd4e 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -30,7 +30,7 @@ class RefsController < ProjectResourceController
   end
 
   def logs_tree
-    contents = @tree.contents
+    contents = @tree.entries
     @logs = contents.map do |content|
       file = params[:path] ? File.join(params[:path], content.name) : content.name
       last_commit = @repo.commits(@commit.id, file, 1).last
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 1cba947617996a971f44922732e8a67ca3889cd3..f21783d00059e6d95305e6ec6de1ba8e93bf5877 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -3,9 +3,9 @@ module TreeHelper
   # their corresponding partials
   #
   # contents - A Grit::Tree object for the current tree
-  def render_tree(contents)
+  def render_tree(tree)
     # Render Folders before Files/Submodules
-    folders, files = contents.partition { |v| v.kind_of?(Grit::Tree) }
+    folders, files = tree.trees, tree.blobs
 
     tree = ""
 
@@ -91,5 +91,4 @@ module TreeHelper
     file = File.join(tree.path, "..")
     tree_join(tree.ref, file)
   end
-
 end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 0bab88313c1b1a14d30c750dbb1b39aeb05951e2..105d9239cf6cf17f0f3399d1a553ff28f97b9d92 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -152,7 +152,7 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def commits
-    load_commits(st_commits) || []
+    load_commits(st_commits || [])
   end
 
   def probably_merged?
diff --git a/app/models/tree.rb b/app/models/tree.rb
index e726c596f7e928b8cd22ced87c4a7f7950a7e938..042050527c1df0979055cf3fa9804330005a1506 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -1,14 +1,10 @@
 class Tree
-  attr_accessor :path, :tree, :ref
+  attr_accessor :raw
 
   def initialize(repository, sha, ref = nil, path = nil)
     @raw = Gitlab::Git::Tree.new(repository, sha, ref, path)
   end
 
-  def invalid?
-    @raw.nil?
-  end
-
   def method_missing(m, *args, &block)
     @raw.send(m, *args, &block)
   end
diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml
index c95215036ae610fccc82d7662656960fa33a6352..26098173d05ce84d83a6cde991263f7fb62c1f6c 100644
--- a/app/views/commits/_diffs.html.haml
+++ b/app/views/commits/_diffs.html.haml
@@ -16,8 +16,8 @@
   - unless @suppress_diff
     - diffs.each_with_index do |diff, i|
       - next if diff.diff.empty?
-      - file = Tree.new(@repository, @commit.id, @ref, diff.new_path)
-      - file = Tree.new(@repository, @commit.parent_id, @ref, diff.old_path) unless file
+      - file = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, diff.new_path)
+      - file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) unless file.exists?
       - next unless file
       .file{id: "diff-#{i}"}
         .header
@@ -25,7 +25,7 @@
             %span= diff.old_path
 
             - if @commit.parent_ids.present?
-              = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
+              = link_to project_tree_path(@project, tree_join(@commit.parent_id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
                 View file @
                 %span.commit-short-id= @commit.short_id(6)
           - else
@@ -43,7 +43,7 @@
           - if file.text?
             = render "commits/text_file", diff: diff, index: i
           - elsif file.image?
-            - old_file = Tree.new(@repository, @commit.parent_id, @ref, diff.old_path) if @commit.parent_id
+            - old_file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) if @commit.parent_id
             = render "commits/image", diff: diff, old_file: old_file, file: file, index: i
           - else
             %p.nothing_here_message No preview for this file type
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index caab6e45bb41f8f87327b6a7bfcda7f59d0512cb..7b1479515f9146f72303edec23016b98d9d41220 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -32,7 +32,7 @@
           %td
           %td
 
-      = render_tree(tree.contents)
+      = render_tree(tree)
 
     - if tree.readme
       = render "tree/readme", readme: tree.readme
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index c3e2441ff2106281f2c91fe6c569736dcac4c712..009c5fcada92925687af4ae0cfbcfa3b94e492bf 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -104,7 +104,7 @@ module ExtractsPath
 
     @tree = Tree.new(@project.repository, @commit.id, @ref, @path)
 
-    raise InvalidPathError if @tree.invalid?
+    raise InvalidPathError unless @tree.exists?
   rescue RuntimeError, NoMethodError, InvalidPathError
     not_found!
   end
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
new file mode 100644
index 0000000000000000000000000000000000000000..405cbddad905e17e81296f4d378c26ad858daf79
--- /dev/null
+++ b/lib/gitlab/git/blob.rb
@@ -0,0 +1,30 @@
+module Gitlab
+  module Git
+    class Blob
+      include Linguist::BlobHelper
+
+      attr_accessor :raw_blob
+
+      delegate :name, to: :raw_blob
+
+      def initialize(repository, sha, ref, path)
+        @repository, @sha, @ref = repository, sha, ref
+
+        @commit = @repository.commit(sha)
+        @raw_blob = @repository.tree(@commit, path)
+      end
+
+      def data
+        if raw_blob
+          raw_blob.data
+        else
+          nil
+        end
+      end
+
+      def exists?
+        @raw_blob
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
index b81ce550f4ce2b4ce585cf2e07d477a59996669e..8bcf71ea217cdf9b68bfdda942000f8179d1ad0e 100644
--- a/lib/gitlab/git/tree.rb
+++ b/lib/gitlab/git/tree.rb
@@ -1,28 +1,36 @@
 module Gitlab
   module Git
     class Tree
-      include Linguist::BlobHelper
-
-      attr_accessor :repository, :sha, :path, :ref, :raw_tree
+      attr_accessor :repository, :sha, :path, :ref, :raw_tree, :id
 
       def initialize(repository, sha, ref = nil, path = nil)
-        @repository, @sha, @ref = repository, sha, ref
+        @repository, @sha, @ref, @path = repository, sha, ref, path
+
+        @path = nil if @path.blank?
 
         # Load tree from repository
-        @commit = @repository.commit(sha)
-        @raw_tree = @repository.tree(@commit, path)
+        @commit = @repository.commit(@sha)
+        @raw_tree = @repository.tree(@commit, @path)
+      end
+
+      def exists?
+        raw_tree
       end
 
       def empty?
         data.blank?
       end
 
-      def data
-        raw_tree.data
+      def trees
+        entries.select { |t| t.is_a?(Grit::Tree) }
+      end
+
+      def blobs
+        entries.select { |t| t.is_a?(Grit::Blob) }
       end
 
       def is_blob?
-        tree.is_a?(Grit::Blob)
+        raw_tree.is_a?(Grit::Blob)
       end
 
       def up_dir?
@@ -30,7 +38,13 @@ module Gitlab
       end
 
       def readme
-        @readme ||= contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
+        @readme ||= entries.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
+      end
+
+      protected
+
+      def entries
+        raw_tree.contents
       end
     end
   end