diff --git a/Gemfile.lock b/Gemfile.lock
index 80ed227..3cee973 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -24,7 +24,8 @@ GEM
erubi (1.8.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
- git (1.5.0)
+ git (1.7.0)
+ rchardet (~> 1.8)
github_api (0.18.2)
addressable (~> 2.4)
descendants_tracker (~> 0.0.4)
@@ -81,6 +82,7 @@ GEM
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
rake (12.3.2)
+ rchardet (1.8.0)
rdoc (3.12.2)
json (~> 1.4)
rspec (3.5.0)
diff --git a/lib/views/log.erb b/lib/views/log.erb
new file mode 100644
index 0000000..184bc79
--- /dev/null
+++ b/lib/views/log.erb
@@ -0,0 +1,130 @@
+
+
+
+ <% created_branches = []%>
+ <% @graph.commit_order.each do |sha| %>
+ <% commit_info = @graph.graph_order[sha] %>
+ <% commit_info %>
+ <% if @graph.commit_order.index(sha) == 0 %>
+ var master = gitgraph.branch("master");
+
+ gitgraph.commit({ sha1: "<%= sha %>"", message: ""}});
+
+ <% created_branches.push "master" %>
+ <% else %>
+ <% if !created_branches.include? commit_info[:branch] %>
+ const <%= commit_info[:branch] %> = gitgraph.branch("<%= commit_info[:branch] %>");
+
+ <% end %>
+ <% created_branches.push commit_info[:branch] %>
+ <%= commit_info[:branch] %>.commit({message: "", sha1: "<%= sha %>"});
+ <% if commit_info[:branches_to].size > 0 %>
+ <% commit_info[:branches_to].each do |branch| %>
+ const <%= branch %> = gitgraph.branch("<%= branch %>");
+
+ <% created_branches.push branch %>
+
+ <% end %>
+ <% end %>
+
+
+ <% end %>
+ <% end %>
+
diff --git a/lib/web_git.rb b/lib/web_git.rb
index 94e7625..6dd274d 100644
--- a/lib/web_git.rb
+++ b/lib/web_git.rb
@@ -14,14 +14,17 @@ class Server < Sinatra::Base
working_dir = File.exist?(Dir.pwd + "/.git") ? Dir.pwd : Dir.pwd + "/.."
g = Git.open(working_dir)
- graph = WebGit::Graph.new(g)
- graph.to_hash.to_json
+ @graph = WebGit::Graph.new(g)
+ # graph.find_common_shas.to_json
+ # graph.tree_traversal.to_json
+ @graph.build_backwards#.to_json
+ # 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)
# * 76eff73 - Wed, 11 Mar 2020 19:58:21 +0000 (13 days ago) (HEAD -> current_branch)
# | blease - Jelani Woods
-
+ erb :log
# " * " + sha + " - " + commit_date + " (" + time_ago_in_words(commit_date) + ") " + "\n\t| " + commit.message
end
@@ -67,8 +70,8 @@ class Server < Sinatra::Base
# (origin/master, origin/jw-non-sweet, origin/HEAD)
# g.branches[:master].gcommit
- graph = WebGit::Graph.new(g)
- @graph_hash = graph.to_hash
+ @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
diff --git a/lib/web_git/graph.rb b/lib/web_git/graph.rb
index bce555f..11dcd64 100644
--- a/lib/web_git/graph.rb
+++ b/lib/web_git/graph.rb
@@ -6,11 +6,15 @@ class Graph
require "action_view/helpers"
include ActionView::Helpers::DateHelper
attr_accessor :heads
+ attr_reader :graph_order
+ attr_reader :commit_order
def initialize(git)
@git = git
@full_list = []
@heads = {}
+ @graph_order = {}
+ @commit_order = []
end
def to_hash
@@ -29,6 +33,255 @@ def to_hash
@full_list
end
+ def list_all_shas
+ @list = []
+ branches = @git.branches.local.map(&:name)
+ branches.each do |branch_name|
+ branch = { name: branch_name }
+ @git.checkout(branch_name)
+ log = []
+ @git.log.each do |git_commit_object|
+ sha = git_commit_object.sha.slice(0..7)
+ log.push sha
+ end
+ branch[:log] = log
+ @list.push branch
+ end
+ end
+
+ def find_common_shas
+ list_all_shas
+ @keep_list = @list
+ new_list = []
+ # Only need to compare to the master branch?
+ # master = @list
+ @list.each do |branch|
+ if branch[:name] == "master"
+ current_log = branch[:log]
+ other_branches = @list - [ branch ]
+ new_list.push({name: "master", log: current_log})
+ p "Current Branch: #{branch[:name]}"
+ p "================================"
+ other_branches.each do |other_branch|
+ p "Other Branch: #{other_branch[:name]}"
+ new_branch = { name: other_branch[:name]}
+ branch_log = other_branch[:log]
+
+ p "Current Log: #{current_log}"
+ p "Branch Log: #{branch_log}"
+ unique_commits = branch_log - current_log
+ p "Unique Log: #{unique_commits}"
+ new_branch[:log] = unique_commits
+ p "Parents"
+ @git.gcommit(unique_commits.first).parents.each do |gcommit|
+ p "---"
+ p gcommit.message + " " + gcommit.sha
+ p "---"
+ end
+ new_list.push new_branch
+ # current_log.each do |sha|
+ # end
+ end
+ p "================================"
+ puts "\n" * 3
+ end
+ end
+ new_list
+ end
+
+ def is_unique_sha?(sha, name, list)
+ # p "IS UNIQUE"
+ list.each do |branch|
+ if branch[:name] != name
+ # p "Branch name: #{branch[:name]}"
+ # p "(real)current: " + name
+ log = branch[:log]
+ # p "log"
+ # p log
+ # p " - " + sha
+ if log.include? sha
+ return false
+ end
+ end
+ end
+ true
+ end
+
+ def find_other_branch_names(sha, name, list)
+ branch_names = []
+ list.each do |branch|
+ if branch[:name] != name
+ log = branch[:log]
+ if log.include? sha
+ branch_names.push branch[:name]
+ end
+ end
+ end
+ branch_names
+ end
+
+ def find_merging_branch_name(first, last)
+ list = @list
+ # Start with two commit shas
+ # f0c357b, 64d6e33
+ # Find branch with f0c357b, (Should already be able to find this one)
+ # Find branch with 64d6e33, but NOT f0c357b
+ branch1 = ""
+ branch2 = ""
+
+ list.each do |branch|
+ if !branch[:log].include?(first) && branch[:log].include?(last)
+ return branch[:name]
+ end
+ end
+ end
+
+ def get_parents(sha, name, list)
+ commit = @git.gcommit(sha)
+ parents = commit.parents
+ # if parents.size > 1 then it's a merge commit
+ if parents.size > 0
+ # Find out if sha is unique,
+ # If not, branch is current
+ # Else branch is 'master'
+ branch_name = "master"
+ # p "SHA CLASSS"
+ # p sha.class
+ # p "#{sha}"
+ # puts "\n" * 3
+ # p "====uniqueness====="
+ if is_unique_sha?(sha, name, @list)
+ # p "IS UNIQUE"
+ branch_name = name
+ end
+ # p "====uniqueness====="
+ # puts "\n" * 3
+ if @graph_order.keys.include? sha
+ p "FINDING OTHER BRANCH NAMES"
+ # if already have a branch to, maybe DON't add another one
+ other_branch_tos = @graph_order.keys.map do |other_sha|
+ @graph_order[other_sha][:branches_to]
+ end
+ p "//////////"
+ p other_branch_tos.reduce(&:+)
+ p "//////////"
+ if !other_branch_tos.reduce(&:+).include?(branch_name)
+ p "First one"
+ @graph_order[sha][:branches_to] = find_other_branch_names(sha, name, @list)
+ p @graph_order[sha][:branches_to]
+ else
+ p "Don't you do it!"
+ end
+ else
+ @graph_order[sha] = { branch: branch_name, branches_to: [], merge_between: [], message: commit.message, author: commit.author.name }
+ end
+ if @commit_order.include? sha
+ i = @commit_order.index(sha)
+ @commit_order.delete_at(i)
+ @commit_order.push sha
+ else
+ @commit_order.push sha
+ end
+ p "Commit: #{sha} - #{commit.message} - branch: #{branch_name}"
+ if parents.size > 1
+ @graph_order[sha][:merge_between] = parents.map{ |c| c.sha.slice(0..7)}
+ p "Merge Point #{parents.map{ |c| c.sha.slice(0..7)}.join(", ")}"
+ first = parents.first.sha.slice(0..7)
+ last = parents.last.sha.slice(0..7)
+ @graph_order[last][:branch] = find_merging_branch_name(first, last)
+ end
+
+ parents.each do |parent|
+ get_parents(parent.sha.slice(0..7), name, list)
+ end
+ else
+ # It's the first commit
+ if @commit_order.include? sha
+ i = @commit_order.index(sha)
+ @commit_order.delete_at(i)
+ @commit_order.push sha
+ else
+ @commit_order.push sha
+ end
+ @graph_order[sha] = { branch: "master", branches_to: [], merge_between: [], message: commit.message, author: commit.author.name }
+ p "Commit: #{sha} - #{commit.message} - branch: master"
+ return
+ end
+ end
+
+ def build_backwards
+ # [{"name":"master","log":["3c391fc0","f0c357bb","64d6e333","f716b366"]},{"name":"c-branch","log":["ef99623c"]},{"name":"update","log":["bc9833b9"]}]
+ list = find_common_shas
+
+ p "building..."
+ list.reverse.each do |branch|
+ name = branch[:name]
+ p "Branch: #{name}"
+ log = branch[:log]
+ # p log.last.class
+ # p @list
+ # p "[][][][]"
+ # p @keep_list
+ last = @git.gcommit(log.first)
+ # p "Last commit #{last.sha.slice(0..7)} - #{last.message}"
+ exclude_branches = {}
+ # Looks like
+ # { "master": [], "update": [], "c-branch": ["master", "update"]}
+ # On the basis that all of master exists in c-branch currently
+ get_parents(last.sha.slice(0..7), name, @list)
+ p "_________________________"
+ p "_________________________"
+ # p @graph_order
+ # TODO
+ # Create Hash of commits, ordered by date—
+ # { "47485296": { branch: "master", branches_to: [] }, "3b3aaccf": { branch: "master", branches_to: ["b-branch"]}, "4bb66595": {}, }
+ p "+++---"
+ end
+ p "======"
+ p @commit_order = @commit_order.reverse
+ # ["f62e91d6", "4bb66595", "de987471", "3b3aaccf", "47485296"]
+ @commit_order.each do |sha|
+ commit_info = @graph_order[sha]
+ if commit_info[:branches_to].size > 0
+ p "#{sha} - #{commit_info[:branch]}, branches to #{commit_info[:branches_to].join(" ,")}"
+ else
+ p "#{sha} - #{@graph_order[sha][:branch]}"
+ end
+ end
+ []
+ end
+
+ def tree_traversal
+ tree = []
+ @git.log.each do |git_commit_object|
+ sha = git_commit_object.sha.slice(0..7)
+ parents = git_commit_object.parents.map{ |parent| { sha: parent.sha, message: parent.message}}
+ git_tree = @git.gtree(git_commit_object.sha)
+ children = git_tree.children#.map{ |child| { sha: child.sha, message: child.message}}
+ object = {message: git_commit_object.message, sha: sha, parents: parents, children: children}
+ tree.push object
+ end
+ tree
+ end
+
+ def to_array
+ # Each element is a branch log
+ # Each branch log has a starting commit and ending commit
+ # Each branch log only has commits that are unique to that branch
+ lists = @full_list.map{|l| l[:log] }
+ combined_branch = { branch: "ALL", head: "_" }
+
+
+ log_commits = []
+ (lists.count - 1).times do |i|
+ log_hash = lists[i]
+
+ log_commits = log_commits | log_hash
+ end
+ combined_branch[:log] = log_commits
+ log_commits
+ end
+
def has_untracked_changes?
@git.diff.size > 0
end
@@ -77,6 +330,7 @@ def build_array_of_commit_hashes
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[:branch_name] = @git.current_branch
commit[:heads] = []
log_commits.push commit
end