gitgo 0.3.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.
- data/History +44 -0
- data/License.txt +22 -0
- data/README +45 -0
- data/bin/gitgo +4 -0
- data/lib/gitgo.rb +1 -0
- data/lib/gitgo/app.rb +63 -0
- data/lib/gitgo/controller.rb +89 -0
- data/lib/gitgo/controllers/code.rb +198 -0
- data/lib/gitgo/controllers/issue.rb +76 -0
- data/lib/gitgo/controllers/repo.rb +186 -0
- data/lib/gitgo/controllers/wiki.rb +19 -0
- data/lib/gitgo/document.rb +680 -0
- data/lib/gitgo/document/invalid_document_error.rb +34 -0
- data/lib/gitgo/documents/comment.rb +20 -0
- data/lib/gitgo/documents/issue.rb +56 -0
- data/lib/gitgo/git.rb +941 -0
- data/lib/gitgo/git/tree.rb +315 -0
- data/lib/gitgo/git/utils.rb +59 -0
- data/lib/gitgo/helper.rb +3 -0
- data/lib/gitgo/helper/doc.rb +28 -0
- data/lib/gitgo/helper/form.rb +88 -0
- data/lib/gitgo/helper/format.rb +200 -0
- data/lib/gitgo/helper/html.rb +19 -0
- data/lib/gitgo/helper/utils.rb +85 -0
- data/lib/gitgo/index.rb +421 -0
- data/lib/gitgo/index/idx_file.rb +119 -0
- data/lib/gitgo/index/sha_file.rb +135 -0
- data/lib/gitgo/patches/grit.rb +47 -0
- data/lib/gitgo/repo.rb +626 -0
- data/lib/gitgo/repo/graph.rb +333 -0
- data/lib/gitgo/repo/node.rb +122 -0
- data/lib/gitgo/rest.rb +87 -0
- data/lib/gitgo/server.rb +114 -0
- data/lib/gitgo/version.rb +8 -0
- data/public/css/gitgo.css +24 -0
- data/public/javascript/gitgo.js +148 -0
- data/public/javascript/jquery-1.4.2.min.js +154 -0
- data/views/app/index.erb +4 -0
- data/views/app/timeline.erb +27 -0
- data/views/app/welcome.erb +13 -0
- data/views/code/_comment.erb +10 -0
- data/views/code/_comment_form.erb +14 -0
- data/views/code/_comments.erb +5 -0
- data/views/code/_commit.erb +25 -0
- data/views/code/_grepnav.erb +5 -0
- data/views/code/_treenav.erb +3 -0
- data/views/code/blob.erb +6 -0
- data/views/code/commit_grep.erb +35 -0
- data/views/code/commits.erb +11 -0
- data/views/code/diff.erb +10 -0
- data/views/code/grep.erb +32 -0
- data/views/code/index.erb +17 -0
- data/views/code/obj/blob.erb +4 -0
- data/views/code/obj/commit.erb +25 -0
- data/views/code/obj/tag.erb +25 -0
- data/views/code/obj/tree.erb +9 -0
- data/views/code/tree.erb +9 -0
- data/views/error.erb +19 -0
- data/views/issue/_issue.erb +15 -0
- data/views/issue/_issue_form.erb +39 -0
- data/views/issue/edit.erb +11 -0
- data/views/issue/index.erb +28 -0
- data/views/issue/new.erb +5 -0
- data/views/issue/show.erb +27 -0
- data/views/layout.erb +34 -0
- data/views/not_found.erb +1 -0
- data/views/repo/fsck.erb +29 -0
- data/views/repo/help.textile +5 -0
- data/views/repo/help/faq.textile +19 -0
- data/views/repo/help/howto.textile +31 -0
- data/views/repo/help/trouble.textile +28 -0
- data/views/repo/idx.erb +29 -0
- data/views/repo/index.erb +72 -0
- data/views/repo/status.erb +16 -0
- data/views/wiki/index.erb +3 -0
- metadata +253 -0
data/History
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
== 0.3.3 2010-04-28
|
2
|
+
|
3
|
+
Fixed (hopefully) usage in repos with no user name/email set.
|
4
|
+
|
5
|
+
== 0.3.2 2010-04-27
|
6
|
+
|
7
|
+
Fixed (hopefully) the cause of zero-padded file modes warning.
|
8
|
+
|
9
|
+
== 0.3.1 2010-04-26
|
10
|
+
|
11
|
+
Improvements to repo lifecycle.
|
12
|
+
|
13
|
+
== 0.3.0 2010-04-26
|
14
|
+
|
15
|
+
Updated internal data store to (more or less) halve the overhead of each new
|
16
|
+
document by storing document information inline with associations. Index now
|
17
|
+
assigns shas an integer index for faster comparisons and smaller index files.
|
18
|
+
Continued overhaul of internals. General updates to the interface.
|
19
|
+
|
20
|
+
== 0.2.0 2010-03-29
|
21
|
+
|
22
|
+
This release significantly changes the internals of Gitgo. Old gitgo branches
|
23
|
+
will not be compatible. To migrate a gitgo-0.1.* branch to the new storage
|
24
|
+
format:
|
25
|
+
|
26
|
+
% git clone git://github.com/bahuvrihi/gitgo.git
|
27
|
+
% cd gitgo
|
28
|
+
% git checkout migrate-0.2.0
|
29
|
+
% ruby script/migrate-0.2.0.rb PATH_TO_REPO SOURCE_BRANCH TARGET_BRANCH
|
30
|
+
|
31
|
+
Then rename the target branch as necessary. You will also have to remove the
|
32
|
+
old gitgo files:
|
33
|
+
|
34
|
+
% cd <path_to_repo>
|
35
|
+
% rm -rf .git/gitgo
|
36
|
+
|
37
|
+
Major changes:
|
38
|
+
|
39
|
+
* changed document serialization format to JSON
|
40
|
+
* complete overhaul of internal classes
|
41
|
+
* implemented a more robust system for calculating
|
42
|
+
(and drawing) a document graph
|
43
|
+
* temporary removal of comments
|
44
|
+
* improvements to indexing system
|
data/License.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2010 Pinnacol Assurance
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software. Except as contained in this
|
12
|
+
notice, the name(s) of the above copyright holders shall not be used in
|
13
|
+
advertising or otherwise to promote the sale, use or other dealings in this
|
14
|
+
Software without prior written authorization.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
= Gitgo
|
2
|
+
|
3
|
+
Gitgo -- git-driven issues, comments, and a wiki... to go.
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
Gitgo is an issue tracker that stores issue information in a git repository.
|
8
|
+
|
9
|
+
At present gitgo is in a developmental state. While the backend and data model
|
10
|
+
both work and appear to be robust, the front-end is highly lacking. Usage will
|
11
|
+
be difficult without insider knowledge.
|
12
|
+
|
13
|
+
== Usage
|
14
|
+
|
15
|
+
In the working directory for a git repository:
|
16
|
+
|
17
|
+
% gitgo
|
18
|
+
|
19
|
+
Then visit http://localhost:8080 in a web browser.
|
20
|
+
|
21
|
+
== Installation
|
22
|
+
|
23
|
+
Gitgo is not available as a gem yet. To clone the project and build your own:
|
24
|
+
|
25
|
+
% git clone git://github.com/pinnacol/gitgo.git
|
26
|
+
% cd gitgo
|
27
|
+
% rake gem
|
28
|
+
% gem install pkg/gitgo-...
|
29
|
+
|
30
|
+
== Development
|
31
|
+
|
32
|
+
Gitgo is open-source and welcomes help from the community! To get started:
|
33
|
+
|
34
|
+
% git clone git://github.com/pinnacol/gitgo.git
|
35
|
+
% cd gitgo
|
36
|
+
% rake test
|
37
|
+
|
38
|
+
To see bugs tracked in the gitgo repo:
|
39
|
+
|
40
|
+
% bin/gitgo
|
41
|
+
|
42
|
+
== Info
|
43
|
+
|
44
|
+
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
|
45
|
+
License:: {MIT-Style}[link:files/License_txt.html]
|
data/bin/gitgo
ADDED
data/lib/gitgo.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'gitgo/server'
|
data/lib/gitgo/app.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'gitgo/controller'
|
2
|
+
require 'gitgo/controllers/code'
|
3
|
+
require 'gitgo/controllers/issue'
|
4
|
+
require 'gitgo/controllers/repo'
|
5
|
+
require 'gitgo/controllers/wiki'
|
6
|
+
|
7
|
+
module Gitgo
|
8
|
+
class App < Controller
|
9
|
+
set :views, File.expand_path("views/app", ROOT)
|
10
|
+
set :static, true
|
11
|
+
|
12
|
+
get('/') { repo.head ? index : welcome }
|
13
|
+
get('/timeline') { timeline }
|
14
|
+
|
15
|
+
use Controllers::Code
|
16
|
+
use Controllers::Issue
|
17
|
+
use Controllers::Wiki
|
18
|
+
use Controllers::Repo
|
19
|
+
|
20
|
+
def index
|
21
|
+
erb :index
|
22
|
+
end
|
23
|
+
|
24
|
+
def welcome
|
25
|
+
erb :welcome, :locals => {
|
26
|
+
:branch => repo.branch,
|
27
|
+
:remotes => repo.refs
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def timeline
|
32
|
+
Document.update_index
|
33
|
+
|
34
|
+
page = (request[:page] || 0).to_i
|
35
|
+
per_page = (request[:per_page] || 5).to_i
|
36
|
+
|
37
|
+
author = request[:author]
|
38
|
+
author = '' if author == 'unknown'
|
39
|
+
|
40
|
+
docs = repo.timeline(:n => per_page, :offset => page * per_page) do |sha|
|
41
|
+
author.nil? || repo[sha]['author'].include?("<#{author}>")
|
42
|
+
end.collect do |sha|
|
43
|
+
Document.cast(repo[sha], sha)
|
44
|
+
end.sort_by do |doc|
|
45
|
+
doc.date
|
46
|
+
end
|
47
|
+
|
48
|
+
erb :timeline, :locals => {
|
49
|
+
:page => page,
|
50
|
+
:per_page => per_page,
|
51
|
+
:docs => docs,
|
52
|
+
:author => author,
|
53
|
+
:authors => repo.index.values('email'),
|
54
|
+
:active_sha => session_head
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_query(params)
|
59
|
+
params.delete_if {|key, value| value.nil? }
|
60
|
+
super(params)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'gitgo/helper'
|
4
|
+
require 'gitgo/document'
|
5
|
+
require 'gitgo/rest'
|
6
|
+
|
7
|
+
module Gitgo
|
8
|
+
class Controller < Sinatra::Base
|
9
|
+
ROOT = File.expand_path(File.dirname(__FILE__) + "/../..")
|
10
|
+
HEAD = 'gitgo.head'
|
11
|
+
MOUNT = 'gitgo.mount'
|
12
|
+
|
13
|
+
set :root, ROOT
|
14
|
+
set :raise_errors, Proc.new { test? }
|
15
|
+
set :dump_errors, true
|
16
|
+
|
17
|
+
template(:layout) do
|
18
|
+
File.read(File.join(ROOT, "views/layout.erb"))
|
19
|
+
end
|
20
|
+
|
21
|
+
not_found do
|
22
|
+
erb :not_found, :views => path("views")
|
23
|
+
end
|
24
|
+
|
25
|
+
error Exception do
|
26
|
+
err = env['sinatra.error']
|
27
|
+
resetable = err.kind_of?(Errno::ENOENT) && err.message =~ /No such file or directory - .*idx/
|
28
|
+
|
29
|
+
erb :error, :views => path("views"), :locals => {:err => err, :resetable => resetable}
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(app=nil, repo=nil)
|
33
|
+
super(app)
|
34
|
+
@repo = repo
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the path expanded relative to the Gitgo::ROOT directory. Paths
|
38
|
+
# often need to be expanded like this so that they will be correct when
|
39
|
+
# Gitgo is running as a gem.
|
40
|
+
def path(path)
|
41
|
+
File.expand_path(path, ROOT)
|
42
|
+
end
|
43
|
+
|
44
|
+
def repo
|
45
|
+
@repo ||= Repo.current
|
46
|
+
end
|
47
|
+
|
48
|
+
def call(env)
|
49
|
+
env[Repo::REPO] ||= @repo
|
50
|
+
Repo.with_env(env) { super(env) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def session_head
|
54
|
+
# grit.head will be nil if not on a local branch
|
55
|
+
@session_head ||= begin
|
56
|
+
if session.has_key?(HEAD)
|
57
|
+
session[HEAD]
|
58
|
+
else
|
59
|
+
grit = repo.git.grit
|
60
|
+
session[HEAD] = grit.head ? grit.head.name : nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def session_head=(input)
|
66
|
+
@session_head = session[HEAD] = input
|
67
|
+
end
|
68
|
+
|
69
|
+
def mount_point
|
70
|
+
@mount_point ||= (env[MOUNT] || '/')
|
71
|
+
end
|
72
|
+
|
73
|
+
def url(paths)
|
74
|
+
File.join(mount_point, *paths)
|
75
|
+
end
|
76
|
+
|
77
|
+
def format
|
78
|
+
@format ||= Helper::Format.new(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
def form
|
82
|
+
@form ||= Helper::Form.new(self)
|
83
|
+
end
|
84
|
+
|
85
|
+
def html
|
86
|
+
Helper::Html
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'gitgo/controller'
|
2
|
+
require 'gitgo/documents/comment'
|
3
|
+
|
4
|
+
module Gitgo
|
5
|
+
module Controllers
|
6
|
+
class Code < Controller
|
7
|
+
include Rest
|
8
|
+
|
9
|
+
set :views, File.expand_path("views/code", ROOT)
|
10
|
+
|
11
|
+
get('/code') { index }
|
12
|
+
get('/blob') { blob_grep }
|
13
|
+
get('/tree') { tree_grep }
|
14
|
+
get('/commit') { commit_grep }
|
15
|
+
|
16
|
+
get('/blob/:treeish/*') {|treeish, path| show_blob(treeish, path) }
|
17
|
+
get('/tree/:treeish') {|treeish| show_tree(treeish, '') }
|
18
|
+
get('/tree/:treeish/*') {|treeish, path| show_tree(treeish, path) }
|
19
|
+
get('/commit/:treeish') {|treeish| show_commit(treeish) }
|
20
|
+
get('/commits/:treeish') {|treeish| show_commits(treeish) }
|
21
|
+
get('/obj/:sha') {|sha| show_object(sha) }
|
22
|
+
|
23
|
+
get('/comment/:sha') {|sha| read(sha) }
|
24
|
+
post('/comment') { create }
|
25
|
+
post('/comment/:sha') do |sha|
|
26
|
+
_method = request[:_method]
|
27
|
+
case _method
|
28
|
+
when /\Aupdate\z/i then update(obj)
|
29
|
+
when /\Adelete\z/i then destroy(obj)
|
30
|
+
else raise("unknown post method: #{_method}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
put('/comment/:sha') {|sha| update(sha) }
|
34
|
+
delete('/comment/:sha') {|sha| destroy(sha) }
|
35
|
+
|
36
|
+
Comment = Documents::Comment
|
37
|
+
|
38
|
+
def git
|
39
|
+
@git ||= repo.git
|
40
|
+
end
|
41
|
+
|
42
|
+
def grit
|
43
|
+
@grit ||= git.grit
|
44
|
+
end
|
45
|
+
|
46
|
+
def model
|
47
|
+
Comment
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# actions
|
52
|
+
#
|
53
|
+
|
54
|
+
def index
|
55
|
+
erb :index, :locals => {
|
56
|
+
:branches => grit.branches,
|
57
|
+
:tags => grit.tags
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def treeish
|
62
|
+
request['at'] || grit.head.commit
|
63
|
+
end
|
64
|
+
|
65
|
+
def grep_opts(overrides={})
|
66
|
+
{
|
67
|
+
:ignore_case => request['ignore_case'] == 'true',
|
68
|
+
:invert_match => request['invert_match'] == 'true',
|
69
|
+
:fixed_strings => request['fixed_strings'] == 'true',
|
70
|
+
}.merge!(overrides)
|
71
|
+
end
|
72
|
+
|
73
|
+
def blob_grep
|
74
|
+
options = grep_opts(:e => request['pattern'])
|
75
|
+
|
76
|
+
selected = []
|
77
|
+
git.grep(options, treeish) do |path, blob|
|
78
|
+
selected << [path, blob.id]
|
79
|
+
end
|
80
|
+
|
81
|
+
erb :grep, :locals => options.merge!(
|
82
|
+
:type => 'blob',
|
83
|
+
:at => treeish,
|
84
|
+
:selected => selected,
|
85
|
+
:refs => grit.refs
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def tree_grep
|
90
|
+
options = grep_opts(:e => request['pattern'])
|
91
|
+
|
92
|
+
selected = []
|
93
|
+
git.tree_grep(options, treeish) do |path, blob|
|
94
|
+
selected << [path, blob.id]
|
95
|
+
end
|
96
|
+
|
97
|
+
erb :grep, :locals => options.merge!(
|
98
|
+
:type => 'tree',
|
99
|
+
:at => treeish,
|
100
|
+
:selected => selected,
|
101
|
+
:refs => grit.refs
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
def commit_grep
|
106
|
+
options = grep_opts(
|
107
|
+
:author => request['author'],
|
108
|
+
:committer => request['committer'],
|
109
|
+
:grep => request['grep'],
|
110
|
+
:regexp_ignore_case => request['regexp_ignore_case'] == 'true',
|
111
|
+
:fixed_strings => request['fixed_strings'] == 'true',
|
112
|
+
:all_match => request['all_match'] == 'true',
|
113
|
+
:max_count => request['max_count'] || '10'
|
114
|
+
)
|
115
|
+
|
116
|
+
selected = []
|
117
|
+
git.commit_grep(options, treeish) {|sha| selected << sha }
|
118
|
+
|
119
|
+
erb :commit_grep, :locals => options.merge!(
|
120
|
+
:selected => selected
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
def show_blob(treeish, path)
|
125
|
+
commit = grit.commit(treeish) || not_found
|
126
|
+
blob = commit.tree / path || not_found
|
127
|
+
|
128
|
+
erb :blob, :locals => {
|
129
|
+
:commit => commit,
|
130
|
+
:treeish => treeish,
|
131
|
+
:blob => blob,
|
132
|
+
:path => path
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
def show_tree(treeish, path)
|
137
|
+
commit = grit.commit(treeish) || not_found
|
138
|
+
tree = path.split("/").inject(commit.tree) do |obj, name|
|
139
|
+
not_found if obj.nil?
|
140
|
+
obj.trees.find {|obj| obj.name == name }
|
141
|
+
end
|
142
|
+
|
143
|
+
erb :tree, :locals => {
|
144
|
+
:commit => commit,
|
145
|
+
:treeish => treeish,
|
146
|
+
:tree => tree,
|
147
|
+
:path => path
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
def show_commit(treeish)
|
152
|
+
commit = grit.commit(treeish) || not_found
|
153
|
+
erb :diff, :locals => {
|
154
|
+
:commit => commit,
|
155
|
+
:treeish => treeish
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
def show_commits(treeish)
|
160
|
+
commit = grit.commit(treeish)
|
161
|
+
page = (request[:page] || 0).to_i
|
162
|
+
per_page = (request[:per_page] || 10).to_i
|
163
|
+
|
164
|
+
erb :commits, :locals => {
|
165
|
+
:treeish => treeish,
|
166
|
+
:page => page,
|
167
|
+
:per_page => per_page,
|
168
|
+
:commits => grit.commits(commit.sha, per_page, page * per_page)
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
def show_object(sha)
|
173
|
+
sha = git.resolve(sha)
|
174
|
+
|
175
|
+
case
|
176
|
+
when request['content'] == 'true'
|
177
|
+
response['Content-Type'] = 'text/plain'
|
178
|
+
grit.git.cat_file({:p => true}, sha)
|
179
|
+
|
180
|
+
when request['download'] == 'true'
|
181
|
+
response['Content-Type'] = 'text/plain'
|
182
|
+
response['Content-Disposition'] = "attachment; filename=#{sha};"
|
183
|
+
raw_object = grit.git.ruby_git.get_raw_object_by_sha1(sha)
|
184
|
+
"%s %d\0" % [raw_object.type, raw_object.content.length] + raw_object.content
|
185
|
+
|
186
|
+
else
|
187
|
+
type = git.type(sha).to_sym
|
188
|
+
obj = git.get(type, sha) or not_found
|
189
|
+
|
190
|
+
erb type, :locals => {
|
191
|
+
:sha => sha,
|
192
|
+
:obj => obj
|
193
|
+
}, :views => path('views/code/obj')
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|