1NAME
2 Algorithm::Merge - Three-way merge and diff
3
4SYNOPSIS
5 use Algorithm::Merge qw(merge diff3 traverse_sequences3);
6
7 @merged = merge(\@ancestor, \@a, \@b, {
8 CONFLICT => sub { }
9 });
10
11 @merged = merge(\@ancestor, \@a, \@b, {
12 CONFLICT => sub { }
13 }, $key_generation_function);
14
15 $merged = merge(\@ancestor, \@a, \@b, {
16 CONFLICT => sub { }
17 });
18
19 $merged = merge(\@ancestor, \@a, \@b, {
20 CONFLICT => sub { }
21 }, $key_generation_function);
22
23 @diff = diff3(\@ancestor, \@a, \@b);
24
25 @diff = diff3(\@ancestor, \@a, \@b, $key_generation_function);
26
27 $diff = diff3(\@ancestor, \@a, \@b);
28
29 $diff = diff3(\@ancestor, \@a, \@b, $key_generation_function);
30
31 @trav = traverse_sequences3(\@ancestor, \@a, \@b, {
32 # callbacks
33 });
34
35 @trav = traverse_sequences3(\@ancestor, \@a, \@b, {
36 # callbacks
37 }, $key_generation_function);
38
39 $trav = traverse_sequences3(\@ancestor, \@a, \@b, {
40 # callbacks
41 });
42
43 $trav = traverse_sequences3(\@ancestor, \@a, \@b, {
44 # callbacks
45 }, $key_generation_function);
46
47USAGE
48 This module complements Algorithm::Diff by providing three-way merge and
49 diff functions.
50
51 In this documentation, the first list to "diff3", "merge", and
52 "traverse_sequences3" is called the `original' list. The second list is
53 the `left' list. The third list is the `right' list.
54
55 The optional key generation arguments are the same as in
56 Algorithm::Diff. See Algorithm::Diff for more information.
57
58 diff3
59 Given references to three lists of items, "diff3" performs a three-way
60 difference.
61
62 This function returns an array of operations describing how the left and
63 right lists differ from the original list. In scalar context, this
64 function returns a reference to such an array.
65
66 Perhaps an example would be useful.
67
68 Given the following three lists,
69
70 original: a b c e f h i k
71 left: a b d e f g i j k
72 right: a b c d e h i j k
73
74 merge: a b d e g i j k
75
76 we have the following result from diff3:
77
78 [ 'u', 'a', 'a', 'a' ],
79 [ 'u', 'b', 'b', 'b' ],
80 [ 'l', 'c', undef, 'c' ],
81 [ 'o', undef, 'd', 'd' ],
82 [ 'u', 'e', 'e', 'e' ],
83 [ 'r', 'f', 'f', undef ],
84 [ 'o', 'h', 'g', 'h' ],
85 [ 'u', 'i', 'i', 'i' ],
86 [ 'o', undef, 'j', 'j' ],
87 [ 'u', 'k', 'k', 'k' ]
88
89 The first element in each row is the array with the difference:
90
91 c - conflict (no two are the same)
92 l - left is different
93 o - original is different
94 r - right is different
95 u - unchanged
96
97 The next three elements are the lists from the original, left, and right
98 arrays respectively that the row refers to (in the synopsis, these are
99 @ancestor, @a, and @b, respectively).
100
101 merge
102 Given references to three lists of items, "merge" performs a three-way
103 merge. The "merge" function uses the "diff3" function to do most of the
104 work.
105
106 The only callback currently used is "CONFLICT" which should be a
107 reference to a subroutine that accepts two array references. The first
108 array reference is to a list of elements from the left list. The second
109 array reference is to a list of elements from the right list. This
110 callback should return a list of elements to place in the merged list in
111 place of the conflict.
112
113 The default "CONFLICT" callback returns the following:
114
115 q{<!-- ------ START CONFLICT ------ -->},
116 (@left),
117 q{<!-- ---------------------------- -->},
118 (@right),
119 q{<!-- ------ END CONFLICT ------ -->},
120
121 traverse_sequences3
122 This is the workhorse function that goes through the three sequences and
123 calls the callback functions.
124
125 The following callbacks are supported.
126
127 NO_CHANGE
128 This is called if all three sequences have the same element at the
129 current position. The arguments are the current positions within
130 each sequence, the first argument being the current position within
131 the first sequence.
132
133 A_DIFF
134 This is called if the first sequence is different than the other two
135 sequences at the current position. This callback will be called with
136 one, two, or three arguments.
137
138 If one argument, then only the element at the given position from
139 the first sequence is not in either of the other two sequences.
140
141 If two arguments, then there is no element in the first sequence
142 that corresponds to the elements at the given positions in the
143 second and third sequences.
144
145 If three arguments, then the element at the given position in the
146 first sequence is different than the corresponding element in the
147 other two sequences, but the other two sequences have corresponding
148 elements.
149
150 B_DIFF
151 This is called if the second sequence is different than the other
152 two sequences at the current position. This callback will be called
153 with one, two, or three arguments.
154
155 If one argument, then only the element at the given position from
156 the second sequence is not in either of the other two sequences.
157
158 If two arguments, then there is no element in the second sequence
159 that corresponds to the elements at the given positions in the first
160 and third sequences.
161
162 If three arguments, then the element at the given position in the
163 second sequence is different than the corresponding element in the
164 other two sequences, but the other two sequences have corresponding
165 elements.
166
167 C_DIFF
168 This is called if the third sequence is different than the other two
169 sequences at the current position. This callback will be called with
170 one, two, or three arguments.
171
172 If one argument, then only the element at the given position from
173 the third sequence is not in either of the other two sequences.
174
175 If two arguments, then there is no element in the third sequence
176 that corresponds to the elements at the given positions in the first
177 and second sequences.
178
179 If three arguments, then the element at the given position in the
180 third sequence is different than the corresponding element in the
181 other two sequences, but the other two sequences have corresponding
182 elements.
183
184 CONFLICT
185 This is called if all three sequences have different elements at the
186 current position. The three arguments are the current positions
187 within each sequence.
188
189BUGS
190 Most assuredly there are bugs. If a pattern similar to the above example
191 does not work, send it to <jsmith@cpan.org> or report it on
192 <http://rt.cpan.org/>, the CPAN bug tracker.
193
194 Algorithm::Diff's implementation of "traverse_sequences" may not be
195 symmetric with respect to the input sequences if the second and third
196 sequence are of different lengths. Because of this,
197 "traverse_sequences3" will calculate the diffs of the second and third
198 sequences as passed and swapped. If the differences are not the same, it
199 will issue an `Algorithm::Diff::diff is not symmetric for second and
200 third sequences...' warning. It will try to handle this, but there may
201 be some cases where it can't.
202
203SEE ALSO
204 Algorithm::Diff.
205
206AUTHOR
207 James G. Smith, <jsmith@cpan.org>
208
209COPYRIGHT
210 Copyright (C) 2003, 2007 Texas A&M University. All Rights Reserved.
211
212 This module is free software; you may redistribute it and/or modify it
213 under the same terms as Perl itself.
214
215