diff --git a/app/contexts/commit_load_context.rb b/app/contexts/commit_load_context.rb
index c8d77d9b5f349cfb2a9b809f97fa6224076cfd1b..a06523776cc68c6a4424eedfa2371b0a614c7b10 100644
--- a/app/contexts/commit_load_context.rb
+++ b/app/contexts/commit_load_context.rb
@@ -13,7 +13,6 @@ class CommitLoadContext < BaseContext
 
     if commit
       commit = Commit.new(commit)
-      commit = CommitDecorator.decorate(commit)
       line_notes = project.notes.for_commit_id(commit.id).inline
 
       result[:commit] = commit
diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb
index de51debfeb52bb4bd0af9fd03038d2e3983dcc0c..769b6e0b8611786458b18b4118f59d69dc8b6295 100644
--- a/app/mailers/emails/notes.rb
+++ b/app/mailers/emails/notes.rb
@@ -3,7 +3,6 @@ module Emails
     def note_commit_email(recipient_id, note_id)
       @note = Note.find(note_id)
       @commit = @note.noteable
-      @commit = CommitDecorator.decorate(@commit)
       @project = @note.project
       mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title))
     end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index ea5b451b28fa1a21558280de3fabae230af64515..96c8577f90e56b189c5c6b97dc1097ac3ada816b 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -10,10 +10,6 @@ class Commit
 
   attr_accessor :raw
 
-  def self.decorate(commits)
-    commits.map { |c| Commit.new(c) }
-  end
-
   def initialize(raw_commit)
     raise "Nil as raw commit passed" unless raw_commit
 
@@ -24,7 +20,54 @@ class Commit
     @raw.id
   end
 
+  # Returns a string describing the commit for use in a link title
+  #
+  # Example
+  #
+  #   "Commit: Alex Denisov - Project git clone panel"
+  def link_title
+    "Commit: #{author_name} - #{title}"
+  end
+
+  # Returns the commits title.
+  #
+  # Usually, the commit title is the first line of the commit message.
+  # In case this first line is longer than 80 characters, it is cut off
+  # after 70 characters and ellipses (`&hellp;`) are appended.
+  def title
+    title = safe_message
+
+    return no_commit_message if title.blank?
+
+    title_end = title.index(/\n/)
+    if (!title_end && title.length > 80) || (title_end && title_end > 80)
+      title[0..69] << "&hellip;".html_safe
+    else
+      title.split(/\n/, 2).first
+    end
+  end
+
+  # Returns the commits description
+  #
+  # cut off, ellipses (`&hellp;`) are prepended to the commit message.
+  def description
+    description = safe_message
+
+    title_end = description.index(/\n/)
+    if (!title_end && description.length > 80) || (title_end && title_end > 80)
+      "&hellip;".html_safe << description[70..-1]
+    else
+      description.split(/\n/, 2)[1].try(:chomp)
+    end
+  end
+
   def method_missing(m, *args, &block)
     @raw.send(m, *args, &block)
   end
+
+  def respond_to?(method)
+    return true if @raw.respond_to?(method)
+
+    super
+  end
 end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 505f6637d770c8aaaf57fbfcf01e2716bc8e1537..8d3780532f39f59da3cb751d641981c59fb89973 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -152,7 +152,17 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def commits
-    st_commits || []
+    if st_commits.present?
+      # check if merge request commits are valid
+      if st_commits.first.respond_to?(:short_id)
+        st_commits
+      else
+        # if commits are invalid - simply reload it from repo
+        reloaded_commits
+      end
+    else
+      []
+    end
   end
 
   def probably_merged?
@@ -171,7 +181,6 @@ class MergeRequest < ActiveRecord::Base
   def unmerged_commits
     self.project.repository.
       commits_between(self.target_branch, self.source_branch).
-      map {|c| Commit.new(c)}.
       sort_by(&:created_at).
       reverse
   end
diff --git a/app/models/project.rb b/app/models/project.rb
index 54abbc3ecb119b5e7428d95b35928a4fa7aa48d1..934dd6b241b0905ada32181aa7268eb89054ac2f 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -142,7 +142,7 @@ class Project < ActiveRecord::Base
 
   def repository
     if path
-      @repository ||= Gitlab::Git::Repository.new(path_with_namespace, default_branch)
+      @repository ||= Repository.new(path_with_namespace, default_branch)
     else
       nil
     end
diff --git a/app/models/tree.rb b/app/models/tree.rb
index 96395a42394a75b77d08621ac6c046ddb26d99cb..4b6c5b133e9c3574018cc2934353792638d877ec 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -26,4 +26,12 @@ class Tree
   def empty?
     data.blank?
   end
+
+  def up_dir?
+    path.present?
+  end
+
+  def readme
+    @readme ||= contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
+  end
 end
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 4ad485c5e520c7b8a09274d0641e231400507ce3..d4871a49e9fc6477c9cf9e0b6e2266a286d1f452 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -101,10 +101,8 @@ module ExtractsPath
     # It is used "@project.repository.commits(@ref, @path, 1, 0)",
     # because "@project.repository.commit(@ref)" returns wrong commit when @ref is tag name.
     @commit = @project.repository.commits(@ref, @path, 1, 0).first
-    @commit = CommitDecorator.decorate(@commit)
 
     @tree = Tree.new(@commit.tree, @ref, @path)
-    @tree = TreeDecorator.new(@tree)
 
     raise InvalidPathError if @tree.invalid?
   rescue RuntimeError, NoMethodError, InvalidPathError