grit 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grit might be problematic. Click here for more details.
- data/History.txt +5 -0
- data/Manifest.txt +36 -0
- data/README.txt +201 -0
- data/Rakefile +24 -0
- data/lib/grit.rb +31 -0
- data/lib/grit/actor.rb +36 -0
- data/lib/grit/blob.rb +117 -0
- data/lib/grit/commit.rb +169 -0
- data/lib/grit/diff.rb +57 -0
- data/lib/grit/errors.rb +7 -0
- data/lib/grit/git.rb +64 -0
- data/lib/grit/head.rb +79 -0
- data/lib/grit/lazy.rb +53 -0
- data/lib/grit/repo.rb +185 -0
- data/lib/grit/tree.rb +109 -0
- data/test/fixtures/blame +131 -0
- data/test/fixtures/cat_file_blob +1 -0
- data/test/fixtures/cat_file_blob_size +1 -0
- data/test/fixtures/diff_p +610 -0
- data/test/fixtures/for_each_ref +0 -0
- data/test/fixtures/ls_tree_a +7 -0
- data/test/fixtures/ls_tree_b +2 -0
- data/test/fixtures/rev_list +24 -0
- data/test/fixtures/rev_list_single +7 -0
- data/test/fixtures/rev_parse +1 -0
- data/test/helper.rb +13 -0
- data/test/profile.rb +21 -0
- data/test/suite.rb +6 -0
- data/test/test_actor.rb +35 -0
- data/test/test_blob.rb +74 -0
- data/test/test_commit.rb +64 -0
- data/test/test_git.rb +21 -0
- data/test/test_head.rb +17 -0
- data/test/test_reality.rb +17 -0
- data/test/test_repo.rb +167 -0
- data/test/test_tree.rb +61 -0
- metadata +99 -0
data/lib/grit/commit.rb
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
class Commit
|
4
|
+
include Lazy
|
5
|
+
|
6
|
+
attr_reader :id
|
7
|
+
lazy_reader :parents
|
8
|
+
lazy_reader :tree
|
9
|
+
lazy_reader :author
|
10
|
+
lazy_reader :authored_date
|
11
|
+
lazy_reader :committer
|
12
|
+
lazy_reader :committed_date
|
13
|
+
lazy_reader :message
|
14
|
+
|
15
|
+
# Instantiate a new Commit
|
16
|
+
# +id+ is the id of the commit
|
17
|
+
# +parents+ is an array of commit ids (will be converted into Commit instances)
|
18
|
+
# +tree+ is the correspdonding tree id (will be converted into a Tree object)
|
19
|
+
# +author+ is the author string
|
20
|
+
# +authored_date+ is the authored Time
|
21
|
+
# +committer+ is the committer string
|
22
|
+
# +committed_date+ is the committed Time
|
23
|
+
# +message+ is the first line of the commit message
|
24
|
+
#
|
25
|
+
# Returns Grit::Commit (baked)
|
26
|
+
def initialize(repo, id, parents, tree, author, authored_date, committer, committed_date, message)
|
27
|
+
@repo = repo
|
28
|
+
@id = id
|
29
|
+
@parents = parents.map { |p| Commit.create(repo, :id => p) }
|
30
|
+
@tree = Tree.create(repo, :id => tree)
|
31
|
+
@author = author
|
32
|
+
@authored_date = authored_date
|
33
|
+
@committer = committer
|
34
|
+
@committed_date = committed_date
|
35
|
+
@message = message
|
36
|
+
|
37
|
+
__baked__
|
38
|
+
end
|
39
|
+
|
40
|
+
def id_abbrev
|
41
|
+
@id_abbrev ||= @repo.git.rev_parse({:short => true}, self.id).chomp
|
42
|
+
end
|
43
|
+
|
44
|
+
# Create an unbaked Commit containing just the specified attributes
|
45
|
+
# +repo+ is the Repo
|
46
|
+
# +atts+ is a Hash of instance variable data
|
47
|
+
#
|
48
|
+
# Returns Grit::Commit (unbaked)
|
49
|
+
def self.create(repo, atts)
|
50
|
+
self.allocate.create_initialize(repo, atts)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Initializer for Commit.create
|
54
|
+
# +repo+ is the Repo
|
55
|
+
# +atts+ is a Hash of instance variable data
|
56
|
+
#
|
57
|
+
# Returns Grit::Commit (unbaked)
|
58
|
+
def create_initialize(repo, atts)
|
59
|
+
@repo = nil
|
60
|
+
@id = nil
|
61
|
+
@parents = nil
|
62
|
+
@tree = nil
|
63
|
+
@author = nil
|
64
|
+
@authored_date = nil
|
65
|
+
@committer = nil
|
66
|
+
@committed_date = nil
|
67
|
+
@message = nil
|
68
|
+
@__baked__ = nil
|
69
|
+
|
70
|
+
@repo = repo
|
71
|
+
atts.each do |k, v|
|
72
|
+
instance_variable_set("@#{k}".to_sym, v)
|
73
|
+
end
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
# Use the id of this instance to populate all of the other fields
|
78
|
+
# when any of them are called.
|
79
|
+
#
|
80
|
+
# Returns nil
|
81
|
+
def __bake__
|
82
|
+
temp = self.class.find_all(@repo, @id, {:max_count => 1}).first
|
83
|
+
@parents = temp.parents
|
84
|
+
@tree = temp.tree
|
85
|
+
@author = temp.author
|
86
|
+
@authored_date = temp.authored_date
|
87
|
+
@committer = temp.committer
|
88
|
+
@committed_date = temp.committed_date
|
89
|
+
@message = temp.message
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
|
93
|
+
# Find all commits matching the given criteria.
|
94
|
+
# +repo+ is the Repo
|
95
|
+
# +ref+ is the ref from which to begin (SHA1 or name)
|
96
|
+
# +options+ is a Hash of optional arguments to git
|
97
|
+
# :max_count is the maximum number of commits to fetch
|
98
|
+
# :skip is the number of commits to skip
|
99
|
+
#
|
100
|
+
# Returns Grit::Commit[] (baked)
|
101
|
+
def self.find_all(repo, ref, options = {})
|
102
|
+
allowed_options = [:max_count, :skip]
|
103
|
+
|
104
|
+
default_options = {:pretty => "raw"}
|
105
|
+
actual_options = default_options.merge(options)
|
106
|
+
|
107
|
+
output = repo.git.rev_list(actual_options, ref)
|
108
|
+
|
109
|
+
self.list_from_string(repo, output)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Parse out commit information into an array of baked Commit objects
|
113
|
+
# +repo+ is the Repo
|
114
|
+
# +text+ is the text output from the git command (raw format)
|
115
|
+
#
|
116
|
+
# Returns Grit::Commit[] (baked)
|
117
|
+
def self.list_from_string(repo, text)
|
118
|
+
# remove empty lines
|
119
|
+
lines = text.split("\n").select { |l| !l.strip.empty? }
|
120
|
+
|
121
|
+
commits = []
|
122
|
+
|
123
|
+
while !lines.empty?
|
124
|
+
id = lines.shift.split.last
|
125
|
+
tree = lines.shift.split.last
|
126
|
+
|
127
|
+
parents = []
|
128
|
+
parents << lines.shift.split.last while lines.first =~ /^parent/
|
129
|
+
|
130
|
+
author, authored_date = self.actor(lines.shift)
|
131
|
+
committer, committed_date = self.actor(lines.shift)
|
132
|
+
|
133
|
+
messages = []
|
134
|
+
messages << lines.shift.strip while lines.first =~ /^ {4}/
|
135
|
+
message = messages.first || ''
|
136
|
+
|
137
|
+
commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message)
|
138
|
+
end
|
139
|
+
|
140
|
+
commits
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.diff(repo, id)
|
144
|
+
text = repo.git.diff({:full_index => true}, id)
|
145
|
+
Diff.list_from_string(repo, text)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Convert this Commit to a String which is just the SHA1 id
|
149
|
+
def to_s
|
150
|
+
@id
|
151
|
+
end
|
152
|
+
|
153
|
+
# Pretty object inspection
|
154
|
+
def inspect
|
155
|
+
%Q{#<Grit::Commit "#{@id}">}
|
156
|
+
end
|
157
|
+
|
158
|
+
# private
|
159
|
+
|
160
|
+
# Parse out the actor (author or committer) info
|
161
|
+
#
|
162
|
+
# Returns [String (actor name and email), Time (acted at time)]
|
163
|
+
def self.actor(line)
|
164
|
+
m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
|
165
|
+
[Actor.from_string(actor), Time.at(epoch.to_i)]
|
166
|
+
end
|
167
|
+
end # Commit
|
168
|
+
|
169
|
+
end # Grit
|
data/lib/grit/diff.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
class Diff
|
4
|
+
attr_reader :a_path, :b_path
|
5
|
+
attr_reader :a_commit, :b_commit
|
6
|
+
attr_reader :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, 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
|
+
@mode = mode
|
17
|
+
@new_file = new_file
|
18
|
+
@deleted_file = deleted_file
|
19
|
+
@diff = diff
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.list_from_string(repo, text)
|
23
|
+
lines = text.split("\n")
|
24
|
+
|
25
|
+
diffs = []
|
26
|
+
|
27
|
+
while !lines.empty?
|
28
|
+
m, a_path, b_path = *lines.shift.match(%r{^diff --git a/(\S+) b/(\S+)$})
|
29
|
+
|
30
|
+
new_file = false
|
31
|
+
deleted_file = false
|
32
|
+
|
33
|
+
if lines.first =~ /^new file/
|
34
|
+
m, mode = lines.shift.match(/^new file mode (.+)$/)
|
35
|
+
new_file = true
|
36
|
+
elsif lines.first =~ /^deleted file/
|
37
|
+
m, mode = lines.shift.match(/^deleted file mode (.+)$/)
|
38
|
+
deleted_file = true
|
39
|
+
end
|
40
|
+
|
41
|
+
m, a_commit, b_commit, mode = *lines.shift.match(%r{^index ([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+) ?(.+)?$})
|
42
|
+
mode.strip! if mode
|
43
|
+
|
44
|
+
diff_lines = []
|
45
|
+
while lines.first && lines.first !~ /^diff/
|
46
|
+
diff_lines << lines.shift
|
47
|
+
end
|
48
|
+
diff = diff_lines.join("\n")
|
49
|
+
|
50
|
+
diffs << Diff.new(repo, a_path, b_path, a_commit, b_commit, mode, new_file, deleted_file, diff)
|
51
|
+
end
|
52
|
+
|
53
|
+
diffs
|
54
|
+
end
|
55
|
+
end # Diff
|
56
|
+
|
57
|
+
end # Grit
|
data/lib/grit/errors.rb
ADDED
data/lib/grit/git.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
class Git
|
4
|
+
class << self
|
5
|
+
attr_accessor :git_binary
|
6
|
+
end
|
7
|
+
|
8
|
+
self.git_binary = "/usr/bin/env git"
|
9
|
+
|
10
|
+
attr_accessor :git_dir
|
11
|
+
|
12
|
+
def initialize(git_dir)
|
13
|
+
self.git_dir = git_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
# Run the given git command with the specified arguments and return
|
17
|
+
# the result as a String
|
18
|
+
# +cmd+ is the command
|
19
|
+
# +options+ is a hash of Ruby style options
|
20
|
+
# +args+ is the list of arguments (to be joined by spaces)
|
21
|
+
#
|
22
|
+
# Examples
|
23
|
+
# git.rev_list({:max_count => 10, :header => true}, "master")
|
24
|
+
#
|
25
|
+
# Returns String
|
26
|
+
def method_missing(cmd, options = {}, *args)
|
27
|
+
opt_args = transform_options(options)
|
28
|
+
|
29
|
+
call = "#{Git.git_binary} --git-dir='#{self.git_dir}' #{cmd.to_s.gsub(/_/, '-')} #{(opt_args + args).join(' ')}"
|
30
|
+
puts call if Grit.debug
|
31
|
+
response = `#{call}`
|
32
|
+
puts response if Grit.debug
|
33
|
+
response
|
34
|
+
end
|
35
|
+
|
36
|
+
# Transform Ruby style options into git command line options
|
37
|
+
# +options+ is a hash of Ruby style options
|
38
|
+
#
|
39
|
+
# Returns String[]
|
40
|
+
# e.g. ["--max-count=10", "--header"]
|
41
|
+
def transform_options(options)
|
42
|
+
args = []
|
43
|
+
options.keys.each do |opt|
|
44
|
+
if opt.to_s.size == 1
|
45
|
+
if options[opt] == true
|
46
|
+
args << "-#{opt}"
|
47
|
+
else
|
48
|
+
val = options.delete(opt)
|
49
|
+
args << "-#{opt.to_s} #{val}"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
if options[opt] == true
|
53
|
+
args << "--#{opt.to_s.gsub(/_/, '-')}"
|
54
|
+
else
|
55
|
+
val = options.delete(opt)
|
56
|
+
args << "--#{opt.to_s.gsub(/_/, '-')}=#{val}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
args
|
61
|
+
end
|
62
|
+
end # Git
|
63
|
+
|
64
|
+
end # Grit
|
data/lib/grit/head.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
# A Head is a named reference to a Commit. Every Head instance contains a name
|
4
|
+
# and a Commit object.
|
5
|
+
#
|
6
|
+
# r = Grit::Repo.new("/path/to/repo")
|
7
|
+
# h = r.heads.first
|
8
|
+
# h.name # => "master"
|
9
|
+
# h.commit # => #<Grit::Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
|
10
|
+
# h.commit.id # => "1c09f116cbc2cb4100fb6935bb162daa4723f455"
|
11
|
+
class Head
|
12
|
+
attr_reader :name
|
13
|
+
attr_reader :commit
|
14
|
+
|
15
|
+
# Instantiate a new Head
|
16
|
+
# +name+ is the name of the head
|
17
|
+
# +commit+ is the Commit that the head points to
|
18
|
+
#
|
19
|
+
# Returns Grit::Head (baked)
|
20
|
+
def initialize(name, commit)
|
21
|
+
@name = name
|
22
|
+
@commit = commit
|
23
|
+
end
|
24
|
+
|
25
|
+
# Find all Heads
|
26
|
+
# +repo+ is the Repo
|
27
|
+
# +options+ is a Hash of options
|
28
|
+
#
|
29
|
+
# Returns Grit::Head[] (baked)
|
30
|
+
def self.find_all(repo, options = {})
|
31
|
+
default_options = {:sort => "committerdate",
|
32
|
+
:format => "'%(refname)%00%(objectname)'"}
|
33
|
+
|
34
|
+
actual_options = default_options.merge(options)
|
35
|
+
|
36
|
+
output = repo.git.for_each_ref(actual_options, "refs/heads")
|
37
|
+
|
38
|
+
Head.list_from_string(repo, output)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Parse out head information into an array of baked head objects
|
42
|
+
# +repo+ is the Repo
|
43
|
+
# +text+ is the text output from the git command
|
44
|
+
#
|
45
|
+
# Returns Grit::Head[] (baked)
|
46
|
+
def self.list_from_string(repo, text)
|
47
|
+
heads = []
|
48
|
+
|
49
|
+
text.split("\n").each do |line|
|
50
|
+
heads << self.from_string(repo, line)
|
51
|
+
end
|
52
|
+
|
53
|
+
heads
|
54
|
+
end
|
55
|
+
|
56
|
+
# Create a new Head instance from the given string.
|
57
|
+
# +repo+ is the Repo
|
58
|
+
# +line+ is the formatted head information
|
59
|
+
#
|
60
|
+
# Format
|
61
|
+
# name: [a-zA-Z_/]+
|
62
|
+
# <null byte>
|
63
|
+
# id: [0-9A-Fa-f]{40}
|
64
|
+
#
|
65
|
+
# Returns Grit::Head (baked)
|
66
|
+
def self.from_string(repo, line)
|
67
|
+
full_name, id = line.split("\0")
|
68
|
+
name = full_name.split("/").last
|
69
|
+
commit = Commit.create(repo, :id => id)
|
70
|
+
self.new(name, commit)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Pretty object inspection
|
74
|
+
def inspect
|
75
|
+
%Q{#<Grit::Head "#{@name}">}
|
76
|
+
end
|
77
|
+
end # Head
|
78
|
+
|
79
|
+
end # Grit
|
data/lib/grit/lazy.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Allows attributes to be declared as lazy, meaning that they won't be
|
2
|
+
# computed until they are asked for. Just mix this module in:
|
3
|
+
#
|
4
|
+
# class Foo
|
5
|
+
# include Lazy
|
6
|
+
# ...
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# To specify a lazy reader:
|
10
|
+
#
|
11
|
+
# lazy_reader :att
|
12
|
+
#
|
13
|
+
# Then, define a method called __bake__ that computes all your lazy
|
14
|
+
# attributes:
|
15
|
+
#
|
16
|
+
# def __bake__
|
17
|
+
# @att = ...
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# If you happen to have already done all the hard work, you can mark an instance
|
21
|
+
# as already baked by calling:
|
22
|
+
#
|
23
|
+
# __baked__
|
24
|
+
#
|
25
|
+
# That's it! (Tom Preston-Werner: rubyisawesome.com)
|
26
|
+
module Lazy
|
27
|
+
module ClassMethods
|
28
|
+
def lazy_reader(*args)
|
29
|
+
args.each do |arg|
|
30
|
+
define_method(arg) do
|
31
|
+
val = instance_variable_get("@#{arg}")
|
32
|
+
return val if val
|
33
|
+
self.__prebake__
|
34
|
+
instance_variable_get("@#{arg}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def __prebake__
|
41
|
+
return if @__baked__
|
42
|
+
self.__bake__
|
43
|
+
@__baked__ = true
|
44
|
+
end
|
45
|
+
|
46
|
+
def __baked__
|
47
|
+
@__baked__ = true
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.included(base)
|
51
|
+
base.extend(ClassMethods)
|
52
|
+
end
|
53
|
+
end
|
data/lib/grit/repo.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
class Repo
|
4
|
+
# The path of the git repo as a String
|
5
|
+
attr_accessor :path
|
6
|
+
attr_reader :bare
|
7
|
+
|
8
|
+
# The git command line interface object
|
9
|
+
attr_accessor :git
|
10
|
+
|
11
|
+
# Create a new Repo instance
|
12
|
+
# +path+ is the path to either the root git directory or the bare git repo
|
13
|
+
#
|
14
|
+
# Examples
|
15
|
+
# g = Repo.new("/Users/tom/dev/grit")
|
16
|
+
# g = Repo.new("/Users/tom/public/grit.git")
|
17
|
+
#
|
18
|
+
# Returns Grit::Repo
|
19
|
+
def initialize(path)
|
20
|
+
epath = File.expand_path(path)
|
21
|
+
|
22
|
+
if File.exist?(File.join(epath, '.git'))
|
23
|
+
self.path = File.join(epath, '.git')
|
24
|
+
@bare = false
|
25
|
+
elsif File.exist?(epath) && epath =~ /\.git$/
|
26
|
+
self.path = epath
|
27
|
+
@bare = true
|
28
|
+
elsif File.exist?(epath)
|
29
|
+
raise InvalidGitRepositoryError.new(epath)
|
30
|
+
else
|
31
|
+
raise NoSuchPathError.new(epath)
|
32
|
+
end
|
33
|
+
|
34
|
+
self.git = Git.new(self.path)
|
35
|
+
end
|
36
|
+
|
37
|
+
# The project's description. Taken verbatim from GIT_REPO/description
|
38
|
+
#
|
39
|
+
# Returns String
|
40
|
+
def description
|
41
|
+
File.open(File.join(self.path, 'description')).read.chomp
|
42
|
+
end
|
43
|
+
|
44
|
+
# An array of Head objects representing the branch heads in
|
45
|
+
# this repo
|
46
|
+
#
|
47
|
+
# Returns Grit::Head[] (baked)
|
48
|
+
def heads
|
49
|
+
Head.find_all(self)
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :branches, :heads
|
53
|
+
|
54
|
+
# An array of Commit objects representing the history of a given ref/commit
|
55
|
+
# +start+ is the branch/commit name (default 'master')
|
56
|
+
# +max_count+ is the maximum number of commits to return (default 10)
|
57
|
+
# +skip+ is the number of commits to skip (default 0)
|
58
|
+
#
|
59
|
+
# Returns Grit::Commit[] (baked)
|
60
|
+
def commits(start = 'master', max_count = 10, skip = 0)
|
61
|
+
options = {:max_count => max_count,
|
62
|
+
:skip => skip}
|
63
|
+
|
64
|
+
Commit.find_all(self, start, options)
|
65
|
+
end
|
66
|
+
|
67
|
+
# The Commit object for the specified id
|
68
|
+
# +id+ is the SHA1 identifier of the commit
|
69
|
+
#
|
70
|
+
# Returns Grit::Commit (baked)
|
71
|
+
def commit(id)
|
72
|
+
options = {:max_count => 1}
|
73
|
+
|
74
|
+
Commit.find_all(self, id, options).first
|
75
|
+
end
|
76
|
+
|
77
|
+
# The Tree object for the given treeish reference
|
78
|
+
# +treeish+ is the reference (default 'master')
|
79
|
+
# +paths+ is an optional Array of directory paths to restrict the tree (deafult [])
|
80
|
+
#
|
81
|
+
# Examples
|
82
|
+
# Repo.tree('master', ['lib/'])
|
83
|
+
#
|
84
|
+
# Returns Grit::Tree (baked)
|
85
|
+
def tree(treeish = 'master', paths = [])
|
86
|
+
Tree.construct(self, treeish, paths)
|
87
|
+
end
|
88
|
+
|
89
|
+
# The Blob object for the given id
|
90
|
+
# +id+ is the SHA1 id of the blob
|
91
|
+
#
|
92
|
+
# Returns Grit::Blob (unbaked)
|
93
|
+
def blob(id)
|
94
|
+
Blob.create(self, :id => id)
|
95
|
+
end
|
96
|
+
|
97
|
+
# The commit log for a treeish
|
98
|
+
#
|
99
|
+
# Returns Grit::Commit[]
|
100
|
+
def log(commit = 'master', path = nil, options = {})
|
101
|
+
default_options = {:pretty => "raw"}
|
102
|
+
actual_options = default_options.merge(options)
|
103
|
+
arg = path ? "#{commit} -- #{path}" : commit
|
104
|
+
commits = self.git.log(actual_options, arg)
|
105
|
+
Commit.list_from_string(self, commits)
|
106
|
+
end
|
107
|
+
|
108
|
+
# The diff from commit +a+ to commit +b+, optionally restricted to the given file(s)
|
109
|
+
# +a+ is the base commit
|
110
|
+
# +b+ is the other commit
|
111
|
+
# +paths+ is an optional list of file paths on which to restrict the diff
|
112
|
+
def diff(a, b, *paths)
|
113
|
+
self.git.diff({}, a, b, '--', *paths)
|
114
|
+
end
|
115
|
+
|
116
|
+
# The commit diff for the given commit
|
117
|
+
# +commit+ is the commit name/id
|
118
|
+
#
|
119
|
+
# Returns Grit::Diff[]
|
120
|
+
def commit_diff(commit)
|
121
|
+
Commit.diff(self, commit)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Initialize a bare git repository at the given path
|
125
|
+
# +path+ is the full path to the repo (traditionally ends with /<name>.git)
|
126
|
+
#
|
127
|
+
# Examples
|
128
|
+
# Grit::Repo.init_bare('/var/git/myrepo.git')
|
129
|
+
#
|
130
|
+
# Returns Grit::Repo (the newly created repo)
|
131
|
+
def self.init_bare(path)
|
132
|
+
git = Git.new(path)
|
133
|
+
git.init
|
134
|
+
self.new(path)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Archive the given treeish
|
138
|
+
# +treeish+ is the treeish name/id (default 'master')
|
139
|
+
# +prefix+ is the optional prefix
|
140
|
+
#
|
141
|
+
# Examples
|
142
|
+
# repo.archive_tar
|
143
|
+
# # => <String containing tar archive>
|
144
|
+
#
|
145
|
+
# repo.archive_tar('a87ff14')
|
146
|
+
# # => <String containing tar archive for commit a87ff14>
|
147
|
+
#
|
148
|
+
# repo.archive_tar('master', 'myproject/')
|
149
|
+
# # => <String containing tar archive and prefixed with 'myproject/'>
|
150
|
+
#
|
151
|
+
# Returns String (containing tar archive)
|
152
|
+
def archive_tar(treeish = 'master', prefix = nil)
|
153
|
+
options = {}
|
154
|
+
options[:prefix] = prefix if prefix
|
155
|
+
self.git.archive(options, treeish)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Archive and gzip the given treeish
|
159
|
+
# +treeish+ is the treeish name/id (default 'master')
|
160
|
+
# +prefix+ is the optional prefix
|
161
|
+
#
|
162
|
+
# Examples
|
163
|
+
# repo.archive_tar_gz
|
164
|
+
# # => <String containing tar.gz archive>
|
165
|
+
#
|
166
|
+
# repo.archive_tar_gz('a87ff14')
|
167
|
+
# # => <String containing tar.gz archive for commit a87ff14>
|
168
|
+
#
|
169
|
+
# repo.archive_tar_gz('master', 'myproject/')
|
170
|
+
# # => <String containing tar.gz archive and prefixed with 'myproject/'>
|
171
|
+
#
|
172
|
+
# Returns String (containing tar.gz archive)
|
173
|
+
def archive_tar_gz(treeish = 'master', prefix = nil)
|
174
|
+
options = {}
|
175
|
+
options[:prefix] = prefix if prefix
|
176
|
+
self.git.archive(options, treeish, "| gzip")
|
177
|
+
end
|
178
|
+
|
179
|
+
# Pretty object inspection
|
180
|
+
def inspect
|
181
|
+
%Q{#<Grit::Repo "#{@path}">}
|
182
|
+
end
|
183
|
+
end # Repo
|
184
|
+
|
185
|
+
end # Grit
|