git-object-browser 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/htdocs/js/main.js +3 -0
- data/htdocs/templates/object.html +73 -44
- data/htdocs/templates/pack_index.html +3 -4
- data/htdocs/templates/packed_object.html +104 -95
- data/htdocs/templates/packed_refs.html +37 -21
- data/htdocs/templates/ref.html +19 -0
- data/lib/git-object-browser/models/directory.rb +3 -3
- data/lib/git-object-browser/models/git_object.rb +24 -22
- data/lib/git-object-browser/models/index.rb +5 -5
- data/lib/git-object-browser/models/index_entry.rb +19 -19
- data/lib/git-object-browser/models/index_reuc_extension.rb +2 -2
- data/lib/git-object-browser/models/index_tree_extension.rb +13 -13
- data/lib/git-object-browser/models/pack_index.rb +3 -3
- data/lib/git-object-browser/models/packed_refs.rb +4 -1
- data/lib/git-object-browser/models/plain_file.rb +1 -1
- data/lib/git-object-browser/models/ref.rb +6 -5
- data/lib/git-object-browser/server/git_servlet.rb +10 -5
- data/lib/git-object-browser/version.rb +1 -1
- data/spec/fixtures/json/tree.json +1 -1
- data/spec/git-object-browser/models/index_spec.rb +14 -14
- data/spec/git-object-browser/models/index_tree_extension_spec.rb +16 -16
- data/spec/git-object-browser/models/plain_file_spec.rb +1 -1
- metadata +5 -2
data/Gemfile
CHANGED
data/htdocs/js/main.js
CHANGED
@@ -201,6 +201,9 @@ function GitCtrl($scope, $location, $routeParams, GitResource, PackedObjectResou
|
|
201
201
|
}
|
202
202
|
});
|
203
203
|
$scope.object.entries = entries;
|
204
|
+
} else if (json.type == "packed_object") {
|
205
|
+
template = json.type;
|
206
|
+
$scope.unpacked = json.unpacked;
|
204
207
|
} else {
|
205
208
|
template = json.type;
|
206
209
|
}
|
@@ -1,54 +1,83 @@
|
|
1
1
|
<article>
|
2
|
-
<h1 style="font-size:1.8em;"><i data-entry-icon="'object'"></i> {{path}} <small>Object</small></h1>
|
2
|
+
<h1 style="font-size:1.8em;"><i data-entry-icon="'object'"></i> {{path}} <small>Object</small></h1>
|
3
3
|
|
4
|
-
<
|
5
|
-
|
6
|
-
<
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<tr><th>sha1</th><td>{{object.sha1}}</td></tr>
|
12
|
-
<tr><th>size</th><td>{{object.size}}</td></tr>
|
13
|
-
|
14
|
-
<tr data-ng-repeat="prop in object.properties">
|
15
|
-
<th>{{prop.key}}</th>
|
16
|
-
<td data-ng-switch="prop.type">
|
17
|
-
<span data-ng-switch-when="sha1"><a href="#/.git/{{prop.path}}">{{prop.value}}</a></span>
|
18
|
-
<span data-ng-switch-when="user">{{prop.value}} <small style="color:#aaa">{{prop.date}}</small></span>
|
19
|
-
<span data-ng-switch-default>{{prop.value}}</span>
|
20
|
-
</td>
|
21
|
-
</tr>
|
22
|
-
</tbody>
|
4
|
+
<div class="tabbable">
|
5
|
+
<ul class="nav nav-tabs">
|
6
|
+
<li class="active"><a href="#parsed" data-toggle="tab">Parsed</a></li>
|
7
|
+
<li><a href="#plain" data-toggle="tab">Plain</a></li>
|
8
|
+
</ul>
|
9
|
+
<div class="tab-content">
|
10
|
+
<div class="tab-pane active" id="parsed">
|
23
11
|
|
24
|
-
<
|
25
|
-
<
|
26
|
-
<tr
|
27
|
-
<
|
28
|
-
<
|
12
|
+
<table class="table">
|
13
|
+
<tbody>
|
14
|
+
<tr>
|
15
|
+
<th>sha1</th>
|
16
|
+
<td>{{object.sha1}}</td>
|
17
|
+
</tr>
|
18
|
+
<tr>
|
19
|
+
<th>type</th>
|
20
|
+
<td><i data-entry-icon="object.type"></i> {{object.type}}</td>
|
21
|
+
</tr>
|
22
|
+
<tr>
|
23
|
+
<th>size</th>
|
24
|
+
<td>{{object.size}}</td>
|
25
|
+
</tr>
|
26
|
+
<tr data-ng-repeat="prop in object.properties">
|
27
|
+
<th>{{prop.key}}</th>
|
28
|
+
<td data-ng-switch="prop.type">
|
29
|
+
<span data-ng-switch-when="sha1"><a href="#/.git/{{prop.path}}">{{prop.value}}</a></span>
|
30
|
+
<span data-ng-switch-when="user">{{prop.value}} <small style="color:#aaa">{{prop.date}}</small></span>
|
31
|
+
<span data-ng-switch-default>{{prop.value}}</span>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
</tbody>
|
29
35
|
|
30
|
-
<
|
31
|
-
<
|
32
|
-
<
|
33
|
-
<
|
34
|
-
|
35
|
-
<
|
36
|
-
</
|
37
|
-
</
|
38
|
-
|
39
|
-
<tr data-ng-
|
40
|
-
<
|
41
|
-
<td>{{
|
42
|
-
|
43
|
-
|
44
|
-
</
|
36
|
+
<tbody data-ng-switch="object.type">
|
37
|
+
<tr data-ng-switch-when="blob">
|
38
|
+
<th>content</th>
|
39
|
+
<td><pre>{{object.content}}</pre></td>
|
40
|
+
</tr>
|
41
|
+
<tr data-ng-switch-when="commit">
|
42
|
+
<th>message</th>
|
43
|
+
<td>{{object.message}}</td>
|
44
|
+
</tr>
|
45
|
+
<tr data-ng-switch-when="tag">
|
46
|
+
<th>message</th>
|
47
|
+
<td>{{object.message}}</td>
|
48
|
+
</tr>
|
49
|
+
<tr data-ng-switch-when="tree">
|
50
|
+
<th>entries</th>
|
51
|
+
<td>
|
52
|
+
<table class="table table-striped table-condensed">
|
53
|
+
<thead>
|
54
|
+
<tr>
|
55
|
+
<th>mode</th>
|
56
|
+
<th>filename</th>
|
57
|
+
<th>sha1</th>
|
58
|
+
</tr>
|
59
|
+
</thead>
|
60
|
+
<tbody>
|
61
|
+
<tr data-ng-repeat="entry in object.entries">
|
62
|
+
<td><i data-mode-icon="entry.mode"></i> {{entry.mode}}</td>
|
63
|
+
<td>{{entry.filename}}</td>
|
64
|
+
<td><a href="#" data-ref-href="entry">{{entry.sha1}}</a></td>
|
65
|
+
</tr>
|
66
|
+
</tbody>
|
67
|
+
</table>
|
68
|
+
</td>
|
69
|
+
</tr>
|
70
|
+
</tbody>
|
45
71
|
|
46
72
|
</table>
|
47
|
-
</td></tr>
|
48
|
-
|
49
|
-
</tbody>
|
50
73
|
|
51
|
-
</
|
74
|
+
</div>
|
75
|
+
<div class="tab-pane" id="plain">
|
52
76
|
|
77
|
+
<pre>{{object.type}} {{object.size}}\0
|
78
|
+
{{object.content}}</pre>
|
53
79
|
|
80
|
+
</div>
|
81
|
+
</div>
|
82
|
+
</div>
|
54
83
|
</article>
|
@@ -9,8 +9,8 @@
|
|
9
9
|
<th>sha1</th>
|
10
10
|
<th>crc32</th>
|
11
11
|
<th><a href="" data-ng-click="orderByOffset()">offset</a></th>
|
12
|
-
<th>type
|
13
|
-
<th>size
|
12
|
+
<th>type</th>
|
13
|
+
<th>size</th>
|
14
14
|
</tr>
|
15
15
|
</thead>
|
16
16
|
<tbody>
|
@@ -26,13 +26,12 @@
|
|
26
26
|
<td><a href="#/{{packUrl}}?offset={{entry.offset}}">{{entry.offset}}</a></td>
|
27
27
|
<td><i data-entry-icon="entry.type"></i> {{entry.type}}
|
28
28
|
<span data-ng-show="entry.base_offset"><a href="#/{{packUrl}}?offset={{entry.base_offset}}">{{entry.base_offset}}</a></span>
|
29
|
-
<span data-ng-show="entry.base_sha1"><a href="
|
29
|
+
<span data-ng-show="entry.base_sha1"><a data-ref-href="entry.base_sha1">{{entry.base_sha1.substr(0,6)}}</a></span>
|
30
30
|
</td>
|
31
31
|
<td>{{entry.size}}</td>
|
32
32
|
</tr>
|
33
33
|
</tbody>
|
34
34
|
</table>
|
35
35
|
|
36
|
-
<a href="#/.git/packed-refs" data-ng-show="limited">Show All</a>
|
37
36
|
</article>
|
38
37
|
|
@@ -1,111 +1,120 @@
|
|
1
1
|
<article>
|
2
2
|
<h1 style="font-size:1.8em;"><i data-entry-icon="'object'"></i> {{path}} <small>Packed Object</small></h1>
|
3
3
|
|
4
|
+
<div class="tabbable">
|
5
|
+
<ul class="nav nav-tabs">
|
6
|
+
<li class="active"><a href="#parsed" data-toggle="tab">Parsed</a></li>
|
7
|
+
<li data-ng-show="object.object.content"><a href="#plain" data-toggle="tab">Plain</a></li>
|
8
|
+
<li data-ng-show="object.delta_commands"><a href="#deltas" data-toggle="tab">Deltas</a></li>
|
9
|
+
<li><a href="#/{{path.replace('.pack', '.idx')}}"><i class="icon-list"></i> Index</a></li>
|
10
|
+
</ul>
|
11
|
+
|
12
|
+
<div class="tab-content">
|
13
|
+
<div class="tab-pane active" id="parsed">
|
4
14
|
<table class="table">
|
5
|
-
<tbody>
|
6
|
-
|
7
|
-
|
8
|
-
<th>
|
9
|
-
<td>{{object.
|
10
|
-
</tr>
|
11
|
-
|
12
|
-
<
|
13
|
-
<
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
<
|
18
|
-
|
19
|
-
<
|
20
|
-
</
|
21
|
-
|
22
|
-
|
23
|
-
<
|
24
|
-
<
|
25
|
-
</
|
26
|
-
|
27
|
-
<tr data-ng-show="object.base_offset">
|
28
|
-
<th>base size</th>
|
29
|
-
<td>{{object.base_size}}</td>
|
30
|
-
</tr>
|
31
|
-
|
32
|
-
<
|
33
|
-
<
|
34
|
-
|
35
|
-
</tr>
|
36
|
-
|
37
|
-
<tr
|
38
|
-
|
39
|
-
<
|
40
|
-
|
41
|
-
<
|
42
|
-
<
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
<
|
47
|
-
</td>
|
48
|
-
</tr>
|
49
|
-
</tbody>
|
50
|
-
|
51
|
-
<tbody data-ng-switch="object.object.type">
|
52
|
-
<tr data-ng-switch-when="blob"><th>content</th><td><pre>{{object.object.content}}</pre></td></tr>
|
53
|
-
<tr data-ng-switch-when="commit"><th>message</th><td>{{object.object.message}}</td></tr>
|
54
|
-
<tr data-ng-switch-when="tag"><th>message</th><td>{{object.object.message}}</td></tr>
|
55
|
-
<tr data-ng-switch-when="tree"><th>entries</th><td>
|
56
|
-
|
57
|
-
<table class="table table-striped table-condensed">
|
58
|
-
<thead>
|
59
|
-
<tr>
|
60
|
-
<th>mode</th>
|
61
|
-
<th>filename</th>
|
62
|
-
<th>sha1</th>
|
63
|
-
</tr>
|
64
|
-
</thead>
|
65
|
-
<tbody>
|
66
|
-
<tr data-ng-repeat="entry in object.object.entries">
|
67
|
-
<td><i data-mode-icon="entry.mode"></i> {{entry.mode}}</td>
|
68
|
-
<td>{{entry.filename}}</td>
|
69
|
-
<td><a href="#" data-ref-href="entry">{{entry.sha1}}</a></td>
|
70
|
-
</tr>
|
71
|
-
</tbody>
|
15
|
+
<tbody>
|
16
|
+
<tr>
|
17
|
+
<!-- Object could be unpacked. -->
|
18
|
+
<th>sha1</th>
|
19
|
+
<td>{{object.object.sha1}} <a data-ref-href="object.object" data-ng-show="unpacked"><i class="icon-arrow-right"></i> unpacked</a></td>
|
20
|
+
</tr>
|
21
|
+
<tr>
|
22
|
+
<th>offset</th>
|
23
|
+
<td><a href="#/{{path}}?offset={{object.offset}}">{{object.offset}}</a></td>
|
24
|
+
</tr>
|
25
|
+
<tr data-ng-show="object.base_offset">
|
26
|
+
<th>base offset</th>
|
27
|
+
<td><a href="#/{{path}}?offset={{object.base_offset}}">{{object.base_offset}}</a></td>
|
28
|
+
</tr>
|
29
|
+
<tr data-ng-show="object.base_offset">
|
30
|
+
<th>delta type</th>
|
31
|
+
<td><i data-entry-icon="object.type"></i> {{object.type}}</td>
|
32
|
+
</tr>
|
33
|
+
<tr>
|
34
|
+
<th>type</th>
|
35
|
+
<td><i data-entry-icon="object.object.type"></i> {{object.object.type}}</td>
|
36
|
+
</tr>
|
37
|
+
<tr data-ng-show="object.base_offset">
|
38
|
+
<th>base size</th>
|
39
|
+
<td>{{object.base_size}}</td>
|
40
|
+
</tr>
|
41
|
+
<tr data-ng-show="object.base_offset">
|
42
|
+
<th>delta size</th>
|
43
|
+
<td>{{object.size}}</td>
|
44
|
+
</tr>
|
45
|
+
<tr><th>size</th><td>{{object.object.size}}</td></tr>
|
46
|
+
|
47
|
+
<tr data-ng-repeat="prop in object.object.properties">
|
48
|
+
<th>{{prop.key}}</th>
|
49
|
+
<td data-ng-switch="prop.type">
|
50
|
+
<span data-ng-switch-when="sha1"><a href="#/.git/{{prop.path}}">{{prop.value}}</a></span>
|
51
|
+
<span data-ng-switch-when="user">{{prop.value}} <small style="color:#aaa">{{prop.date}}</small></span>
|
52
|
+
<span data-ng-switch-default>{{prop.value}}</span>
|
53
|
+
</td>
|
54
|
+
</tr>
|
55
|
+
</tbody>
|
56
|
+
<table>
|
72
57
|
|
58
|
+
<table class="table">
|
59
|
+
<tbody data-ng-switch="object.object.type">
|
60
|
+
<tr data-ng-switch-when="blob"><th>content</th><td><pre>{{object.object.content}}</pre></td></tr>
|
61
|
+
<tr data-ng-switch-when="commit"><th>message</th><td>{{object.object.message}}</td></tr>
|
62
|
+
<tr data-ng-switch-when="tag"><th>message</th><td>{{object.object.message}}</td></tr>
|
63
|
+
<tr data-ng-switch-when="tree">
|
64
|
+
<th>entries</th>
|
65
|
+
<td>
|
66
|
+
<table class="table table-striped table-condensed">
|
67
|
+
<thead>
|
68
|
+
<tr>
|
69
|
+
<th>mode</th>
|
70
|
+
<th>filename</th>
|
71
|
+
<th>sha1</th>
|
72
|
+
</tr>
|
73
|
+
</thead>
|
74
|
+
<tbody>
|
75
|
+
<tr data-ng-repeat="entry in object.object.entries">
|
76
|
+
<td><i data-mode-icon="entry.mode"></i> {{entry.mode}}</td>
|
77
|
+
<td>{{entry.filename}}</td>
|
78
|
+
<td><a href="#" data-ref-href="entry">{{entry.sha1}}</a></td>
|
79
|
+
</tr>
|
80
|
+
</tbody>
|
81
|
+
</table>
|
82
|
+
</td>
|
83
|
+
</tr>
|
84
|
+
</tbody>
|
73
85
|
</table>
|
74
|
-
</td></tr>
|
75
|
-
</tbody>
|
76
86
|
|
77
|
-
|
87
|
+
</div>
|
88
|
+
<div class="tab-pane" id="deltas">
|
78
89
|
|
79
|
-
<
|
80
|
-
<
|
81
|
-
<
|
90
|
+
<table class="table table-striped">
|
91
|
+
<thead>
|
92
|
+
<th>source</th>
|
93
|
+
<th>offset</th>
|
94
|
+
<th>size</th>
|
95
|
+
<th>data</th>
|
96
|
+
</thead>
|
97
|
+
<tbody>
|
98
|
+
<tr data-ng-repeat="command in object.delta_commands">
|
99
|
+
<td>{{command.source}}</td>
|
100
|
+
<td>{{command.offset}}</td>
|
101
|
+
<td>{{command.size}}</td>
|
102
|
+
<td><pre data-ng-show="command.data">{{command.data}}</pre></td>
|
103
|
+
</tr>
|
104
|
+
</tbody>
|
105
|
+
</table>
|
82
106
|
|
83
|
-
|
84
|
-
<
|
85
|
-
<th>source</th>
|
86
|
-
<th>offset</th>
|
87
|
-
<th>size</th>
|
88
|
-
<th>data</th>
|
89
|
-
</thead>
|
90
|
-
<tbody>
|
91
|
-
<tr data-ng-repeat="command in object.delta_commands">
|
92
|
-
<td>{{command.source}}</td>
|
93
|
-
<td>{{command.offset}}</td>
|
94
|
-
<td>{{command.size}}</td>
|
95
|
-
<td><pre data-ng-show="command.data">{{command.data}}</pre></td>
|
96
|
-
</tr>
|
97
|
-
</tbody>
|
107
|
+
</div>
|
108
|
+
<div class="tab-pane" id="plain">
|
98
109
|
|
99
|
-
|
110
|
+
<pre>{{object.object.type}} {{object.object.size}}\0
|
111
|
+
{{object.object.content}}</pre>
|
100
112
|
|
101
|
-
</
|
102
|
-
</
|
113
|
+
</div>
|
114
|
+
</div>
|
115
|
+
</div>
|
103
116
|
|
104
117
|
|
105
118
|
|
106
|
-
</tbody>
|
107
|
-
</table>
|
108
119
|
|
109
|
-
<a href="#/.git/packed-refs" data-ng-show="limited">Show All</a>
|
110
120
|
</article>
|
111
|
-
|
@@ -1,27 +1,43 @@
|
|
1
1
|
<article>
|
2
|
-
<h1><i data-entry-icon="'ref'"></i> {{path}} <small>Packed References</small></h1>
|
2
|
+
<h1><i data-entry-icon="'ref'"></i> {{path}} <small>Packed References</small></h1>
|
3
|
+
|
4
|
+
<div class="tabbable">
|
5
|
+
<ul class="nav nav-tabs">
|
6
|
+
<li class="active"><a href="#parsed" data-toggle="tab">Parsed</a></li>
|
7
|
+
<li><a href="#plain" data-toggle="tab">Plain</a></li>
|
8
|
+
</ul>
|
9
|
+
<div class="tab-content">
|
10
|
+
<div class="tab-pane active" id="parsed">
|
3
11
|
|
4
12
|
<table class="table table-striped">
|
5
|
-
<thead>
|
6
|
-
<tr>
|
7
|
-
<th>sha1</th>
|
8
|
-
<th>ref</th>
|
9
|
-
</tr>
|
10
|
-
</thead>
|
11
|
-
<tbody>
|
12
|
-
<tr data-ng-repeat="entry in object.entries">
|
13
|
-
<td>
|
14
|
-
<i data-entry-icon="'commit'" data-ng-hide="entry.tag_sha1"></i>
|
15
|
-
<i data-entry-icon="'tag'" data-ng-show="entry.tag_sha1"></i>
|
16
|
-
|
17
|
-
<span data-ng-show="entry.tag_sha1"><br>
|
18
|
-
<i data-entry-icon="'commit'"></i> <a data-ref-href="entry.tag_sha1">{{entry.tag_sha1}}</a>
|
19
|
-
</span>
|
20
|
-
</td>
|
21
|
-
<td><a href="#/.git/packed-refs?ref={{entry.ref}}">{{entry.ref}}</a></td>
|
22
|
-
</tr>
|
23
|
-
</tbody>
|
13
|
+
<thead>
|
14
|
+
<tr>
|
15
|
+
<th>sha1</th>
|
16
|
+
<th>ref</th>
|
17
|
+
</tr>
|
18
|
+
</thead>
|
19
|
+
<tbody>
|
20
|
+
<tr data-ng-repeat="entry in object.entries">
|
21
|
+
<td>
|
22
|
+
<i data-entry-icon="'commit'" data-ng-hide="entry.tag_sha1"></i>
|
23
|
+
<i data-entry-icon="'tag'" data-ng-show="entry.tag_sha1"></i>
|
24
|
+
<a data-ref-href="entry">{{entry.sha1}}</a>
|
25
|
+
<span data-ng-show="entry.tag_sha1"><br>
|
26
|
+
<i data-entry-icon="'commit'"></i> <a data-ref-href="entry.tag_sha1">{{entry.tag_sha1}}</a>
|
27
|
+
</span>
|
28
|
+
</td>
|
29
|
+
<td><a href="#/.git/packed-refs?ref={{entry.ref}}">{{entry.ref}}</a></td>
|
30
|
+
</tr>
|
31
|
+
</tbody>
|
24
32
|
</table>
|
25
|
-
|
26
33
|
<a href="#/.git/packed-refs" data-ng-show="limited">Show All</a>
|
34
|
+
|
35
|
+
</div>
|
36
|
+
<div class="tab-pane" id="plain">
|
37
|
+
<pre>{{object.content}}</pre>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</article>
|
42
|
+
|
27
43
|
</article>
|
data/htdocs/templates/ref.html
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
<article>
|
2
2
|
<h1><i data-entry-icon="'ref'"></i> {{path}} <small>Reference</small></h1>
|
3
3
|
|
4
|
+
<div class="tabbable">
|
5
|
+
<ul class="nav nav-tabs">
|
6
|
+
<li class="active"><a href="#parsed" data-toggle="tab">Parsed</a></li>
|
7
|
+
<li><a href="#plain" data-toggle="tab">Plain</a></li>
|
8
|
+
</ul>
|
9
|
+
<div class="tab-content">
|
10
|
+
<div class="tab-pane active" id="parsed">
|
11
|
+
|
4
12
|
<table class="table">
|
5
13
|
<tr data-ng-show="object.sha1">
|
6
14
|
<th>sha1</th><td><a data-ref-href="object">{{object.sha1}}</a></td>
|
@@ -9,4 +17,15 @@
|
|
9
17
|
<th>ref</th><td><a data-ref-href="object">{{object.ref}}</a></td>
|
10
18
|
</tr>
|
11
19
|
</table>
|
20
|
+
|
21
|
+
</div>
|
22
|
+
<div class="tab-pane" id="plain">
|
23
|
+
|
24
|
+
<pre>{{object.content}}</pre>
|
25
|
+
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
|
12
31
|
</article>
|
@@ -47,13 +47,13 @@ module GitObjectBrowser
|
|
47
47
|
|
48
48
|
def to_hash
|
49
49
|
return {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
:type => @type,
|
51
|
+
:sha1 => @sha1,
|
52
|
+
:size => @size,
|
53
|
+
:entries => @entries,
|
54
|
+
:content => @content,
|
55
|
+
:properties => @properties,
|
56
|
+
:message => @message
|
57
57
|
}
|
58
58
|
end
|
59
59
|
|
@@ -65,6 +65,7 @@ module GitObjectBrowser
|
|
65
65
|
private
|
66
66
|
|
67
67
|
def parse_tree_entries
|
68
|
+
@content = ''
|
68
69
|
entries = []
|
69
70
|
loop do
|
70
71
|
entry = {}
|
@@ -72,6 +73,7 @@ module GitObjectBrowser
|
|
72
73
|
break if entry[:mode].empty?
|
73
74
|
entry[:filename] = find_char "\0"
|
74
75
|
entry[:sha1] = hex(20)
|
76
|
+
@content += "#{entry[:mode]} #{entry[:filename]}\\0\\#{entry[:sha1]}\n"
|
75
77
|
entries << entry
|
76
78
|
end
|
77
79
|
return entries
|
@@ -86,23 +88,23 @@ module GitObjectBrowser
|
|
86
88
|
line = lines.shift
|
87
89
|
break if line.empty?
|
88
90
|
prop = {}
|
89
|
-
(prop[
|
90
|
-
if prop[
|
91
|
-
prop[
|
92
|
-
prop[
|
93
|
-
elsif %w{author committer tagger}.include?(prop[
|
91
|
+
(prop[:key], prop[:value]) = line.split(/ /, 2)
|
92
|
+
if prop[:value] =~ /\A([0-9a-f]{2})([0-9a-f]{38})\z/
|
93
|
+
prop[:type] = 'sha1'
|
94
|
+
prop[:path] = "objects/#{ $1 }/#{ $2 }"
|
95
|
+
elsif %w{author committer tagger}.include?(prop[:key]) &&
|
94
96
|
# couldn't find the spec...
|
95
|
-
prop[
|
96
|
-
prop[
|
97
|
-
prop[
|
98
|
-
prop[
|
99
|
-
prop[
|
100
|
-
prop[
|
101
|
-
prop[
|
102
|
-
prop[
|
103
|
-
prop[
|
97
|
+
prop[:value].to_s =~ /\A(.*) <(.*)> (\d+)(?: ((?:(?:\+|-)(?:\d{4}|\d{2}:\d{2}))|Z))?\z/
|
98
|
+
prop[:type] = 'user'
|
99
|
+
prop[:name] = $1.force_encoding("UTF-8")
|
100
|
+
prop[:name] = '(not UTF-8)' unless prop[:name].valid_encoding?
|
101
|
+
prop[:email] = $2.force_encoding("UTF-8")
|
102
|
+
prop[:email] = '(not UTF-8)' unless prop[:email].valid_encoding?
|
103
|
+
prop[:unixtime] = $3
|
104
|
+
prop[:timezone] = $4
|
105
|
+
prop[:date] = epoch($3.to_i, $4).iso8601
|
104
106
|
else
|
105
|
-
prop[
|
107
|
+
prop[:type] = 'text'
|
106
108
|
end
|
107
109
|
properties << prop
|
108
110
|
end
|
@@ -60,11 +60,11 @@ module GitObjectBrowser
|
|
60
60
|
end
|
61
61
|
|
62
62
|
return {
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
:version => @version,
|
64
|
+
:entry_count => @entry_count,
|
65
|
+
:entries => entries,
|
66
|
+
:extensions => extensions,
|
67
|
+
:sha1 => @sha1,
|
68
68
|
}
|
69
69
|
end
|
70
70
|
|
@@ -66,27 +66,27 @@ module GitObjectBrowser
|
|
66
66
|
|
67
67
|
def to_hash
|
68
68
|
return {
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
69
|
+
:ctime => @ctime,
|
70
|
+
:cnano => @cnano,
|
71
|
+
:mtime => @mtime,
|
72
|
+
:mnano => @mnano,
|
73
|
+
:dev => @dev,
|
74
|
+
:ino => @ino,
|
75
|
+
:object_type => @object_type,
|
76
|
+
:unix_permission => @unix_permission,
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
:uid => @uid,
|
79
|
+
:gid => @gid,
|
80
|
+
:size => @size,
|
81
|
+
:sha1 => @sha1,
|
82
|
+
:path => @path,
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
84
|
+
:assume_valid_flag => @assume_valid_flag,
|
85
|
+
:extended_flag => @extended_flag,
|
86
|
+
:stage => @stage,
|
87
|
+
:skip_worktree => @skip_worktree,
|
88
|
+
:intent_to_add => @intent_to_add,
|
89
|
+
:name_length => @name_length,
|
90
90
|
}
|
91
91
|
end
|
92
92
|
|
@@ -18,19 +18,19 @@ module GitObjectBrowser
|
|
18
18
|
length = 0
|
19
19
|
while (length < @total_length)
|
20
20
|
entry = {}
|
21
|
-
entry[
|
22
|
-
entry[
|
23
|
-
entry[
|
21
|
+
entry[:path_component] = find_char "\0"
|
22
|
+
entry[:entry_count] = find_char " "
|
23
|
+
entry[:subtree_count] = find_char "\n"
|
24
24
|
|
25
|
-
length += entry[
|
26
|
-
length += entry[
|
27
|
-
length += entry[
|
25
|
+
length += entry[:path_component].bytesize + 1
|
26
|
+
length += entry[:entry_count].bytesize + 1
|
27
|
+
length += entry[:subtree_count].bytesize + 1
|
28
28
|
|
29
|
-
entry[
|
30
|
-
entry[
|
29
|
+
entry[:entry_count] = entry[:entry_count].to_i
|
30
|
+
entry[:subtree_count] = entry[:subtree_count].to_i
|
31
31
|
|
32
|
-
if 0 <= entry[
|
33
|
-
entry[
|
32
|
+
if 0 <= entry[:entry_count]
|
33
|
+
entry[:sha1] = hex(20)
|
34
34
|
length += 20
|
35
35
|
end
|
36
36
|
@entries << entry
|
@@ -41,9 +41,9 @@ module GitObjectBrowser
|
|
41
41
|
|
42
42
|
def to_hash
|
43
43
|
return {
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
:signature => @signature,
|
45
|
+
:total_length => @total_length,
|
46
|
+
:entries => @entries
|
47
47
|
}
|
48
48
|
end
|
49
49
|
|
@@ -121,10 +121,10 @@ module GitObjectBrowser
|
|
121
121
|
|
122
122
|
def to_hash
|
123
123
|
return {
|
124
|
-
:fanout
|
125
|
-
:entries
|
124
|
+
:fanout => @fanout,
|
125
|
+
:entries => @entries,
|
126
126
|
:packfile_sha1 => @packfile_sha1,
|
127
|
-
:index_sha1
|
127
|
+
:index_sha1 => @index_sha1,
|
128
128
|
}
|
129
129
|
end
|
130
130
|
|
@@ -5,6 +5,8 @@ module GitObjectBrowser
|
|
5
5
|
|
6
6
|
class PackedRefs
|
7
7
|
def initialize(input)
|
8
|
+
@content = input.read(nil)
|
9
|
+
input.seek(0)
|
8
10
|
@entries = []
|
9
11
|
while (line = input.gets) do
|
10
12
|
next if line =~ /\A\s*#/
|
@@ -25,7 +27,8 @@ module GitObjectBrowser
|
|
25
27
|
|
26
28
|
def to_hash
|
27
29
|
return {
|
28
|
-
:entries => @entries
|
30
|
+
:entries => @entries,
|
31
|
+
:content => @content
|
29
32
|
}
|
30
33
|
end
|
31
34
|
|
@@ -5,19 +5,20 @@ module GitObjectBrowser
|
|
5
5
|
|
6
6
|
class Ref
|
7
7
|
def initialize(input)
|
8
|
-
|
8
|
+
@content = input.read(nil)
|
9
9
|
|
10
|
-
if
|
10
|
+
if @content =~ %r{\Aref:\s*(.+)}
|
11
11
|
@ref = $1
|
12
|
-
elsif
|
12
|
+
elsif @content =~ %r{\A([0-9a-f]{40})}
|
13
13
|
@sha1 = $1
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def to_hash
|
18
18
|
return {
|
19
|
-
|
20
|
-
|
19
|
+
:ref => @ref,
|
20
|
+
:sha1 => @sha1,
|
21
|
+
:content => @content
|
21
22
|
}
|
22
23
|
end
|
23
24
|
|
@@ -65,11 +65,16 @@ module GitObjectBrowser
|
|
65
65
|
def response_wrapped_object(response, type, obj)
|
66
66
|
ok(response)
|
67
67
|
hash = {}
|
68
|
-
hash[
|
69
|
-
hash[
|
70
|
-
hash[
|
71
|
-
hash[
|
72
|
-
hash[
|
68
|
+
hash[:type] = type
|
69
|
+
hash[:object] = obj.to_hash
|
70
|
+
hash[:root] = @target
|
71
|
+
hash[:path] = @relpath
|
72
|
+
hash[:wroking_dir] = File.basename(File.dirname(@target))
|
73
|
+
|
74
|
+
if type == 'packed_object'
|
75
|
+
sha1 = hash[:object][:object][:sha1]
|
76
|
+
hash[:unpacked] = File.exist?(File.join(@target, 'objects', sha1[0..1], sha1[2..-1]).to_s)
|
77
|
+
end
|
73
78
|
|
74
79
|
response.body = ::JSON.generate(hash)
|
75
80
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
"sha1": "d234c5e057fe32c676ea67e8cb38f4625ddaeb54"
|
15
15
|
}
|
16
16
|
],
|
17
|
-
"content":
|
17
|
+
"content": "100644 sample-a.txt\\0\\1d3dc60b5a117054e43741d51e599ff31bb15f9f\n100644 sample.txt\\0\\d234c5e057fe32c676ea67e8cb38f4625ddaeb54\n",
|
18
18
|
"properties": null,
|
19
19
|
"message": null
|
20
20
|
}
|
@@ -11,30 +11,30 @@ module GitObjectBrowser::Models
|
|
11
11
|
|
12
12
|
it 'should parse header' do
|
13
13
|
index = subject.parse.to_hash
|
14
|
-
index[
|
15
|
-
index[
|
14
|
+
index[:version].should eq 2
|
15
|
+
index[:entry_count].should eq index[:entries].length
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should parse entries' do
|
19
19
|
index = subject.parse.to_hash
|
20
|
-
entries = index[
|
20
|
+
entries = index[:entries]
|
21
21
|
entries.length.should eq 2
|
22
|
-
entries[0][
|
23
|
-
entries[0][
|
24
|
-
entries[0][
|
25
|
-
entries[0][
|
26
|
-
entries[0][
|
22
|
+
entries[0][:path].should eq 'sample-a.txt'
|
23
|
+
entries[0][:sha1].should eq '1d3dc60b5a117054e43741d51e599ff31bb15f9f'
|
24
|
+
entries[0][:object_type].should eq '1000'
|
25
|
+
entries[0][:unix_permission].should eq '644'
|
26
|
+
entries[0][:size].should eq 9
|
27
27
|
|
28
|
-
entries[1][
|
29
|
-
entries[1][
|
30
|
-
entries[1][
|
31
|
-
entries[1][
|
32
|
-
entries[0][
|
28
|
+
entries[1][:path].should eq 'sample.txt'
|
29
|
+
entries[1][:sha1].should eq 'd234c5e057fe32c676ea67e8cb38f4625ddaeb54'
|
30
|
+
entries[1][:object_type].should eq '1000'
|
31
|
+
entries[1][:unix_permission].should eq '644'
|
32
|
+
entries[0][:size].should eq 9
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'should parse extensions (index_tree_extension_spec.rb tests the content)' do
|
36
36
|
index = subject.parse.to_hash
|
37
|
-
extensions = index[
|
37
|
+
extensions = index[:extensions]
|
38
38
|
extensions.length.should eq 1
|
39
39
|
end
|
40
40
|
|
@@ -14,18 +14,18 @@ module GitObjectBrowser::Models
|
|
14
14
|
|
15
15
|
it 'should parse extension signature and length' do
|
16
16
|
data = subject.parse.to_hash
|
17
|
-
tree = data[
|
18
|
-
tree[
|
19
|
-
tree[
|
17
|
+
tree = data[:extensions][0]
|
18
|
+
tree[:signature].should eq 'TREE'
|
19
|
+
tree[:total_length].should eq 25
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'should parse entries' do
|
23
|
-
entries = subject.parse.to_hash[
|
23
|
+
entries = subject.parse.to_hash[:extensions][0][:entries]
|
24
24
|
entries.length.should eq 1
|
25
25
|
entry = entries.first
|
26
|
-
entry[
|
27
|
-
entry[
|
28
|
-
entry[
|
26
|
+
entry[:sha1].should eq 'c36491256978d26c08cd7aa97eee0f5631f96659'
|
27
|
+
entry[:entry_count].should eq 2
|
28
|
+
entry[:subtree_count].should eq 0
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -34,24 +34,24 @@ module GitObjectBrowser::Models
|
|
34
34
|
|
35
35
|
it 'should parse extension signature and length' do
|
36
36
|
data = subject.parse.to_hash
|
37
|
-
tree = data[
|
38
|
-
tree[
|
39
|
-
tree[
|
37
|
+
tree = data[:extensions][0]
|
38
|
+
tree[:signature].should eq 'TREE'
|
39
|
+
tree[:total_length].should eq 6
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'should return -1 entry_count' do
|
43
|
-
entries = subject.parse.to_hash[
|
43
|
+
entries = subject.parse.to_hash[:extensions][0][:entries]
|
44
44
|
entries.length.should eq 1
|
45
45
|
entry = entries.first
|
46
|
-
entry[
|
47
|
-
entry[
|
48
|
-
entry[
|
49
|
-
entry[
|
46
|
+
entry[:entry_count].should eq -1
|
47
|
+
entry[:subtree_count].should eq 0
|
48
|
+
entry[:path_component].should eq ''
|
49
|
+
entry[:sha1].should be_nil
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'return correct hash' do
|
53
53
|
data = subject.parse.to_hash
|
54
|
-
data[
|
54
|
+
data[:sha1].should eq 'ad7408a5d4e6050d3b95c21d260ae568b24e4d19'
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -5,7 +5,7 @@ module GitObjectBrowser::Models
|
|
5
5
|
it 'should read content' do
|
6
6
|
input = File.open(File.join(FIXTURES_DIR, 'git/plain_file'))
|
7
7
|
data = PlainFile.new(input).parse.to_hash
|
8
|
-
data.should eq({
|
8
|
+
data.should eq({ :content => 'sample' })
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-object-browser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Browse git raw objects.
|
15
15
|
email:
|
@@ -182,6 +182,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
182
|
- - ! '>='
|
183
183
|
- !ruby/object:Gem::Version
|
184
184
|
version: '0'
|
185
|
+
segments:
|
186
|
+
- 0
|
187
|
+
hash: -211213857821396965
|
185
188
|
requirements: []
|
186
189
|
rubyforge_project:
|
187
190
|
rubygems_version: 1.8.24
|