summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Stubler <brunsa2@gmail.com>2015-07-20 20:34:19 -0500
committerJeff Stubler <brunsa2@gmail.com>2015-11-01 11:38:00 -0600
commitc843722de2d778b6ec8fef0656797fd5a8074666 (patch)
tree75040853228588298e29d91b8ce606861f2bb468
parent8f75200d466d41707f3b1ca12ca4244cfa2e2e7b (diff)
downloadgitlab-ce-c843722de2d778b6ec8fef0656797fd5a8074666.tar.gz
Add graphs showing commits ahead and behind default to branches page
-rw-r--r--CHANGELOG1
-rw-r--r--app/assets/stylesheets/pages/commits.scss59
-rw-r--r--app/controllers/projects/branches_controller.rb6
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/repository.rb42
-rw-r--r--app/views/projects/branches/_branch.html.haml14
6 files changed, 122 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 6bec4f606e7..98702088199 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@ v 8.2.0 (unreleased)
- 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)
v 8.1.1
- Fix cloning Wiki repositories via HTTP (Stan Hu)
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 4e121b95d13..4a080db7464 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -113,3 +113,62 @@ li.commit {
}
}
}
+
+.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 3ac0a75fa70..c3cd7642dd2 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -9,6 +9,12 @@ 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 74b89aad499..e73a856c289 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -714,6 +714,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 c9b36bd8170..9b270bc9d18 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -146,10 +146,27 @@ class Repository
def size
cache.fetch(:size) { raw_repository.size }
end
+
+ def diverging_commit_counts(branch)
+ branch_cache_key = ('diverging_commit_counts_' + branch.name).to_sym
+ cache.fetch(branch_cache_key) do
+ number_commits_behind = commits_between(branch.name, root_ref).size
+ number_commits_ahead = commits_between(root_ref, branch.name).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)
+ %i(size branch_names tag_names commit_count readme
+ contribution_guide changelog license)
+ end
+
+ def branch_cache_keys
+ branches.map do
+ |branch|
+ ('diverging_commit_counts_' + branch.name).to_sym
+ end
end
def build_cache
@@ -158,12 +175,28 @@ class Repository
send(key)
end
end
+
+ branches.each do |branch|
+ unless cache.exist?(('diverging_commit_counts_' + branch.name).to_sym)
+ send(:diverging_commit_counts, branch)
+ end
+ end
end
def expire_cache
cache_keys.each do |key|
cache.expire(key)
end
+
+ branches.each do |branch|
+ cache.expire(('diverging_commit_counts_' + branch.name).to_sym)
+ end
+ end
+
+ def expire_branch_cache
+ branches.each do |branch|
+ cache.expire(('diverging_commit_counts_' + branch.name).to_sym)
+ end
end
def rebuild_cache
@@ -171,6 +204,11 @@ class Repository
cache.expire(key)
send(key)
end
+
+ branches.each do |branch|
+ cache.expire(('diverging_commit_counts_' + branch.name).to_sym)
+ send(: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 cc0ec9483d2..9ddb10a1c74 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -1,4 +1,7 @@
- commit = @repository.commit(branch.target)
+- bar_graph_width_factor = @max_commits > 0 ? 100.0/@max_commits : 0
+- number_commits_behind = @repository.diverging_commit_counts(branch)[:behind]
+- number_commits_ahead = @repository.diverging_commit_counts(branch)[:ahead]
%li(class="js-branch-#{branch.name}")
%div
= link_to namespace_project_tree_path(@project.namespace, @project, branch.name) do
@@ -29,6 +32,17 @@
= link_to namespace_project_branch_path(@project.namespace, @project, branch.name), class: 'btn btn-grouped btn-xs btn-remove remove-row', method: :delete, data: { confirm: 'Removed branch cannot be restored. Are you sure?'}, 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