diff --git a/CHANGELOG b/CHANGELOG
index d841b1496157b2884de4966c4aca08f670baf2e2..b0972ceab685d9798182acea95d346a5a9acd2ae 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -156,6 +156,8 @@ v 8.2.0
   - Allow to define cache in `.gitlab-ci.yml`
   - Fix: 500 error returned if destroy request without HTTP referer (Kazuki Shimizu)
   - Remove deprecated CI events from project settings page
+  - Use issue editor as cross reference comment author when issue is edited with a new mention.
+  - Add graphs of commits ahead and behind default branch (Jeff Stubler)
   - Improve personal snippet access workflow (Douglas Alexandre)
   - [API] Add ability to fetch the commit ID of the last commit that actually touched a file
   - Fix omniauth documentation setting for omnibus configuration (Jon Cairns)
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index c9dfcff62905997f8603e9ed49938503f77dbe62..879bd287470041aec774186a4f1d3f2025449e74 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -122,3 +122,59 @@ li.commit {
     color: $gl-gray;
   }
 }
+
+.divergence-graph {
+  padding: 12px 12px 0 0;
+  float: right;
+  
+  .graph-side {
+    position: relative;
+    width: 80px;
+    height: 22px;
+    padding: 5px 0 13px;
+    float: left;
+    
+    .bar {
+      position: absolute;
+      height: 4px;
+      background-color: #ccc;
+    }
+
+    .bar-behind {
+      right: 0;
+      border-radius: 3px 0 0 3px;
+    }
+
+    .bar-ahead {
+      left: 0;
+      border-radius: 0 3px 3px 0;
+    }
+    
+    .count {
+      padding-top: 6px;
+      padding-bottom: 0px;
+      font-size: 12px;
+      color: #333;
+      display: block;
+    }
+
+    .count-behind {
+      padding-right: 4px;
+      text-align: right;
+    }
+
+    .count-ahead {
+      padding-left: 4px;
+      text-align: left;
+    }
+  }
+
+  .graph-separator {
+    position: relative;
+    width: 1px;
+    height: 18px;
+    margin: 5px 0 0;
+    float: left;
+    background-color: #ccc;
+  }
+}
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 3c2849a760106202a63ac49a3a106fdf88c712c3..4db3b3bf23db19e3cec742473fd5b3531a28e431 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -9,6 +9,11 @@ class Projects::BranchesController < Projects::ApplicationController
     @sort = params[:sort] || 'name'
     @branches = @repository.branches_sorted_by(@sort)
     @branches = Kaminari.paginate_array(@branches).page(params[:page]).per(PER_PAGE)
+    
+    @max_commits = @branches.reduce(0) do |memo, branch|
+      diverging_commit_counts = repository.diverging_commit_counts(branch)
+      [memo, diverging_commit_counts[:behind], diverging_commit_counts[:ahead]].max
+    end
   end
 
   def recent
diff --git a/app/models/project.rb b/app/models/project.rb
index eadc42d1da5cb393607864e04e2c5de5ee2add13..b1a6cfa86af6e9e9dd878d682f265d597260ea28 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -775,6 +775,8 @@ class Project < ActiveRecord::Base
   end
 
   def change_head(branch)
+    # Cached divergent commit counts are based on repository head
+    repository.expire_branch_cache
     gitlab_shell.update_repository_head(self.path_with_namespace, branch)
     reload_default_branch
   end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index a9bf4eb4033251fcd67261f5ebaaeca7e1e45a58..6ecd2d2f27eb5039e939bd72cd8144a1bcaf2eb9 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -175,11 +175,29 @@ class Repository
   def size
     cache.fetch(:size) { raw_repository.size }
   end
+  
+  def diverging_commit_counts(branch)
+    root_ref_hash = raw_repository.rev_parse_target(root_ref).oid
+    cache.fetch(:"diverging_commit_counts_#{branch.name}") do
+      # Rugged seems to throw a `ReferenceError` when given branch_names rather
+      # than SHA-1 hashes
+      number_commits_behind = commits_between(branch.target, root_ref_hash).size
+      number_commits_ahead = commits_between(root_ref_hash, branch.target).size
+      
+      { behind: number_commits_behind, ahead: number_commits_ahead }
+    end
+  end
 
   def cache_keys
     %i(size branch_names tag_names commit_count
        readme version contribution_guide changelog license)
   end
+  
+  def branch_cache_keys
+    branches.map do |branch|
+      :"diverging_commit_counts_#{branch.name}"
+    end
+  end
 
   def build_cache
     cache_keys.each do |key|
@@ -187,6 +205,12 @@ class Repository
         send(key)
       end
     end
+    
+    branches.each do |branch|
+      unless cache.exist?(:"diverging_commit_counts_#{branch.name}")
+        send(:diverging_commit_counts, branch)
+      end
+    end
   end
 
   def expire_tags_cache
@@ -203,6 +227,14 @@ class Repository
     cache_keys.each do |key|
       cache.expire(key)
     end
+    
+    expire_branch_cache
+  end
+  
+  def expire_branch_cache
+    branches.each do |branch|
+      cache.expire(:"diverging_commit_counts_#{branch.name}")
+    end
   end
 
   def rebuild_cache
@@ -210,6 +242,11 @@ class Repository
       cache.expire(key)
       send(key)
     end
+    
+    branches.each do |branch|
+      cache.expire(:"diverging_commit_counts_#{branch.name}")
+      diverging_commit_counts(branch)
+    end
   end
 
   def lookup_cache
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index 5081bae6801d0cdde8a0060374f328e8a2ab23dc..a234536723ee59f41803db5d3e060ebd325e813d 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -1,4 +1,8 @@
 - commit = @repository.commit(branch.target)
+- bar_graph_width_factor = @max_commits > 0 ? 100.0/@max_commits : 0
+- diverging_commit_counts = @repository.diverging_commit_counts(branch) 
+- number_commits_behind = diverging_commit_counts[:behind]
+- number_commits_ahead = diverging_commit_counts[:ahead]
 %li(class="js-branch-#{branch.name}")
   %div
     = link_to namespace_project_tree_path(@project.namespace, @project, branch.name) do
@@ -29,6 +33,17 @@
         = link_to namespace_project_branch_path(@project.namespace, @project, branch.name), class: 'btn btn-grouped btn-xs btn-remove remove-row has_tooltip', title: "Delete branch", method: :delete, data: { confirm: "Deleting the '#{branch.name}' branch cannot be undone. Are you sure?", container: 'body' }, remote: true do
           = icon("trash-o")
 
+    - if branch.name != @repository.root_ref
+      .divergence-graph{ title: "#{number_commits_ahead} commits ahead, #{number_commits_behind} commits behind #{@repository.root_ref}" }
+        .graph-side
+          .bar.bar-behind{ style: "width: #{number_commits_behind * bar_graph_width_factor}%" }
+          %span.count.count-behind= number_commits_behind
+        .graph-separator
+        .graph-side
+          .bar.bar-ahead{ style: "width: #{number_commits_ahead * bar_graph_width_factor}%" }
+          %span.count.count-ahead= number_commits_ahead
+
+
   - if commit
     = render 'projects/branches/commit', commit: commit, project: @project
   - else