git-dag 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ output
2
+ history.pdf
3
+ pkg/
@@ -0,0 +1,28 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ namespace :test do
6
+ Rake::TestTask.new(:unit) do |test|
7
+ test.libs << 'test'
8
+ test.pattern = '{test/unit/*_test.rb}'
9
+ end
10
+
11
+ Rake::TestTask.new(:integ) do |test|
12
+ test.libs << 'test' << 'lib'
13
+ test.pattern = '{test/integ/*_test.rb}'
14
+ end
15
+
16
+ Rake::TestTask.new(:all) do |test|
17
+ test.libs << 'test'
18
+ test.pattern = '{test/**/*_test.rb}'
19
+ end
20
+
21
+ end
22
+
23
+ desc "Run tests and generate coverage"
24
+ task :coverage do
25
+ ENV['COVERAGE'] = 'true'
26
+ end
27
+
28
+ task :default => :test
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/git-dag"
4
+
5
+ GitDag::Application.run(ARGV[0])
6
+
7
+ # vim: set filetype=ruby
@@ -0,0 +1,5 @@
1
+ require 'git-dag/application'
2
+ require 'git-dag/git_graph'
3
+ require 'git-dag/node'
4
+ require 'git-dag/commit_node'
5
+ require 'git-dag/fake_head'
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'grit'
4
+ require 'pry'
5
+
6
+ module GitDag
7
+ module Application
8
+ def self.run(git_repo_path)
9
+ git_graph = GitGraph.new(git_repo_path)
10
+ puts git_graph.output_dot_file
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ module GitDag
2
+ class CommitNode < Node
3
+ def initialize(grit_commit)
4
+ @grit_commit = grit_commit
5
+ @parents = []
6
+ end
7
+
8
+ def label
9
+ %Q([color="#{color}"])
10
+ end
11
+
12
+ def id
13
+ @grit_commit.id
14
+ end
15
+
16
+ def add_parent(parent)
17
+ #puts "commit #{id} add parent #{parent.id}"
18
+ @parents << parent
19
+ #puts "parents: #{@parents}" if id =~ /07da/
20
+ end
21
+
22
+ def dot_node
23
+ %Q("#{short_sha1}")
24
+ end
25
+
26
+ private
27
+ def color
28
+ if merge?
29
+ "red"
30
+ else
31
+ "black"
32
+ end
33
+ end
34
+
35
+ def short_sha1
36
+ @grit_commit.id[0,6]
37
+ end
38
+
39
+ def merge?
40
+ @parents.size > 1
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ module GitDag
2
+ class FakeHead < Node
3
+ def initialize(id, dot_node, label, parents)
4
+ @id = id
5
+ @dot_node = dot_node
6
+ @label = label
7
+ @parents = parents
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,60 @@
1
+ module GitDag
2
+ class GitGraph
3
+ def initialize(git_repo)
4
+ @repo = Grit::Repo.new(git_repo)
5
+ @branches = @repo.branches
6
+ @remotes = @repo.remotes
7
+ @all_branches = @remotes.reject {|r| r.name =~ /HEAD/} + @branches
8
+ end
9
+
10
+ def output_dot_file
11
+ all_commits = build_entire_graph
12
+ get_dot_str(all_commits)
13
+ end
14
+
15
+ def get_dot_str(all_commits)
16
+ #puts "all_commits: #{all_commits.size}"
17
+ dot_str = "digraph G {\n"
18
+ all_commits.each do |id, node|
19
+ node.parents.each do |parent|
20
+ dot_str << "#{node.dot_node} -> #{parent.dot_node};\n"
21
+ end
22
+ dot_str << %Q(#{node.dot_node} #{node.label};\n)
23
+ end
24
+ dot_str << "}\n"
25
+ end
26
+
27
+ def build_entire_graph
28
+ all_commits = {}
29
+ @all_branches.each do |branch|
30
+ commits = find_commits_per_branch(branch.name)
31
+ commits.each do |commit|
32
+ my_commit = CommitNode.new(commit)
33
+ all_commits[commit.id] = my_commit unless all_commits.has_key? commit.id
34
+ #puts "adding #{commit.id} to hash"
35
+ commit.parents.each do |parent|
36
+ parent_commit = CommitNode.new(parent)
37
+ my_commit.add_parent(parent_commit)
38
+ #all_commits[parent.id] = parent_commit unless all_commits.has_key? parent.id
39
+ end
40
+ end
41
+
42
+ parent_of_fake_head = all_commits[commits[0].id]
43
+ fake_head = create_fake_commit_for_head(branch.name, parent_of_fake_head)
44
+ all_commits[fake_head.id] = fake_head
45
+ end
46
+ all_commits
47
+ end
48
+
49
+ def create_fake_commit_for_head(branch_name, parent)
50
+ id = branch_name
51
+ dot_node = %Q("#{branch_name}")
52
+ label = %Q([color="blue" shape=box])
53
+ FakeHead.new(id, dot_node, label, [parent])
54
+ end
55
+
56
+ def find_commits_per_branch(branch)
57
+ @repo.commits(branch, false) # false indicates all commits
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,5 @@
1
+ module GitDag
2
+ class Node
3
+ attr_accessor :parents, :label, :id, :dot_node
4
+ end
5
+ end
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+ EXPECTED_DOT_FILE = <<HERE
4
+ digraph G {
5
+ "8b61ae" -> "100099";
6
+ "8b61ae" -> "37f6a9";
7
+ "8b61ae" [color="red"];
8
+ "37f6a9" -> "45b109";
9
+ "37f6a9" [color="black"];
10
+ "100099" -> "45b109";
11
+ "100099" [color="black"];
12
+ "45b109" -> "bdd658";
13
+ "45b109" -> "2253ce";
14
+ "45b109" [color="red"];
15
+ "bdd658" -> "5defde";
16
+ "bdd658" -> "c554da";
17
+ "bdd658" [color="red"];
18
+ "5defde" -> "7b1e4b";
19
+ "5defde" [color="black"];
20
+ "2253ce" -> "7b1e4b";
21
+ "2253ce" [color="black"];
22
+ "c554da" -> "7b5eb3";
23
+ "c554da" [color="black"];
24
+ "7b1e4b" -> "7b5eb3";
25
+ "7b1e4b" [color="black"];
26
+ "7b5eb3" [color="black"];
27
+ "origin/dev" -> "8b61ae";
28
+ "origin/dev" [color="blue" shape=box];
29
+ "origin/master" -> "8b61ae";
30
+ "origin/master" [color="blue" shape=box];
31
+ "dev" -> "37f6a9";
32
+ "dev" [color="blue" shape=box];
33
+ "master" -> "8b61ae";
34
+ "master" [color="blue" shape=box];
35
+ }
36
+ HERE
37
+
38
+ module GitDag
39
+ class GitGraphTest < MiniTest::Unit::TestCase
40
+ def test_output_dot_file
41
+ git_graph = GitGraph.new("./sample_repo")
42
+ dot_file = git_graph.output_dot_file
43
+ assert_equal(EXPECTED_DOT_FILE, dot_file)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,2 @@
1
+ require 'minitest/autorun'
2
+ require 'git-dag'
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-dag
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jingjing Duan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: grit
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.5.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.5.0
30
+ description: A ruby script that generates a 'dot' file (Git DAG tree) for a given
31
+ Git repository.
32
+ email:
33
+ - jingjing.duan@gmail.com
34
+ executables:
35
+ - git-dag
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - .gitignore
40
+ - Rakefile
41
+ - bin/git-dag
42
+ - lib/git-dag.rb
43
+ - lib/git-dag/application.rb
44
+ - lib/git-dag/commit_node.rb
45
+ - lib/git-dag/fake_head.rb
46
+ - lib/git-dag/git_graph.rb
47
+ - lib/git-dag/node.rb
48
+ - test/integ/git_graph_test.rb
49
+ - test/test_helper.rb
50
+ homepage: https://github.com/jduan/git-dag
51
+ licenses: []
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: 1.8.10
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.23
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: A ruby script that generates a 'dot' file (Git DAG tree) for a given Git
74
+ repository.
75
+ test_files:
76
+ - test/integ/git_graph_test.rb
77
+ - test/test_helper.rb
78
+ has_rdoc: