git_spelunk 0.4.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1b01cdc9019c68eea06ac6c29c082825ca79fe38
4
- data.tar.gz: 3b735af021fb4cc09e22ee3f27658094bf87c70f
2
+ SHA256:
3
+ metadata.gz: 4f571a8a5c7f7c2e3d00e1b104353202244f01ea94e789f1783b416b941586c0
4
+ data.tar.gz: 9327729f1087501a9865f17b03eac8e2b833733766909441357df7b2e2f3da43
5
5
  SHA512:
6
- metadata.gz: 977b086900391210e36e91eda889a68c9327ca0e84cab598dcc51ca071658f30163ac797f650e096fbd2e410e25f767d5a9b2cf13d24b53a912b9f1ccffc5a8a
7
- data.tar.gz: 30d809b6d384b71491be31d48501f435ad2de9f8dd61cbdba87ca4ac80c7e016a7e5f832cd565316ae7d99724d289d01aa593293d99ac47683322612bbb38421
6
+ metadata.gz: cbe0f470a68bfd871f0c2872ca7937d7162b995306ed1c27f0404356d4e488248661a93d81610a2d5d53381843d2e7319c5101ce6bc41866da98767661cc7447
7
+ data.tar.gz: 5ad729cf39617c9b2b5474f64ac9c34d2149f6cf47a5c6dfbd86d6d6c1585b4d67b8947acbce625f990abacd5229b1e69893ae4553ed0aacf947c0dda1dbb87d
data/bin/git-spelunk CHANGED
@@ -25,8 +25,8 @@ end
25
25
 
26
26
  options = parse_options(ARGV)
27
27
 
28
- raise "No filename specified. You must provide a file to blame-on." if ARGV.size == 0
29
- raise "Too many arguments" if ARGV.size > 1
28
+ abort "No filename specified. You must provide a file to blame-on." if ARGV.size == 0
29
+ abort "Too many arguments" if ARGV.size > 1
30
30
 
31
31
  file = ARGV[0]
32
32
 
@@ -1,7 +1,23 @@
1
+ require 'open3'
2
+
1
3
  module GitSpelunk
2
4
  BlameLine = Struct.new(:line_number, :old_line_number, :sha, :commit, :filename, :content)
3
5
  class EmptyBlame < StandardError ; end
4
- class Blame < Grit::Blame
6
+ class Blame
7
+ def initialize(repo, file, sha)
8
+ @lines = nil
9
+ @repo = repo
10
+ @file = file
11
+ @sha = sha
12
+ end
13
+
14
+ def lines
15
+ return @lines if @lines
16
+ cmd = ["git", "--git-dir", @repo.path, "blame", "--porcelain", @sha, "--", @file]
17
+ output, err, status = Open3.capture3(*cmd)
18
+ @lines ||= process_raw_blame(output)
19
+ end
20
+
5
21
  def process_raw_blame(output)
6
22
  lines = []
7
23
  commits = {}
@@ -17,8 +33,7 @@ module GitSpelunk
17
33
 
18
34
  sha, old_lineno, lineno = sha_split[0], sha_split[1].to_i, sha_split[2].to_i
19
35
 
20
- # indicate we need to fetch this sha in the bulk-fetch
21
- commits[sha] = nil
36
+ commits[sha] ||= @repo.lookup(sha)
22
37
 
23
38
  if rest =~ /^filename (.*)$/
24
39
  commit_file_map[sha] = $1
@@ -28,16 +43,9 @@ module GitSpelunk
28
43
  { :data => data, :sha => sha, :filename => commit_file_map[sha], :old_line_number => old_lineno, :line_number => lineno }
29
44
  end
30
45
 
31
-
32
- # load all commits in single call
33
- @repo.batch(*commits.keys).each do |commit|
34
- commits[commit.id] = commit
35
- end
36
-
37
- @lines = lines.map do |hash|
46
+ lines.map do |hash|
38
47
  GitSpelunk::BlameLine.new(hash[:line_number], hash[:old_line_number], hash[:sha], commits[hash[:sha]], hash[:filename], hash[:data])
39
48
  end
40
49
  end
41
50
  end
42
51
  end
43
-
@@ -1,4 +1,4 @@
1
- require 'grit'
1
+ require 'rugged'
2
2
  require 'fileutils'
3
3
  require 'git_spelunk/blame'
4
4
 
@@ -12,12 +12,10 @@ module GitSpelunk
12
12
  @line_number = options[:line_number] || 1
13
13
 
14
14
  @repo = options.fetch(:repo) do
15
- repo_directory = find_repo_from_file(file)
16
- @file = File.expand_path(file).sub(%r{^#{repo_directory}/}, '')
17
- Grit::Repo.new(repo_directory)
15
+ find_repo_from_file(file)
18
16
  end
19
17
 
20
- @file ||= options.fetch(:file)
18
+ @file = File.expand_path(file).sub(@repo.workdir, '')
21
19
  @commit_cache = {}
22
20
  end
23
21
 
@@ -32,18 +30,7 @@ module GitSpelunk
32
30
  end
33
31
 
34
32
  def find_repo_from_file(file)
35
- file = './' + file unless file.start_with?('/')
36
- targets = File.expand_path(file).split('/')
37
- targets.pop
38
- while !File.directory?(targets.join("/") + "/.git")
39
- targets.pop
40
- end
41
-
42
- if targets.empty?
43
- nil
44
- else
45
- targets.join("/")
46
- end
33
+ Rugged::Repository.discover(file)
47
34
  end
48
35
 
49
36
  def get_blame
@@ -58,15 +45,17 @@ module GitSpelunk
58
45
  get_blame
59
46
  commit = blame_line.commit
60
47
  return nil unless commit
61
-
62
- author_info = commit.author_string.split(" ")
63
- tz = author_info.pop
64
- utc = Time.at(author_info.pop.to_i)
65
- [
66
- "commit " + commit.id,
67
- "Author: " + author_info.join(" "),
68
- "Date: " + utc.to_s
69
- ].join("\n") + "\n\n" + " " + commit.short_message
48
+ author = commit.author
49
+
50
+ author_info = "%s %s" % [author[:name], author[:email]]
51
+ short_message = commit.message.split("\n").find { |x| !x.strip.empty? } || ''
52
+ utc = author[:time]
53
+ {
54
+ commit: commit.oid,
55
+ author: author_info,
56
+ date: author[:time].to_s,
57
+ message: commit.message
58
+ }
70
59
  end
71
60
  end
72
61
  end
@@ -33,17 +33,16 @@
33
33
 
34
34
 
35
35
  module GitSpelunk
36
- require 'grit'
37
-
38
36
  class Offset
39
- attr_reader :repo, :file_name, :sha, :chunks
37
+ attr_reader :repo, :file_name, :sha, :hunks
40
38
 
41
39
  def initialize(repo, file_name, sha, line_number)
42
40
  @repo = repo
43
41
  @file_name = file_name
44
42
  @sha = sha
45
43
  @line_number = line_number
46
- @parent = @repo.commits(@sha)[0].parents[0]
44
+ @commit = @repo.lookup(@sha)
45
+ @parent = @commit.parents[0]
47
46
  true
48
47
  end
49
48
 
@@ -51,9 +50,13 @@ module GitSpelunk
51
50
  class Chunk
52
51
  attr_reader :minus_offset, :minus_length, :plus_offset, :plus_length, :lines
53
52
 
54
- def initialize(data)
55
- @minus_offset, @minus_length, @plus_offset, @plus_length = *extract_stats(data[0])
56
- @lines = data[1..-1]
53
+ def initialize(hunk)
54
+ @minus_offset = hunk.old_start
55
+ @minus_length = hunk.old_lines
56
+ @plus_offset = hunk.new_start
57
+ @plus_length = hunk.new_lines
58
+
59
+ @lines = hunk.lines
57
60
  end
58
61
 
59
62
  def has_line?(line_number)
@@ -66,7 +69,7 @@ module GitSpelunk
66
69
  end
67
70
 
68
71
  def type
69
- data.first[0]
72
+ data.first.line_origin
70
73
  end
71
74
 
72
75
  def size
@@ -79,6 +82,7 @@ module GitSpelunk
79
82
  end
80
83
 
81
84
  def find_parent_line_number(target)
85
+ return 1 if target == 1
82
86
  # separate in blocks of lines with the same prefix
83
87
 
84
88
  old_line_number = minus_offset
@@ -86,16 +90,15 @@ module GitSpelunk
86
90
 
87
91
  blocks = []
88
92
  lines.each do |l|
89
- next if l =~ /\/
90
93
  last_block = blocks.last
91
94
 
92
- if last_block.nil? || last_block.type != l[0]
95
+ if last_block.nil? || last_block.type != l.line_origin
93
96
  blocks << LineBlock.new(old_line_number, l)
94
97
  else
95
98
  last_block << l
96
99
  end
97
100
 
98
- if l[0] == "+" || l[0] == " "
101
+ if l.line_origin == :context || l.line_origin == :addition
99
102
  if new_line_number == target
100
103
  # important: we don't finish building the structure.
101
104
  break
@@ -104,7 +107,7 @@ module GitSpelunk
104
107
  new_line_number += 1
105
108
  end
106
109
 
107
- if l[0] == "-" || l[0] == " "
110
+ if l.line_origin == :deletion || l.line_origin == :context
108
111
  old_line_number += 1
109
112
  end
110
113
  end
@@ -112,7 +115,7 @@ module GitSpelunk
112
115
  addition_block = blocks.pop
113
116
  last_old_block = blocks.last
114
117
 
115
- if last_old_block.type == " "
118
+ if last_old_block.type == :context
116
119
  # if the previous context existed in both, just go to the end of that.
117
120
  last_old_block.offset + (last_old_block.size - 1)
118
121
  else
@@ -120,37 +123,14 @@ module GitSpelunk
120
123
  last_old_block.offset + [addition_block.size - 1, last_old_block.size].min
121
124
  end
122
125
  end
123
-
124
- private
125
-
126
- def extract_stats(l)
127
- #@@ -1,355 +1,355 @@
128
- l.scan(STATS_PATTERN).first.map(&:to_i)
129
- end
130
-
131
- def old_has?(line)
132
- # Src line will either have a "+" or will be an unchanged line
133
- line[0] == '-' || line[0] == " "
134
- end
135
-
136
- def new_has?(line)
137
- # Src line will either have a "-" or will be an unchanged line
138
- line[0] == '+' || line[0] == " "
139
- end
140
126
  end
141
127
 
142
- def chunks
143
- @chunks ||= begin
144
- diffs = @repo.diff(@parent.id, @sha, @file_name)
145
- return nil if diffs.empty?
146
-
147
- chunks = diffs[0].diff.split(/\n/).inject([[]]) do |arr, line|
148
- arr.push([]) if line =~ STATS_PATTERN
149
- arr.last << line
150
- arr
151
- end
128
+ def hunks
129
+ @hunks ||= begin
130
+ diff = @parent.diff(@commit, paths: [@file_name])
131
+ return nil unless diff
152
132
 
153
- chunks[1..-1].map { |c| Chunk.new(c) } # slice off first chunk -- it's just the filename
133
+ diff.patches[0].hunks.map { |h| Chunk.new(h) }
154
134
  end
155
135
  end
156
136
 
@@ -159,11 +139,11 @@ module GitSpelunk
159
139
  end
160
140
 
161
141
  def unable_to_trace_lineage?
162
- @parent && (@chunks.nil? || target_chunk.nil?)
142
+ @parent && (@hunks.nil? || target_chunk.nil?)
163
143
  end
164
144
 
165
145
  def line_number_to_parent
166
- return :at_beginning_of_time unless @parent && chunks
146
+ return :at_beginning_of_time unless @parent && hunks
167
147
  chunk = target_chunk(@line_number)
168
148
  return :unable_to_trace unless chunk
169
149
 
@@ -175,7 +155,7 @@ module GitSpelunk
175
155
  private
176
156
 
177
157
  def target_chunk(line_number)
178
- chunks.find { |c| c.has_line?(line_number) }
158
+ hunks.find { |c| c.has_line?(line_number) }
179
159
  end
180
160
  end
181
161
  end
@@ -13,7 +13,7 @@ module GitSpelunk
13
13
  @highlight_sha = true
14
14
  end
15
15
 
16
- attr_accessor :data, :highlight_sha, :search_term
16
+ attr_accessor :data, :highlight_sha, :search_term, :height
17
17
  attr_reader :cursor, :top, :data
18
18
 
19
19
  def blame_line
@@ -1,7 +1,7 @@
1
1
  module GitSpelunk
2
2
  class UI
3
3
  class RepoWindow
4
- attr_accessor :content, :command_mode, :command_buffer
4
+ attr_accessor :content, :command_mode, :command_buffer, :height
5
5
 
6
6
  def initialize(height)
7
7
  @height = height
@@ -18,7 +18,6 @@ module GitSpelunk
18
18
 
19
19
  private
20
20
 
21
- #with_highlighting do
22
21
  def status_line
23
22
  [
24
23
  "navigation: j k CTRL-D CTRL-U",
@@ -6,22 +6,23 @@ module GitSpelunk
6
6
  class UI
7
7
  def initialize(file_context)
8
8
  Dispel::Screen.open(:colors => true) do |screen|
9
- calculate_heights!
10
9
  @file_context = file_context
11
10
  @history = [file_context]
12
11
 
13
- @pager = PagerWindow.new(@pager_height)
12
+ @pager = PagerWindow.new(0)
14
13
  @pager.data = @file_context.get_blame
15
14
 
16
- @repo = RepoWindow.new(@repo_height)
15
+ @repo = RepoWindow.new(0)
17
16
  set_repo_content
18
17
 
19
18
  @status = StatusWindow.new
20
19
  set_status_message
21
20
 
21
+ calculate_heights!(screen)
22
22
  screen.draw *draw
23
- Dispel::Keyboard.output :timeout => 0.30 do |key|
23
+ Dispel::Keyboard.output(timeout: 0.5) do |key|
24
24
  handle_key(key)
25
+ calculate_heights!(screen)
25
26
  screen.draw *draw
26
27
  end
27
28
  end
@@ -45,10 +46,10 @@ module GitSpelunk
45
46
  ]
46
47
  end
47
48
 
48
- def calculate_heights!
49
- @status_height = 1
50
- @repo_height = [(Curses.lines.to_f * 0.20).to_i, 6].max
51
- @pager_height = Curses.lines - @repo_height - @status_height
49
+ def calculate_heights!(screen)
50
+ status_height = 1
51
+ @repo.height = [(screen.lines.to_f * 0.20).to_i, 6].max
52
+ @pager.height = screen.lines - @repo.height - status_height
52
53
  end
53
54
 
54
55
  def set_status_message
@@ -56,7 +57,16 @@ module GitSpelunk
56
57
  end
57
58
 
58
59
  def set_repo_content
59
- @repo.content = @file_context.get_line_commit_info(@pager.blame_line)
60
+ info = @file_context.get_line_commit_info(@pager.blame_line)
61
+ content = <<-EOL
62
+ commit: #{info[:commit]}
63
+ Author: #{info[:author]}
64
+ Date: #{info[:date]}
65
+
66
+ EOL
67
+ message_lines = info[:message].split(/\r?\n/)
68
+ content += message_lines[0..(@repo.height - 6)].join("\n")
69
+ @repo.content = content
60
70
  @repo.draw
61
71
  end
62
72
 
@@ -1,3 +1,3 @@
1
1
  module GitSpelunk
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.1"
3
3
  end
data/lib/git_spelunk.rb CHANGED
@@ -2,5 +2,4 @@ require 'git_spelunk/version'
2
2
  require 'git_spelunk/ui'
3
3
  require 'git_spelunk/file_context'
4
4
  require 'git_spelunk/offset'
5
- require 'git_spelunk/grit_patches'
6
5
 
metadata CHANGED
@@ -1,18 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_spelunk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Osheroff
8
8
  - Saroj Yadav
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-10-10 00:00:00.000000000 Z
12
+ date: 2023-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: grit
15
+ name: rugged
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - ">="
@@ -68,7 +68,6 @@ files:
68
68
  - lib/git_spelunk.rb
69
69
  - lib/git_spelunk/blame.rb
70
70
  - lib/git_spelunk/file_context.rb
71
- - lib/git_spelunk/grit_patches.rb
72
71
  - lib/git_spelunk/offset.rb
73
72
  - lib/git_spelunk/ui.rb
74
73
  - lib/git_spelunk/ui/pager.rb
@@ -79,7 +78,7 @@ homepage: https://github.com/osheroff/git-spelunk
79
78
  licenses:
80
79
  - MIT
81
80
  metadata: {}
82
- post_install_message:
81
+ post_install_message:
83
82
  rdoc_options: []
84
83
  require_paths:
85
84
  - lib
@@ -94,9 +93,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
93
  - !ruby/object:Gem::Version
95
94
  version: '0'
96
95
  requirements: []
97
- rubyforge_project:
98
- rubygems_version: 2.4.5.1
99
- signing_key:
96
+ rubygems_version: 3.4.2
97
+ signing_key:
100
98
  specification_version: 4
101
99
  summary: A git tool for exploring history and blame
102
100
  test_files: []
@@ -1,14 +0,0 @@
1
- require 'grit'
2
-
3
- if RUBY_VERSION >= "2.0.0"
4
- class String
5
- def getord(offset); self[offset].ord; end
6
- end
7
-
8
- begin
9
- old, $VERBOSE = $VERBOSE, nil
10
- PACK_IDX_SIGNATURE = "\377tOc".force_encoding(Encoding::ASCII_8BIT)
11
- ensure
12
- $VERBOSE = old
13
- end
14
- end