diff --git a/lib/views/status.erb b/lib/views/status.erb index 169dac5..fc335f0 100644 --- a/lib/views/status.erb +++ b/lib/views/status.erb @@ -261,23 +261,29 @@ <% end%> - - <% @list.each do |commit| %> - <% commit_parts = commit.split "\n" %> + <% @graph_branches.each do |branch_hash| %> +

<%= branch_hash[:branch] %>

+ + <% branch_hash[:log].reverse.each do |commit| %>
+ + + + — <%= commit[:date].strftime("%a, %d %b %Y, %H:%M %z") %> (<%= commit[:formatted_date] %> ago) + <% heads = "(#{commit[:heads].join(", ")})" if !commit[:heads].empty? %> + <% if commit[:heads].include? @current_branch %> + <%= heads.gsub(@current_branch, 'HEAD --> ' + @current_branch) %> + <% else %> + <%= heads %> + <% end %>
- - <% first_line = commit_parts.first %> - <% sha = first_line.split[1] %> - <% copy_sha = '' %> - <%= first_line.gsub(sha, copy_sha) %> - - +   | <%= commit[:message] + " - " + commit[:author] %>
- <%= commit_parts.last.gsub("\t", " ") %>
- <% end %> -
+ <% end %> +
+
+ <% end %> diff --git a/lib/web_git.rb b/lib/web_git.rb index 2a75123..c707806 100644 --- a/lib/web_git.rb +++ b/lib/web_git.rb @@ -3,30 +3,19 @@ module WebGit require "web_git/diff" + require "web_git/graph" require "web_git/string" require "sinatra" require "date" require "git" class Server < Sinatra::Base - require 'action_view' - require 'action_view/helpers' - include ActionView::Helpers::DateHelper get '/log' do working_dir = File.exist?(Dir.pwd + "/.git") ? Dir.pwd : Dir.pwd + "/.." g = Git.open(working_dir) - logs = g.log - list = [] - logs.each do |commit| - # line = commit.sha + " " + commit.author.name + " " + - # commit.date.strftime("%a, %d %b %Y, %H:%M %z") + " " + commit.message - sha = commit.sha.slice(0..7) - commit_date = commit.date - line = " * " + sha + " - " + commit.date.strftime("%a, %d %b %Y, %H:%M %z") + - " (#{time_ago_in_words(commit_date)} ago) " + "
 | " + commit.message - list.push line - end - list.join("
") + + graph = WebGit::Graph.new(g) + graph.to_hash.to_json #sha = commit.sha.slice(0..7) # commit_date = Date.parse commit.date # strftime("%a, %d %b %Y, %H:%M %z") -> time_ago_in_words(commit_date) @@ -71,24 +60,19 @@ class Server < Sinatra::Base logs = g.log @last_commit_message = logs.first.message - head = g.show.split("\n").first.split[1].slice(0..7) + @head = g.show.split("\n").first.split[1].slice(0..7) @list = [] # (HEAD -> jw-non-sweet) # TODO show where branches are on different remotes # (origin/master, origin/jw-non-sweet, origin/HEAD) # g.branches[:master].gcommit - logs.each do |commit| - sha = commit.sha.slice(0..7) - commit_date = commit.date - line = " * " + sha + " - " + commit.date.strftime("%a, %d %b %Y, %H:%M %z") + - " (#{time_ago_in_words(commit_date)}) " - if sha == head - line += %Q{(HEAD -> #{@current_branch})} - end - line += "\n\t| " + "#{commit.message} - #{commit.author.name}" - @list.push line + graph = WebGit::Graph.new(g) + @graph_hash = graph.to_hash + @graph_branches = @graph_hash.sort do |branch_a, branch_b| + branch_b[:log].last[:date] <=> branch_a[:log].last[:date] end + erb :status end diff --git a/lib/web_git/graph.rb b/lib/web_git/graph.rb new file mode 100644 index 0000000..bce555f --- /dev/null +++ b/lib/web_git/graph.rb @@ -0,0 +1,86 @@ +module WebGit + require "git" + + class Graph + require "action_view" + require "action_view/helpers" + include ActionView::Helpers::DateHelper + attr_accessor :heads + + def initialize(git) + @git = git + @full_list = [] + @heads = {} + end + + def to_hash + + has_changes = has_untracked_changes? + if has_changes + temporarily_stash_changes + end + + draw_graph + + if has_changes + stash_pop + end + + @full_list + end + + def has_untracked_changes? + @git.diff.size > 0 + end + + def temporarily_stash_changes + @git.add(all: true) + stash_count = Git::Stashes.new(@git).count + Git::Stash.new(@git, "Temporary Stash #{stash_count}") + end + + def stash_pop + stashes = Git::Stashes.new(@git) + stashes.apply(0) + end + + def draw_graph + branches = @git.branches.local.map(&:name) + branches.each do |branch_name| + branch = { branch: branch_name } + @git.checkout(branch_name) + log_commits = build_array_of_commit_hashes + branch[:log] = log_commits + branch[:head] = log_commits.last[:sha] + @full_list.push branch + end + + @full_list.each do |branch_hash| + head_sha = branch_hash[:head] + branch_name = branch_hash[:branch] + + if @heads[head_sha].nil? + @heads[head_sha] = [ branch_name ] + else + @heads[head_sha].push branch_name + end + end + + end + + def build_array_of_commit_hashes + log_commits = [] + @git.log.sort_by(&:date).each do |git_commit_object| + commit = {} + commit[:sha] = git_commit_object.sha.slice(0..7) + commit[:date] = git_commit_object.date + commit[:formatted_date] = time_ago_in_words(git_commit_object.date) + commit[:message] = git_commit_object.message + commit[:author] = git_commit_object.author.name + commit[:heads] = [] + log_commits.push commit + end + log_commits + end + end +end