tekkub-fugit 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +19 -0
- data/VERSION.yml +3 -3
- data/bin/fugit +0 -0
- data/lib/fugit/commit_dialog.rb +6 -9
- data/lib/fugit/commit_tab.rb +1 -1
- data/lib/fugit/create_branch_dialog.rb +65 -0
- data/lib/fugit/delete_branch_dialog.rb +1 -1
- data/lib/fugit/fetch_dialog.rb +52 -0
- data/lib/fugit/history_list.rb +16 -12
- data/lib/fugit/history_tab.rb +3 -0
- data/lib/fugit/index_list.rb +8 -3
- data/lib/fugit/io_get_line.rb +4 -4
- data/lib/fugit/logged_dialog.rb +49 -0
- data/lib/fugit/main_frame.rb +16 -1
- data/lib/fugit/merge_dialog.rb +68 -0
- data/lib/fugit/push_dialog.rb +11 -61
- data/lib/fugit/revert_commit_dialog.rb +51 -0
- data/lib/fugit/run_command_dialog.rb +40 -0
- data/lib/fugit/tab_toolbar.rb +145 -0
- data/lib/fugit.rb +19 -1
- data/lib/grit/API.txt +101 -0
- data/lib/grit/History.txt +28 -0
- data/lib/grit/PURE_TODO +35 -0
- data/lib/grit/README.txt +222 -0
- data/lib/grit/Rakefile +54 -0
- data/lib/grit/VERSION.yml +4 -0
- data/lib/grit/benchmarks.rb +129 -0
- data/lib/grit/benchmarks.txt +21 -0
- data/lib/grit/examples/ex_add_commit.rb +13 -0
- data/lib/grit/examples/ex_index.rb +14 -0
- data/lib/grit/grit.gemspec +36 -0
- data/lib/grit/lib/grit/actor.rb +36 -0
- data/lib/grit/lib/grit/blame.rb +61 -0
- data/lib/grit/lib/grit/blob.rb +117 -0
- data/lib/grit/lib/grit/commit.rb +238 -0
- data/lib/grit/lib/grit/commit_stats.rb +104 -0
- data/lib/grit/lib/grit/config.rb +44 -0
- data/lib/grit/lib/grit/diff.rb +70 -0
- data/lib/grit/lib/grit/errors.rb +7 -0
- data/lib/grit/lib/grit/git-ruby/commit_db.rb +52 -0
- data/lib/grit/lib/grit/git-ruby/file_index.rb +193 -0
- data/lib/grit/lib/grit/git-ruby/git_object.rb +344 -0
- data/lib/grit/lib/grit/git-ruby/internal/loose.rb +137 -0
- data/lib/grit/lib/grit/git-ruby/internal/mmap.rb +58 -0
- data/lib/grit/lib/grit/git-ruby/internal/pack.rb +382 -0
- data/lib/grit/lib/grit/git-ruby/internal/raw_object.rb +37 -0
- data/lib/grit/lib/grit/git-ruby/object.rb +319 -0
- data/lib/grit/lib/grit/git-ruby/repository.rb +736 -0
- data/lib/grit/lib/grit/git-ruby.rb +186 -0
- data/lib/grit/lib/grit/git.rb +141 -0
- data/lib/grit/lib/grit/index.rb +122 -0
- data/lib/grit/lib/grit/lazy.rb +33 -0
- data/lib/grit/lib/grit/merge.rb +45 -0
- data/lib/grit/lib/grit/ref.rb +99 -0
- data/lib/grit/lib/grit/repo.rb +441 -0
- data/lib/grit/lib/grit/status.rb +151 -0
- data/lib/grit/lib/grit/submodule.rb +84 -0
- data/lib/grit/lib/grit/tag.rb +66 -0
- data/lib/grit/lib/grit/tree.rb +104 -0
- data/lib/grit/lib/grit.rb +71 -0
- data/lib/grit/lib/open3_detach.rb +46 -0
- data/lib/icons/application_go.png +0 -0
- data/lib/icons/arrow_divide_add.png +0 -0
- data/lib/icons/arrow_refresh.png +0 -0
- data/lib/icons/cross.png +0 -0
- metadata +56 -10
- data/fugit.gemspec +0 -32
- data/lib/fugit/commit_tab_toolbar.rb +0 -111
@@ -0,0 +1,40 @@
|
|
1
|
+
include Wx
|
2
|
+
|
3
|
+
module Fugit
|
4
|
+
class RunCommandDialog < Dialog
|
5
|
+
def initialize(parent)
|
6
|
+
super(parent, ID_ANY, "Run command", :size => Size.new(300, 100))
|
7
|
+
|
8
|
+
@cmd = TextCtrl.new(self, ID_ANY)
|
9
|
+
|
10
|
+
butt_sizer = create_button_sizer(OK|CANCEL)
|
11
|
+
butt_sizer.get_children.map {|s| s.get_window}.compact.each {|b| b.set_label("Run") if b.get_label == "OK"}
|
12
|
+
evt_button(get_affirmative_id, :on_ok)
|
13
|
+
|
14
|
+
box = BoxSizer.new(VERTICAL)
|
15
|
+
box.add(StaticText.new(self, ID_ANY, "Command:"), 0, EXPAND|ALL, 4)
|
16
|
+
box.add(@cmd, 0, EXPAND|LEFT|RIGHT|BOTTOM, 4)
|
17
|
+
box.add(butt_sizer, 0, EXPAND|BOTTOM, 4)
|
18
|
+
|
19
|
+
self.set_sizer(box)
|
20
|
+
end
|
21
|
+
|
22
|
+
def show()
|
23
|
+
@cmd.set_value("")
|
24
|
+
|
25
|
+
super()
|
26
|
+
@cmd.set_focus
|
27
|
+
end
|
28
|
+
|
29
|
+
def on_ok
|
30
|
+
command = @cmd.get_value
|
31
|
+
|
32
|
+
end_modal(ID_OK)
|
33
|
+
|
34
|
+
@log_dialog ||= LoggedDialog.new(self, "Run command")
|
35
|
+
@log_dialog.show
|
36
|
+
@log_dialog.run_command(command)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
include Wx
|
2
|
+
include IconLoader
|
3
|
+
|
4
|
+
module Fugit
|
5
|
+
class TabToolbar < ToolBar
|
6
|
+
def initialize(parent, is_commit_bar = true)
|
7
|
+
super(parent, ID_ANY, nil, nil, TB_HORIZONTAL|NO_BORDER|TB_NODIVIDER)
|
8
|
+
|
9
|
+
self.set_tool_bitmap_size(Size.new(16,16))
|
10
|
+
|
11
|
+
if is_commit_bar
|
12
|
+
stage_all_button = self.add_tool(ID_ANY, "Stage all", get_icon("folder_add.png"), "Stage all")
|
13
|
+
evt_tool(stage_all_button, :on_stage_all_clicked)
|
14
|
+
|
15
|
+
stage_button = self.add_tool(ID_ANY, "Stage", get_icon("page_add.png"), "Stage changed files")
|
16
|
+
evt_tool(stage_button, :on_stage_changed_clicked)
|
17
|
+
|
18
|
+
unstage_all_button = self.add_tool(ID_ANY, "Unstage all", get_icon("folder_delete.png"), "Unstage all")
|
19
|
+
evt_tool(unstage_all_button, :on_unstage_all_clicked)
|
20
|
+
|
21
|
+
self.add_separator
|
22
|
+
|
23
|
+
commit = self.add_tool(ID_ANY, "Commit", get_icon("disk.png"), "Commit")
|
24
|
+
evt_tool(commit, :on_commit_clicked)
|
25
|
+
end
|
26
|
+
|
27
|
+
refresh = self.add_tool(ID_ANY, "Refresh", get_icon("arrow_refresh.png"), "Refresh")
|
28
|
+
evt_tool(refresh, :on_refresh_clicked)
|
29
|
+
|
30
|
+
self.add_separator
|
31
|
+
|
32
|
+
push = self.add_tool(ID_ANY, "Push", get_icon("page_up.gif"), "Push")
|
33
|
+
evt_tool(push, :on_push_clicked)
|
34
|
+
|
35
|
+
fetch = self.add_tool(ID_ANY, "Fetch", get_icon("page_down.gif"), "Fetch")
|
36
|
+
evt_tool(fetch, :on_fetch_clicked)
|
37
|
+
|
38
|
+
self.add_separator
|
39
|
+
|
40
|
+
self.add_control(@branch = Choice.new(self, ID_ANY))
|
41
|
+
set_branches
|
42
|
+
evt_choice(@branch, :on_branch_choice)
|
43
|
+
|
44
|
+
create_branch_button = self.add_tool(ID_ANY, "Create branch", get_icon("arrow_divide_add.png"), "Create branch")
|
45
|
+
evt_tool(create_branch_button, :on_create_branch_clicked)
|
46
|
+
|
47
|
+
merge_branch_button = self.add_tool(ID_ANY, "Merge branch", get_icon("arrow_join.png"), "Merge branch")
|
48
|
+
evt_tool(merge_branch_button, :on_merge_branch_clicked)
|
49
|
+
|
50
|
+
delete_branch_button = self.add_tool(ID_ANY, "Delete branch", get_icon("arrow_divide_delete.png"), "Delete branch")
|
51
|
+
evt_tool(delete_branch_button, :on_delete_branch_clicked)
|
52
|
+
|
53
|
+
self.add_separator
|
54
|
+
|
55
|
+
run_command_button = self.add_tool(ID_ANY, "Run command", get_icon("application_go.png"), "Run command")
|
56
|
+
evt_tool(run_command_button, :on_run_command_clicked)
|
57
|
+
|
58
|
+
self.realize
|
59
|
+
|
60
|
+
register_for_message(:tab_switch, :update_tools)
|
61
|
+
register_for_message(:branch_created, :update_tools)
|
62
|
+
register_for_message(:branch_deleted, :update_tools)
|
63
|
+
register_for_message(:refresh, :update_tools)
|
64
|
+
register_for_message(:save_clicked, :on_commit_clicked)
|
65
|
+
register_for_message(:push_clicked, :on_push_clicked)
|
66
|
+
end
|
67
|
+
|
68
|
+
def update_tools
|
69
|
+
return unless is_shown_on_screen
|
70
|
+
set_branches
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_branches
|
74
|
+
@branch.clear
|
75
|
+
repo.branches.each {|b| @branch.append(b.name)}
|
76
|
+
@branch.set_string_selection(repo.head.name)
|
77
|
+
end
|
78
|
+
|
79
|
+
def on_stage_all_clicked(event)
|
80
|
+
repo.add_all
|
81
|
+
send_message(:index_changed)
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_stage_changed_clicked(event)
|
85
|
+
repo.add_updated
|
86
|
+
send_message(:index_changed)
|
87
|
+
end
|
88
|
+
|
89
|
+
def on_unstage_all_clicked(event)
|
90
|
+
repo.reset_all
|
91
|
+
send_message(:index_changed)
|
92
|
+
end
|
93
|
+
|
94
|
+
def on_commit_clicked
|
95
|
+
@commit_dialog ||= CommitDialog.new(self)
|
96
|
+
send_message(:commit_saved) if @commit_dialog.show_modal == ID_OK
|
97
|
+
end
|
98
|
+
|
99
|
+
def on_refresh_clicked
|
100
|
+
send_message(:refresh)
|
101
|
+
end
|
102
|
+
|
103
|
+
def on_push_clicked
|
104
|
+
@push_dialog ||= PushDialog.new(self)
|
105
|
+
@push_dialog.show
|
106
|
+
end
|
107
|
+
|
108
|
+
def on_fetch_clicked
|
109
|
+
@fetch_dialog ||= FetchDialog.new(self)
|
110
|
+
@fetch_dialog.show
|
111
|
+
end
|
112
|
+
|
113
|
+
def on_branch_choice(event)
|
114
|
+
branch = @branch.get_string(event.get_selection)
|
115
|
+
success, err = repo.checkout(branch)
|
116
|
+
if success
|
117
|
+
send_message(:branch_checkout)
|
118
|
+
else
|
119
|
+
MessageDialog.new(self, err, "Branch checkout error", OK|ICON_ERROR).show_modal
|
120
|
+
@branch.set_string_selection(repo.head.name)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def on_create_branch_clicked
|
125
|
+
@create_branch_dialog ||= CreateBranchDialog.new(self)
|
126
|
+
@create_branch_dialog.show
|
127
|
+
end
|
128
|
+
|
129
|
+
def on_delete_branch_clicked
|
130
|
+
@delete_branch_dialog ||= DeleteBranchDialog.new(self)
|
131
|
+
@delete_branch_dialog.show
|
132
|
+
end
|
133
|
+
|
134
|
+
def on_merge_branch_clicked
|
135
|
+
@merge_branch_dialog ||= MergeDialog.new(self)
|
136
|
+
@merge_branch_dialog.show
|
137
|
+
end
|
138
|
+
|
139
|
+
def on_run_command_clicked
|
140
|
+
@run_command_dialog ||= RunCommandDialog.new(self)
|
141
|
+
@run_command_dialog.show
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
data/lib/fugit.rb
CHANGED
@@ -1,25 +1,43 @@
|
|
1
1
|
|
2
2
|
$:.unshift File.dirname(__FILE__)
|
3
3
|
|
4
|
+
require "rubygems"
|
5
|
+
|
4
6
|
require 'wx'
|
7
|
+
require "grit/lib/grit"
|
5
8
|
|
6
9
|
require "fugit/icon_loader"
|
7
10
|
|
8
11
|
require "fugit/commit_dialog"
|
9
12
|
require "fugit/commit_tab"
|
10
|
-
require "fugit/commit_tab_toolbar"
|
11
13
|
require "fugit/console"
|
14
|
+
require "fugit/create_branch_dialog"
|
12
15
|
require "fugit/delete_branch_dialog"
|
13
16
|
require "fugit/diff"
|
17
|
+
require "fugit/fetch_dialog"
|
14
18
|
require "fugit/graph_renderer"
|
15
19
|
require "fugit/history_list"
|
16
20
|
require "fugit/history_tab"
|
17
21
|
require "fugit/index_list"
|
18
22
|
require "fugit/io_get_line"
|
23
|
+
require "fugit/logged_dialog"
|
19
24
|
require "fugit/main_frame"
|
25
|
+
require "fugit/merge_dialog"
|
20
26
|
require "fugit/messages"
|
21
27
|
require "fugit/push_dialog"
|
28
|
+
require "fugit/revert_commit_dialog"
|
29
|
+
require "fugit/run_command_dialog"
|
30
|
+
require "fugit/tab_toolbar"
|
31
|
+
|
22
32
|
|
33
|
+
unless Wx::MenuItem.method_defined?("set_bitmap")
|
34
|
+
module Wx
|
35
|
+
class MenuItem
|
36
|
+
def set_bitmap(a=nil)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
23
41
|
|
24
42
|
version = File.exist?(File.join(File.dirname(__FILE__), "..", ".git")) ? "Developer's alpha" : Gem.searcher.find("fugit").version.to_s rescue "Unknown"
|
25
43
|
|
data/lib/grit/API.txt
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
== TODO ==
|
2
|
+
|
3
|
+
* Add remote branch references (Grit::Remote)
|
4
|
+
* Add status - what is modified, staged
|
5
|
+
|
6
|
+
g.checkout('new_branch')
|
7
|
+
g.checkout(g.branch('new_branch'))
|
8
|
+
|
9
|
+
g.branch(name).merge(branch2)
|
10
|
+
g.branch(branch2).merge # merges HEAD with branch2
|
11
|
+
|
12
|
+
g.branch(name).in_branch(message) { # add files } # auto-commits
|
13
|
+
g.merge('new_branch')
|
14
|
+
g.merge('origin/remote_branch')
|
15
|
+
g.merge(b.branch('master'))
|
16
|
+
g.merge([branch1, branch2])
|
17
|
+
|
18
|
+
r = g.add_remote(name, uri) # Git::Remote
|
19
|
+
r = g.add_remote(name, Git::Base) # Git::Remote
|
20
|
+
|
21
|
+
g.remotes # array of Git::Remotes
|
22
|
+
g.remote(name).fetch
|
23
|
+
g.remote(name).remove
|
24
|
+
g.remote(name).merge
|
25
|
+
g.remote(name).merge(branch)
|
26
|
+
|
27
|
+
g.fetch
|
28
|
+
g.fetch(g.remotes.first)
|
29
|
+
|
30
|
+
g.pull
|
31
|
+
g.pull(Git::Repo, Git::Branch) # fetch and a merge
|
32
|
+
|
33
|
+
g.add_tag('tag_name') # returns Git::Tag
|
34
|
+
|
35
|
+
g.repack
|
36
|
+
|
37
|
+
g.push
|
38
|
+
g.push(g.remote('name'))
|
39
|
+
|
40
|
+
g.reset # defaults to HEAD
|
41
|
+
g.reset_hard(Git::Commit)
|
42
|
+
|
43
|
+
g.branch('new_branch') # creates new or fetches existing
|
44
|
+
g.branch('new_branch').checkout
|
45
|
+
g.branch('new_branch').delete
|
46
|
+
g.branch('existing_branch').checkout
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
require 'mojombo-grit'
|
53
|
+
|
54
|
+
include Grit
|
55
|
+
Grit.debug
|
56
|
+
Grit.use_pure_ruby
|
57
|
+
|
58
|
+
repo = Repo.new("/Users/tom/dev/grit")
|
59
|
+
|
60
|
+
= Commit Log
|
61
|
+
|
62
|
+
repo.commits('mybranch')
|
63
|
+
repo.commits('40d3057d09a7a4d61059bca9dca5ae698de58cbe')
|
64
|
+
repo.commits('v0.1')
|
65
|
+
|
66
|
+
repo.log('mybranch', 100, 20)
|
67
|
+
|
68
|
+
head = repo.commits.first
|
69
|
+
head.id
|
70
|
+
# => "e80bbd2ce67651aa18e57fb0b43618ad4baf7750"
|
71
|
+
head.parents
|
72
|
+
# => [#<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">]
|
73
|
+
head.tree
|
74
|
+
# => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f">
|
75
|
+
head.author
|
76
|
+
# => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
|
77
|
+
head.authored_date
|
78
|
+
# => Wed Oct 24 22:02:31 -0700 2007
|
79
|
+
head.committer
|
80
|
+
# => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
|
81
|
+
head.committed_date
|
82
|
+
# => Wed Oct 24 22:02:31 -0700 2007
|
83
|
+
head.message
|
84
|
+
# => "add Actor inspect"
|
85
|
+
contents = tree.contents
|
86
|
+
# => [#<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">,
|
87
|
+
#<Grit::Blob "81d2c27608b352814cbe979a6acd678d30219678">,
|
88
|
+
#<Grit::Tree "c3d07b0083f01a6e1ac969a0f32b8d06f20c62e5">,
|
89
|
+
#<Grit::Tree "4d00fe177a8407dbbc64a24dbfc564762c0922d8">]
|
90
|
+
blob.id
|
91
|
+
# => "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666"
|
92
|
+
blob.name
|
93
|
+
# => "README.txt"
|
94
|
+
blob.mode
|
95
|
+
# => "100644"
|
96
|
+
blob.size
|
97
|
+
# => 7726
|
98
|
+
blob.data
|
99
|
+
|
100
|
+
repo.blob("4ebc8aea50e0a67e000ba29a30809d0a7b9b2666")
|
101
|
+
# => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== 1.0.3 / 2009-02-13
|
2
|
+
* Minor Enhancements
|
3
|
+
* Added Grit::Commit#to_patch for plaintext formatted patches.
|
4
|
+
* Fixed Grit::Tag to work with annotated tags.
|
5
|
+
|
6
|
+
== 1.0.2 / 2009-02-10
|
7
|
+
* Minor Enhancements
|
8
|
+
* Implement Grit.version to use VERSION.yml file
|
9
|
+
|
10
|
+
== 1.0.1 / 2009-02-10
|
11
|
+
* Bug Fixes
|
12
|
+
* Add diff-lcs as a dependency
|
13
|
+
|
14
|
+
== 1.0.0 / 2009-01-27
|
15
|
+
* Tons of awesome in here. Also, we suck at updating the history.
|
16
|
+
* Let's do better at that from now on.
|
17
|
+
|
18
|
+
== 0.8.3 / 2008-07-07
|
19
|
+
* Capture stderr and log if debug is true (rsanheim)
|
20
|
+
|
21
|
+
== 0.8.2 / 2008-06-27
|
22
|
+
* Allow user provided logger (rsanheim)
|
23
|
+
|
24
|
+
== 0.8.0 / 2008-04-24
|
25
|
+
* Lots of fixes and additions
|
26
|
+
|
27
|
+
== 0.7.0 / 2008-01-07
|
28
|
+
* First public release!
|
data/lib/grit/PURE_TODO
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
This is a listing of all the places I can find that Grit actually does a
|
2
|
+
'git' system call. My goal is to add native Ruby versions of all of them.
|
3
|
+
|
4
|
+
Completed
|
5
|
+
===========================
|
6
|
+
** lib/grit/blob.rb:36: @size ||= @repo.git.cat_file({:s => true}, id).chomp.to_i
|
7
|
+
** lib/grit/blob.rb:43: @data ||= @repo.git.cat_file({:p => true}, id)
|
8
|
+
** lib/grit/tree.rb:16: output = repo.git.ls_tree({}, treeish, *paths)
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
lib/grit/commit.rb:74: repo.git.rev_list({}, ref).strip.split("\n").size
|
13
|
+
lib/grit/commit.rb:92: output = repo.git.rev_list(actual_options, ref)
|
14
|
+
lib/grit/commit.rb:94: output = repo.git.rev_list(actual_options.merge(:all => true))
|
15
|
+
|
16
|
+
|
17
|
+
Next to do
|
18
|
+
===========================
|
19
|
+
lib/grit/tag.rb:28: output = repo.git.for_each_ref(actual_options, "refs/tags")
|
20
|
+
lib/grit/head.rb:37: output = repo.git.for_each_ref(actual_options, HEAD_PREFIX)
|
21
|
+
lib/grit/head.rb:50: self.new($1, repo.git.rev_parse(options, 'HEAD'))
|
22
|
+
lib/grit/config.rb:9: @repo.git.config({}, key, value)
|
23
|
+
lib/grit/config.rb:40: @repo.git.config(:list => true).split(/\n/)
|
24
|
+
|
25
|
+
|
26
|
+
May not be fast enough
|
27
|
+
=============================
|
28
|
+
lib/grit/blob.rb:58: data = repo.git.blame({:p => true}, commit, '--', file)
|
29
|
+
|
30
|
+
|
31
|
+
More Difficult
|
32
|
+
===========================
|
33
|
+
lib/grit/commit.rb:39: @id_abbrev ||= @repo.git.rev_parse({:short => true}, self.id).chomp
|
34
|
+
lib/grit/commit.rb:150: text = repo.git.diff({:full_index => true}, *paths)
|
35
|
+
lib/grit/commit.rb:156: diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
|
data/lib/grit/README.txt
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
grit
|
2
|
+
by Tom Preston-Werner, Scott Chacon
|
3
|
+
http://github.com/mojombo/grit
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Grit is a Ruby library for extracting information from a git repository in an
|
8
|
+
object oriented manner.
|
9
|
+
|
10
|
+
== REQUIREMENTS:
|
11
|
+
|
12
|
+
* git (http://git-scm.com) tested with 1.6.0.2
|
13
|
+
|
14
|
+
== INSTALL:
|
15
|
+
|
16
|
+
Easiest install is via RubyGems:
|
17
|
+
|
18
|
+
$ gem install grit
|
19
|
+
|
20
|
+
or
|
21
|
+
|
22
|
+
$ gem sources -a http://gems.github.com/ (you only need to do this once)
|
23
|
+
$ gem install mojombo-grit
|
24
|
+
|
25
|
+
The gem from GitHub will generally be available sooner than the gem from
|
26
|
+
Rubyforge. Both sources will eventually contain the same releases.
|
27
|
+
|
28
|
+
== SOURCE:
|
29
|
+
|
30
|
+
Grit's git repo is available on GitHub, which can be browsed at:
|
31
|
+
|
32
|
+
http://github.com/mojombo/grit
|
33
|
+
|
34
|
+
and cloned from:
|
35
|
+
|
36
|
+
git://github.com/mojombo/grit.git
|
37
|
+
|
38
|
+
== USAGE:
|
39
|
+
|
40
|
+
Grit gives you object model access to your git repository. Once you have
|
41
|
+
created a repository object, you can traverse it to find parent commit(s),
|
42
|
+
trees, blobs, etc.
|
43
|
+
|
44
|
+
= Initialize a Repo object
|
45
|
+
|
46
|
+
The first step is to create a Grit::Repo object to represent your repo. I
|
47
|
+
include the Grit module so reduce typing.
|
48
|
+
|
49
|
+
require 'grit'
|
50
|
+
include Grit
|
51
|
+
repo = Repo.new("/Users/tom/dev/grit")
|
52
|
+
|
53
|
+
In the above example, the directory /Users/tom/dev/grit is my working
|
54
|
+
repo and contains the .git directory. You can also initialize Grit with a
|
55
|
+
bare repo.
|
56
|
+
|
57
|
+
repo = Repo.new("/var/git/grit.git")
|
58
|
+
|
59
|
+
= Getting a list of commits
|
60
|
+
|
61
|
+
From the Repo object, you can get a list of commits as an array of Commit
|
62
|
+
objects.
|
63
|
+
|
64
|
+
repo.commits
|
65
|
+
# => [#<Grit::Commit "e80bbd2ce67651aa18e57fb0b43618ad4baf7750">,
|
66
|
+
#<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">,
|
67
|
+
#<Grit::Commit "038af8c329ef7c1bae4568b98bd5c58510465493">,
|
68
|
+
#<Grit::Commit "40d3057d09a7a4d61059bca9dca5ae698de58cbe">,
|
69
|
+
#<Grit::Commit "4ea50f4754937bf19461af58ce3b3d24c77311d9">]
|
70
|
+
|
71
|
+
Called without arguments, Repo#commits returns a list of up to ten commits
|
72
|
+
reachable by the master branch (starting at the latest commit). You can ask
|
73
|
+
for commits beginning at a different branch, commit, tag, etc.
|
74
|
+
|
75
|
+
repo.commits('mybranch')
|
76
|
+
repo.commits('40d3057d09a7a4d61059bca9dca5ae698de58cbe')
|
77
|
+
repo.commits('v0.1')
|
78
|
+
|
79
|
+
You can specify the maximum number of commits to return.
|
80
|
+
|
81
|
+
repo.commits('master', 100)
|
82
|
+
|
83
|
+
If you need paging, you can specify a number of commits to skip.
|
84
|
+
|
85
|
+
repo.commits('master', 10, 20)
|
86
|
+
|
87
|
+
The above will return commits 21-30 from the commit list.
|
88
|
+
|
89
|
+
= The Commit object
|
90
|
+
|
91
|
+
Commit objects contain information about that commit.
|
92
|
+
|
93
|
+
head = repo.commits.first
|
94
|
+
|
95
|
+
head.id
|
96
|
+
# => "e80bbd2ce67651aa18e57fb0b43618ad4baf7750"
|
97
|
+
|
98
|
+
head.parents
|
99
|
+
# => [#<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">]
|
100
|
+
|
101
|
+
head.tree
|
102
|
+
# => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f">
|
103
|
+
|
104
|
+
head.author
|
105
|
+
# => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
|
106
|
+
|
107
|
+
head.authored_date
|
108
|
+
# => Wed Oct 24 22:02:31 -0700 2007
|
109
|
+
|
110
|
+
head.committer
|
111
|
+
# => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
|
112
|
+
|
113
|
+
head.committed_date
|
114
|
+
# => Wed Oct 24 22:02:31 -0700 2007
|
115
|
+
|
116
|
+
head.message
|
117
|
+
# => "add Actor inspect"
|
118
|
+
|
119
|
+
You can traverse a commit's ancestry by chaining calls to #parents.
|
120
|
+
|
121
|
+
repo.commits.first.parents[0].parents[0].parents[0]
|
122
|
+
|
123
|
+
The above corresponds to master^^^ or master~3 in git parlance.
|
124
|
+
|
125
|
+
= The Tree object
|
126
|
+
|
127
|
+
A tree records pointers to the contents of a directory. Let's say you want
|
128
|
+
the root tree of the latest commit on the master branch.
|
129
|
+
|
130
|
+
tree = repo.commits.first.tree
|
131
|
+
# => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f">
|
132
|
+
|
133
|
+
tree.id
|
134
|
+
# => "3536eb9abac69c3e4db583ad38f3d30f8db4771f"
|
135
|
+
|
136
|
+
Once you have a tree, you can get the contents.
|
137
|
+
|
138
|
+
contents = tree.contents
|
139
|
+
# => [#<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">,
|
140
|
+
#<Grit::Blob "81d2c27608b352814cbe979a6acd678d30219678">,
|
141
|
+
#<Grit::Tree "c3d07b0083f01a6e1ac969a0f32b8d06f20c62e5">,
|
142
|
+
#<Grit::Tree "4d00fe177a8407dbbc64a24dbfc564762c0922d8">]
|
143
|
+
|
144
|
+
This tree contains two Blob objects and two Tree objects. The trees are
|
145
|
+
subdirectories and the blobs are files. Trees below the root have additional
|
146
|
+
attributes.
|
147
|
+
|
148
|
+
contents.last.name
|
149
|
+
# => "lib"
|
150
|
+
|
151
|
+
contents.last.mode
|
152
|
+
# => "040000"
|
153
|
+
|
154
|
+
There is a convenience method that allows you to get a named sub-object
|
155
|
+
from a tree.
|
156
|
+
|
157
|
+
tree/"lib"
|
158
|
+
# => #<Grit::Tree "e74893a3d8a25cbb1367cf241cc741bfd503c4b2">
|
159
|
+
|
160
|
+
You can also get a tree directly from the repo if you know its name.
|
161
|
+
|
162
|
+
repo.tree
|
163
|
+
# => #<Grit::Tree "master">
|
164
|
+
|
165
|
+
repo.tree("91169e1f5fa4de2eaea3f176461f5dc784796769")
|
166
|
+
# => #<Grit::Tree "91169e1f5fa4de2eaea3f176461f5dc784796769">
|
167
|
+
|
168
|
+
= The Blob object
|
169
|
+
|
170
|
+
A blob represents a file. Trees often contain blobs.
|
171
|
+
|
172
|
+
blob = tree.contents.first
|
173
|
+
# => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
|
174
|
+
|
175
|
+
A blob has certain attributes.
|
176
|
+
|
177
|
+
blob.id
|
178
|
+
# => "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666"
|
179
|
+
|
180
|
+
blob.name
|
181
|
+
# => "README.txt"
|
182
|
+
|
183
|
+
blob.mode
|
184
|
+
# => "100644"
|
185
|
+
|
186
|
+
blob.size
|
187
|
+
# => 7726
|
188
|
+
|
189
|
+
You can get the data of a blob as a string.
|
190
|
+
|
191
|
+
blob.data
|
192
|
+
# => "Grit is a library to ..."
|
193
|
+
|
194
|
+
You can also get a blob directly from the repo if you know its name.
|
195
|
+
|
196
|
+
repo.blob("4ebc8aea50e0a67e000ba29a30809d0a7b9b2666")
|
197
|
+
# => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
|
198
|
+
|
199
|
+
== LICENSE:
|
200
|
+
|
201
|
+
(The MIT License)
|
202
|
+
|
203
|
+
Copyright (c) 2007 Tom Preston-Werner
|
204
|
+
|
205
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
206
|
+
a copy of this software and associated documentation files (the
|
207
|
+
'Software'), to deal in the Software without restriction, including
|
208
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
209
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
210
|
+
permit persons to whom the Software is furnished to do so, subject to
|
211
|
+
the following conditions:
|
212
|
+
|
213
|
+
The above copyright notice and this permission notice shall be
|
214
|
+
included in all copies or substantial portions of the Software.
|
215
|
+
|
216
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
217
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
218
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
219
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
220
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
221
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
222
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/grit/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |s|
|
8
|
+
s.name = "grit"
|
9
|
+
s.rubyforge_project = "grit"
|
10
|
+
s.summary = "Grit is a Ruby library for extracting information from a git repository in an object oriented manner."
|
11
|
+
s.email = "tom@mojombo.com"
|
12
|
+
s.homepage = "http://github.com/mojombo/grit"
|
13
|
+
s.description = "Grit is a Ruby library for extracting information from a git repository in an object oriented manner."
|
14
|
+
s.authors = ["Tom Preston-Werner", "Scott Chacon"]
|
15
|
+
s.add_dependency('mime-types', '>= 1.15')
|
16
|
+
s.add_dependency('diff-lcs', '>= 1.1.2')
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::TestTask.new do |t|
|
23
|
+
t.libs << 'lib'
|
24
|
+
t.pattern = 'test/**/test_*.rb'
|
25
|
+
t.verbose = false
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::RDocTask.new do |rdoc|
|
29
|
+
rdoc.rdoc_dir = 'rdoc'
|
30
|
+
rdoc.title = 'grit'
|
31
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
32
|
+
rdoc.rdoc_files.include('README*')
|
33
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => :test
|
37
|
+
|
38
|
+
# custom
|
39
|
+
|
40
|
+
desc "Open an irb session preloaded with this library"
|
41
|
+
task :console do
|
42
|
+
sh "irb -rubygems -r ./lib/grit.rb"
|
43
|
+
end
|
44
|
+
|
45
|
+
task :coverage do
|
46
|
+
system("rm -fr coverage")
|
47
|
+
system("rcov test/test_*.rb")
|
48
|
+
system("open coverage/index.html")
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Upload site to Rubyforge"
|
52
|
+
task :site do
|
53
|
+
sh "scp -r doc/* mojombo@grit.rubyforge.org:/var/www/gforge-projects/grit"
|
54
|
+
end
|