Fossil SCM

Improve merge conflict markings.

drh 2009-03-20 01:23 trunk
Commit e45d478f0c37add20a1dad418706b42745b1911e
1 file changed +151 -96
+151 -96
--- src/merge3.c
+++ src/merge3.c
@@ -24,18 +24,26 @@
2424
** This module implements a 3-way merge
2525
*/
2626
#include "config.h"
2727
#include "merge3.h"
2828
29
-#if 0
29
+#if 1
3030
#define DEBUG(X) X
31
+#define ISDEBUG 1
3132
#else
3233
#define DEBUG(X)
34
+#define ISDEBUG 0
3335
#endif
3436
3537
/*
36
-** Opcodes
38
+** Opcodes.
39
+**
40
+** Values are important here. The text_diff() function returns an array
41
+** of triples of integers where within each triple, the 0 element is
42
+** the number of lines to copy, the 1 element is the number of lines to
43
+** delete and the 2 element is the number of lines to insert. The CPY,
44
+** DEL, and INS opcodes must correspond to these indices.
3745
*/
3846
#define CPY 0
3947
#define DEL 1
4048
#define INS 2
4149
#define END 3
@@ -56,10 +64,13 @@
5664
for(i=0; z1[i]!='\n' && z1[i]==z2[i]; i++){}
5765
return z2[i]=='\n' || (z2[i]=='\r' && z2[i+1]=='\n')
5866
|| (z1[i]=='\r' && z2[i]=='\n' && z1[i+1]=='\n');
5967
}
6068
69
+/* The minimum of two integers */
70
+#define min(A,B) (A<B?A:B)
71
+
6172
/*
6273
** Do a three-way merge. Initialize pOut to contain the result.
6374
**
6475
** The merge is an edit against pV2. Both pV1 and pV2 have a
6576
** common origin at pPivot. Apply the changes of pPivot ==> pV1
@@ -69,33 +80,41 @@
6980
** -1 is returned and pOut is unmodified. If there are merge
7081
** conflicts, the merge proceeds as best as it can and the number
7182
** of conflicts is returns
7283
*/
7384
int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){
74
- int *aC1; /* Changes from pPivot to pV1 */
75
- int *aC2; /* Changes from pPivot to pV2 */
76
- int i1, i2;
77
- int op1, op2;
78
- int limit1, limit2;
79
- int inConflict = 0;
80
- int nConflict = 0;
81
- static const char zBegin[] = ">>>>>>>> BEGIN MERGE CONFLICT <<<<<<<<\n";
82
- static const char zEnd[] = ">>>>>>>>> END MERGE CONFLICT <<<<<<<<<\n";
83
-
85
+ int *aC1; /* Changes from pPivot to pV1 */
86
+ int *aC2; /* Changes from pPivot to pV2 */
87
+ int i1, i2; /* Index into aC1[] and aC2[] */
88
+ int op1, op2; /* Opcode for aC1[] and aC2[] */
89
+ int n1, n2; /* Counts for op1 and op2 */
90
+ int mn; /* Minimum count of op1 and op2 */
91
+ int limit1, limit2; /* Sizes of aC1[] and aC2[] */
92
+ int nConflict = 0; /* Number of merge conflicts seen so far */
93
+ static const char zBegin[] = ">>>>>>> BEGIN MERGE CONFLICT\n";
94
+ static const char zMid[] = "============================\n";
95
+ static const char zEnd[] = "<<<<<<< END MERGE CONFLICT\n";
96
+
97
+#if ISDEBUG
98
+ static const char *zOp[] = { "CPY", "DEL", "INS", "END", "UNK" };
99
+#endif
100
+
101
+ /* Compute the edits that occur from pPivot => pV1 and pPivot => pV2 */
84102
aC1 = text_diff(pPivot, pV1, 0, 0);
85103
aC2 = text_diff(pPivot, pV2, 0, 0);
86
-
87104
if( aC2==0 || aC2==0 ){
88105
free(aC1);
89106
free(aC2);
90107
return -1;
91108
}
92
- blob_zero(pOut);
93
- blob_rewind(pV1);
109
+
110
+ blob_zero(pOut); /* Merge results stored in pOut */
111
+ blob_rewind(pV1); /* Rewind inputs: Needed to reconstruct output */
94112
blob_rewind(pV2);
95113
blob_rewind(pPivot);
96114
115
+ /* Determine the length of the aC1[] and aC2[] change vectors */
97116
for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){}
98117
limit1 = i1;
99118
for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){}
100119
limit2 = i2;
101120
@@ -107,100 +126,136 @@
107126
printf("c2: %4d %4d %4d\n", aC2[i2], aC2[i2+1], aC2[i2+2]);
108127
}
109128
)
110129
111130
op1 = op2 = UNK;
112
- i1 = i2 = 0;
113
- while( i1<limit1 && aC1[i1]==0 ){ i1++; }
114
- while( i2<limit2 && aC2[i2]==0 ){ i2++; }
115
-
131
+ i1 = i2 = -1;
132
+ n1 = n2 = 0;
116133
while(1){
117134
if( op1==UNK ){
118
- if( i1>=limit1 ){
119
- op1 = END;
120
- DEBUG( printf("get op1=END\n"); )
135
+ if( n1 ){
136
+ op1 = i1 % 3;
121137
}else{
122
- op1 = i1 % 3;
123
- aC1[i1]--;
124
- DEBUG( printf("get op1=%d from %d (%d->%d)\n",
125
- op1,i1,aC1[i1]+1,aC1[i1]); )
138
+ i1++;
126139
while( i1<limit1 && aC1[i1]==0 ){ i1++; }
140
+ if( i1>=limit1 ){
141
+ op1 = END;
142
+ }else{
143
+ op1 = i1 % 3;
144
+ n1 = aC1[i1];
145
+ }
127146
}
128147
}
129148
if( op2==UNK ){
130
- if( i2>=limit2 ){
131
- op2 = END;
132
- DEBUG( printf("get op2=END\n"); )
133
- }else{
134
- op2 = i2 % 3;
135
- aC2[i2]--;
136
- DEBUG( printf("get op2=%d from %d (%d->%d)\n",
137
- op2,i2,aC2[i2]+1,aC2[i2]); )
138
- while( i2<limit2 && aC2[i2]==0 ){ i2++; }
139
- }
140
- }
141
- DEBUG( printf("op1=%d op2=%d\n", op1, op2); )
142
- if( op1==END ){
143
- if( op2==INS ){
144
- blob_copy_lines(pOut, pV2, 1);
145
- op2 = UNK;
146
- }else{
147
- break;
148
- }
149
+ if( n2 ){
150
+ op2 = i2 % 3;
151
+ }else{
152
+ i2++;
153
+ while( i2<limit2 && aC2[i2]==0 ){ i2++; }
154
+ if( i2>=limit2 ){
155
+ op2 = END;
156
+ }else{
157
+ op2 = i2 % 3;
158
+ n2 = aC2[i2];
159
+ }
160
+ }
161
+ }
162
+ DEBUG( printf("op1=%s(%d) op2=%s(%d)\n", zOp[op1], n1, zOp[op2], n2); )
163
+ if( op1==END ){
164
+ if( op2==INS ){
165
+ DEBUG( printf("INSERT %d FROM 2\n", n2); )
166
+ blob_copy_lines(pOut, pV2, n2);
167
+ }
168
+ break;
149169
}else if( op2==END ){
150170
if( op1==INS ){
151
- blob_copy_lines(pOut, pV1, 1);
152
- op1 = UNK;
153
- }else{
154
- break;
155
- }
156
- }else if( op1==INS && op2==INS ){
157
- if( !inConflict && sameLine(pV1, pV2) ){
158
- blob_copy_lines(pOut, pV2, 1);
159
- blob_copy_lines(0, pV1, 0);
160
- op1 = UNK;
161
- op2 = UNK;
162
- }else{
163
- if( !inConflict ){
164
- inConflict = 1;
165
- nConflict++;
166
- blob_appendf(pOut, zBegin);
167
- }
168
- blob_copy_lines(pOut, pV1, 1);
169
- op1 = UNK;
170
- }
171
- }else if( op1==INS ){
172
- blob_copy_lines(pOut, pV1, 1);
173
- op1 = UNK;
174
- }else if( op2==INS ){
175
- blob_copy_lines(pOut, pV2, 1);
176
- op2 = UNK;
177
- }else{
178
- if( inConflict ){
179
- inConflict = 0;
180
- blob_appendf(pOut, zEnd);
181
- }
182
- if( op1==DEL || op2==DEL ){
183
- blob_copy_lines(0, pPivot, 1);
184
- if( op2==CPY ){
185
- blob_copy_lines(0, pV2, 1);
186
- }
187
- if( op1==CPY ){
188
- blob_copy_lines(0, pV1, 1);
189
- }
190
- }else{
191
- assert( op1==CPY && op2==CPY );
192
- blob_copy_lines(pOut, pPivot, 1);
193
- blob_copy_lines(0, pV1, 1);
194
- blob_copy_lines(0, pV2, 1);
195
- }
196
- op1 = UNK;
197
- op2 = UNK;
198
- }
199
- }
200
- if( inConflict ){
201
- blob_appendf(pOut, zEnd);
171
+ DEBUG( printf("INSERT %d FROM 1\n", n1); )
172
+ blob_copy_lines(pOut, pV1, n1);
173
+ }
174
+ break;
175
+ }else if( op1==CPY && op2==CPY ){
176
+ mn = min(n1,n2);
177
+ DEBUG( printf("COPY %d\n", mn); )
178
+ blob_copy_lines(pOut, pPivot, mn);
179
+ blob_copy_lines(0, pV1, mn);
180
+ blob_copy_lines(0, pV2, mn);
181
+ n1 -= mn;
182
+ n2 -= mn;
183
+ op1 = op2 = UNK;
184
+ }else if( op1==DEL && op2==DEL ){
185
+ mn = min(n1,n2);
186
+ DEBUG( printf("SKIP %d both\n", mn); )
187
+ blob_copy_lines(0, pPivot, mn);
188
+ n1 -= mn;
189
+ n2 -= mn;
190
+ op1 = op2 = UNK;
191
+ }else if( op1==INS && op2==INS && sameLine(pV1, pV2) ){
192
+ DEBUG( printf("DUPLICATE INSERT\n"); )
193
+ blob_copy_lines(pOut, pV2, 1);
194
+ blob_copy_lines(0, pV1, 1);
195
+ n1--;
196
+ n2--;
197
+ op1 = op2 = UNK;
198
+ }else if( op1==CPY && op2==DEL ){
199
+ mn = min(n1,n2);
200
+ DEBUG( printf("SKIP %d two\n", mn); )
201
+ blob_copy_lines(0, pPivot, mn);
202
+ blob_copy_lines(0, pV1, mn);
203
+ n1 -= mn;
204
+ n2 -= mn;
205
+ op1 = op2 = UNK;
206
+ }else if( op2==CPY && op1==DEL ){
207
+ mn = min(n1,n2);
208
+ DEBUG( printf("SKIP %d one\n", mn); )
209
+ blob_copy_lines(0, pPivot, mn);
210
+ blob_copy_lines(0, pV2, mn);
211
+ n2 -= mn;
212
+ n1 -= mn;
213
+ op1 = op2 = UNK;
214
+ }else if( op1==CPY && op2==INS ){
215
+ DEBUG( printf("INSERT %d two\n", n2); )
216
+ blob_copy_lines(pOut, pV2, n2);
217
+ n2 = 0;
218
+ op2 = UNK;
219
+ }else if( op2==CPY && op1==INS ){
220
+ DEBUG( printf("INSERT %d one\n", n1); )
221
+ blob_copy_lines(pOut, pV1, n1);
222
+ n1 = 0;
223
+ op1 = UNK;
224
+ }else{
225
+ int toSkip = 0;
226
+ nConflict++;
227
+ DEBUG( printf("CONFLICT\n"); )
228
+ blob_appendf(pOut, zBegin);
229
+ if( op1==DEL ){
230
+ toSkip = n1;
231
+ i1++;
232
+ if( aC1[i1] ){
233
+ blob_copy_lines(pOut, pV1, aC1[i1]);
234
+ }
235
+ }else{
236
+ blob_copy_lines(pOut, pV1, n1);
237
+ }
238
+ n1 = 0;
239
+ op1 = UNK;
240
+ blob_appendf(pOut, zMid);
241
+ if( op2==DEL ){
242
+ blob_copy_lines(0, pPivot, n2);
243
+ i2++;
244
+ if( aC2[i2] ){
245
+ blob_copy_lines(pOut, pV2, aC2[i2]);
246
+ }
247
+ }else{
248
+ blob_copy_lines(pOut, pV2, n2);
249
+ }
250
+ if( toSkip ){
251
+ blob_copy_lines(0, pPivot, toSkip);
252
+ }
253
+ n2 = 0;
254
+ op2 = UNK;
255
+ blob_appendf(pOut, zEnd);
256
+ }
202257
}
203258
204259
free(aC1);
205260
free(aC2);
206261
return nConflict;
207262
--- src/merge3.c
+++ src/merge3.c
@@ -24,18 +24,26 @@
24 ** This module implements a 3-way merge
25 */
26 #include "config.h"
27 #include "merge3.h"
28
29 #if 0
30 #define DEBUG(X) X
 
31 #else
32 #define DEBUG(X)
 
33 #endif
34
35 /*
36 ** Opcodes
 
 
 
 
 
 
37 */
38 #define CPY 0
39 #define DEL 1
40 #define INS 2
41 #define END 3
@@ -56,10 +64,13 @@
56 for(i=0; z1[i]!='\n' && z1[i]==z2[i]; i++){}
57 return z2[i]=='\n' || (z2[i]=='\r' && z2[i+1]=='\n')
58 || (z1[i]=='\r' && z2[i]=='\n' && z1[i+1]=='\n');
59 }
60
 
 
 
61 /*
62 ** Do a three-way merge. Initialize pOut to contain the result.
63 **
64 ** The merge is an edit against pV2. Both pV1 and pV2 have a
65 ** common origin at pPivot. Apply the changes of pPivot ==> pV1
@@ -69,33 +80,41 @@
69 ** -1 is returned and pOut is unmodified. If there are merge
70 ** conflicts, the merge proceeds as best as it can and the number
71 ** of conflicts is returns
72 */
73 int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){
74 int *aC1; /* Changes from pPivot to pV1 */
75 int *aC2; /* Changes from pPivot to pV2 */
76 int i1, i2;
77 int op1, op2;
78 int limit1, limit2;
79 int inConflict = 0;
80 int nConflict = 0;
81 static const char zBegin[] = ">>>>>>>> BEGIN MERGE CONFLICT <<<<<<<<\n";
82 static const char zEnd[] = ">>>>>>>>> END MERGE CONFLICT <<<<<<<<<\n";
83
 
 
 
 
 
 
 
84 aC1 = text_diff(pPivot, pV1, 0, 0);
85 aC2 = text_diff(pPivot, pV2, 0, 0);
86
87 if( aC2==0 || aC2==0 ){
88 free(aC1);
89 free(aC2);
90 return -1;
91 }
92 blob_zero(pOut);
93 blob_rewind(pV1);
 
94 blob_rewind(pV2);
95 blob_rewind(pPivot);
96
 
97 for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){}
98 limit1 = i1;
99 for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){}
100 limit2 = i2;
101
@@ -107,100 +126,136 @@
107 printf("c2: %4d %4d %4d\n", aC2[i2], aC2[i2+1], aC2[i2+2]);
108 }
109 )
110
111 op1 = op2 = UNK;
112 i1 = i2 = 0;
113 while( i1<limit1 && aC1[i1]==0 ){ i1++; }
114 while( i2<limit2 && aC2[i2]==0 ){ i2++; }
115
116 while(1){
117 if( op1==UNK ){
118 if( i1>=limit1 ){
119 op1 = END;
120 DEBUG( printf("get op1=END\n"); )
121 }else{
122 op1 = i1 % 3;
123 aC1[i1]--;
124 DEBUG( printf("get op1=%d from %d (%d->%d)\n",
125 op1,i1,aC1[i1]+1,aC1[i1]); )
126 while( i1<limit1 && aC1[i1]==0 ){ i1++; }
 
 
 
 
 
 
127 }
128 }
129 if( op2==UNK ){
130 if( i2>=limit2 ){
131 op2 = END;
132 DEBUG( printf("get op2=END\n"); )
133 }else{
134 op2 = i2 % 3;
135 aC2[i2]--;
136 DEBUG( printf("get op2=%d from %d (%d->%d)\n",
137 op2,i2,aC2[i2]+1,aC2[i2]); )
138 while( i2<limit2 && aC2[i2]==0 ){ i2++; }
139 }
140 }
141 DEBUG( printf("op1=%d op2=%d\n", op1, op2); )
142 if( op1==END ){
143 if( op2==INS ){
144 blob_copy_lines(pOut, pV2, 1);
145 op2 = UNK;
146 }else{
147 break;
148 }
 
149 }else if( op2==END ){
150 if( op1==INS ){
151 blob_copy_lines(pOut, pV1, 1);
152 op1 = UNK;
153 }else{
154 break;
155 }
156 }else if( op1==INS && op2==INS ){
157 if( !inConflict && sameLine(pV1, pV2) ){
158 blob_copy_lines(pOut, pV2, 1);
159 blob_copy_lines(0, pV1, 0);
160 op1 = UNK;
161 op2 = UNK;
162 }else{
163 if( !inConflict ){
164 inConflict = 1;
165 nConflict++;
166 blob_appendf(pOut, zBegin);
167 }
168 blob_copy_lines(pOut, pV1, 1);
169 op1 = UNK;
170 }
171 }else if( op1==INS ){
172 blob_copy_lines(pOut, pV1, 1);
173 op1 = UNK;
174 }else if( op2==INS ){
175 blob_copy_lines(pOut, pV2, 1);
176 op2 = UNK;
177 }else{
178 if( inConflict ){
179 inConflict = 0;
180 blob_appendf(pOut, zEnd);
181 }
182 if( op1==DEL || op2==DEL ){
183 blob_copy_lines(0, pPivot, 1);
184 if( op2==CPY ){
185 blob_copy_lines(0, pV2, 1);
186 }
187 if( op1==CPY ){
188 blob_copy_lines(0, pV1, 1);
189 }
190 }else{
191 assert( op1==CPY && op2==CPY );
192 blob_copy_lines(pOut, pPivot, 1);
193 blob_copy_lines(0, pV1, 1);
194 blob_copy_lines(0, pV2, 1);
195 }
196 op1 = UNK;
197 op2 = UNK;
198 }
199 }
200 if( inConflict ){
201 blob_appendf(pOut, zEnd);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202 }
203
204 free(aC1);
205 free(aC2);
206 return nConflict;
207
--- src/merge3.c
+++ src/merge3.c
@@ -24,18 +24,26 @@
24 ** This module implements a 3-way merge
25 */
26 #include "config.h"
27 #include "merge3.h"
28
29 #if 1
30 #define DEBUG(X) X
31 #define ISDEBUG 1
32 #else
33 #define DEBUG(X)
34 #define ISDEBUG 0
35 #endif
36
37 /*
38 ** Opcodes.
39 **
40 ** Values are important here. The text_diff() function returns an array
41 ** of triples of integers where within each triple, the 0 element is
42 ** the number of lines to copy, the 1 element is the number of lines to
43 ** delete and the 2 element is the number of lines to insert. The CPY,
44 ** DEL, and INS opcodes must correspond to these indices.
45 */
46 #define CPY 0
47 #define DEL 1
48 #define INS 2
49 #define END 3
@@ -56,10 +64,13 @@
64 for(i=0; z1[i]!='\n' && z1[i]==z2[i]; i++){}
65 return z2[i]=='\n' || (z2[i]=='\r' && z2[i+1]=='\n')
66 || (z1[i]=='\r' && z2[i]=='\n' && z1[i+1]=='\n');
67 }
68
69 /* The minimum of two integers */
70 #define min(A,B) (A<B?A:B)
71
72 /*
73 ** Do a three-way merge. Initialize pOut to contain the result.
74 **
75 ** The merge is an edit against pV2. Both pV1 and pV2 have a
76 ** common origin at pPivot. Apply the changes of pPivot ==> pV1
@@ -69,33 +80,41 @@
80 ** -1 is returned and pOut is unmodified. If there are merge
81 ** conflicts, the merge proceeds as best as it can and the number
82 ** of conflicts is returns
83 */
84 int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){
85 int *aC1; /* Changes from pPivot to pV1 */
86 int *aC2; /* Changes from pPivot to pV2 */
87 int i1, i2; /* Index into aC1[] and aC2[] */
88 int op1, op2; /* Opcode for aC1[] and aC2[] */
89 int n1, n2; /* Counts for op1 and op2 */
90 int mn; /* Minimum count of op1 and op2 */
91 int limit1, limit2; /* Sizes of aC1[] and aC2[] */
92 int nConflict = 0; /* Number of merge conflicts seen so far */
93 static const char zBegin[] = ">>>>>>> BEGIN MERGE CONFLICT\n";
94 static const char zMid[] = "============================\n";
95 static const char zEnd[] = "<<<<<<< END MERGE CONFLICT\n";
96
97 #if ISDEBUG
98 static const char *zOp[] = { "CPY", "DEL", "INS", "END", "UNK" };
99 #endif
100
101 /* Compute the edits that occur from pPivot => pV1 and pPivot => pV2 */
102 aC1 = text_diff(pPivot, pV1, 0, 0);
103 aC2 = text_diff(pPivot, pV2, 0, 0);
 
104 if( aC2==0 || aC2==0 ){
105 free(aC1);
106 free(aC2);
107 return -1;
108 }
109
110 blob_zero(pOut); /* Merge results stored in pOut */
111 blob_rewind(pV1); /* Rewind inputs: Needed to reconstruct output */
112 blob_rewind(pV2);
113 blob_rewind(pPivot);
114
115 /* Determine the length of the aC1[] and aC2[] change vectors */
116 for(i1=0; aC1[i1] || aC1[i1+1] || aC1[i1+2]; i1+=3){}
117 limit1 = i1;
118 for(i2=0; aC2[i2] || aC2[i2+1] || aC2[i2+2]; i2+=3){}
119 limit2 = i2;
120
@@ -107,100 +126,136 @@
126 printf("c2: %4d %4d %4d\n", aC2[i2], aC2[i2+1], aC2[i2+2]);
127 }
128 )
129
130 op1 = op2 = UNK;
131 i1 = i2 = -1;
132 n1 = n2 = 0;
 
 
133 while(1){
134 if( op1==UNK ){
135 if( n1 ){
136 op1 = i1 % 3;
 
137 }else{
138 i1++;
 
 
 
139 while( i1<limit1 && aC1[i1]==0 ){ i1++; }
140 if( i1>=limit1 ){
141 op1 = END;
142 }else{
143 op1 = i1 % 3;
144 n1 = aC1[i1];
145 }
146 }
147 }
148 if( op2==UNK ){
149 if( n2 ){
150 op2 = i2 % 3;
151 }else{
152 i2++;
153 while( i2<limit2 && aC2[i2]==0 ){ i2++; }
154 if( i2>=limit2 ){
155 op2 = END;
156 }else{
157 op2 = i2 % 3;
158 n2 = aC2[i2];
159 }
160 }
161 }
162 DEBUG( printf("op1=%s(%d) op2=%s(%d)\n", zOp[op1], n1, zOp[op2], n2); )
163 if( op1==END ){
164 if( op2==INS ){
165 DEBUG( printf("INSERT %d FROM 2\n", n2); )
166 blob_copy_lines(pOut, pV2, n2);
167 }
168 break;
169 }else if( op2==END ){
170 if( op1==INS ){
171 DEBUG( printf("INSERT %d FROM 1\n", n1); )
172 blob_copy_lines(pOut, pV1, n1);
173 }
174 break;
175 }else if( op1==CPY && op2==CPY ){
176 mn = min(n1,n2);
177 DEBUG( printf("COPY %d\n", mn); )
178 blob_copy_lines(pOut, pPivot, mn);
179 blob_copy_lines(0, pV1, mn);
180 blob_copy_lines(0, pV2, mn);
181 n1 -= mn;
182 n2 -= mn;
183 op1 = op2 = UNK;
184 }else if( op1==DEL && op2==DEL ){
185 mn = min(n1,n2);
186 DEBUG( printf("SKIP %d both\n", mn); )
187 blob_copy_lines(0, pPivot, mn);
188 n1 -= mn;
189 n2 -= mn;
190 op1 = op2 = UNK;
191 }else if( op1==INS && op2==INS && sameLine(pV1, pV2) ){
192 DEBUG( printf("DUPLICATE INSERT\n"); )
193 blob_copy_lines(pOut, pV2, 1);
194 blob_copy_lines(0, pV1, 1);
195 n1--;
196 n2--;
197 op1 = op2 = UNK;
198 }else if( op1==CPY && op2==DEL ){
199 mn = min(n1,n2);
200 DEBUG( printf("SKIP %d two\n", mn); )
201 blob_copy_lines(0, pPivot, mn);
202 blob_copy_lines(0, pV1, mn);
203 n1 -= mn;
204 n2 -= mn;
205 op1 = op2 = UNK;
206 }else if( op2==CPY && op1==DEL ){
207 mn = min(n1,n2);
208 DEBUG( printf("SKIP %d one\n", mn); )
209 blob_copy_lines(0, pPivot, mn);
210 blob_copy_lines(0, pV2, mn);
211 n2 -= mn;
212 n1 -= mn;
213 op1 = op2 = UNK;
214 }else if( op1==CPY && op2==INS ){
215 DEBUG( printf("INSERT %d two\n", n2); )
216 blob_copy_lines(pOut, pV2, n2);
217 n2 = 0;
218 op2 = UNK;
219 }else if( op2==CPY && op1==INS ){
220 DEBUG( printf("INSERT %d one\n", n1); )
221 blob_copy_lines(pOut, pV1, n1);
222 n1 = 0;
223 op1 = UNK;
224 }else{
225 int toSkip = 0;
226 nConflict++;
227 DEBUG( printf("CONFLICT\n"); )
228 blob_appendf(pOut, zBegin);
229 if( op1==DEL ){
230 toSkip = n1;
231 i1++;
232 if( aC1[i1] ){
233 blob_copy_lines(pOut, pV1, aC1[i1]);
234 }
235 }else{
236 blob_copy_lines(pOut, pV1, n1);
237 }
238 n1 = 0;
239 op1 = UNK;
240 blob_appendf(pOut, zMid);
241 if( op2==DEL ){
242 blob_copy_lines(0, pPivot, n2);
243 i2++;
244 if( aC2[i2] ){
245 blob_copy_lines(pOut, pV2, aC2[i2]);
246 }
247 }else{
248 blob_copy_lines(pOut, pV2, n2);
249 }
250 if( toSkip ){
251 blob_copy_lines(0, pPivot, toSkip);
252 }
253 n2 = 0;
254 op2 = UNK;
255 blob_appendf(pOut, zEnd);
256 }
257 }
258
259 free(aC1);
260 free(aC2);
261 return nConflict;
262

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button