diff-lcs 1.2.2 → 1.4
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 +7 -0
- data/.rspec +0 -1
- data/Code-of-Conduct.md +74 -0
- data/Contributing.md +84 -0
- data/History.md +247 -0
- data/{License.rdoc → License.md} +0 -0
- data/Manifest.txt +15 -9
- data/README.rdoc +21 -18
- data/Rakefile +35 -23
- data/autotest/discover.rb +3 -1
- data/bin/htmldiff +7 -4
- data/bin/ldiff +4 -1
- data/lib/diff-lcs.rb +1 -1
- data/lib/diff/lcs.rb +181 -254
- data/lib/diff/lcs/array.rb +1 -1
- data/lib/diff/lcs/backports.rb +9 -0
- data/lib/diff/lcs/block.rb +1 -1
- data/lib/diff/lcs/callbacks.rb +15 -12
- data/lib/diff/lcs/change.rb +34 -37
- data/lib/diff/lcs/htmldiff.rb +17 -16
- data/lib/diff/lcs/hunk.rb +59 -47
- data/lib/diff/lcs/internals.rb +44 -40
- data/lib/diff/lcs/ldiff.rb +45 -65
- data/lib/diff/lcs/string.rb +1 -1
- data/spec/change_spec.rb +31 -7
- data/spec/diff_spec.rb +28 -18
- data/spec/fixtures/aX +1 -0
- data/spec/fixtures/bXaX +1 -0
- data/spec/fixtures/ds1.csv +50 -0
- data/spec/fixtures/ds2.csv +51 -0
- data/spec/fixtures/ldiff/output.diff +4 -0
- data/spec/fixtures/ldiff/output.diff-c +7 -0
- data/spec/fixtures/ldiff/output.diff-e +3 -0
- data/spec/fixtures/ldiff/output.diff-f +3 -0
- data/spec/fixtures/ldiff/output.diff-u +5 -0
- data/spec/hunk_spec.rb +54 -45
- data/spec/issues_spec.rb +50 -17
- data/spec/lcs_spec.rb +24 -22
- data/spec/ldiff_spec.rb +72 -0
- data/spec/patch_spec.rb +182 -180
- data/spec/sdiff_spec.rb +99 -87
- data/spec/spec_helper.rb +141 -58
- data/spec/traverse_balanced_spec.rb +177 -177
- data/spec/traverse_sequences_spec.rb +63 -63
- metadata +100 -169
- data.tar.gz.sig +0 -0
- data/.autotest +0 -3
- data/.gemtest +0 -0
- data/.hoerc +0 -2
- data/.travis.yml +0 -22
- data/Contributing.rdoc +0 -64
- data/Gemfile +0 -19
- data/History.rdoc +0 -117
- data/diff-lcs.gemspec +0 -63
- metadata.gz.sig +0 -4
data/README.rdoc
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
= Diff::LCS
|
2
2
|
|
3
|
-
home
|
4
|
-
code
|
5
|
-
bugs
|
6
|
-
rdoc
|
3
|
+
home :: https://github.com/halostatue/diff-lcs
|
4
|
+
code :: https://github.com/halostatue/diff-lcs
|
5
|
+
bugs :: https://github.com/halostatue/diff-lcs/issues
|
6
|
+
rdoc :: http://rubydoc.info/github/halostatue/diff-lcs
|
7
|
+
continuous integration :: {<img src="https://github.com/halostatue/diff-lcs/workflows/CI/badge.svg" />}[https://github.com/halostatue/diff-lcs/actions]
|
7
8
|
|
8
9
|
== Description
|
9
10
|
|
@@ -11,9 +12,14 @@ Diff::LCS computes the difference between two Enumerable sequences using the
|
|
11
12
|
McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities
|
12
13
|
to create a simple HTML diff output format and a standard diff-like tool.
|
13
14
|
|
14
|
-
This is release 1.
|
15
|
-
|
16
|
-
|
15
|
+
This is release 1.4, providing a simple extension that allows for
|
16
|
+
Diff::LCS::Change objects to be treated implicitly as arrays. Ruby versions
|
17
|
+
below 2.5 are soft-deprecated.
|
18
|
+
|
19
|
+
This means that older versions are no longer part of the CI test suite. If any
|
20
|
+
changes have been introduced that break those versions, bug reports and patches
|
21
|
+
will be accepted, but it will be up to the reporter to verify any fixes prior
|
22
|
+
to release. A future release will completely break compatibility.
|
17
23
|
|
18
24
|
== Synopsis
|
19
25
|
|
@@ -64,17 +70,14 @@ or Array will perform best.
|
|
64
70
|
Diff::LCS is a port of Perl's Algorithm::Diff that uses the McIlroy-Hunt
|
65
71
|
longest common subsequence (LCS) algorithm to compute intelligent differences
|
66
72
|
between two sequenced enumerable containers. The implementation is based on
|
67
|
-
Mario I. Wolczko's
|
73
|
+
Mario I. Wolczko's
|
74
|
+
{Smalltalk version 1.2}[ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st]
|
68
75
|
(1993) and Ned Konz's Perl version
|
69
76
|
{Algorithm::Diff 1.15}[http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/].
|
77
|
+
Diff::LCS#sdiff and Diff::LCS#traverse_balanced were originally written for the
|
78
|
+
Perl version by Mike Schilli.
|
70
79
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
{<img src="https://travis-ci.org/halostatue/diff-lcs.png" />}[https://travis-ci.org/halostatue/diff-lcs]
|
77
|
-
|
78
|
-
:include: Contributing.rdoc
|
79
|
-
|
80
|
-
:include: License.rdoc
|
80
|
+
The algorithm is described in <em>A Fast Algorithm for Computing Longest Common
|
81
|
+
Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor
|
82
|
+
improvements to improve the speed. A simplified description of the algorithm,
|
83
|
+
originally written for the Perl version, was written by Mark-Jason Dominus.
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'rspec'
|
@@ -6,34 +6,46 @@ require 'hoe'
|
|
6
6
|
|
7
7
|
Hoe.plugin :bundler
|
8
8
|
Hoe.plugin :doofus
|
9
|
-
Hoe.plugin :email
|
10
|
-
Hoe.plugin :
|
9
|
+
Hoe.plugin :email unless ENV['CI'] or ENV['TRAVIS']
|
10
|
+
Hoe.plugin :gemspec2
|
11
11
|
Hoe.plugin :git
|
12
|
-
Hoe.plugin :rubyforge
|
13
12
|
Hoe.plugin :travis
|
14
13
|
|
15
|
-
Hoe.spec 'diff-lcs' do
|
16
|
-
developer('Austin Ziegler', '
|
14
|
+
_spec = Hoe.spec 'diff-lcs' do
|
15
|
+
developer('Austin Ziegler', 'halostatue@gmail.com')
|
17
16
|
|
18
|
-
|
19
|
-
self.rsync_args << ' --exclude=statsvn/'
|
17
|
+
require_ruby_version '>= 1.8'
|
20
18
|
|
21
|
-
self.history_file = 'History.
|
19
|
+
self.history_file = 'History.md'
|
22
20
|
self.readme_file = 'README.rdoc'
|
23
|
-
self.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
self.licenses = ['MIT', 'Artistic-2.0', 'GPL-2.0+']
|
22
|
+
|
23
|
+
extra_dev_deps << ['hoe-doofus', '~> 1.0']
|
24
|
+
extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
|
25
|
+
extra_dev_deps << ['hoe-git', '~> 1.6']
|
26
|
+
extra_dev_deps << ['hoe-rubygems', '~> 1.0']
|
27
|
+
extra_dev_deps << ['hoe-travis', '~> 1.2']
|
28
|
+
extra_dev_deps << ['rspec', '>= 2.0', '< 4']
|
29
|
+
extra_dev_deps << ['rake', '>= 10.0', '< 14']
|
30
|
+
extra_dev_deps << ['rdoc', '>= 0']
|
33
31
|
end
|
34
32
|
|
35
|
-
|
36
|
-
task :test => :spec
|
37
|
-
end
|
33
|
+
require "rspec/core/rake_task"
|
38
34
|
|
39
|
-
|
35
|
+
desc "Run all specifications"
|
36
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
37
|
+
rspec_dirs = %w(spec lib)
|
38
|
+
t.rspec_opts = []
|
39
|
+
t.rspec_opts << "-I#{rspec_dirs.join(":")}" unless rspec_dirs.empty?
|
40
|
+
end
|
41
|
+
task :default => :spec
|
42
|
+
|
43
|
+
if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'
|
44
|
+
namespace :spec do
|
45
|
+
desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed."
|
46
|
+
task :coverage do
|
47
|
+
ENV['COVERAGE'] = 'yes'
|
48
|
+
Rake::Task['spec'].execute
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/autotest/discover.rb
CHANGED
data/bin/htmldiff
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#!ruby -w
|
1
|
+
#! /usr/bin/env ruby -w
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'diff/lcs'
|
4
5
|
require 'diff/lcs/htmldiff'
|
@@ -10,8 +11,8 @@ rescue LoadError
|
|
10
11
|
end
|
11
12
|
|
12
13
|
if ARGV.size < 2 or ARGV.size > 3
|
13
|
-
|
14
|
-
|
14
|
+
warn "usage: #{File.basename($0)} old new [output.html]"
|
15
|
+
warn " #{File.basename($0)} old new > output.html"
|
15
16
|
exit 127
|
16
17
|
end
|
17
18
|
|
@@ -23,10 +24,12 @@ options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" }
|
|
23
24
|
htmldiff = Diff::LCS::HTMLDiff.new(left, right, options)
|
24
25
|
|
25
26
|
if ARGV[2]
|
26
|
-
File.open(ARGV[2],
|
27
|
+
File.open(ARGV[2], 'w') do |f|
|
27
28
|
htmldiff.options[:output] = f
|
28
29
|
htmldiff.run
|
29
30
|
end
|
30
31
|
else
|
31
32
|
htmldiff.run
|
32
33
|
end
|
34
|
+
|
35
|
+
# vim: ft=ruby
|
data/bin/ldiff
CHANGED
data/lib/diff-lcs.rb
CHANGED
data/lib/diff/lcs.rb
CHANGED
@@ -1,76 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Diff; end unless defined? Diff
|
4
|
-
|
5
|
-
#
|
6
|
-
# Computes "intelligent" differences between two sequenced Enumerables. This
|
7
|
-
# is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
|
8
|
-
# objects that include Diffable.
|
9
|
-
#
|
10
|
-
# Based on Mario I. Wolczko's Smalltalk version (1.2, 1993) and Ned Konz's
|
11
|
-
# Perl version (Algorithm::Diff 1.15).
|
12
|
-
#
|
13
|
-
# == Synopsis
|
14
|
-
# require 'diff/lcs'
|
15
|
-
#
|
16
|
-
# seq1 = %w(a b c e h j l m n p)
|
17
|
-
# seq2 = %w(b c d e f j k l m r s t)
|
18
|
-
#
|
19
|
-
# lcs = Diff::LCS.lcs(seq1, seq2)
|
20
|
-
# diffs = Diff::LCS.diff(seq1, seq2)
|
21
|
-
# sdiff = Diff::LCS.sdiff(seq1, seq2)
|
22
|
-
# seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
|
23
|
-
# bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
|
24
|
-
# seq2 == Diff::LCS.patch(seq1, diffs)
|
25
|
-
# seq2 == Diff::LCS.patch!(seq1, diffs)
|
26
|
-
# seq1 == Diff::LCS.unpatch(seq2, diffs)
|
27
|
-
# seq1 == Diff::LCS.unpatch!(seq2, diffs)
|
28
|
-
# seq2 == Diff::LCS.patch(seq1, sdiff)
|
29
|
-
# seq2 == Diff::LCS.patch!(seq1, sdiff)
|
30
|
-
# seq1 == Diff::LCS.unpatch(seq2, sdiff)
|
31
|
-
# seq1 == Diff::LCS.unpatch!(seq2, sdiff)
|
32
|
-
#
|
33
|
-
# Alternatively, objects can be extended with Diff::LCS:
|
34
|
-
#
|
35
|
-
# seq1.extend(Diff::LCS)
|
36
|
-
# lcs = seq1.lcs(seq2)
|
37
|
-
# diffs = seq1.diff(seq2)
|
38
|
-
# sdiff = seq1.sdiff(seq2)
|
39
|
-
# seq = seq1.traverse_sequences(seq2, callback_obj)
|
40
|
-
# bal = seq1.traverse_balanced(seq2, callback_obj)
|
41
|
-
# seq2 == seq1.patch(diffs)
|
42
|
-
# seq2 == seq1.patch!(diffs)
|
43
|
-
# seq1 == seq2.unpatch(diffs)
|
44
|
-
# seq1 == seq2.unpatch!(diffs)
|
45
|
-
# seq2 == seq1.patch(sdiff)
|
46
|
-
# seq2 == seq1.patch!(sdiff)
|
47
|
-
# seq1 == seq2.unpatch(sdiff)
|
48
|
-
# seq1 == seq2.unpatch!(sdiff)
|
49
|
-
#
|
50
|
-
# Default extensions are provided for Array and String objects through the
|
51
|
-
# use of 'diff/lcs/array' and 'diff/lcs/string'.
|
52
|
-
#
|
53
|
-
# == Introduction (by Mark-Jason Dominus)
|
54
|
-
#
|
55
|
-
# <em>The following text is from the Perl documentation. The only changes
|
56
|
-
# have been to make the text appear better in Rdoc</em>.
|
3
|
+
module Diff; end unless defined? Diff # rubocop:disable Style/Documentation
|
4
|
+
|
5
|
+
# == How Diff Works (by Mark-Jason Dominus)
|
57
6
|
#
|
58
|
-
# I once read an article written by the authors of +diff+; they said that
|
59
|
-
#
|
60
|
-
# one.
|
7
|
+
# I once read an article written by the authors of +diff+; they said that they
|
8
|
+
# hard worked very hard on the algorithm until they found the right one.
|
61
9
|
#
|
62
|
-
# I think what they ended up using (and I hope someone will correct me,
|
63
|
-
#
|
64
|
-
#
|
10
|
+
# I think what they ended up using (and I hope someone will correct me, because
|
11
|
+
# I am not very confident about this) was the `longest common subsequence'
|
12
|
+
# method. In the LCS problem, you have two sequences of items:
|
65
13
|
#
|
66
14
|
# a b c d f g h j q z
|
67
15
|
# a b c d e f g i j k r x y z
|
68
16
|
#
|
69
17
|
# and you want to find the longest sequence of items that is present in both
|
70
18
|
# original sequences in the same order. That is, you want to find a new
|
71
|
-
# sequence *S* which can be obtained from the first sequence by deleting
|
72
|
-
#
|
73
|
-
#
|
19
|
+
# sequence *S* which can be obtained from the first sequence by deleting some
|
20
|
+
# items, and from the second sequence by deleting other items. You also want
|
21
|
+
# *S* to be as long as possible. In this case *S* is:
|
74
22
|
#
|
75
23
|
# a b c d f g j z
|
76
24
|
#
|
@@ -82,9 +30,9 @@ module Diff; end unless defined? Diff
|
|
82
30
|
# This module solves the LCS problem. It also includes a canned function to
|
83
31
|
# generate +diff+-like output.
|
84
32
|
#
|
85
|
-
# It might seem from the example above that the LCS of two sequences is
|
86
|
-
#
|
87
|
-
#
|
33
|
+
# It might seem from the example above that the LCS of two sequences is always
|
34
|
+
# pretty obvious, but that's not always the case, especially when the two
|
35
|
+
# sequences have many repeated elements. For example, consider
|
88
36
|
#
|
89
37
|
# a x b y c z p d q
|
90
38
|
# a b c a x b y c z
|
@@ -95,57 +43,28 @@ module Diff; end unless defined? Diff
|
|
95
43
|
# a x b y c z p d q
|
96
44
|
# a b c a b y c z
|
97
45
|
#
|
98
|
-
# This finds the common subsequence +a b c z+. But actually, the LCS is +a x
|
99
|
-
#
|
46
|
+
# This finds the common subsequence +a b c z+. But actually, the LCS is +a x b
|
47
|
+
# y c z+:
|
100
48
|
#
|
101
49
|
# a x b y c z p d q
|
102
50
|
# a b c a x b y c z
|
103
|
-
#
|
104
|
-
# == Author
|
105
|
-
# This version is by Austin Ziegler <austin@rubyforge.org>.
|
106
|
-
#
|
107
|
-
# It is based on the Perl Algorithm::Diff (1.15) by Ned Konz , copyright
|
108
|
-
# © 2000–2002 and the Smalltalk diff version by Mario I.
|
109
|
-
# Wolczko, copyright © 1993. Documentation includes work by
|
110
|
-
# Mark-Jason Dominus.
|
111
|
-
#
|
112
|
-
# == Licence
|
113
|
-
# Copyright © 2004–2013 Austin Ziegler
|
114
|
-
# This program is free software; you can redistribute it and/or modify it
|
115
|
-
# under the same terms as Ruby, or alternatively under the Perl Artistic
|
116
|
-
# licence.
|
117
|
-
#
|
118
|
-
# == Credits
|
119
|
-
# Much of the documentation is taken directly from the Perl Algorithm::Diff
|
120
|
-
# implementation and was written originally by Mark-Jason Dominus and later
|
121
|
-
# by Ned Konz. The basic Ruby implementation was re-ported from the
|
122
|
-
# Smalltalk implementation, available at
|
123
|
-
# ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
|
124
|
-
#
|
125
|
-
# #sdiff and #traverse_balanced were written for the Perl version by Mike
|
126
|
-
# Schilli <m@perlmeister.com>.
|
127
|
-
#
|
128
|
-
# "The algorithm is described in <em>A Fast Algorithm for Computing Longest
|
129
|
-
# Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May
|
130
|
-
# 1977, with a few minor improvements to improve the speed."
|
131
51
|
module Diff::LCS
|
132
|
-
VERSION = '1.
|
52
|
+
VERSION = '1.4'
|
133
53
|
end
|
134
54
|
|
135
55
|
require 'diff/lcs/callbacks'
|
136
56
|
require 'diff/lcs/internals'
|
137
57
|
|
138
|
-
module Diff::LCS
|
58
|
+
module Diff::LCS # rubocop:disable Style/Documentation
|
139
59
|
# Returns an Array containing the longest common subsequence(s) between
|
140
|
-
# +self+ and +other+. See Diff::LCS#
|
60
|
+
# +self+ and +other+. See Diff::LCS#lcs.
|
141
61
|
#
|
142
62
|
# lcs = seq1.lcs(seq2)
|
143
63
|
def lcs(other, &block) #:yields self[i] if there are matched subsequences:
|
144
64
|
Diff::LCS.lcs(self, other, &block)
|
145
65
|
end
|
146
66
|
|
147
|
-
# Returns the difference set between +self+ and +other+. See
|
148
|
-
# Diff::LCS#diff.
|
67
|
+
# Returns the difference set between +self+ and +other+. See Diff::LCS#diff.
|
149
68
|
def diff(other, callbacks = nil, &block)
|
150
69
|
Diff::LCS.diff(self, other, callbacks, &block)
|
151
70
|
end
|
@@ -159,29 +78,27 @@ module Diff::LCS
|
|
159
78
|
# Traverses the discovered longest common subsequences between +self+ and
|
160
79
|
# +other+. See Diff::LCS#traverse_sequences.
|
161
80
|
def traverse_sequences(other, callbacks = nil, &block)
|
162
|
-
traverse_sequences(self, other, callbacks ||
|
163
|
-
Diff::LCS.YieldingCallbacks, &block)
|
81
|
+
traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block)
|
164
82
|
end
|
165
83
|
|
166
84
|
# Traverses the discovered longest common subsequences between +self+ and
|
167
85
|
# +other+ using the alternate, balanced algorithm. See
|
168
86
|
# Diff::LCS#traverse_balanced.
|
169
87
|
def traverse_balanced(other, callbacks = nil, &block)
|
170
|
-
traverse_balanced(self, other, callbacks ||
|
171
|
-
Diff::LCS.YieldingCallbacks, &block)
|
88
|
+
traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block)
|
172
89
|
end
|
173
90
|
|
174
|
-
# Attempts to patch +self+ with the provided +patchset+. A new sequence
|
175
|
-
#
|
176
|
-
#
|
91
|
+
# Attempts to patch +self+ with the provided +patchset+. A new sequence based
|
92
|
+
# on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Attempts
|
93
|
+
# to autodiscover the direction of the patch.
|
177
94
|
def patch(patchset)
|
178
95
|
Diff::LCS.patch(self, patchset)
|
179
96
|
end
|
180
|
-
|
97
|
+
alias unpatch patch
|
181
98
|
|
182
|
-
# Attempts to patch +self+ with the provided +patchset+. A new sequence
|
183
|
-
#
|
184
|
-
#
|
99
|
+
# Attempts to patch +self+ with the provided +patchset+. A new sequence based
|
100
|
+
# on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Does no
|
101
|
+
# patch direction autodiscovery.
|
185
102
|
def patch!(patchset)
|
186
103
|
Diff::LCS.patch!(self, patchset)
|
187
104
|
end
|
@@ -194,8 +111,8 @@ module Diff::LCS
|
|
194
111
|
end
|
195
112
|
|
196
113
|
# Attempts to patch +self+ with the provided +patchset+, using #patch!. If
|
197
|
-
# the sequence this is used on supports #replace, the value of +self+ will
|
198
|
-
#
|
114
|
+
# the sequence this is used on supports #replace, the value of +self+ will be
|
115
|
+
# replaced. See Diff::LCS#patch. Does no patch direction autodiscovery.
|
199
116
|
def patch_me(patchset)
|
200
117
|
if respond_to? :replace
|
201
118
|
replace(patch!(patchset))
|
@@ -204,10 +121,9 @@ module Diff::LCS
|
|
204
121
|
end
|
205
122
|
end
|
206
123
|
|
207
|
-
# Attempts to unpatch +self+ with the provided +patchset+, using
|
208
|
-
#
|
209
|
-
#
|
210
|
-
# autodiscovery.
|
124
|
+
# Attempts to unpatch +self+ with the provided +patchset+, using #unpatch!.
|
125
|
+
# If the sequence this is used on supports #replace, the value of +self+ will
|
126
|
+
# be replaced. See Diff::LCS#unpatch. Does no patch direction autodiscovery.
|
211
127
|
def unpatch_me(patchset)
|
212
128
|
if respond_to? :replace
|
213
129
|
replace(unpatch!(patchset))
|
@@ -222,29 +138,28 @@ class << Diff::LCS
|
|
222
138
|
matches = Diff::LCS::Internals.lcs(seq1, seq2)
|
223
139
|
ret = []
|
224
140
|
string = seq1.kind_of? String
|
225
|
-
matches.each_with_index do |
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
141
|
+
matches.each_with_index do |_e, i|
|
142
|
+
next if matches[i].nil?
|
143
|
+
|
144
|
+
v = string ? seq1[i, 1] : seq1[i]
|
145
|
+
v = block[v] if block
|
146
|
+
ret << v
|
231
147
|
end
|
232
148
|
ret
|
233
149
|
end
|
234
|
-
|
150
|
+
alias LCS lcs
|
235
151
|
|
236
152
|
# #diff computes the smallest set of additions and deletions necessary to
|
237
|
-
# turn the first sequence into the second, and returns a description of
|
238
|
-
#
|
153
|
+
# turn the first sequence into the second, and returns a description of these
|
154
|
+
# changes.
|
239
155
|
#
|
240
156
|
# See Diff::LCS::DiffCallbacks for the default behaviour. An alternate
|
241
157
|
# behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a
|
242
158
|
# Class argument is provided for +callbacks+, #diff will attempt to
|
243
|
-
# initialise it. If the +callbacks+ object (possibly initialised) responds
|
244
|
-
#
|
159
|
+
# initialise it. If the +callbacks+ object (possibly initialised) responds to
|
160
|
+
# #finish, it will be called.
|
245
161
|
def diff(seq1, seq2, callbacks = nil, &block) # :yields diff changes:
|
246
|
-
diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks,
|
247
|
-
&block)
|
162
|
+
diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks, &block)
|
248
163
|
end
|
249
164
|
|
250
165
|
# #sdiff computes all necessary components to show two sequences and their
|
@@ -259,18 +174,31 @@ class << Diff::LCS
|
|
259
174
|
# See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate
|
260
175
|
# behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a
|
261
176
|
# Class argument is provided for +callbacks+, #diff will attempt to
|
262
|
-
# initialise it. If the +callbacks+ object (possibly initialised) responds
|
263
|
-
#
|
177
|
+
# initialise it. If the +callbacks+ object (possibly initialised) responds to
|
178
|
+
# #finish, it will be called.
|
179
|
+
#
|
180
|
+
# Each element of a returned array is a Diff::LCS::ContextChange object,
|
181
|
+
# which can be implicitly converted to an array.
|
182
|
+
#
|
183
|
+
# Diff::LCS.sdiff(a, b).each do |action, (old_pos, old_element), (new_pos, new_element)|
|
184
|
+
# case action
|
185
|
+
# when '!'
|
186
|
+
# # replace
|
187
|
+
# when '-'
|
188
|
+
# # delete
|
189
|
+
# when '+'
|
190
|
+
# # insert
|
191
|
+
# end
|
192
|
+
# end
|
264
193
|
def sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
|
265
|
-
diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks,
|
266
|
-
&block)
|
194
|
+
diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block)
|
267
195
|
end
|
268
196
|
|
269
|
-
# #traverse_sequences is the most general facility provided by this
|
270
|
-
#
|
197
|
+
# #traverse_sequences is the most general facility provided by this module;
|
198
|
+
# #diff and #lcs are implemented as calls to it.
|
271
199
|
#
|
272
|
-
# The arguments to #traverse_sequences are the two sequences to traverse,
|
273
|
-
#
|
200
|
+
# The arguments to #traverse_sequences are the two sequences to traverse, and
|
201
|
+
# a callback object, like this:
|
274
202
|
#
|
275
203
|
# traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
|
276
204
|
#
|
@@ -298,56 +226,55 @@ class << Diff::LCS
|
|
298
226
|
# ^
|
299
227
|
# b---+
|
300
228
|
#
|
301
|
-
# If there are two arrows (+a+ and +b+) pointing to elements of sequences
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
#
|
308
|
-
#
|
309
|
-
#
|
310
|
-
#
|
311
|
-
#
|
312
|
-
#
|
313
|
-
#
|
314
|
-
#
|
315
|
-
# that
|
316
|
-
#
|
317
|
-
#
|
318
|
-
#
|
319
|
-
#
|
320
|
-
#
|
321
|
-
#
|
322
|
-
#
|
323
|
-
#
|
324
|
-
#
|
325
|
-
#
|
326
|
-
# discarded by #traverse_sequences.
|
229
|
+
# If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+
|
230
|
+
# and +B+, the arrows will initially point to the first elements of their
|
231
|
+
# respective sequences. #traverse_sequences will advance the arrows through
|
232
|
+
# the sequences one element at a time, calling a method on the user-specified
|
233
|
+
# callback object before each advance. It will advance the arrows in such a
|
234
|
+
# way that if there are elements <tt>A[i]</tt> and <tt>B[j]</tt> which are
|
235
|
+
# both equal and part of the longest common subsequence, there will be some
|
236
|
+
# moment during the execution of #traverse_sequences when arrow +a+ is
|
237
|
+
# pointing to <tt>A[i]</tt> and arrow +b+ is pointing to <tt>B[j]</tt>. When
|
238
|
+
# this happens, #traverse_sequences will call <tt>callbacks#match</tt> and
|
239
|
+
# then it will advance both arrows.
|
240
|
+
#
|
241
|
+
# Otherwise, one of the arrows is pointing to an element of its sequence that
|
242
|
+
# is not part of the longest common subsequence. #traverse_sequences will
|
243
|
+
# advance that arrow and will call <tt>callbacks#discard_a</tt> or
|
244
|
+
# <tt>callbacks#discard_b</tt>, depending on which arrow it advanced. If both
|
245
|
+
# arrows point to elements that are not part of the longest common
|
246
|
+
# subsequence, then #traverse_sequences will advance one of them and call the
|
247
|
+
# appropriate callback, but it is not specified which it will call.
|
248
|
+
#
|
249
|
+
# The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>, and
|
250
|
+
# <tt>callbacks#discard_b</tt> are invoked with an event comprising the
|
251
|
+
# action ("=", "+", or "-", respectively), the indicies +i+ and +j+, and the
|
252
|
+
# elements <tt>A[i]</tt> and <tt>B[j]</tt>. Return values are discarded by
|
253
|
+
# #traverse_sequences.
|
327
254
|
#
|
328
255
|
# === End of Sequences
|
329
256
|
#
|
330
257
|
# If arrow +a+ reaches the end of its sequence before arrow +b+ does,
|
331
|
-
# #traverse_sequence will try to call <tt>callbacks#finished_a</tt> with
|
332
|
-
#
|
333
|
-
#
|
334
|
-
#
|
335
|
-
#
|
336
|
-
#
|
258
|
+
# #traverse_sequence will try to call <tt>callbacks#finished_a</tt> with the
|
259
|
+
# last index and element of +A+ (<tt>A[-1]</tt>) and the current index and
|
260
|
+
# element of +B+ (<tt>B[j]</tt>). If <tt>callbacks#finished_a</tt> does not
|
261
|
+
# exist, then <tt>callbacks#discard_b</tt> will be called on each element of
|
262
|
+
# +B+ until the end of the sequence is reached (the call will be done with
|
263
|
+
# <tt>A[-1]</tt> and <tt>B[j]</tt> for each element).
|
337
264
|
#
|
338
265
|
# If +b+ reaches the end of +B+ before +a+ reaches the end of +A+,
|
339
266
|
# <tt>callbacks#finished_b</tt> will be called with the current index and
|
340
267
|
# element of +A+ (<tt>A[i]</tt>) and the last index and element of +B+
|
341
|
-
# (<tt>A[-1]</tt>). Again, if <tt>callbacks#finished_b</tt> does not exist
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
268
|
+
# (<tt>A[-1]</tt>). Again, if <tt>callbacks#finished_b</tt> does not exist on
|
269
|
+
# the callback object, then <tt>callbacks#discard_a</tt> will be called on
|
270
|
+
# each element of +A+ until the end of the sequence is reached (<tt>A[i]</tt>
|
271
|
+
# and <tt>B[-1]</tt>).
|
345
272
|
#
|
346
273
|
# There is a chance that one additional <tt>callbacks#discard_a</tt> or
|
347
|
-
# <tt>callbacks#discard_b</tt> will be called after the end of the
|
348
|
-
#
|
349
|
-
#
|
350
|
-
def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks
|
274
|
+
# <tt>callbacks#discard_b</tt> will be called after the end of the sequence
|
275
|
+
# is reached, if +a+ has not yet reached the end of +A+ or +b+ has not yet
|
276
|
+
# reached the end of +B+.
|
277
|
+
def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks) #:yields change events:
|
351
278
|
callbacks ||= Diff::LCS::SequenceCallbacks
|
352
279
|
matches = Diff::LCS::Internals.lcs(seq1, seq2)
|
353
280
|
|
@@ -373,6 +300,7 @@ class << Diff::LCS
|
|
373
300
|
else
|
374
301
|
loop do
|
375
302
|
break unless bj < b_line
|
303
|
+
|
376
304
|
bx = string ? seq2[bj, 1] : seq2[bj]
|
377
305
|
event = Diff::LCS::ContextChange.new('+', i, ax, bj, bx)
|
378
306
|
event = yield event if block_given?
|
@@ -389,12 +317,12 @@ class << Diff::LCS
|
|
389
317
|
end
|
390
318
|
ai += 1
|
391
319
|
|
392
|
-
# The last entry (if any) processed was a match. +ai+ and +bj+ point
|
393
|
-
#
|
320
|
+
# The last entry (if any) processed was a match. +ai+ and +bj+ point just
|
321
|
+
# past the last matching lines in their sequences.
|
394
322
|
while (ai < a_size) or (bj < b_size)
|
395
323
|
# last A?
|
396
324
|
if ai == a_size and bj < b_size
|
397
|
-
if callbacks.respond_to?(:finished_a) and
|
325
|
+
if callbacks.respond_to?(:finished_a) and !run_finished_a
|
398
326
|
ax = string ? seq1[-1, 1] : seq1[-1]
|
399
327
|
bx = string ? seq2[bj, 1] : seq2[bj]
|
400
328
|
event = Diff::LCS::ContextChange.new('>', (a_size - 1), ax, bj, bx)
|
@@ -416,7 +344,7 @@ class << Diff::LCS
|
|
416
344
|
|
417
345
|
# last B?
|
418
346
|
if bj == b_size and ai < a_size
|
419
|
-
if callbacks.respond_to?(:finished_b) and
|
347
|
+
if callbacks.respond_to?(:finished_b) and !run_finished_b
|
420
348
|
ax = string ? seq1[ai, 1] : seq1[ai]
|
421
349
|
bx = string ? seq2[-1, 1] : seq2[-1]
|
422
350
|
event = Diff::LCS::ContextChange.new('<', ai, ax, (b_size - 1), bx)
|
@@ -445,25 +373,25 @@ class << Diff::LCS
|
|
445
373
|
ai += 1
|
446
374
|
end
|
447
375
|
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
376
|
+
next unless bj < b_size
|
377
|
+
|
378
|
+
ax = string ? seq1[ai, 1] : seq1[ai]
|
379
|
+
bx = string ? seq2[bj, 1] : seq2[bj]
|
380
|
+
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
|
381
|
+
event = yield event if block_given?
|
382
|
+
callbacks.discard_b(event)
|
383
|
+
bj += 1
|
456
384
|
end
|
457
385
|
end
|
458
386
|
|
459
387
|
# #traverse_balanced is an alternative to #traverse_sequences. It uses a
|
460
|
-
# different algorithm to iterate through the entries in the computed
|
461
|
-
#
|
462
|
-
#
|
388
|
+
# different algorithm to iterate through the entries in the computed longest
|
389
|
+
# common subsequence. Instead of viewing the changes as insertions or
|
390
|
+
# deletions from one of the sequences, #traverse_balanced will report
|
463
391
|
# <em>changes</em> between the sequences.
|
464
392
|
#
|
465
|
-
# The arguments to #traverse_balanced are the two sequences to traverse
|
466
|
-
#
|
393
|
+
# The arguments to #traverse_balanced are the two sequences to traverse and a
|
394
|
+
# callback object, like this:
|
467
395
|
#
|
468
396
|
# traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
|
469
397
|
#
|
@@ -499,24 +427,23 @@ class << Diff::LCS
|
|
499
427
|
#
|
500
428
|
# === Matches
|
501
429
|
#
|
502
|
-
# If there are two arrows (+a+ and +b+) pointing to elements of sequences
|
503
|
-
#
|
504
|
-
#
|
505
|
-
#
|
506
|
-
#
|
507
|
-
#
|
508
|
-
#
|
509
|
-
#
|
510
|
-
#
|
511
|
-
#
|
512
|
-
#
|
513
|
-
# advance both arrows.
|
430
|
+
# If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+
|
431
|
+
# and +B+, the arrows will initially point to the first elements of their
|
432
|
+
# respective sequences. #traverse_sequences will advance the arrows through
|
433
|
+
# the sequences one element at a time, calling a method on the user-specified
|
434
|
+
# callback object before each advance. It will advance the arrows in such a
|
435
|
+
# way that if there are elements <tt>A[i]</tt> and <tt>B[j]</tt> which are
|
436
|
+
# both equal and part of the longest common subsequence, there will be some
|
437
|
+
# moment during the execution of #traverse_sequences when arrow +a+ is
|
438
|
+
# pointing to <tt>A[i]</tt> and arrow +b+ is pointing to <tt>B[j]</tt>. When
|
439
|
+
# this happens, #traverse_sequences will call <tt>callbacks#match</tt> and
|
440
|
+
# then it will advance both arrows.
|
514
441
|
#
|
515
442
|
# === Discards
|
516
443
|
#
|
517
|
-
# Otherwise, one of the arrows is pointing to an element of its sequence
|
518
|
-
#
|
519
|
-
#
|
444
|
+
# Otherwise, one of the arrows is pointing to an element of its sequence that
|
445
|
+
# is not part of the longest common subsequence. #traverse_sequences will
|
446
|
+
# advance that arrow and will call <tt>callbacks#discard_a</tt> or
|
520
447
|
# <tt>callbacks#discard_b</tt>, depending on which arrow it advanced.
|
521
448
|
#
|
522
449
|
# === Changes
|
@@ -530,14 +457,14 @@ class << Diff::LCS
|
|
530
457
|
#
|
531
458
|
# The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
|
532
459
|
# <tt>callbacks#discard_b</tt>, and <tt>callbacks#change</tt> are invoked
|
533
|
-
# with an event comprising the action ("=", "+", "-", or "!",
|
534
|
-
#
|
535
|
-
#
|
536
|
-
# #traverse_balanced.
|
460
|
+
# with an event comprising the action ("=", "+", "-", or "!", respectively),
|
461
|
+
# the indicies +i+ and +j+, and the elements <tt>A[i]</tt> and <tt>B[j]</tt>.
|
462
|
+
# Return values are discarded by #traverse_balanced.
|
537
463
|
#
|
538
464
|
# === Context
|
539
|
-
#
|
540
|
-
# and +
|
465
|
+
#
|
466
|
+
# Note that +i+ and +j+ may not be the same index position, even if +a+ and
|
467
|
+
# +b+ are considered to be pointing to matching or changed elements.
|
541
468
|
def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
|
542
469
|
matches = Diff::LCS::Internals.lcs(seq1, seq2)
|
543
470
|
a_size = seq1.size
|
@@ -555,6 +482,7 @@ class << Diff::LCS
|
|
555
482
|
end
|
556
483
|
|
557
484
|
break if ma >= matches.size # end of matches?
|
485
|
+
|
558
486
|
mb = matches[ma]
|
559
487
|
|
560
488
|
# Change(seq2)
|
@@ -569,7 +497,6 @@ class << Diff::LCS
|
|
569
497
|
event = yield event if block_given?
|
570
498
|
callbacks.change(event)
|
571
499
|
ai += 1
|
572
|
-
bj += 1
|
573
500
|
else
|
574
501
|
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
|
575
502
|
event = yield event if block_given?
|
@@ -579,8 +506,9 @@ class << Diff::LCS
|
|
579
506
|
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
|
580
507
|
event = yield event if block_given?
|
581
508
|
callbacks.discard_b(event)
|
582
|
-
bj += 1
|
583
509
|
end
|
510
|
+
|
511
|
+
bj += 1
|
584
512
|
when [true, false]
|
585
513
|
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
|
586
514
|
event = yield event if block_given?
|
@@ -615,7 +543,6 @@ class << Diff::LCS
|
|
615
543
|
event = yield event if block_given?
|
616
544
|
callbacks.change(event)
|
617
545
|
ai += 1
|
618
|
-
bj += 1
|
619
546
|
else
|
620
547
|
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
|
621
548
|
event = yield event if block_given?
|
@@ -625,8 +552,9 @@ class << Diff::LCS
|
|
625
552
|
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
|
626
553
|
event = yield event if block_given?
|
627
554
|
callbacks.discard_b(event)
|
628
|
-
bj += 1
|
629
555
|
end
|
556
|
+
|
557
|
+
bj += 1
|
630
558
|
when [true, false]
|
631
559
|
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
|
632
560
|
event = yield event if block_given?
|
@@ -642,9 +570,9 @@ class << Diff::LCS
|
|
642
570
|
end
|
643
571
|
|
644
572
|
PATCH_MAP = { #:nodoc:
|
645
|
-
:patch => { '+' => '+', '-' => '-', '!' => '!', '=' => '=' },
|
646
|
-
:unpatch => { '+' => '-', '-' => '+', '!' => '!', '=' => '=' }
|
647
|
-
}
|
573
|
+
:patch => { '+' => '+', '-' => '-', '!' => '!', '=' => '=' }.freeze,
|
574
|
+
:unpatch => { '+' => '-', '-' => '+', '!' => '!', '=' => '=' }.freeze
|
575
|
+
}.freeze
|
648
576
|
|
649
577
|
# Applies a +patchset+ to the sequence +src+ according to the +direction+
|
650
578
|
# (<tt>:patch</tt> or <tt>:unpatch</tt>), producing a new sequence.
|
@@ -657,23 +585,23 @@ class << Diff::LCS
|
|
657
585
|
#
|
658
586
|
# patch(s1, diff(s1, s2)) -> s2
|
659
587
|
#
|
660
|
-
# A +patchset+ can be considered to apply backward (<tt>:unpatch</tt>) if
|
661
|
-
#
|
588
|
+
# A +patchset+ can be considered to apply backward (<tt>:unpatch</tt>) if the
|
589
|
+
# following expression is true:
|
662
590
|
#
|
663
591
|
# patch(s2, diff(s1, s2)) -> s1
|
664
592
|
#
|
665
|
-
# If the +patchset+ contains no changes, the +src+ value will be returned
|
666
|
-
#
|
667
|
-
#
|
593
|
+
# If the +patchset+ contains no changes, the +src+ value will be returned as
|
594
|
+
# either <tt>src.dup</tt> or +src+. A +patchset+ can be deemed as having no
|
595
|
+
# changes if the following predicate returns true:
|
668
596
|
#
|
669
597
|
# patchset.empty? or
|
670
|
-
# patchset.flatten.all? { |change| change.unchanged? }
|
598
|
+
# patchset.flatten(1).all? { |change| change.unchanged? }
|
671
599
|
#
|
672
600
|
# === Patchsets
|
673
601
|
#
|
674
|
-
# A +patchset+ is always an enumerable sequence of changes, hunks of
|
675
|
-
#
|
676
|
-
#
|
602
|
+
# A +patchset+ is always an enumerable sequence of changes, hunks of changes,
|
603
|
+
# or a mix of the two. A hunk of changes is an enumerable sequence of
|
604
|
+
# changes:
|
677
605
|
#
|
678
606
|
# [ # patchset
|
679
607
|
# # change
|
@@ -682,18 +610,15 @@ class << Diff::LCS
|
|
682
610
|
# ]
|
683
611
|
# ]
|
684
612
|
#
|
685
|
-
# The +patch+ method accepts <tt>patchset</tt>s that are enumerable
|
686
|
-
#
|
687
|
-
#
|
613
|
+
# The +patch+ method accepts <tt>patchset</tt>s that are enumerable sequences
|
614
|
+
# containing either Diff::LCS::Change objects (or a subclass) or the array
|
615
|
+
# representations of those objects. Prior to application, array
|
688
616
|
# representations of Diff::LCS::Change objects will be reified.
|
689
617
|
def patch(src, patchset, direction = nil)
|
690
618
|
# Normalize the patchset.
|
691
619
|
has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset)
|
692
620
|
|
693
|
-
|
694
|
-
return src.dup if src.respond_to? :dup
|
695
|
-
return src
|
696
|
-
end
|
621
|
+
return src.respond_to?(:dup) ? src.dup : src unless has_changes
|
697
622
|
|
698
623
|
string = src.kind_of?(String)
|
699
624
|
# Start with a new empty type of the source's class
|
@@ -705,7 +630,7 @@ class << Diff::LCS
|
|
705
630
|
|
706
631
|
patch_map = PATCH_MAP[direction]
|
707
632
|
|
708
|
-
patchset.
|
633
|
+
patchset.each do |change|
|
709
634
|
# Both Change and ContextChange support #action
|
710
635
|
action = patch_map[change.action]
|
711
636
|
|
@@ -737,8 +662,8 @@ class << Diff::LCS
|
|
737
662
|
bj += 1
|
738
663
|
end
|
739
664
|
|
740
|
-
|
741
|
-
|
665
|
+
res << el
|
666
|
+
bj += 1
|
742
667
|
when '='
|
743
668
|
# This only appears in sdiff output with the SDiff callback.
|
744
669
|
# Therefore, we only need to worry about dealing with a single
|
@@ -754,10 +679,10 @@ class << Diff::LCS
|
|
754
679
|
bj += 1
|
755
680
|
end
|
756
681
|
|
757
|
-
|
758
|
-
|
682
|
+
bj += 1
|
683
|
+
ai += 1
|
759
684
|
|
760
|
-
|
685
|
+
res << el
|
761
686
|
end
|
762
687
|
when Diff::LCS::Change
|
763
688
|
case action
|
@@ -767,7 +692,7 @@ class << Diff::LCS
|
|
767
692
|
ai += 1
|
768
693
|
bj += 1
|
769
694
|
end
|
770
|
-
|
695
|
+
ai += 1
|
771
696
|
when '+'
|
772
697
|
while bj < change.position
|
773
698
|
res << (string ? src[ai, 1] : src[ai])
|
@@ -775,9 +700,9 @@ class << Diff::LCS
|
|
775
700
|
bj += 1
|
776
701
|
end
|
777
702
|
|
778
|
-
|
703
|
+
bj += 1
|
779
704
|
|
780
|
-
|
705
|
+
res << change.element
|
781
706
|
end
|
782
707
|
end
|
783
708
|
end
|
@@ -791,15 +716,17 @@ class << Diff::LCS
|
|
791
716
|
res
|
792
717
|
end
|
793
718
|
|
794
|
-
# Given a set of patchset, convert the current version to the prior
|
795
|
-
#
|
719
|
+
# Given a set of patchset, convert the current version to the prior version.
|
720
|
+
# Does no auto-discovery.
|
796
721
|
def unpatch!(src, patchset)
|
797
722
|
patch(src, patchset, :unpatch)
|
798
723
|
end
|
799
724
|
|
800
|
-
# Given a set of patchset, convert the current version to the next
|
801
|
-
#
|
725
|
+
# Given a set of patchset, convert the current version to the next version.
|
726
|
+
# Does no auto-discovery.
|
802
727
|
def patch!(src, patchset)
|
803
728
|
patch(src, patchset, :patch)
|
804
729
|
end
|
805
730
|
end
|
731
|
+
|
732
|
+
require 'diff/lcs/backports'
|