git_spelunk 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzAyMWIwY2EzMjU2NWM1YTFmMDE3NDFkOTQzODg2ZmEwYzBiZDM5MQ==
4
+ YjQwOThjMDk4OGM4YjhjMTY2OWUxNDBjOTc4NGU1MzdjN2MxYzQ1MQ==
5
5
  data.tar.gz: !binary |-
6
- Zjg4Nzg3ZDhkN2QwODAzOTQxY2Y2YTYzMWE0NWQ3NjE2ZjFiYjg1OQ==
6
+ MzA1ZGE4ZmJlMDY2OGRiZDhjZjgyZjNmNGFiZDJlMzFiMTQ5YWZmNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- M2M4MjljMTM1ODMwMjZlZGY1YTFjOGNiODYxNWRjMGNmOTM2ZmFjZTU0NDc1
10
- MDNlYWQxMzJlOTc2Njg1Y2EyMDMxNzI1YjZlYTVhODNhMjY4Yjg4ZDQyOGIy
11
- OWUwODI5YzI2Mjg5N2E4YWI2ZWQxZWE2ZmExMDIxYzkwNzZlZmY=
9
+ YTgxODcyZTNkMTk5YmU0ODE4MDg5NjA0ZGVjNDNmNjQxMDAzMWI5ZmNlZWQ2
10
+ OTQ5MTAwMmFlOTA2N2ZkMmMxNWM4NDM0OTM0NTlhNTAxZGRmNjYxZGFhNDcw
11
+ MDFkODE1MzQwNzkxOGRjYzczMGRjYzRiZjMzYzk4OTE2MjM5OGM=
12
12
  data.tar.gz: !binary |-
13
- NTUxYTYwZGZlNGM3MTIzMDIyY2EzMTI4ZTkwMzJjZWY2NjRlNTlhYzJmZGVm
14
- OWQwMmVhYzZjYTAxNTRmMmJmZGFmMmNhYmE1NjY1YzYyMGY0M2NmOTU0YjFm
15
- YWU5ZTc0M2YzYTlhYTk2ODIzMTI0NzU0NWYzOTNjMDUzMDA2MDg=
13
+ ODY2YTIxNTU5YzQ5ZDBmYjM1NGI2MWIxYzJiZGQzMWE5NGYyZTA5Mzk4ZjI0
14
+ MWEwNTYyM2Q0YzQ4YjNhYTM1NDYzMjJiNzU2YmM5MmY4N2ZlYzk5ODllMDQz
15
+ NmRmODM5M2YyMjMwZGIzM2M2ZDJhZWVjMDQxZGQwYmUzODdkMWI=
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (C) 2013 Ben Osheroff <ben@zendesk.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/git-spelunk CHANGED
@@ -1,6 +1,36 @@
1
1
  #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
3
  require 'git_spelunk'
4
+ require 'optparse'
3
5
 
4
- file_context = GitSpelunk::FileContext.new(ARGV[0], {:sha => ARGV[1], :line_number => ARGV[2]})
6
+ def parse_options(argv)
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = <<-BANNER.gsub(/^ {6}/, "")
10
+ An interactive tool for exploring blame history.
11
+
12
+ Usage:
13
+ git-spelunk some_file.rb
14
+ git-spelunk some_file.rb:123
15
+
16
+ Options:
17
+ BANNER
18
+ opts.on("-s", "--sha SHA", String, "Start on this sha") { |sha| options[:sha] = sha }
19
+ opts.on("-h", "--help", "Show this.") { puts opts; exit }
20
+ opts.on("-v", "--version", "Show Version"){ puts GitSpelunk::VERSION; exit}
21
+ end.parse!(argv)
22
+ options
23
+ end
24
+
25
+ options = parse_options(ARGV)
26
+
27
+ raise "Too many arguments" if ARGV.size != 1
28
+
29
+ file = ARGV[0]
30
+
31
+ file, line = file.split(':',2) if file.include?(':')
32
+ options[:line_number] = line
33
+
34
+ file_context = GitSpelunk::FileContext.new(file, options)
5
35
  ui = GitSpelunk::UI.new(file_context)
6
36
  ui.run
@@ -12,7 +12,7 @@ module GitSpelunk
12
12
 
13
13
  @repo = options.fetch(:repo) do
14
14
  repo_directory = find_repo_from_file(file)
15
- @file = file.sub(%r{^#{repo_directory}/}, '')
15
+ @file = File.expand_path(file).sub(%r{^#{repo_directory}/}, '')
16
16
  Grit::Repo.new(repo_directory)
17
17
  end
18
18
 
@@ -28,21 +28,12 @@ module GitSpelunk
28
28
 
29
29
  def get_line_for_sha_parent(line_number)
30
30
  o = GitSpelunk::Offset.new(@repo, @file, sha_for_line(line_number), @new_to_old[line_number])
31
- line = o.line_number_to_parent
32
- if line
33
- line
34
- else
35
- if o.at_beginning_of_time?
36
- :at_beginning_of_time
37
- elsif o.unable_to_trace_lineage?
38
- :unable_to_trace
39
- end
40
- end
31
+ o.line_number_to_parent
41
32
  end
42
33
 
43
34
  def find_repo_from_file(file)
44
35
  file = './' + file unless file.start_with?('/')
45
- targets = file.split('/')
36
+ targets = File.expand_path(file).split('/')
46
37
  targets.pop
47
38
  while !File.directory?(targets.join("/") + "/.git")
48
39
  targets.pop
@@ -5,5 +5,10 @@ if RUBY_VERSION >= "2.0.0"
5
5
  def getord(offset); self[offset].ord; end
6
6
  end
7
7
 
8
- PACK_IDX_SIGNATURE = "\377tOc".force_encoding(Encoding::ASCII_8BIT)
8
+ begin
9
+ old, $VERBOSE = $VERBOSE, nil
10
+ PACK_IDX_SIGNATURE = "\377tOc".force_encoding(Encoding::ASCII_8BIT)
11
+ ensure
12
+ $VERBOSE = old
13
+ end
9
14
  end
@@ -59,13 +59,19 @@ module GitSpelunk
59
59
  @parent && (@chunks.nil? || target_chunk.nil?)
60
60
  end
61
61
 
62
+ def first_commit_for_file?
63
+
64
+ end
65
+
62
66
  def line_number_to_parent
63
- return nil unless @parent && chunks
67
+ return :at_beginning_of_time unless @parent && chunks
64
68
  chunk = target_chunk(@line_number)
65
- return nil unless chunk
69
+ return :unable_to_trace unless chunk
70
+
71
+ parent_starting_line, parent_total_lines = parent_start_and_total(stats_line(chunk))
72
+ return :first_commit_for_file if parent_starting_line == 0 && parent_total_lines == 0
66
73
 
67
74
  chunk_starting_line, chunk_total_lines = src_start_and_total(stats_line(chunk))
68
- parent_starting_line = parent_start_and_total(stats_line(chunk))[0]
69
75
  parent_line_offset = find_parent_line_number(diff_lines(chunk), @line_number, chunk_starting_line, chunk_total_lines)
70
76
  parent_starting_line + parent_line_offset
71
77
  end
@@ -93,11 +99,11 @@ module GitSpelunk
93
99
  def src_start_and_total(line)
94
100
  # Get the offset and line number where lines were added
95
101
  # @@ -3,10 +3,17 @@ optionally a line\n unchnaged_line_1\n- deleted_line_1\n+ new_line_1"
96
- line.scan(/\+(.*)@@/)[0][0].split(",").map {|str| str.to_i}
102
+ line.scan(/\+(\d+),(\d+)/).first.map { |str| str.to_i }
97
103
  end
98
104
 
99
105
  def parent_start_and_total(line)
100
- line.scan(/\-(.*)\+/)[0][0].split(",").map {|str| str.to_i}
106
+ line.scan(/\-(\d+),(\d+)/).first.map { |str| str.to_i }
101
107
  end
102
108
 
103
109
  def find_parent_line_number(lines, src_line_number, src_starting_line, src_number_of_lines)
@@ -122,8 +128,9 @@ module GitSpelunk
122
128
  removals = additions = 0
123
129
  diff_index -= 1
124
130
 
125
- while true
131
+ while diff_index > 0
126
132
  line = lines[diff_index]
133
+
127
134
  break unless ["-", "+"].include?(line[0])
128
135
 
129
136
  if parent_line?(line)
@@ -14,7 +14,7 @@ module GitSpelunk
14
14
  @window.setpos(0,0)
15
15
  draw_status_line
16
16
  @window.addstr(@content + "\n") if content
17
- @window.addstr("\n" * (@height - @content.split("\n").size - 2))
17
+ @window.addstr("\n" * (@height - @content.split("\n").size - 1))
18
18
  @window.refresh
19
19
  end
20
20
 
@@ -24,6 +24,7 @@ module GitSpelunk
24
24
  @window.addstr("history: [ ] ")
25
25
  @window.addstr("search: / ? n N ")
26
26
  @window.addstr("git-show: s ")
27
+ @window.addstr("quit: q ")
27
28
  @window.addstr(" " * line_remainder + "\n")
28
29
  end
29
30
  end
@@ -36,7 +36,7 @@ module GitSpelunk
36
36
  end
37
37
 
38
38
  def calculate_heights!
39
- @repo_height = (Curses.lines.to_f * 0.20).to_i
39
+ @repo_height = [(Curses.lines.to_f * 0.20).to_i, 6].max
40
40
  @pager_height = Curses.lines - @repo_height - 1
41
41
  @status_height = 1
42
42
  end
@@ -84,6 +84,44 @@ module GitSpelunk
84
84
  @status.clear_onetime_message!
85
85
  end
86
86
 
87
+ def history_back
88
+ @status.set_onetime_message("Rewinding...")
89
+ goto = @file_context.get_line_for_sha_parent(@pager.cursor)
90
+ if goto.is_a?(Fixnum)
91
+ @file_context.line_number = @pager.cursor
92
+ @history.push(@file_context)
93
+
94
+ @file_context = @file_context.clone_for_parent_sha(@pager.cursor)
95
+ @pager.data = @file_context.get_blame
96
+ @pager.go_to(goto)
97
+
98
+ # force commit info update
99
+ @status.clear_onetime_message!
100
+ set_status_message
101
+ @last_line = nil
102
+ elsif goto == :at_beginning_of_time
103
+ @status.set_onetime_message("At beginning of repository history!")
104
+ elsif goto == :unable_to_trace
105
+ @status.set_onetime_message("Unable to trace lineage of file line")
106
+ elsif goto == :first_commit_for_file
107
+ @status.set_onetime_message("At first appearance of file")
108
+ end
109
+ end
110
+
111
+ def history_forward
112
+ if @history.last
113
+ @file_context = @history.pop
114
+ @pager.data = @file_context.get_blame
115
+ @pager.go_to(@file_context.line_number)
116
+
117
+ @status.clear_onetime_message!
118
+ set_status_message
119
+
120
+ # force commit info update
121
+ @last_line = nil
122
+ end
123
+ end
124
+
87
125
  def handle_key(key)
88
126
  @heartbeat = Time.now
89
127
  case key
@@ -114,37 +152,9 @@ module GitSpelunk
114
152
  end
115
153
  after_navigation
116
154
  when '['
117
- @status.set_onetime_message("Rewinding...")
118
- goto = @file_context.get_line_for_sha_parent(@pager.cursor)
119
- if goto.is_a?(Fixnum)
120
- @file_context.line_number = @pager.cursor
121
- @history.push(@file_context)
122
-
123
- @file_context = @file_context.clone_for_parent_sha(@pager.cursor)
124
- @pager.data = @file_context.get_blame
125
- @pager.go_to(goto)
126
-
127
- # force commit info update
128
- @status.clear_onetime_message!
129
- set_status_message
130
- @last_line = nil
131
- elsif goto == :at_beginning_of_time
132
- @status.set_onetime_message("At beginning of repository history!")
133
- elsif goto == :unable_to_trace
134
- @status.set_onetime_message("Unable to trace lineage of file line")
135
- end
155
+ history_back
136
156
  when ']'
137
- if @history.last
138
- @file_context = @history.pop
139
- @pager.data = @file_context.get_blame
140
- @pager.go_to(@file_context.line_number)
141
-
142
- @status.clear_onetime_message!
143
- set_status_message
144
-
145
- # force commit info update
146
- @last_line = nil
147
- end
157
+ history_forward
148
158
  when 's'
149
159
  @heartbeat = nil
150
160
  sha = @file_context.sha_for_line(@pager.cursor)
@@ -167,7 +177,7 @@ module GitSpelunk
167
177
  when 'N'
168
178
  @pager.search(nil, true, true)
169
179
  after_navigation
170
- when 'q'
180
+ when 'q', Curses::KEY_CTRL_C
171
181
  exit
172
182
  end
173
183
  end
@@ -0,0 +1,3 @@
1
+ module GitSpelunk
2
+ VERSION = "0.2.3"
3
+ end
data/lib/git_spelunk.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'debugger'
1
+ require 'git_spelunk/version'
2
2
  require 'git_spelunk/ui'
3
3
  require 'git_spelunk/file_context'
4
4
  require 'git_spelunk/offset'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_spelunk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Osheroff
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-12 00:00:00.000000000 Z
12
+ date: 2013-12-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: grit
@@ -35,19 +35,21 @@ executables:
35
35
  extensions: []
36
36
  extra_rdoc_files: []
37
37
  files:
38
- - lib/git_spelunk/file.rb
38
+ - MIT-LICENSE.txt
39
+ - bin/git-spelunk
40
+ - lib/git_spelunk.rb
39
41
  - lib/git_spelunk/file_context.rb
40
42
  - lib/git_spelunk/grit_patches.rb
41
43
  - lib/git_spelunk/offset.rb
44
+ - lib/git_spelunk/ui.rb
42
45
  - lib/git_spelunk/ui/pager.rb
43
46
  - lib/git_spelunk/ui/repo.rb
44
47
  - lib/git_spelunk/ui/status.rb
45
48
  - lib/git_spelunk/ui/window.rb
46
- - lib/git_spelunk/ui.rb
47
- - lib/git_spelunk.rb
48
- - bin/git-spelunk
49
+ - lib/git_spelunk/version.rb
49
50
  homepage: https://github.com/osheroff/git-spelunk
50
- licenses: []
51
+ licenses:
52
+ - MIT
51
53
  metadata: {}
52
54
  post_install_message:
53
55
  rdoc_options: []
@@ -62,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
64
  requirements:
63
65
  - - ! '>='
64
66
  - !ruby/object:Gem::Version
65
- version: 1.3.6
67
+ version: '0'
66
68
  requirements: []
67
69
  rubyforge_project:
68
70
  rubygems_version: 2.1.11
@@ -1,25 +0,0 @@
1
- require 'grit'
2
-
3
- module GitSpelunk
4
- class File
5
- def initialize(filename, sha, line=1)
6
- @filename = filename
7
- @sha = sha
8
- @line = line
9
- end
10
-
11
- def blame
12
- [
13
- ["abcdef", "content"],
14
- ["abcdef", "content"],
15
- ["abcdef", "content"],
16
- ["abcdef", "content"],
17
- ["abcdef", "content"]
18
- ["abcdef", "content"]
19
- ["abcdef", "content"]
20
- ["abcdef", "content"]
21
- ["abcdef", "content"]
22
- ]
23
- end
24
- end
25
- end