diff-lcs 1.4.4 → 1.5.1
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.
- checksums.yaml +4 -4
- data/Contributing.md +3 -0
- data/History.md +219 -107
- data/License.md +6 -4
- data/Manifest.txt +15 -1
- data/Rakefile +81 -25
- data/bin/htmldiff +4 -4
- data/lib/diff/lcs/array.rb +1 -1
- data/lib/diff/lcs/backports.rb +2 -2
- data/lib/diff/lcs/block.rb +4 -4
- data/lib/diff/lcs/callbacks.rb +9 -7
- data/lib/diff/lcs/change.rb +19 -19
- data/lib/diff/lcs/htmldiff.rb +24 -16
- data/lib/diff/lcs/hunk.rb +35 -30
- data/lib/diff/lcs/internals.rb +24 -20
- data/lib/diff/lcs/ldiff.rb +37 -35
- data/lib/diff/lcs.rb +77 -75
- data/lib/diff-lcs.rb +1 -1
- data/spec/change_spec.rb +50 -50
- data/spec/diff_spec.rb +14 -14
- data/spec/fixtures/ldiff/output.diff.chef +4 -0
- data/spec/fixtures/ldiff/output.diff.chef-c +15 -0
- data/spec/fixtures/ldiff/output.diff.chef-e +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-f +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-u +9 -0
- data/spec/fixtures/ldiff/output.diff.chef2 +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-c +20 -0
- data/spec/fixtures/ldiff/output.diff.chef2-d +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-e +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-f +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-u +16 -0
- data/spec/fixtures/new-chef +4 -0
- data/spec/fixtures/new-chef2 +17 -0
- data/spec/fixtures/old-chef +4 -0
- data/spec/fixtures/old-chef2 +14 -0
- data/spec/hunk_spec.rb +19 -19
- data/spec/issues_spec.rb +48 -42
- data/spec/lcs_spec.rb +11 -11
- data/spec/ldiff_spec.rb +13 -11
- data/spec/patch_spec.rb +84 -84
- data/spec/sdiff_spec.rb +111 -109
- data/spec/spec_helper.rb +77 -76
- data/spec/traverse_balanced_spec.rb +191 -189
- data/spec/traverse_sequences_spec.rb +31 -33
- metadata +50 -23
- data/autotest/discover.rb +0 -3
data/lib/diff/lcs/hunk.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "diff/lcs/block"
|
4
4
|
|
5
5
|
# A Hunk is a group of Blocks which overlap because of the context surrounding
|
6
6
|
# each block. (So if we're not using context, every hunk will contain one
|
7
7
|
# block.) Used in the diff program (bin/ldiff).
|
8
8
|
class Diff::LCS::Hunk
|
9
|
-
OLD_DIFF_OP_ACTION = {
|
10
|
-
ED_DIFF_OP_ACTION = {
|
9
|
+
OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
10
|
+
ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
11
11
|
|
12
12
|
private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant)
|
13
13
|
|
@@ -22,7 +22,7 @@ class Diff::LCS::Hunk
|
|
22
22
|
end
|
23
23
|
|
24
24
|
if String.method_defined?(:encoding)
|
25
|
-
@preferred_data_encoding = data_old.fetch(0
|
25
|
+
@preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0, "") }.encoding
|
26
26
|
end
|
27
27
|
|
28
28
|
@data_old = data_old
|
@@ -33,7 +33,6 @@ class Diff::LCS::Hunk
|
|
33
33
|
@file_length_difference = after # The caller must get this manually
|
34
34
|
@max_diff_size = @blocks.map { |e| e.diff_size.abs }.max
|
35
35
|
|
36
|
-
|
37
36
|
# Save the start & end of each array. If the array doesn't exist (e.g.,
|
38
37
|
# we're only adding items in this block), then figure out the line number
|
39
38
|
# based on the line number of the other file and the current difference in
|
@@ -54,8 +53,8 @@ class Diff::LCS::Hunk
|
|
54
53
|
|
55
54
|
@start_old = a1 || (b1 - before)
|
56
55
|
@start_new = b1 || (a1 + before)
|
57
|
-
@end_old
|
58
|
-
@end_new
|
56
|
+
@end_old = a2 || (b2 - after)
|
57
|
+
@end_new = b2 || (a2 + after)
|
59
58
|
|
60
59
|
self.flag_context = flag_context
|
61
60
|
end
|
@@ -67,12 +66,12 @@ class Diff::LCS::Hunk
|
|
67
66
|
|
68
67
|
# Change the "start" and "end" fields to note that context should be added
|
69
68
|
# to this hunk.
|
70
|
-
attr_accessor :flag_context
|
69
|
+
attr_accessor :flag_context
|
71
70
|
undef :flag_context=
|
72
|
-
def flag_context=(context)
|
73
|
-
return if context.nil?
|
71
|
+
def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods
|
72
|
+
return if context.nil? || context.zero?
|
74
73
|
|
75
|
-
add_start = context > @start_old ? @start_old : context
|
74
|
+
add_start = (context > @start_old) ? @start_old : context
|
76
75
|
|
77
76
|
@start_old -= add_start
|
78
77
|
@start_new -= add_start
|
@@ -102,7 +101,7 @@ class Diff::LCS::Hunk
|
|
102
101
|
@start_new = hunk.start_new
|
103
102
|
blocks.unshift(*hunk.blocks)
|
104
103
|
end
|
105
|
-
|
104
|
+
alias_method :unshift, :merge
|
106
105
|
|
107
106
|
# Determines whether there is an overlap between this hunk and the
|
108
107
|
# provided hunk. This will be true if the difference between the two hunks
|
@@ -133,24 +132,24 @@ class Diff::LCS::Hunk
|
|
133
132
|
# Note that an old diff can't have any context. Therefore, we know that
|
134
133
|
# there's only one block in the hunk.
|
135
134
|
def old_diff(_last = false)
|
136
|
-
warn
|
135
|
+
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
137
136
|
|
138
137
|
block = @blocks[0]
|
139
138
|
|
140
139
|
# Calculate item number range. Old diff range is just like a context
|
141
140
|
# diff range, except the ranges are on one line with the action between
|
142
141
|
# them.
|
143
|
-
s = encode("#{context_range(:old,
|
142
|
+
s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n")
|
144
143
|
# If removing anything, just print out all the remove lines in the hunk
|
145
144
|
# which is just all the remove lines in the block.
|
146
145
|
unless block.remove.empty?
|
147
|
-
@data_old[@start_old..@end_old].each { |e| s << encode(
|
146
|
+
@data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") }
|
148
147
|
end
|
149
148
|
|
150
|
-
s << encode("---\n") if block.op ==
|
149
|
+
s << encode("---\n") if block.op == "!"
|
151
150
|
|
152
151
|
unless block.insert.empty?
|
153
|
-
@data_new[@start_new..@end_new].each { |e| s << encode(
|
152
|
+
@data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") }
|
154
153
|
end
|
155
154
|
|
156
155
|
s
|
@@ -172,7 +171,9 @@ class Diff::LCS::Hunk
|
|
172
171
|
# file -- don't take removed items into account.
|
173
172
|
lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
|
174
173
|
|
175
|
-
|
174
|
+
# standard:disable Performance/UnfreezeString
|
175
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
176
|
+
# standard:enable Performance/UnfreezeString
|
176
177
|
|
177
178
|
last_block = blocks[-1]
|
178
179
|
|
@@ -183,7 +184,7 @@ class Diff::LCS::Hunk
|
|
183
184
|
|
184
185
|
@blocks.each do |block|
|
185
186
|
block.remove.each do |item|
|
186
|
-
op
|
187
|
+
op = item.action.to_s # -
|
187
188
|
offset = item.position - lo + num_added
|
188
189
|
outlist[offset][0, 1] = encode(op)
|
189
190
|
num_removed += 1
|
@@ -195,7 +196,7 @@ class Diff::LCS::Hunk
|
|
195
196
|
end
|
196
197
|
|
197
198
|
block.insert.each do |item|
|
198
|
-
op
|
199
|
+
op = item.action.to_s # +
|
199
200
|
offset = item.position - @start_new + num_removed
|
200
201
|
outlist[offset, 0] = encode(op) + @data_new[item.position].chomp
|
201
202
|
num_added += 1
|
@@ -212,8 +213,8 @@ class Diff::LCS::Hunk
|
|
212
213
|
|
213
214
|
def context_diff(last = false)
|
214
215
|
s = encode("***************\n")
|
215
|
-
s << encode("*** #{context_range(:old,
|
216
|
-
r = context_range(:new,
|
216
|
+
s << encode("*** #{context_range(:old, ",", last)} ****\n")
|
217
|
+
r = context_range(:new, ",", last)
|
217
218
|
|
218
219
|
if last
|
219
220
|
old_missing_newline = missing_last_newline?(@data_old)
|
@@ -226,7 +227,9 @@ class Diff::LCS::Hunk
|
|
226
227
|
removes = @blocks.reject { |e| e.remove.empty? }
|
227
228
|
|
228
229
|
unless removes.empty?
|
229
|
-
|
230
|
+
# standard:disable Performance/UnfreezeString
|
231
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
232
|
+
# standard:enable Performance/UnfreezeString
|
230
233
|
|
231
234
|
last_block = removes[-1]
|
232
235
|
|
@@ -248,7 +251,9 @@ class Diff::LCS::Hunk
|
|
248
251
|
inserts = @blocks.reject { |e| e.insert.empty? }
|
249
252
|
|
250
253
|
unless inserts.empty?
|
251
|
-
|
254
|
+
# standard:disable Performance/UnfreezeString
|
255
|
+
outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
256
|
+
# standard:enable Performance/UnfreezeString
|
252
257
|
|
253
258
|
last_block = inserts[-1]
|
254
259
|
|
@@ -269,13 +274,13 @@ class Diff::LCS::Hunk
|
|
269
274
|
private :context_diff
|
270
275
|
|
271
276
|
def ed_diff(format, _last = false)
|
272
|
-
warn
|
277
|
+
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
273
278
|
|
274
279
|
s =
|
275
280
|
if format == :reverse_ed
|
276
|
-
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old,
|
281
|
+
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, ",")}\n")
|
277
282
|
else
|
278
|
-
encode("#{context_range(:old,
|
283
|
+
encode("#{context_range(:old, " ")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
|
279
284
|
end
|
280
285
|
|
281
286
|
unless @blocks[0].insert.empty?
|
@@ -301,7 +306,7 @@ class Diff::LCS::Hunk
|
|
301
306
|
e -= 1 if last
|
302
307
|
e = 1 if e.zero?
|
303
308
|
|
304
|
-
s < e ? "#{s}#{op}#{e}" : e.to_s
|
309
|
+
(s < e) ? "#{s}#{op}#{e}" : e.to_s
|
305
310
|
end
|
306
311
|
private :context_range
|
307
312
|
|
@@ -318,8 +323,8 @@ class Diff::LCS::Hunk
|
|
318
323
|
|
319
324
|
length = e - s + (last ? 0 : 1)
|
320
325
|
|
321
|
-
first = length < 2 ? e : s # "strange, but correct"
|
322
|
-
length <= 1 ? first.to_s : "#{first},#{length}"
|
326
|
+
first = (length < 2) ? e : s # "strange, but correct"
|
327
|
+
(length <= 1) ? first.to_s : "#{first},#{length}"
|
323
328
|
end
|
324
329
|
private :unified_range
|
325
330
|
|
data/lib/diff/lcs/internals.rb
CHANGED
@@ -13,7 +13,7 @@ class << Diff::LCS
|
|
13
13
|
|
14
14
|
if block
|
15
15
|
callbacks.diffs.map do |hunk|
|
16
|
-
if hunk.
|
16
|
+
if hunk.is_a? Array
|
17
17
|
hunk.map { |hunk_block| block[hunk_block] }
|
18
18
|
else
|
19
19
|
block[hunk]
|
@@ -44,34 +44,38 @@ class << Diff::LCS::Internals
|
|
44
44
|
b_finish = b.size - 1
|
45
45
|
vector = []
|
46
46
|
|
47
|
-
#
|
48
|
-
while (a_start <= a_finish)
|
47
|
+
# Collect any common elements at the beginning...
|
48
|
+
while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_start] == b[b_start])
|
49
49
|
vector[a_start] = b_start
|
50
50
|
a_start += 1
|
51
51
|
b_start += 1
|
52
52
|
end
|
53
|
-
b_start = a_start
|
54
53
|
|
55
54
|
# Now the end...
|
56
|
-
while (a_start <= a_finish)
|
55
|
+
while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_finish] == b[b_finish])
|
57
56
|
vector[a_finish] = b_finish
|
58
57
|
a_finish -= 1
|
59
58
|
b_finish -= 1
|
60
59
|
end
|
61
60
|
|
62
61
|
# Now, compute the equivalence classes of positions of elements.
|
62
|
+
# An explanation for how this works: https://codeforces.com/topic/92191
|
63
63
|
b_matches = position_hash(b, b_start..b_finish)
|
64
64
|
|
65
65
|
thresh = []
|
66
|
-
links
|
67
|
-
string = a.
|
66
|
+
links = []
|
67
|
+
string = a.is_a?(String)
|
68
68
|
|
69
69
|
(a_start..a_finish).each do |i|
|
70
70
|
ai = string ? a[i, 1] : a[i]
|
71
71
|
bm = b_matches[ai]
|
72
72
|
k = nil
|
73
73
|
bm.reverse_each do |j|
|
74
|
-
|
74
|
+
# Although the threshold check is not mandatory for this to work,
|
75
|
+
# it may have an optimization purpose
|
76
|
+
# An attempt to remove it: https://github.com/halostatue/diff-lcs/pull/72
|
77
|
+
# Why it is reintroduced: https://github.com/halostatue/diff-lcs/issues/78
|
78
|
+
if k && (thresh[k] > j) && (thresh[k - 1] < j)
|
75
79
|
thresh[k] = j
|
76
80
|
else
|
77
81
|
k = replace_next_larger(thresh, j, k)
|
@@ -96,7 +100,7 @@ class << Diff::LCS::Internals
|
|
96
100
|
# the object form of same) and detection of whether the patchset represents
|
97
101
|
# changes to be made.
|
98
102
|
def analyze_patchset(patchset, depth = 0)
|
99
|
-
fail
|
103
|
+
fail "Patchset too complex" if depth > 1
|
100
104
|
|
101
105
|
has_changes = false
|
102
106
|
new_patchset = []
|
@@ -141,7 +145,7 @@ class << Diff::LCS::Internals
|
|
141
145
|
# Diff::LCS::Change as its source, as an array will cause the creation
|
142
146
|
# of one of the above.
|
143
147
|
def intuit_diff_direction(src, patchset, limit = nil)
|
144
|
-
string = src.
|
148
|
+
string = src.is_a?(String)
|
145
149
|
count = left_match = left_miss = right_match = right_miss = 0
|
146
150
|
|
147
151
|
patchset.each do |change|
|
@@ -153,22 +157,22 @@ class << Diff::LCS::Internals
|
|
153
157
|
re = string ? src[change.new_position, 1] : src[change.new_position]
|
154
158
|
|
155
159
|
case change.action
|
156
|
-
when
|
160
|
+
when "-" # Remove details from the old string
|
157
161
|
if le == change.old_element
|
158
162
|
left_match += 1
|
159
163
|
else
|
160
164
|
left_miss += 1
|
161
165
|
end
|
162
|
-
when
|
166
|
+
when "+"
|
163
167
|
if re == change.new_element
|
164
168
|
right_match += 1
|
165
169
|
else
|
166
170
|
right_miss += 1
|
167
171
|
end
|
168
|
-
when
|
172
|
+
when "="
|
169
173
|
left_miss += 1 if le != change.old_element
|
170
174
|
right_miss += 1 if re != change.new_element
|
171
|
-
when
|
175
|
+
when "!"
|
172
176
|
if le == change.old_element
|
173
177
|
left_match += 1
|
174
178
|
elsif re == change.new_element
|
@@ -185,19 +189,19 @@ class << Diff::LCS::Internals
|
|
185
189
|
element = string ? src[change.position, 1] : src[change.position]
|
186
190
|
|
187
191
|
case change.action
|
188
|
-
when
|
192
|
+
when "-"
|
189
193
|
if element == change.element
|
190
194
|
left_match += 1
|
191
195
|
else
|
192
196
|
left_miss += 1
|
193
197
|
end
|
194
|
-
when
|
198
|
+
when "+"
|
195
199
|
if element == change.element
|
196
200
|
right_match += 1
|
197
201
|
else
|
198
202
|
right_miss += 1
|
199
203
|
end
|
200
|
-
when
|
204
|
+
when "="
|
201
205
|
if element != change.element
|
202
206
|
left_miss += 1
|
203
207
|
right_miss += 1
|
@@ -247,13 +251,13 @@ enumerable as either source or destination value."
|
|
247
251
|
# This operation preserves the sort order.
|
248
252
|
def replace_next_larger(enum, value, last_index = nil)
|
249
253
|
# Off the end?
|
250
|
-
if enum.empty?
|
254
|
+
if enum.empty? || (value > enum[-1])
|
251
255
|
enum << value
|
252
256
|
return enum.size - 1
|
253
257
|
end
|
254
258
|
|
255
259
|
# Binary search for the insertion point
|
256
|
-
last_index ||= enum.size
|
260
|
+
last_index ||= enum.size - 1
|
257
261
|
first_index = 0
|
258
262
|
while first_index <= last_index
|
259
263
|
i = (first_index + last_index) >> 1
|
@@ -292,7 +296,7 @@ enumerable as either source or destination value."
|
|
292
296
|
# positions it occupies in the Enumerable, optionally restricted to the
|
293
297
|
# elements specified in the range of indexes specified by +interval+.
|
294
298
|
def position_hash(enum, interval)
|
295
|
-
string = enum.
|
299
|
+
string = enum.is_a?(String)
|
296
300
|
hash = Hash.new { |h, k| h[k] = [] }
|
297
301
|
interval.each do |i|
|
298
302
|
k = string ? enum[i, 1] : enum[i]
|
data/lib/diff/lcs/ldiff.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "optparse"
|
4
|
+
require "ostruct"
|
5
|
+
require "diff/lcs/hunk"
|
6
6
|
|
7
|
-
module Diff::LCS::Ldiff
|
7
|
+
module Diff::LCS::Ldiff # :nodoc:
|
8
|
+
# standard:disable Layout/HeredocIndentation
|
8
9
|
BANNER = <<-COPYRIGHT
|
9
10
|
ldiff #{Diff::LCS::VERSION}
|
10
11
|
Copyright 2004-2019 Austin Ziegler
|
@@ -16,60 +17,61 @@ ldiff #{Diff::LCS::VERSION}
|
|
16
17
|
the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
|
17
18
|
MIT licence.
|
18
19
|
COPYRIGHT
|
20
|
+
# standard:enable Layout/HeredocIndentation
|
19
21
|
end
|
20
22
|
|
21
23
|
class << Diff::LCS::Ldiff
|
22
|
-
attr_reader :format, :lines
|
23
|
-
attr_reader :file_old, :file_new
|
24
|
-
attr_reader :data_old, :data_new
|
24
|
+
attr_reader :format, :lines # :nodoc:
|
25
|
+
attr_reader :file_old, :file_new # :nodoc:
|
26
|
+
attr_reader :data_old, :data_new # :nodoc:
|
25
27
|
|
26
|
-
def run(args, _input = $stdin, output = $stdout, error = $stderr)
|
28
|
+
def run(args, _input = $stdin, output = $stdout, error = $stderr) # :nodoc:
|
27
29
|
@binary = nil
|
28
30
|
|
29
31
|
args.options do |o|
|
30
32
|
o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
|
31
|
-
o.separator
|
33
|
+
o.separator ""
|
32
34
|
o.on(
|
33
|
-
|
34
|
-
|
35
|
+
"-c", "-C", "--context [LINES]", Integer,
|
36
|
+
"Displays a context diff with LINES lines", "of context. Default 3 lines."
|
35
37
|
) do |ctx|
|
36
38
|
@format = :context
|
37
|
-
@lines
|
39
|
+
@lines = ctx || 3
|
38
40
|
end
|
39
41
|
o.on(
|
40
|
-
|
41
|
-
|
42
|
+
"-u", "-U", "--unified [LINES]", Integer,
|
43
|
+
"Displays a unified diff with LINES lines", "of context. Default 3 lines."
|
42
44
|
) do |ctx|
|
43
45
|
@format = :unified
|
44
|
-
@lines
|
46
|
+
@lines = ctx || 3
|
45
47
|
end
|
46
|
-
o.on(
|
48
|
+
o.on("-e", "Creates an 'ed' script to change", "oldfile to newfile.") do |_ctx|
|
47
49
|
@format = :ed
|
48
50
|
end
|
49
|
-
o.on(
|
51
|
+
o.on("-f", "Creates an 'ed' script to change", "oldfile to newfile in reverse order.") do |_ctx|
|
50
52
|
@format = :reverse_ed
|
51
53
|
end
|
52
54
|
o.on(
|
53
|
-
|
54
|
-
|
55
|
+
"-a", "--text",
|
56
|
+
"Treat the files as text and compare them", "line-by-line, even if they do not seem", "to be text."
|
55
57
|
) do |_txt|
|
56
58
|
@binary = false
|
57
59
|
end
|
58
|
-
o.on(
|
60
|
+
o.on("--binary", "Treats the files as binary.") do |_bin|
|
59
61
|
@binary = true
|
60
62
|
end
|
61
|
-
o.on(
|
63
|
+
o.on("-q", "--brief", "Report only whether or not the files", "differ, not the details.") do |_ctx|
|
62
64
|
@format = :report
|
63
65
|
end
|
64
|
-
o.on_tail(
|
66
|
+
o.on_tail("--help", "Shows this text.") do
|
65
67
|
error << o
|
66
68
|
return 0
|
67
69
|
end
|
68
|
-
o.on_tail(
|
70
|
+
o.on_tail("--version", "Shows the version of Diff::LCS.") do
|
69
71
|
error << Diff::LCS::Ldiff::BANNER
|
70
72
|
return 0
|
71
73
|
end
|
72
|
-
o.on_tail
|
74
|
+
o.on_tail ""
|
73
75
|
o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
|
74
76
|
o.parse!
|
75
77
|
end
|
@@ -81,25 +83,25 @@ class << Diff::LCS::Ldiff
|
|
81
83
|
|
82
84
|
# Defaults are for old-style diff
|
83
85
|
@format ||= :old
|
84
|
-
@lines
|
86
|
+
@lines ||= 0
|
85
87
|
|
86
88
|
file_old, file_new = *ARGV
|
87
89
|
|
88
90
|
case @format
|
89
91
|
when :context
|
90
|
-
char_old =
|
91
|
-
char_new =
|
92
|
+
char_old = "*" * 3
|
93
|
+
char_new = "-" * 3
|
92
94
|
when :unified
|
93
|
-
char_old =
|
94
|
-
char_new =
|
95
|
+
char_old = "-" * 3
|
96
|
+
char_new = "+" * 3
|
95
97
|
end
|
96
98
|
|
97
99
|
# After we've read up to a certain point in each file, the number of
|
98
100
|
# items we've read from each file will differ by FLD (could be 0).
|
99
101
|
file_length_difference = 0
|
100
102
|
|
101
|
-
data_old =
|
102
|
-
data_new =
|
103
|
+
data_old = File.read(file_old)
|
104
|
+
data_new = File.read(file_new)
|
103
105
|
|
104
106
|
# Test binary status
|
105
107
|
if @binary.nil?
|
@@ -128,10 +130,10 @@ class << Diff::LCS::Ldiff
|
|
128
130
|
return 1
|
129
131
|
end
|
130
132
|
|
131
|
-
if (@format == :unified)
|
132
|
-
ft = File.stat(file_old).mtime.localtime.strftime(
|
133
|
+
if (@format == :unified) || (@format == :context)
|
134
|
+
ft = File.stat(file_old).mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z")
|
133
135
|
output << "#{char_old} #{file_old}\t#{ft}\n"
|
134
|
-
ft = File.stat(file_new).mtime.localtime.strftime(
|
136
|
+
ft = File.stat(file_new).mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z")
|
135
137
|
output << "#{char_new} #{file_new}\t#{ft}\n"
|
136
138
|
end
|
137
139
|
|
@@ -150,7 +152,7 @@ class << Diff::LCS::Ldiff
|
|
150
152
|
file_length_difference = hunk.file_length_difference
|
151
153
|
|
152
154
|
next unless oldhunk
|
153
|
-
next if @lines.positive?
|
155
|
+
next if @lines.positive? && hunk.merge(oldhunk)
|
154
156
|
|
155
157
|
output << oldhunk.diff(@format)
|
156
158
|
output << "\n" if @format == :unified
|