Fossil SCM

Bug fixes sufficient to get the automated merge conflict resolution working.

drh 2024-12-05 13:16 better-merge
Commit 1174e5f2fdd9ca2976b15f3b59ba59281490322442d486c98a4cfa052eb904d8
+1
--- src/blob.c
+++ src/blob.c
@@ -713,10 +713,11 @@
713713
mx = pFrom->nUsed;
714714
while( N>0 ){
715715
while( i<mx && z[i]!='\n' ){ i++; }
716716
if( i>=mx ) break;
717717
i++;
718
+ N--;
718719
}
719720
iStart = pFrom->iCursor;
720721
n = blob_extract(pFrom, i-pFrom->iCursor, pTo);
721722
pFrom->iCursor = iStart;
722723
return n;
723724
--- src/blob.c
+++ src/blob.c
@@ -713,10 +713,11 @@
713 mx = pFrom->nUsed;
714 while( N>0 ){
715 while( i<mx && z[i]!='\n' ){ i++; }
716 if( i>=mx ) break;
717 i++;
 
718 }
719 iStart = pFrom->iCursor;
720 n = blob_extract(pFrom, i-pFrom->iCursor, pTo);
721 pFrom->iCursor = iStart;
722 return n;
723
--- src/blob.c
+++ src/blob.c
@@ -713,10 +713,11 @@
713 mx = pFrom->nUsed;
714 while( N>0 ){
715 while( i<mx && z[i]!='\n' ){ i++; }
716 if( i>=mx ) break;
717 i++;
718 N--;
719 }
720 iStart = pFrom->iCursor;
721 n = blob_extract(pFrom, i-pFrom->iCursor, pTo);
722 pFrom->iCursor = iStart;
723 return n;
724
+2 -2
--- src/merge.tcl
+++ src/merge.tcl
@@ -183,11 +183,11 @@
183183
.txtC insert end [string range $B 1 end]\n chng
184184
} else {
185185
.txtC insert end [string range $C 1 end]\n $tag
186186
}
187187
}
188
- if {$key4=="." || $key4=="X"} {
188
+ if {$key4=="."} {
189189
.lnD insert end \n -
190190
.txtD insert end \n $dtag
191191
} elseif {$key4=="N"} {
192192
.nameD config -text [string range $D 1 end]
193193
} else {
@@ -198,11 +198,11 @@
198198
} elseif {$key4=="2"} {
199199
.txtD insert end [string range $B 1 end]\n chng
200200
} elseif {$key4=="3"} {
201201
.txtD insert end [string range $C 1 end]\n add
202202
} else {
203
- .txtD insert end [string range $D 1 end]\n -
203
+ .txtD insert end [string range $D 1 end]\n $dtag
204204
}
205205
}
206206
}
207207
foreach c [cols] {
208208
set type [colType $c]
209209
--- src/merge.tcl
+++ src/merge.tcl
@@ -183,11 +183,11 @@
183 .txtC insert end [string range $B 1 end]\n chng
184 } else {
185 .txtC insert end [string range $C 1 end]\n $tag
186 }
187 }
188 if {$key4=="." || $key4=="X"} {
189 .lnD insert end \n -
190 .txtD insert end \n $dtag
191 } elseif {$key4=="N"} {
192 .nameD config -text [string range $D 1 end]
193 } else {
@@ -198,11 +198,11 @@
198 } elseif {$key4=="2"} {
199 .txtD insert end [string range $B 1 end]\n chng
200 } elseif {$key4=="3"} {
201 .txtD insert end [string range $C 1 end]\n add
202 } else {
203 .txtD insert end [string range $D 1 end]\n -
204 }
205 }
206 }
207 foreach c [cols] {
208 set type [colType $c]
209
--- src/merge.tcl
+++ src/merge.tcl
@@ -183,11 +183,11 @@
183 .txtC insert end [string range $B 1 end]\n chng
184 } else {
185 .txtC insert end [string range $C 1 end]\n $tag
186 }
187 }
188 if {$key4=="."} {
189 .lnD insert end \n -
190 .txtD insert end \n $dtag
191 } elseif {$key4=="N"} {
192 .nameD config -text [string range $D 1 end]
193 } else {
@@ -198,11 +198,11 @@
198 } elseif {$key4=="2"} {
199 .txtD insert end [string range $B 1 end]\n chng
200 } elseif {$key4=="3"} {
201 .txtD insert end [string range $C 1 end]\n add
202 } else {
203 .txtD insert end [string range $D 1 end]\n $dtag
204 }
205 }
206 }
207 foreach c [cols] {
208 set type [colType $c]
209
+37 -25
--- src/merge3.c
+++ src/merge3.c
@@ -163,10 +163,11 @@
163163
unsigned int lnPivot; /* Lines read from pivot */
164164
unsigned int lnV1; /* Lines read from v1 */
165165
unsigned int lnV2; /* Lines read from v2 */
166166
unsigned int lnOut; /* Lines written to out */
167167
unsigned int nConflict; /* Number of conflicts seen */
168
+ u64 diffFlags; /* Flags for difference engine */
168169
};
169170
#endif /* INTERFACE */
170171
171172
172173
/************************* Generic MergeBuilder ******************************/
@@ -308,10 +309,11 @@
308309
p->xSame = tokenSame;
309310
p->xChngV1 = tokenChngV1;
310311
p->xChngV2 = tokenChngV2;
311312
p->xChngBoth = tokenChngBoth;
312313
p->xConflict = tokenConflict;
314
+ p->diffFlags = DIFF_BY_TOKEN;
313315
}
314316
315317
/*
316318
** Attempt to do a low-level merge on a conflict. The conflict is
317319
** described by the first four parameters, which are the same as the
@@ -336,17 +338,21 @@
336338
mergebuilder_init_token(&mb);
337339
blob_extract_lines(pMB->pPivot, nPivot, &pv);
338340
blob_extract_lines(pMB->pV1, nV1, &v1);
339341
blob_extract_lines(pMB->pV2, nV2, &v2);
340342
blob_zero(pOut);
343
+ blob_materialize(&pv);
344
+ blob_materialize(&v1);
345
+ blob_materialize(&v2);
341346
mb.pPivot = &pv;
342347
mb.pV1 = &v1;
343348
mb.pV2 = &v2;
344349
mb.pOut = pOut;
345350
nConflict = merge_three_blobs(&mb);
346
- /* pv, v1, and v2 should all be ephemeral blobs, so they do not
347
- ** need to be freed. */
351
+ blob_reset(&pv);
352
+ blob_reset(&v1);
353
+ blob_reset(&v2);
348354
/* mb has not allocated any resources, so we do not need to invoke
349355
** the xDestroy method. */
350356
blob_add_final_newline(pOut);
351357
return nConflict;
352358
}
@@ -426,11 +432,11 @@
426432
**
427433
** . This line is omitted.
428434
** N Name of the file.
429435
** T Literal text follows that should have a \n terminator.
430436
** R Literal text follows that needs a \r\n terminator.
431
-** X Merge conflict. (Column 4 only)
437
+** X Merge conflict.
432438
** Z Literal text without a line terminator.
433439
** S Skipped lines in all 4 files.
434440
** 1 Text is a copy of token 1
435441
** 2 Use data from data-token 2
436442
** 3 Use data from data-token 3
@@ -458,22 +464,25 @@
458464
}
459465
}
460466
}
461467
462468
/* Copy one line of text from pIn and append to pOut, encoded as TCL */
463
-static void tclLineOfText(Blob *pOut, Blob *pIn){
469
+static void tclLineOfText(Blob *pOut, Blob *pIn, char cType){
464470
int i, k;
465471
for(i=pIn->iCursor; i<pIn->nUsed && pIn->aData[i]!='\n'; i++){}
466472
if( i==pIn->nUsed ){
467
- blob_append(pOut, "\"Z", 2);
473
+ blob_append_char(pOut, '"');
474
+ blob_append_char(pOut, cType ? cType : 'Z');
468475
k = i;
469476
}else if( i>pIn->iCursor && pIn->aData[i-1]=='\r' ){
470
- blob_append(pOut, "\"R", 2);
477
+ blob_append_char(pOut, '"');
478
+ blob_append_char(pOut, cType ? cType : 'R');
471479
k = i-1;
472480
i++;
473481
}else{
474
- blob_append(pOut, "\"T", 2);
482
+ blob_append_char(pOut, '"');
483
+ blob_append_char(pOut, cType ? cType : 'T');
475484
k = i;
476485
i++;
477486
}
478487
tclWriteQuotedText(pOut, pIn->aData+pIn->iCursor, k-pIn->iCursor);
479488
pIn->iCursor = i;
@@ -499,11 +508,11 @@
499508
int i = 0;
500509
int nSkip;
501510
502511
if( p->lnPivot>=2 || p->lnV1>2 || p->lnV2>2 ){
503512
while( i<N && i<p->nContext ){
504
- tclLineOfText(p->pOut, p->pPivot);
513
+ tclLineOfText(p->pOut, p->pPivot, 0);
505514
blob_append(p->pOut, " 1 1 1\n", 7);
506515
i++;
507516
}
508517
nSkip = N - p->nContext*2;
509518
}else{
@@ -519,11 +528,11 @@
519528
p->lnV1 += N;
520529
p->lnV2 += N;
521530
522531
if( p->lnPivot<p->mxPivot || p->lnV1<p->mxV1 || p->lnV2<p->mxV2 ){
523532
while( i<N ){
524
- tclLineOfText(p->pOut, p->pPivot);
533
+ tclLineOfText(p->pOut, p->pPivot, 0);
525534
blob_append(p->pOut, " 1 1 1\n", 7);
526535
i++;
527536
}
528537
}
529538
@@ -531,23 +540,23 @@
531540
blob_copy_lines(0, p->pV2, N);
532541
}
533542
static void tclChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
534543
int i;
535544
for(i=0; i<nPivot && i<nV1; i++){
536
- tclLineOfText(p->pOut, p->pPivot);
545
+ tclLineOfText(p->pOut, p->pPivot, 0);
537546
blob_append_char(p->pOut, ' ');
538
- tclLineOfText(p->pOut, p->pV1);
547
+ tclLineOfText(p->pOut, p->pV1, 0);
539548
blob_append(p->pOut, " 1 2\n", 5);
540549
}
541550
while( i<nPivot ){
542
- tclLineOfText(p->pOut, p->pPivot);
551
+ tclLineOfText(p->pOut, p->pPivot, 0);
543552
blob_append(p->pOut, " . 1 .\n", 7);
544553
i++;
545554
}
546555
while( i<nV1 ){
547556
blob_append(p->pOut, ". ", 2);
548
- tclLineOfText(p->pOut, p->pV1);
557
+ tclLineOfText(p->pOut, p->pV1, 0);
549558
blob_append(p->pOut, " . 2\n", 5);
550559
i++;
551560
}
552561
p->lnPivot += nPivot;
553562
p->lnV1 += nV1;
@@ -555,23 +564,23 @@
555564
blob_copy_lines(0, p->pV2, nPivot);
556565
}
557566
static void tclChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
558567
int i;
559568
for(i=0; i<nPivot && i<nV2; i++){
560
- tclLineOfText(p->pOut, p->pPivot);
569
+ tclLineOfText(p->pOut, p->pPivot, 0);
561570
blob_append(p->pOut, " 1 ", 3);
562
- tclLineOfText(p->pOut, p->pV2);
571
+ tclLineOfText(p->pOut, p->pV2, 0);
563572
blob_append(p->pOut, " 3\n", 3);
564573
}
565574
while( i<nPivot ){
566
- tclLineOfText(p->pOut, p->pPivot);
575
+ tclLineOfText(p->pOut, p->pPivot, 0);
567576
blob_append(p->pOut, " 1 . .\n", 7);
568577
i++;
569578
}
570579
while( i<nV2 ){
571580
blob_append(p->pOut, ". . ", 4);
572
- tclLineOfText(p->pOut, p->pV2);
581
+ tclLineOfText(p->pOut, p->pV2, 0);
573582
blob_append(p->pOut, " 3\n", 3);
574583
i++;
575584
}
576585
p->lnPivot += nPivot;
577586
p->lnV1 += nPivot;
@@ -579,23 +588,23 @@
579588
blob_copy_lines(0, p->pV1, nPivot);
580589
}
581590
static void tclChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
582591
int i;
583592
for(i=0; i<nPivot && i<nV; i++){
584
- tclLineOfText(p->pOut, p->pPivot);
593
+ tclLineOfText(p->pOut, p->pPivot, 0);
585594
blob_append_char(p->pOut, ' ');
586
- tclLineOfText(p->pOut, p->pV1);
595
+ tclLineOfText(p->pOut, p->pV1, 0);
587596
blob_append(p->pOut, " 2 2\n", 5);
588597
}
589598
while( i<nPivot ){
590
- tclLineOfText(p->pOut, p->pPivot);
599
+ tclLineOfText(p->pOut, p->pPivot, 0);
591600
blob_append(p->pOut, " . . .\n", 7);
592601
i++;
593602
}
594603
while( i<nV ){
595604
blob_append(p->pOut, ". ", 2);
596
- tclLineOfText(p->pOut, p->pV1);
605
+ tclLineOfText(p->pOut, p->pV1, 0);
597606
blob_append(p->pOut, " 2 2\n", 5);
598607
i++;
599608
}
600609
p->lnPivot += nPivot;
601610
p->lnV1 += nV;
@@ -618,28 +627,30 @@
618627
if( nV1>mx ) mx = nV1;
619628
if( nV2>mx ) mx = nV2;
620629
if( nOut>mx ) mx = nOut;
621630
for(i=0; i<mx; i++){
622631
if( i<nPivot ){
623
- tclLineOfText(p->pOut, p->pPivot);
632
+ tclLineOfText(p->pOut, p->pPivot, 0);
624633
}else{
625634
blob_append_char(p->pOut, '.');
626635
}
627636
blob_append_char(p->pOut, ' ');
628637
if( i<nV1 ){
629
- tclLineOfText(p->pOut, p->pV1);
638
+ tclLineOfText(p->pOut, p->pV1, 0);
630639
}else{
631640
blob_append_char(p->pOut, '.');
632641
}
633642
blob_append_char(p->pOut, ' ');
634643
if( i<nV2 ){
635
- tclLineOfText(p->pOut, p->pV2);
644
+ tclLineOfText(p->pOut, p->pV2, 0);
636645
}else{
637646
blob_append_char(p->pOut, '.');
638647
}
639648
if( i<nOut ){
640
- tclLineOfText(p->pOut, &out);
649
+ blob_append_char(p->pOut, ' ');
650
+ tclLineOfText(p->pOut, &out, 'X');
651
+ blob_append_char(p->pOut, '\n');
641652
}else{
642653
blob_append(p->pOut, " X\n", 3);
643654
}
644655
}
645656
blob_reset(&out);
@@ -736,10 +747,11 @@
736747
** the second integer is the number of lines of text to omit from the
737748
** pivot, and the third integer is the number of lines of text that are
738749
** inserted. The edit array ends with a triple of 0,0,0.
739750
*/
740751
diff_config_init(&DCfg, 0);
752
+ DCfg.diffFlags = p->diffFlags;
741753
aC1 = text_diff(p->pPivot, p->pV1, 0, &DCfg);
742754
aC2 = text_diff(p->pPivot, p->pV2, 0, &DCfg);
743755
if( aC1==0 || aC2==0 ){
744756
free(aC1);
745757
free(aC2);
746758
--- src/merge3.c
+++ src/merge3.c
@@ -163,10 +163,11 @@
163 unsigned int lnPivot; /* Lines read from pivot */
164 unsigned int lnV1; /* Lines read from v1 */
165 unsigned int lnV2; /* Lines read from v2 */
166 unsigned int lnOut; /* Lines written to out */
167 unsigned int nConflict; /* Number of conflicts seen */
 
168 };
169 #endif /* INTERFACE */
170
171
172 /************************* Generic MergeBuilder ******************************/
@@ -308,10 +309,11 @@
308 p->xSame = tokenSame;
309 p->xChngV1 = tokenChngV1;
310 p->xChngV2 = tokenChngV2;
311 p->xChngBoth = tokenChngBoth;
312 p->xConflict = tokenConflict;
 
313 }
314
315 /*
316 ** Attempt to do a low-level merge on a conflict. The conflict is
317 ** described by the first four parameters, which are the same as the
@@ -336,17 +338,21 @@
336 mergebuilder_init_token(&mb);
337 blob_extract_lines(pMB->pPivot, nPivot, &pv);
338 blob_extract_lines(pMB->pV1, nV1, &v1);
339 blob_extract_lines(pMB->pV2, nV2, &v2);
340 blob_zero(pOut);
 
 
 
341 mb.pPivot = &pv;
342 mb.pV1 = &v1;
343 mb.pV2 = &v2;
344 mb.pOut = pOut;
345 nConflict = merge_three_blobs(&mb);
346 /* pv, v1, and v2 should all be ephemeral blobs, so they do not
347 ** need to be freed. */
 
348 /* mb has not allocated any resources, so we do not need to invoke
349 ** the xDestroy method. */
350 blob_add_final_newline(pOut);
351 return nConflict;
352 }
@@ -426,11 +432,11 @@
426 **
427 ** . This line is omitted.
428 ** N Name of the file.
429 ** T Literal text follows that should have a \n terminator.
430 ** R Literal text follows that needs a \r\n terminator.
431 ** X Merge conflict. (Column 4 only)
432 ** Z Literal text without a line terminator.
433 ** S Skipped lines in all 4 files.
434 ** 1 Text is a copy of token 1
435 ** 2 Use data from data-token 2
436 ** 3 Use data from data-token 3
@@ -458,22 +464,25 @@
458 }
459 }
460 }
461
462 /* Copy one line of text from pIn and append to pOut, encoded as TCL */
463 static void tclLineOfText(Blob *pOut, Blob *pIn){
464 int i, k;
465 for(i=pIn->iCursor; i<pIn->nUsed && pIn->aData[i]!='\n'; i++){}
466 if( i==pIn->nUsed ){
467 blob_append(pOut, "\"Z", 2);
 
468 k = i;
469 }else if( i>pIn->iCursor && pIn->aData[i-1]=='\r' ){
470 blob_append(pOut, "\"R", 2);
 
471 k = i-1;
472 i++;
473 }else{
474 blob_append(pOut, "\"T", 2);
 
475 k = i;
476 i++;
477 }
478 tclWriteQuotedText(pOut, pIn->aData+pIn->iCursor, k-pIn->iCursor);
479 pIn->iCursor = i;
@@ -499,11 +508,11 @@
499 int i = 0;
500 int nSkip;
501
502 if( p->lnPivot>=2 || p->lnV1>2 || p->lnV2>2 ){
503 while( i<N && i<p->nContext ){
504 tclLineOfText(p->pOut, p->pPivot);
505 blob_append(p->pOut, " 1 1 1\n", 7);
506 i++;
507 }
508 nSkip = N - p->nContext*2;
509 }else{
@@ -519,11 +528,11 @@
519 p->lnV1 += N;
520 p->lnV2 += N;
521
522 if( p->lnPivot<p->mxPivot || p->lnV1<p->mxV1 || p->lnV2<p->mxV2 ){
523 while( i<N ){
524 tclLineOfText(p->pOut, p->pPivot);
525 blob_append(p->pOut, " 1 1 1\n", 7);
526 i++;
527 }
528 }
529
@@ -531,23 +540,23 @@
531 blob_copy_lines(0, p->pV2, N);
532 }
533 static void tclChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
534 int i;
535 for(i=0; i<nPivot && i<nV1; i++){
536 tclLineOfText(p->pOut, p->pPivot);
537 blob_append_char(p->pOut, ' ');
538 tclLineOfText(p->pOut, p->pV1);
539 blob_append(p->pOut, " 1 2\n", 5);
540 }
541 while( i<nPivot ){
542 tclLineOfText(p->pOut, p->pPivot);
543 blob_append(p->pOut, " . 1 .\n", 7);
544 i++;
545 }
546 while( i<nV1 ){
547 blob_append(p->pOut, ". ", 2);
548 tclLineOfText(p->pOut, p->pV1);
549 blob_append(p->pOut, " . 2\n", 5);
550 i++;
551 }
552 p->lnPivot += nPivot;
553 p->lnV1 += nV1;
@@ -555,23 +564,23 @@
555 blob_copy_lines(0, p->pV2, nPivot);
556 }
557 static void tclChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
558 int i;
559 for(i=0; i<nPivot && i<nV2; i++){
560 tclLineOfText(p->pOut, p->pPivot);
561 blob_append(p->pOut, " 1 ", 3);
562 tclLineOfText(p->pOut, p->pV2);
563 blob_append(p->pOut, " 3\n", 3);
564 }
565 while( i<nPivot ){
566 tclLineOfText(p->pOut, p->pPivot);
567 blob_append(p->pOut, " 1 . .\n", 7);
568 i++;
569 }
570 while( i<nV2 ){
571 blob_append(p->pOut, ". . ", 4);
572 tclLineOfText(p->pOut, p->pV2);
573 blob_append(p->pOut, " 3\n", 3);
574 i++;
575 }
576 p->lnPivot += nPivot;
577 p->lnV1 += nPivot;
@@ -579,23 +588,23 @@
579 blob_copy_lines(0, p->pV1, nPivot);
580 }
581 static void tclChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
582 int i;
583 for(i=0; i<nPivot && i<nV; i++){
584 tclLineOfText(p->pOut, p->pPivot);
585 blob_append_char(p->pOut, ' ');
586 tclLineOfText(p->pOut, p->pV1);
587 blob_append(p->pOut, " 2 2\n", 5);
588 }
589 while( i<nPivot ){
590 tclLineOfText(p->pOut, p->pPivot);
591 blob_append(p->pOut, " . . .\n", 7);
592 i++;
593 }
594 while( i<nV ){
595 blob_append(p->pOut, ". ", 2);
596 tclLineOfText(p->pOut, p->pV1);
597 blob_append(p->pOut, " 2 2\n", 5);
598 i++;
599 }
600 p->lnPivot += nPivot;
601 p->lnV1 += nV;
@@ -618,28 +627,30 @@
618 if( nV1>mx ) mx = nV1;
619 if( nV2>mx ) mx = nV2;
620 if( nOut>mx ) mx = nOut;
621 for(i=0; i<mx; i++){
622 if( i<nPivot ){
623 tclLineOfText(p->pOut, p->pPivot);
624 }else{
625 blob_append_char(p->pOut, '.');
626 }
627 blob_append_char(p->pOut, ' ');
628 if( i<nV1 ){
629 tclLineOfText(p->pOut, p->pV1);
630 }else{
631 blob_append_char(p->pOut, '.');
632 }
633 blob_append_char(p->pOut, ' ');
634 if( i<nV2 ){
635 tclLineOfText(p->pOut, p->pV2);
636 }else{
637 blob_append_char(p->pOut, '.');
638 }
639 if( i<nOut ){
640 tclLineOfText(p->pOut, &out);
 
 
641 }else{
642 blob_append(p->pOut, " X\n", 3);
643 }
644 }
645 blob_reset(&out);
@@ -736,10 +747,11 @@
736 ** the second integer is the number of lines of text to omit from the
737 ** pivot, and the third integer is the number of lines of text that are
738 ** inserted. The edit array ends with a triple of 0,0,0.
739 */
740 diff_config_init(&DCfg, 0);
 
741 aC1 = text_diff(p->pPivot, p->pV1, 0, &DCfg);
742 aC2 = text_diff(p->pPivot, p->pV2, 0, &DCfg);
743 if( aC1==0 || aC2==0 ){
744 free(aC1);
745 free(aC2);
746
--- src/merge3.c
+++ src/merge3.c
@@ -163,10 +163,11 @@
163 unsigned int lnPivot; /* Lines read from pivot */
164 unsigned int lnV1; /* Lines read from v1 */
165 unsigned int lnV2; /* Lines read from v2 */
166 unsigned int lnOut; /* Lines written to out */
167 unsigned int nConflict; /* Number of conflicts seen */
168 u64 diffFlags; /* Flags for difference engine */
169 };
170 #endif /* INTERFACE */
171
172
173 /************************* Generic MergeBuilder ******************************/
@@ -308,10 +309,11 @@
309 p->xSame = tokenSame;
310 p->xChngV1 = tokenChngV1;
311 p->xChngV2 = tokenChngV2;
312 p->xChngBoth = tokenChngBoth;
313 p->xConflict = tokenConflict;
314 p->diffFlags = DIFF_BY_TOKEN;
315 }
316
317 /*
318 ** Attempt to do a low-level merge on a conflict. The conflict is
319 ** described by the first four parameters, which are the same as the
@@ -336,17 +338,21 @@
338 mergebuilder_init_token(&mb);
339 blob_extract_lines(pMB->pPivot, nPivot, &pv);
340 blob_extract_lines(pMB->pV1, nV1, &v1);
341 blob_extract_lines(pMB->pV2, nV2, &v2);
342 blob_zero(pOut);
343 blob_materialize(&pv);
344 blob_materialize(&v1);
345 blob_materialize(&v2);
346 mb.pPivot = &pv;
347 mb.pV1 = &v1;
348 mb.pV2 = &v2;
349 mb.pOut = pOut;
350 nConflict = merge_three_blobs(&mb);
351 blob_reset(&pv);
352 blob_reset(&v1);
353 blob_reset(&v2);
354 /* mb has not allocated any resources, so we do not need to invoke
355 ** the xDestroy method. */
356 blob_add_final_newline(pOut);
357 return nConflict;
358 }
@@ -426,11 +432,11 @@
432 **
433 ** . This line is omitted.
434 ** N Name of the file.
435 ** T Literal text follows that should have a \n terminator.
436 ** R Literal text follows that needs a \r\n terminator.
437 ** X Merge conflict.
438 ** Z Literal text without a line terminator.
439 ** S Skipped lines in all 4 files.
440 ** 1 Text is a copy of token 1
441 ** 2 Use data from data-token 2
442 ** 3 Use data from data-token 3
@@ -458,22 +464,25 @@
464 }
465 }
466 }
467
468 /* Copy one line of text from pIn and append to pOut, encoded as TCL */
469 static void tclLineOfText(Blob *pOut, Blob *pIn, char cType){
470 int i, k;
471 for(i=pIn->iCursor; i<pIn->nUsed && pIn->aData[i]!='\n'; i++){}
472 if( i==pIn->nUsed ){
473 blob_append_char(pOut, '"');
474 blob_append_char(pOut, cType ? cType : 'Z');
475 k = i;
476 }else if( i>pIn->iCursor && pIn->aData[i-1]=='\r' ){
477 blob_append_char(pOut, '"');
478 blob_append_char(pOut, cType ? cType : 'R');
479 k = i-1;
480 i++;
481 }else{
482 blob_append_char(pOut, '"');
483 blob_append_char(pOut, cType ? cType : 'T');
484 k = i;
485 i++;
486 }
487 tclWriteQuotedText(pOut, pIn->aData+pIn->iCursor, k-pIn->iCursor);
488 pIn->iCursor = i;
@@ -499,11 +508,11 @@
508 int i = 0;
509 int nSkip;
510
511 if( p->lnPivot>=2 || p->lnV1>2 || p->lnV2>2 ){
512 while( i<N && i<p->nContext ){
513 tclLineOfText(p->pOut, p->pPivot, 0);
514 blob_append(p->pOut, " 1 1 1\n", 7);
515 i++;
516 }
517 nSkip = N - p->nContext*2;
518 }else{
@@ -519,11 +528,11 @@
528 p->lnV1 += N;
529 p->lnV2 += N;
530
531 if( p->lnPivot<p->mxPivot || p->lnV1<p->mxV1 || p->lnV2<p->mxV2 ){
532 while( i<N ){
533 tclLineOfText(p->pOut, p->pPivot, 0);
534 blob_append(p->pOut, " 1 1 1\n", 7);
535 i++;
536 }
537 }
538
@@ -531,23 +540,23 @@
540 blob_copy_lines(0, p->pV2, N);
541 }
542 static void tclChngV1(MergeBuilder *p, unsigned int nPivot, unsigned int nV1){
543 int i;
544 for(i=0; i<nPivot && i<nV1; i++){
545 tclLineOfText(p->pOut, p->pPivot, 0);
546 blob_append_char(p->pOut, ' ');
547 tclLineOfText(p->pOut, p->pV1, 0);
548 blob_append(p->pOut, " 1 2\n", 5);
549 }
550 while( i<nPivot ){
551 tclLineOfText(p->pOut, p->pPivot, 0);
552 blob_append(p->pOut, " . 1 .\n", 7);
553 i++;
554 }
555 while( i<nV1 ){
556 blob_append(p->pOut, ". ", 2);
557 tclLineOfText(p->pOut, p->pV1, 0);
558 blob_append(p->pOut, " . 2\n", 5);
559 i++;
560 }
561 p->lnPivot += nPivot;
562 p->lnV1 += nV1;
@@ -555,23 +564,23 @@
564 blob_copy_lines(0, p->pV2, nPivot);
565 }
566 static void tclChngV2(MergeBuilder *p, unsigned int nPivot, unsigned int nV2){
567 int i;
568 for(i=0; i<nPivot && i<nV2; i++){
569 tclLineOfText(p->pOut, p->pPivot, 0);
570 blob_append(p->pOut, " 1 ", 3);
571 tclLineOfText(p->pOut, p->pV2, 0);
572 blob_append(p->pOut, " 3\n", 3);
573 }
574 while( i<nPivot ){
575 tclLineOfText(p->pOut, p->pPivot, 0);
576 blob_append(p->pOut, " 1 . .\n", 7);
577 i++;
578 }
579 while( i<nV2 ){
580 blob_append(p->pOut, ". . ", 4);
581 tclLineOfText(p->pOut, p->pV2, 0);
582 blob_append(p->pOut, " 3\n", 3);
583 i++;
584 }
585 p->lnPivot += nPivot;
586 p->lnV1 += nPivot;
@@ -579,23 +588,23 @@
588 blob_copy_lines(0, p->pV1, nPivot);
589 }
590 static void tclChngBoth(MergeBuilder *p, unsigned int nPivot, unsigned int nV){
591 int i;
592 for(i=0; i<nPivot && i<nV; i++){
593 tclLineOfText(p->pOut, p->pPivot, 0);
594 blob_append_char(p->pOut, ' ');
595 tclLineOfText(p->pOut, p->pV1, 0);
596 blob_append(p->pOut, " 2 2\n", 5);
597 }
598 while( i<nPivot ){
599 tclLineOfText(p->pOut, p->pPivot, 0);
600 blob_append(p->pOut, " . . .\n", 7);
601 i++;
602 }
603 while( i<nV ){
604 blob_append(p->pOut, ". ", 2);
605 tclLineOfText(p->pOut, p->pV1, 0);
606 blob_append(p->pOut, " 2 2\n", 5);
607 i++;
608 }
609 p->lnPivot += nPivot;
610 p->lnV1 += nV;
@@ -618,28 +627,30 @@
627 if( nV1>mx ) mx = nV1;
628 if( nV2>mx ) mx = nV2;
629 if( nOut>mx ) mx = nOut;
630 for(i=0; i<mx; i++){
631 if( i<nPivot ){
632 tclLineOfText(p->pOut, p->pPivot, 0);
633 }else{
634 blob_append_char(p->pOut, '.');
635 }
636 blob_append_char(p->pOut, ' ');
637 if( i<nV1 ){
638 tclLineOfText(p->pOut, p->pV1, 0);
639 }else{
640 blob_append_char(p->pOut, '.');
641 }
642 blob_append_char(p->pOut, ' ');
643 if( i<nV2 ){
644 tclLineOfText(p->pOut, p->pV2, 0);
645 }else{
646 blob_append_char(p->pOut, '.');
647 }
648 if( i<nOut ){
649 blob_append_char(p->pOut, ' ');
650 tclLineOfText(p->pOut, &out, 'X');
651 blob_append_char(p->pOut, '\n');
652 }else{
653 blob_append(p->pOut, " X\n", 3);
654 }
655 }
656 blob_reset(&out);
@@ -736,10 +747,11 @@
747 ** the second integer is the number of lines of text to omit from the
748 ** pivot, and the third integer is the number of lines of text that are
749 ** inserted. The edit array ends with a triple of 0,0,0.
750 */
751 diff_config_init(&DCfg, 0);
752 DCfg.diffFlags = p->diffFlags;
753 aC1 = text_diff(p->pPivot, p->pV1, 0, &DCfg);
754 aC2 = text_diff(p->pPivot, p->pV2, 0, &DCfg);
755 if( aC1==0 || aC2==0 ){
756 free(aC1);
757 free(aC2);
758

Keyboard Shortcuts

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