diff --git a/app/services/git_operation_service.rb b/app/services/git_operation_service.rb
index df9c393844d5bbb17601ad6b5ecd7deaa97bbad8..27bcc0476018b216c0a8b281f39015dc2dabe6c1 100644
--- a/app/services/git_operation_service.rb
+++ b/app/services/git_operation_service.rb
@@ -82,12 +82,7 @@ class GitOperationService
     end
 
     branch = repository.find_branch(branch_name)
-    oldrev = if branch
-               # This could verify we're not losing commits
-               repository.rugged.merge_base(newrev, branch.target)
-             else
-               Gitlab::Git::BLANK_SHA
-             end
+    oldrev = find_oldrev_from_branch(newrev, branch)
 
     ref = Gitlab::Git::BRANCH_REF_PREFIX + branch_name
     update_ref_in_hooks(ref, newrev, oldrev)
@@ -100,6 +95,18 @@ class GitOperationService
     newrev
   end
 
+  def find_oldrev_from_branch(newrev, branch)
+    return Gitlab::Git::BLANK_SHA unless branch
+
+    oldrev = branch.target
+
+    if oldrev == repository.rugged.merge_base(newrev, branch.target)
+      oldrev
+    else
+      raise Repository::CommitError.new('Branch diverged')
+    end
+  end
+
   def update_ref_in_hooks(ref, newrev, oldrev)
     with_hooks(ref, newrev, oldrev) do
       update_ref(ref, newrev, oldrev)