diff --git a/app/assets/javascripts/lib/utils/sticky.js b/app/assets/javascripts/lib/utils/sticky.js
new file mode 100644
index 0000000000000000000000000000000000000000..f53acaa17b1c27e4f825f6c792d105e52aa7a4ed
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/sticky.js
@@ -0,0 +1,21 @@
+export const isSticky = (el, stickyTop) => {
+  const top = el.getBoundingClientRect().top;
+
+  if (top === stickyTop) {
+    el.classList.add('is-stuck');
+  } else {
+    el.classList.remove('is-stuck');
+  }
+};
+
+export default (el) => {
+  const computedStyle = window.getComputedStyle(el);
+
+  if (!/sticky/.test(computedStyle.position)) return;
+
+  const stickyTop = parseInt(computedStyle.top, 10);
+
+  document.addEventListener('scroll', () => isSticky(el, stickyTop), {
+    passive: true,
+  });
+};
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index d3faa2d8e515135ce1ddb3f08993f7ad7fb76fac..4ffd71d9de5d9c2957d3e5cb2aba20937d1f690a 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -7,6 +7,7 @@ import Cookies from 'js-cookie';
 import './breakpoints';
 import './flash';
 import BlobForkSuggestion from './blob/blob_fork_suggestion';
+import stickyMonitor from './lib/utils/sticky';
 
 /* eslint-disable max-len */
 // MergeRequestTabs
@@ -268,6 +269,8 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
 
           this.initChangesDropdown();
 
+          stickyMonitor(document.querySelector('.js-diff-files-changed'));
+
           if (typeof gl.diffNotesCompileComponents !== 'undefined') {
             gl.diffNotesCompileComponents();
           }
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index 972e6c7425f84b886977aa04e198ef68d2bb2890..7d765f45812bf8b62584c0faee7e0f0a5549ab3d 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -559,6 +559,47 @@
   }
 }
 
+.diff-files-changed {
+  .commit-stat-summary {
+    z-index: -1;
+  }
+
+  @media (min-width: $screen-sm-min) {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 100px;
+    background-color: $white-light;
+    z-index: 190;
+
+    + .files {
+      margin-top: 1px;
+    }
+
+    .diff-stats-additions-deletions-collapsed {
+      display: none;
+    }
+
+    &.is-stuck {
+      padding-top: 0;
+      padding-bottom: 0;
+      border-bottom: 1px solid $white-dark;
+
+      .diff-stats-additions-deletions-expanded,
+      .inline-parallel-buttons {
+        display: none;
+      }
+
+      .diff-stats-additions-deletions-collapsed {
+        display: block;
+      }
+
+      + .files {
+        margin-top: 16px;
+      }
+    }
+  }
+}
+
 .diff-file-changes {
   width: 450px;
   z-index: 150;
diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml
index 307311a090f898f98f8ef7e255329e450845d9a5..4f784f87f2b407af913eaf9348a46a17185b0fd8 100644
--- a/app/views/projects/diffs/_stats.html.haml
+++ b/app/views/projects/diffs/_stats.html.haml
@@ -1,12 +1,20 @@
+- sum_added_lines = diff_files.sum(&:added_lines)
+- sum_removed_lines = diff_files.sum(&:removed_lines)
 .commit-stat-summary.dropdown
   Showing
   %button.diff-stats-summary-toggler.js-diff-stats-dropdown{ type: "button", data: { toggle: "dropdown" } }<
     = pluralize(diff_files.size, "changed file")
     = icon("caret-down fw")
-  with
-  %strong.cgreen #{diff_files.sum(&:added_lines)} additions
-  and
-  %strong.cred #{diff_files.sum(&:removed_lines)} deletions
+  %span.diff-stats-additions-deletions-expanded
+    with
+    %strong.cgreen #{sum_added_lines} additions
+    and
+    %strong.cred #{sum_removed_lines} deletions
+  .diff-stats-additions-deletions-collapsed.pull-right{ "aria-hidden": "true" }
+    %strong.cgreen<
+      +#{sum_added_lines}
+    %strong.cred<
+      \-#{sum_removed_lines}
   .dropdown-menu.diff-file-changes
     = dropdown_filter("Search file")
     .dropdown-content