git-trip 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +21 -0
  3. data/Manifest.txt +89 -0
  4. data/README.txt +60 -0
  5. data/Rakefile +31 -0
  6. data/bin/git-trip +0 -0
  7. data/doc/USAGE.txt +54 -0
  8. data/lib/core_ext/hash.rb +15 -0
  9. data/lib/git-trip.rb +23 -0
  10. data/lib/git-trip/errors.rb +22 -0
  11. data/lib/git-trip/gitter.rb +10 -0
  12. data/lib/git-trip/gitter/base.rb +18 -0
  13. data/lib/git-trip/gitter/dir.rb +32 -0
  14. data/lib/git-trip/gitter/uri.rb +40 -0
  15. data/lib/git-trip/paint_mode.rb +52 -0
  16. data/lib/git-trip/painter.rb +167 -0
  17. data/spec/core_ext/hash_spec.rb +25 -0
  18. data/spec/git-trip/errors_spec.rb +43 -0
  19. data/spec/git-trip/gitter/base_spec.rb +15 -0
  20. data/spec/git-trip/gitter/dir_spec.rb +37 -0
  21. data/spec/git-trip/gitter/uri_spec.rb +25 -0
  22. data/spec/git-trip/gitter_spec.rb +11 -0
  23. data/spec/git-trip/paint_mode_spec.rb +56 -0
  24. data/spec/git-trip/painter_spec.rb +173 -0
  25. data/spec/git_trip_spec.rb +23 -0
  26. data/spec/rcov.opts +1 -0
  27. data/spec/spec.opts +4 -0
  28. data/spec/spec_helper.rb +15 -0
  29. data/tasks/ditz.rake +42 -0
  30. data/tasks/docs.rake +68 -0
  31. data/tasks/gittrip.rake +63 -0
  32. data/tasks/rspec.rake +22 -0
  33. data/tasks/site.rake +48 -0
  34. data/tasks/util.rake +44 -0
  35. data/vendor/grit/History.txt +6 -0
  36. data/vendor/grit/Manifest.txt +53 -0
  37. data/vendor/grit/README.txt +213 -0
  38. data/vendor/grit/Rakefile +29 -0
  39. data/vendor/grit/grit.gemspec +16 -0
  40. data/vendor/grit/lib/grit.rb +37 -0
  41. data/vendor/grit/lib/grit/actor.rb +36 -0
  42. data/vendor/grit/lib/grit/blob.rb +117 -0
  43. data/vendor/grit/lib/grit/commit.rb +208 -0
  44. data/vendor/grit/lib/grit/config.rb +44 -0
  45. data/vendor/grit/lib/grit/diff.rb +70 -0
  46. data/vendor/grit/lib/grit/errors.rb +7 -0
  47. data/vendor/grit/lib/grit/git.rb +116 -0
  48. data/vendor/grit/lib/grit/index.rb +77 -0
  49. data/vendor/grit/lib/grit/lazy.rb +31 -0
  50. data/vendor/grit/lib/grit/ref.rb +110 -0
  51. data/vendor/grit/lib/grit/repo.rb +318 -0
  52. data/vendor/grit/lib/grit/tree.rb +99 -0
  53. data/vendor/grit/test/fixtures/blame +131 -0
  54. data/vendor/grit/test/fixtures/cat_file_blob +1 -0
  55. data/vendor/grit/test/fixtures/cat_file_blob_size +1 -0
  56. data/vendor/grit/test/fixtures/diff_2 +54 -0
  57. data/vendor/grit/test/fixtures/diff_2f +19 -0
  58. data/vendor/grit/test/fixtures/diff_f +15 -0
  59. data/vendor/grit/test/fixtures/diff_i +201 -0
  60. data/vendor/grit/test/fixtures/diff_mode_only +1152 -0
  61. data/vendor/grit/test/fixtures/diff_new_mode +17 -0
  62. data/vendor/grit/test/fixtures/diff_p +610 -0
  63. data/vendor/grit/test/fixtures/for_each_ref +0 -0
  64. data/vendor/grit/test/fixtures/for_each_ref_remotes +0 -0
  65. data/vendor/grit/test/fixtures/for_each_ref_tags +0 -0
  66. data/vendor/grit/test/fixtures/ls_tree_a +7 -0
  67. data/vendor/grit/test/fixtures/ls_tree_b +2 -0
  68. data/vendor/grit/test/fixtures/ls_tree_commit +3 -0
  69. data/vendor/grit/test/fixtures/rev_list +26 -0
  70. data/vendor/grit/test/fixtures/rev_list_count +655 -0
  71. data/vendor/grit/test/fixtures/rev_list_single +7 -0
  72. data/vendor/grit/test/fixtures/rev_parse +1 -0
  73. data/vendor/grit/test/fixtures/show_empty_commit +6 -0
  74. data/vendor/grit/test/fixtures/simple_config +2 -0
  75. data/vendor/grit/test/helper.rb +17 -0
  76. data/vendor/grit/test/profile.rb +21 -0
  77. data/vendor/grit/test/suite.rb +6 -0
  78. data/vendor/grit/test/test_actor.rb +35 -0
  79. data/vendor/grit/test/test_blob.rb +74 -0
  80. data/vendor/grit/test/test_commit.rb +182 -0
  81. data/vendor/grit/test/test_config.rb +58 -0
  82. data/vendor/grit/test/test_diff.rb +18 -0
  83. data/vendor/grit/test/test_git.rb +52 -0
  84. data/vendor/grit/test/test_head.rb +22 -0
  85. data/vendor/grit/test/test_real.rb +19 -0
  86. data/vendor/grit/test/test_reality.rb +17 -0
  87. data/vendor/grit/test/test_remote.rb +15 -0
  88. data/vendor/grit/test/test_repo.rb +278 -0
  89. data/vendor/grit/test/test_tag.rb +29 -0
  90. data/vendor/grit/test/test_tree.rb +91 -0
  91. metadata +179 -0
  92. metadata.gz.sig +0 -0
@@ -0,0 +1,44 @@
1
+ module Grit
2
+
3
+ class Config
4
+ def initialize(repo)
5
+ @repo = repo
6
+ end
7
+
8
+ def []=(key, value)
9
+ @repo.git.config({}, key, value)
10
+ @data = nil
11
+ end
12
+
13
+ def [](key)
14
+ data[key]
15
+ end
16
+
17
+ def fetch(key, default = nil)
18
+ data[key] || default || raise(IndexError.new("key not found"))
19
+ end
20
+
21
+ def keys
22
+ data.keys
23
+ end
24
+
25
+ protected
26
+ def data
27
+ @data ||= load_config
28
+ end
29
+
30
+ def load_config
31
+ hash = {}
32
+ config_lines.map do |line|
33
+ key, value = line.split(/=/, 2)
34
+ hash[key] = value
35
+ end
36
+ hash
37
+ end
38
+
39
+ def config_lines
40
+ @repo.git.config(:list => true).split(/\n/)
41
+ end
42
+ end # Config
43
+
44
+ end # Grit
@@ -0,0 +1,70 @@
1
+ module Grit
2
+
3
+ class Diff
4
+ attr_reader :a_path, :b_path
5
+ attr_reader :a_commit, :b_commit
6
+ attr_reader :a_mode, :b_mode
7
+ attr_reader :new_file, :deleted_file
8
+ attr_reader :diff
9
+
10
+ def initialize(repo, a_path, b_path, a_commit, b_commit, a_mode, b_mode, new_file, deleted_file, diff)
11
+ @repo = repo
12
+ @a_path = a_path
13
+ @b_path = b_path
14
+ @a_commit = a_commit =~ /^0{40}$/ ? nil : Commit.create(repo, :id => a_commit)
15
+ @b_commit = b_commit =~ /^0{40}$/ ? nil : Commit.create(repo, :id => b_commit)
16
+ @a_mode = a_mode
17
+ @b_mode = b_mode
18
+ @new_file = new_file
19
+ @deleted_file = deleted_file
20
+ @diff = diff
21
+ end
22
+
23
+ def self.list_from_string(repo, text)
24
+ lines = text.split("\n")
25
+
26
+ diffs = []
27
+
28
+ while !lines.empty?
29
+ m, a_path, b_path = *lines.shift.match(%r{^diff --git a/(.+?) b/(.+)$})
30
+
31
+ if lines.first =~ /^old mode/
32
+ m, a_mode = *lines.shift.match(/^old mode (\d+)/)
33
+ m, b_mode = *lines.shift.match(/^new mode (\d+)/)
34
+ end
35
+
36
+ if lines.empty? || lines.first =~ /^diff --git/
37
+ diffs << Diff.new(repo, a_path, b_path, nil, nil, a_mode, b_mode, false, false, nil)
38
+ next
39
+ end
40
+
41
+ new_file = false
42
+ deleted_file = false
43
+
44
+ if lines.first =~ /^new file/
45
+ m, b_mode = lines.shift.match(/^new file mode (.+)$/)
46
+ a_mode = nil
47
+ new_file = true
48
+ elsif lines.first =~ /^deleted file/
49
+ m, a_mode = lines.shift.match(/^deleted file mode (.+)$/)
50
+ b_mode = nil
51
+ deleted_file = true
52
+ end
53
+
54
+ m, a_commit, b_commit, b_mode = *lines.shift.match(%r{^index ([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+) ?(.+)?$})
55
+ b_mode.strip! if b_mode
56
+
57
+ diff_lines = []
58
+ while lines.first && lines.first !~ /^diff/
59
+ diff_lines << lines.shift
60
+ end
61
+ diff = diff_lines.join("\n")
62
+
63
+ diffs << Diff.new(repo, a_path, b_path, a_commit, b_commit, a_mode, b_mode, new_file, deleted_file, diff)
64
+ end
65
+
66
+ diffs
67
+ end
68
+ end # Diff
69
+
70
+ end # Grit
@@ -0,0 +1,7 @@
1
+ module Grit
2
+ class InvalidGitRepositoryError < StandardError
3
+ end
4
+
5
+ class NoSuchPathError < StandardError
6
+ end
7
+ end
@@ -0,0 +1,116 @@
1
+ trap("CHLD") do
2
+ begin
3
+ Process.wait(-1, Process::WNOHANG)
4
+ rescue Object
5
+ end
6
+ end
7
+
8
+ module Grit
9
+
10
+ class Git
11
+ class GitTimeout < RuntimeError
12
+ attr_reader :command, :bytes_read
13
+
14
+ def initialize(command = nil, bytes_read = nil)
15
+ @command = command
16
+ @bytes_read = bytes_read
17
+ end
18
+ end
19
+
20
+ undef_method :clone
21
+
22
+ class << self
23
+ attr_accessor :git_binary, :git_timeout
24
+ end
25
+
26
+ self.git_binary = "/usr/bin/env git"
27
+ self.git_timeout = 5
28
+
29
+ attr_accessor :git_dir, :bytes_read
30
+
31
+ def initialize(git_dir)
32
+ self.git_dir = git_dir
33
+ self.bytes_read = 0
34
+ end
35
+
36
+ # Run the given git command with the specified arguments and return
37
+ # the result as a String
38
+ # +cmd+ is the command
39
+ # +options+ is a hash of Ruby style options
40
+ # +args+ is the list of arguments (to be joined by spaces)
41
+ #
42
+ # Examples
43
+ # git.rev_list({:max_count => 10, :header => true}, "master")
44
+ #
45
+ # Returns String
46
+ def method_missing(cmd, options = {}, *args)
47
+ run('', cmd, '', options, args)
48
+ end
49
+
50
+ def run(prefix, cmd, postfix, options, args)
51
+ timeout = options.delete(:timeout)
52
+ timeout = true if timeout.nil?
53
+
54
+ opt_args = transform_options(options)
55
+ ext_args = args.map { |a| a == '--' ? a : "'#{a}'" }
56
+
57
+ call = "#{prefix}#{Git.git_binary} --git-dir='#{self.git_dir}' #{cmd.to_s.gsub(/_/, '-')} #{(opt_args + ext_args).join(' ')}#{postfix}"
58
+ puts call if Grit.debug
59
+ response = timeout ? sh(call) : wild_sh(call)
60
+ puts response if Grit.debug
61
+ response
62
+ end
63
+
64
+ def sh(command)
65
+ pid, _, io, _ = Open4.popen4(command)
66
+ ret = Timeout.timeout(self.class.git_timeout) { io.read }
67
+ @bytes_read += ret.size
68
+
69
+ if @bytes_read > 5242880 # 5.megabytes
70
+ bytes = @bytes_read
71
+ @bytes_read = 0
72
+ raise GitTimeout.new(command, bytes)
73
+ end
74
+
75
+ ret
76
+ rescue Object => e
77
+ Process.kill('KILL', pid) rescue nil
78
+ bytes = @bytes_read
79
+ @bytes_read = 0
80
+ raise GitTimeout.new(command, bytes)
81
+ end
82
+
83
+ def wild_sh(command)
84
+ pid, _, io, _ = Open4.popen4(command)
85
+ io.read
86
+ end
87
+
88
+ # Transform Ruby style options into git command line options
89
+ # +options+ is a hash of Ruby style options
90
+ #
91
+ # Returns String[]
92
+ # e.g. ["--max-count=10", "--header"]
93
+ def transform_options(options)
94
+ args = []
95
+ options.keys.each do |opt|
96
+ if opt.to_s.size == 1
97
+ if options[opt] == true
98
+ args << "-#{opt}"
99
+ else
100
+ val = options.delete(opt)
101
+ args << "-#{opt.to_s} '#{val}'"
102
+ end
103
+ else
104
+ if options[opt] == true
105
+ args << "--#{opt.to_s.gsub(/_/, '-')}"
106
+ else
107
+ val = options.delete(opt)
108
+ args << "--#{opt.to_s.gsub(/_/, '-')}='#{val}'"
109
+ end
110
+ end
111
+ end
112
+ args
113
+ end
114
+ end # Git
115
+
116
+ end # Grit
@@ -0,0 +1,77 @@
1
+ module Grit
2
+
3
+ class Index
4
+ attr_accessor :repo, :tree
5
+
6
+ def initialize(repo)
7
+ self.repo = repo
8
+ self.tree = {}
9
+ end
10
+
11
+ # Add a file to the index
12
+ # +path+ is the path (including filename)
13
+ # +data+ is the binary contents of the file
14
+ #
15
+ # Returns nothing
16
+ def add(file_path, data)
17
+ path = file_path.split('/')
18
+ filename = path.pop
19
+
20
+ current = self.tree
21
+
22
+ path.each do |dir|
23
+ current[dir] ||= {}
24
+ node = current[dir]
25
+ current = node
26
+ end
27
+
28
+ current[filename] = data
29
+ end
30
+
31
+ # Commit the contents of the index
32
+ # +message+ is the commit message
33
+ #
34
+ # Returns a String of the SHA1 of the commit
35
+ def commit(message)
36
+ tree_sha1 = write_tree(self.tree)
37
+
38
+ message = message.gsub("'", "\\'")
39
+ commit_sha1 = self.repo.git.run("echo '#{message}' | ", :commit_tree, '', {}, [tree_sha1])
40
+
41
+ # self.repo.git.update_ref({}, 'HEAD', commit_sha1)
42
+ File.open(File.join(self.repo.path, 'refs', 'heads', 'master'), 'w') do |f|
43
+ f.write(commit_sha1)
44
+ end
45
+
46
+ commit_sha1
47
+ end
48
+
49
+ # Recursively write a tree to the index
50
+ # +tree+ is the tree
51
+ #
52
+ # Returns the SHA1 String of the tree
53
+ def write_tree(tree)
54
+ lstree = []
55
+ tree.each do |k, v|
56
+ case v
57
+ when String:
58
+ lstree << "100644 blob #{write_blob(v)}\t#{k}"
59
+ when Hash:
60
+ lstree << "040000 tree #{write_tree(v)}\t#{k}"
61
+ end
62
+ end
63
+
64
+ lstree_string = lstree.join("\n").gsub("'", "\\'")
65
+ self.repo.git.run("echo '#{lstree_string}' | ", :mktree, '', {}, []).chomp
66
+ end
67
+
68
+ # Write the blob to the index
69
+ # +data+ is the data to write
70
+ #
71
+ # Returns the SHA1 String of the blob
72
+ def write_blob(data)
73
+ self.repo.git.run("echo '#{data}' | ", :hash_object, '', {:w => true, :stdin => true}, []).chomp
74
+ end
75
+ end # Index
76
+
77
+ end # Grit
@@ -0,0 +1,31 @@
1
+ ##
2
+ # Allows attributes to be declared as lazy, meaning that they won't be
3
+ # computed until they are asked for.
4
+ #
5
+ # Works by delegating each lazy_reader to a cached lazy_source method.
6
+ #
7
+ # class Person
8
+ # lazy_reader :eyes
9
+ #
10
+ # def lazy_source
11
+ # OpenStruct.new(:eyes => 2)
12
+ # end
13
+ # end
14
+ #
15
+ # >> Person.new.eyes
16
+ # => 2
17
+ #
18
+ module Lazy
19
+ def lazy_reader(*args)
20
+ args.each do |arg|
21
+ ivar = "@#{arg}"
22
+ define_method(arg) do
23
+ val = instance_variable_get(ivar)
24
+ return val if val
25
+ instance_variable_set(ivar, (@lazy_source ||= lazy_source).send(arg))
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ Object.extend Lazy unless Object.ancestors.include? Lazy
@@ -0,0 +1,110 @@
1
+ module Grit
2
+
3
+ class Ref
4
+
5
+ class << self
6
+
7
+ # Find all Refs
8
+ # +repo+ is the Repo
9
+ # +options+ is a Hash of options
10
+ #
11
+ # Returns Grit::Ref[] (baked)
12
+ def find_all(repo, options = {})
13
+ default_options = {:sort => "committerdate",
14
+ :format => "%(refname)%00%(objectname)"}
15
+
16
+ actual_options = default_options.merge(options)
17
+
18
+ output = repo.git.for_each_ref(actual_options, prefix)
19
+
20
+ self.list_from_string(repo, output)
21
+ end
22
+
23
+ # Parse out ref information into an array of baked refs objects
24
+ # +repo+ is the Repo
25
+ # +text+ is the text output from the git command
26
+ #
27
+ # Returns Grit::Ref[] (baked)
28
+ def list_from_string(repo, text)
29
+ refs = []
30
+
31
+ text.split("\n").each do |line|
32
+ refs << self.from_string(repo, line)
33
+ end
34
+
35
+ refs.sort { | x, y | x.name <=> y.name }
36
+ end
37
+
38
+ # Create a new Ref instance from the given string.
39
+ # +repo+ is the Repo
40
+ # +line+ is the formatted head information
41
+ #
42
+ # Format
43
+ # name: [a-zA-Z_/]+
44
+ # <null byte>
45
+ # id: [0-9A-Fa-f]{40}
46
+ #
47
+ # Returns Grit::Ref (baked)
48
+ def from_string(repo, line)
49
+ full_name, id = line.split("\0")
50
+ name = full_name.sub("#{prefix}/", '')
51
+ commit = Commit.create(repo, :id => id)
52
+ self.new(name, commit)
53
+ end
54
+
55
+ protected
56
+
57
+ def prefix
58
+ "refs/#{name.to_s.gsub(/^.*::/, '').downcase}s"
59
+ end
60
+
61
+ end
62
+
63
+ attr_reader :name
64
+ attr_reader :commit
65
+
66
+ # Instantiate a new Head
67
+ # +name+ is the name of the head
68
+ # +commit+ is the Commit that the head points to
69
+ #
70
+ # Returns Grit::Head (baked)
71
+ def initialize(name, commit)
72
+ @name = name
73
+ @commit = commit
74
+ end
75
+
76
+ # Pretty object inspection
77
+ def inspect
78
+ %Q{#<#{self.class.name} "#{@name}">}
79
+ end
80
+ end # Ref
81
+
82
+ # A Head is a named reference to a Commit. Every Head instance contains a name
83
+ # and a Commit object.
84
+ #
85
+ # r = Grit::Repo.new("/path/to/repo")
86
+ # h = r.heads.first
87
+ # h.name # => "master"
88
+ # h.commit # => #<Grit::Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
89
+ # h.commit.id # => "1c09f116cbc2cb4100fb6935bb162daa4723f455"
90
+ class Head < Ref
91
+
92
+ # Get the HEAD revision of the repo.
93
+ # +repo+ is the Repo
94
+ # +options+ is a Hash of options
95
+ #
96
+ # Returns Grit::Head (baked)
97
+ def self.current(repo, options = {})
98
+ head = File.open(File.join(repo.path, 'HEAD')).read.chomp
99
+ if /ref: refs\/heads\/(.*)/.match(head)
100
+ self.new($1, repo.git.rev_parse(options, 'HEAD'))
101
+ end
102
+ end
103
+
104
+ end # Head
105
+
106
+ class Tag < Ref ; end
107
+
108
+ class Remote < Ref ; end
109
+
110
+ end # Grit