diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index f886f3f566fb171bed9eabd9b210857502a0e49a..e89c869872f4fb3f3d57702f414a499e689409d6 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -193,7 +193,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
   end
 
   def revert
-    @repository.find_or_create_branch(@merge_request.reverse_branch_name, @merge_request.target_branch)
+    @repository.revert_merge(current_user, @merge_request.merge_commit_sha, @merge_request.reverse_branch_name)
 
     url_params = { merge_request: {
       source_branch: @merge_request.reverse_branch_name,
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 1463446bcc2706bf13fb41deb591fd0bd22dce3c..553f7bca1f67e467063b94e73031cc265749dca9 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -137,8 +137,8 @@ class Repository
     find_branch(branch_name)
   end
 
-  def find_or_create_branch(name, ref)
-    find_branch(name) or add_branch(name, ref)
+  def find_or_create_branch(user, name, ref)
+    find_branch(name) or add_branch(user, name, ref)
   end
 
   def add_tag(tag_name, ref, message = nil)
@@ -605,6 +605,7 @@ class Repository
   def merge(user, source_sha, target_branch, options = {})
     our_commit = rugged.branches[target_branch].target
     their_commit = rugged.lookup(source_sha)
+    merge_commit_sha = nil
 
     raise "Invalid merge target" if our_commit.nil?
     raise "Invalid merge source" if their_commit.nil?
@@ -619,8 +620,31 @@ class Repository
         update_ref: ref
       )
 
-      Rugged::Commit.create(rugged, actual_options)
+      merge_commit_sha = Rugged::Commit.create(rugged, actual_options)
     end
+
+    merge_commit_sha
+  end
+
+  def revert_merge(user, merge_commit_id, revert_branch_name)
+    find_or_create_branch(user, revert_branch_name, merge_commit_id)
+
+    new_index = rugged.revert_commit(merge_commit_id, merge_commit_id, mainline: 1)
+    committer = user_to_committer(user)
+
+    commit_with_hooks(user, revert_branch_name) do |ref|
+      options = {
+        message: 'Revert MR',
+        author: committer,
+        committer: committer,
+        tree: new_index.write_tree(rugged),
+        parents: [rugged.lookup(merge_commit_id)],
+        update_ref: ref
+      }
+
+      Rugged::Commit.create(rugged, options)
+    end
+
   end
 
   def merged_to_root_ref?(branch_name)
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index e8bef250d8b6c45764302ef5a7568b4ac548229f..9a58383b398a8580fcecf934433d5b9bc802af3b 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -34,7 +34,8 @@ module MergeRequests
         committer: committer
       }
 
-      repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options)
+      commit_id = repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options)
+      merge_request.update(merge_commit_sha: commit_id)
     rescue StandardError => e
       merge_request.update(merge_error: "Something went wrong during merge")
       Rails.logger.error(e.message)
diff --git a/db/migrate/20160129155512_add_merge_commit_sha_to_merge_requests.rb b/db/migrate/20160129155512_add_merge_commit_sha_to_merge_requests.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f0d942265148372a5712f337f0cf8ac34a575961
--- /dev/null
+++ b/db/migrate/20160129155512_add_merge_commit_sha_to_merge_requests.rb
@@ -0,0 +1,5 @@
+class AddMergeCommitShaToMergeRequests < ActiveRecord::Migration
+  def change
+    add_column :merge_requests, :merge_commit_sha, :string
+  end
+end
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 0c6a881f868aadb299609e231417a2973703b553..00de7bb529444a2428b8afa19e9bc30469c90859 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -24,6 +24,7 @@
 #  merge_params              :text
 #  merge_when_build_succeeds :boolean          default(FALSE), not null
 #  merge_user_id             :integer
+#  merge_commit_sha          :string
 #
 
 FactoryGirl.define do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index f35b48601ada4856029b9e186053f0ad2faabad5..c51f34034d70e9e0c4c4a3af355757d8000b1db2 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -24,6 +24,7 @@
 #  merge_params              :text
 #  merge_when_build_succeeds :boolean          default(FALSE), not null
 #  merge_user_id             :integer
+#  merge_commit_sha          :string
 #
 
 require 'spec_helper'