Fossil SCM

Add support for side-by-side diff from the command-line "diff" command.

drh 2011-10-21 21:31 UTC diff-enhancements
Commit ac81759f65abdc4bf28062380bbb4b41a0282eea
2 files changed +179 -6 +9 -3
+179 -6
--- src/diff.c
+++ src/diff.c
@@ -25,14 +25,15 @@
2525
2626
#if INTERFACE
2727
/*
2828
** Allowed flag parameters to the text_diff() and html_sbsdiff() funtions:
2929
*/
30
-#define DIFF_CONTEXT_MASK 0x00fff /* Lines of context. Default if 0 */
31
-#define DIFF_IGNORE_EOLWS 0x01000 /* Ignore end-of-line whitespace */
32
-#define DIFF_SIDEBYSIDE 0x02000 /* Generate a side-by-side diff */
33
-#define DIFF_NEWFILE 0x04000 /* Non-existing files are as empty files */
30
+#define DIFF_CONTEXT_MASK 0x0000fff /* Lines of context. Default if 0 */
31
+#define DIFF_WIDTH_MASK 0x00ff000 /* side-by-side column width */
32
+#define DIFF_IGNORE_EOLWS 0x0100000 /* Ignore end-of-line whitespace */
33
+#define DIFF_SIDEBYSIDE 0x0200000 /* Generate a side-by-side diff */
34
+#define DIFF_NEWFILE 0x0400000 /* Missing files are as empty files */
3435
3536
#endif /* INTERFACE */
3637
3738
/*
3839
** Maximum length of a line in a text file. (8192)
@@ -296,10 +297,176 @@
296297
for(j=0; j<m; j++){
297298
appendDiffLine(pOut, " ", &B[b+j]);
298299
}
299300
}
300301
}
302
+
303
+/*
304
+** Append spaces to a blob
305
+*/
306
+static void appendSpace(Blob *pOut, int n){
307
+ const char z100[101] =
308
+ " "
309
+ " ";
310
+ while( n>100 ){
311
+ blob_append(pOut, z100, 100); n -= 100;
312
+ }
313
+ if( n>0 ){
314
+ blob_append(pOut, z100, n);
315
+ }
316
+}
317
+
318
+/*
319
+** Append text to a sbs diff output
320
+*/
321
+static void appendSbsLine(Blob *pOut, DLine *pLine, int width, int pad){
322
+ int sz = pLine->h & LENGTH_MASK;
323
+ if( sz<width ){
324
+ blob_append(pOut, pLine->z, sz);
325
+ if( pad ) appendSpace(pOut, width-sz);
326
+ }else{
327
+ blob_append(pOut, pLine->z, width);
328
+ }
329
+}
330
+
331
+
332
+/*
333
+** Given a diff context in which the aEdit[] array has been filled
334
+** in, compute a side-by-side diff into pOut.
335
+*/
336
+static void sbsDiff(DContext *p, Blob *pOut, int nContext, int width){
337
+ DLine *A; /* Left side of the diff */
338
+ DLine *B; /* Right side of the diff */
339
+ int a = 0; /* Index of next line in A[] */
340
+ int b = 0; /* Index of next line in B[] */
341
+ int *R; /* Array of COPY/DELETE/INSERT triples */
342
+ int r; /* Index into R[] */
343
+ int nr; /* Number of COPY/DELETE/INSERT triples to process */
344
+ int mxr; /* Maximum value for r */
345
+ int na, nb; /* Number of lines shown from A and B */
346
+ int i, j; /* Loop counters */
347
+ int m, ma, mb;/* Number of lines to output */
348
+ int skip; /* Number of lines to skip */
349
+ char zFormat[50]; /* Output format */
350
+
351
+ sqlite3_snprintf(sizeof(zFormat), zFormat,
352
+ "%%4d %%%d.%ds %%c %%4d %%.%ds\n",
353
+ width, width, width);
354
+ A = p->aFrom;
355
+ B = p->aTo;
356
+ R = p->aEdit;
357
+ mxr = p->nEdit;
358
+ while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
359
+ for(r=0; r<mxr; r += 3*nr){
360
+ /* Figure out how many triples to show in a single block */
361
+ for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
362
+ /* printf("r=%d nr=%d\n", r, nr); */
363
+
364
+ /* For the current block comprising nr triples, figure out
365
+ ** how many lines of A and B are to be displayed
366
+ */
367
+ if( R[r]>nContext ){
368
+ na = nb = nContext;
369
+ skip = R[r] - nContext;
370
+ }else{
371
+ na = nb = R[r];
372
+ skip = 0;
373
+ }
374
+ for(i=0; i<nr; i++){
375
+ na += R[r+i*3+1];
376
+ nb += R[r+i*3+2];
377
+ }
378
+ if( R[r+nr*3]>nContext ){
379
+ na += nContext;
380
+ nb += nContext;
381
+ }else{
382
+ na += R[r+nr*3];
383
+ nb += R[r+nr*3];
384
+ }
385
+ for(i=1; i<nr; i++){
386
+ na += R[r+i*3];
387
+ nb += R[r+i*3];
388
+ }
389
+ /*
390
+ * If the patch changes an empty file or results in an empty file,
391
+ * the block header must use 0,0 as position indicator and not 1,0.
392
+ * Otherwise, patch would be confused and may reject the diff.
393
+ */
394
+ blob_appendf(pOut,"@@ -%d,%d +%d,%d @@\n",
395
+ na ? a+skip+1 : 0, na,
396
+ nb ? b+skip+1 : 0, nb);
397
+
398
+ /* Show the initial common area */
399
+ a += skip;
400
+ b += skip;
401
+ m = R[r] - skip;
402
+ for(j=0; j<m; j++){
403
+ blob_appendf(pOut, "%6d ", a+j);
404
+ appendSbsLine(pOut, &A[a+j], width, 1);
405
+ blob_appendf(pOut, " %6d ", b+j);
406
+ appendSbsLine(pOut, &B[b+j], width, 0);
407
+ blob_append(pOut, "\n", 1);
408
+ }
409
+ a += m;
410
+ b += m;
411
+
412
+ /* Show the differences */
413
+ for(i=0; i<nr; i++){
414
+ ma = R[r+i*3+1];
415
+ mb = R[r+i*3+2];
416
+ m = ma<mb ? ma : mb;
417
+ for(j=0; j<m; j++){
418
+ blob_appendf(pOut, "%6d ", a+j);
419
+ appendSbsLine(pOut, &A[a+j], width, 1);
420
+ blob_appendf(pOut, " | %6d ", b+j);
421
+ appendSbsLine(pOut, &B[b+j], width, 0);
422
+ blob_append(pOut, "\n", 1);
423
+ }
424
+ a += m;
425
+ b += m;
426
+ ma -= m;
427
+ mb -= m;
428
+ for(j=0; j<ma; j++){
429
+ blob_appendf(pOut, "%6d ", a+j);
430
+ appendSbsLine(pOut, &A[a+j], width, 1);
431
+ blob_append(pOut, " <\n", 3);
432
+ }
433
+ a += ma;
434
+ for(j=0; j<mb; j++){
435
+ appendSpace(pOut, width+7);
436
+ blob_appendf(pOut, " > %6d", b+j);
437
+ appendSbsLine(pOut, &B[b+j], width, 0);
438
+ blob_append(pOut, "\n", 1);
439
+ }
440
+ b += mb;
441
+ if( i<nr-1 ){
442
+ m = R[r+i*3+3];
443
+ for(j=0; j<m; j++){
444
+ blob_appendf(pOut, "%6d ", a+j);
445
+ appendSbsLine(pOut, &A[a+j], width, 1);
446
+ blob_appendf(pOut, " %6d ", b+j);
447
+ appendSbsLine(pOut, &B[b+j], width, 0);
448
+ blob_append(pOut, "\n", 1);
449
+ }
450
+ b += m;
451
+ a += m;
452
+ }
453
+ }
454
+
455
+ /* Show the final common area */
456
+ assert( nr==i );
457
+ m = R[r+nr*3];
458
+ if( m>nContext ) m = nContext;
459
+ for(j=0; j<m; j++){
460
+ blob_appendf(pOut, "%6d ", a+j);
461
+ appendSbsLine(pOut, &A[a+j], width, 1);
462
+ blob_appendf(pOut, " %6d ", b+j);
463
+ appendSbsLine(pOut, &B[b+j], width, 0);
464
+ blob_append(pOut, "\n", 1);
465
+ }
466
+ }
467
+}
301468
302469
/*
303470
** Compute the optimal longest common subsequence (LCS) using an
304471
** exhaustive search. This version of the LCS is only used for
305472
** shorter input strings since runtime is O(N*N) where N is the
@@ -579,12 +746,18 @@
579746
580747
/* Compute the difference */
581748
diff_all(&c);
582749
583750
if( pOut ){
584
- /* Compute a context diff if requested */
585
- contextDiff(&c, pOut, nContext);
751
+ /* Compute a context or side-by-side diff into pOut */
752
+ if( diffFlags & DIFF_SIDEBYSIDE ){
753
+ int width = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
754
+ if( width==0 ) width = 80;
755
+ sbsDiff(&c, pOut, nContext, width);
756
+ }else{
757
+ contextDiff(&c, pOut, nContext);
758
+ }
586759
free(c.aFrom);
587760
free(c.aTo);
588761
free(c.aEdit);
589762
return 0;
590763
}else{
591764
--- src/diff.c
+++ src/diff.c
@@ -25,14 +25,15 @@
25
26 #if INTERFACE
27 /*
28 ** Allowed flag parameters to the text_diff() and html_sbsdiff() funtions:
29 */
30 #define DIFF_CONTEXT_MASK 0x00fff /* Lines of context. Default if 0 */
31 #define DIFF_IGNORE_EOLWS 0x01000 /* Ignore end-of-line whitespace */
32 #define DIFF_SIDEBYSIDE 0x02000 /* Generate a side-by-side diff */
33 #define DIFF_NEWFILE 0x04000 /* Non-existing files are as empty files */
 
34
35 #endif /* INTERFACE */
36
37 /*
38 ** Maximum length of a line in a text file. (8192)
@@ -296,10 +297,176 @@
296 for(j=0; j<m; j++){
297 appendDiffLine(pOut, " ", &B[b+j]);
298 }
299 }
300 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
302 /*
303 ** Compute the optimal longest common subsequence (LCS) using an
304 ** exhaustive search. This version of the LCS is only used for
305 ** shorter input strings since runtime is O(N*N) where N is the
@@ -579,12 +746,18 @@
579
580 /* Compute the difference */
581 diff_all(&c);
582
583 if( pOut ){
584 /* Compute a context diff if requested */
585 contextDiff(&c, pOut, nContext);
 
 
 
 
 
 
586 free(c.aFrom);
587 free(c.aTo);
588 free(c.aEdit);
589 return 0;
590 }else{
591
--- src/diff.c
+++ src/diff.c
@@ -25,14 +25,15 @@
25
26 #if INTERFACE
27 /*
28 ** Allowed flag parameters to the text_diff() and html_sbsdiff() funtions:
29 */
30 #define DIFF_CONTEXT_MASK 0x0000fff /* Lines of context. Default if 0 */
31 #define DIFF_WIDTH_MASK 0x00ff000 /* side-by-side column width */
32 #define DIFF_IGNORE_EOLWS 0x0100000 /* Ignore end-of-line whitespace */
33 #define DIFF_SIDEBYSIDE 0x0200000 /* Generate a side-by-side diff */
34 #define DIFF_NEWFILE 0x0400000 /* Missing files are as empty files */
35
36 #endif /* INTERFACE */
37
38 /*
39 ** Maximum length of a line in a text file. (8192)
@@ -296,10 +297,176 @@
297 for(j=0; j<m; j++){
298 appendDiffLine(pOut, " ", &B[b+j]);
299 }
300 }
301 }
302
303 /*
304 ** Append spaces to a blob
305 */
306 static void appendSpace(Blob *pOut, int n){
307 const char z100[101] =
308 " "
309 " ";
310 while( n>100 ){
311 blob_append(pOut, z100, 100); n -= 100;
312 }
313 if( n>0 ){
314 blob_append(pOut, z100, n);
315 }
316 }
317
318 /*
319 ** Append text to a sbs diff output
320 */
321 static void appendSbsLine(Blob *pOut, DLine *pLine, int width, int pad){
322 int sz = pLine->h & LENGTH_MASK;
323 if( sz<width ){
324 blob_append(pOut, pLine->z, sz);
325 if( pad ) appendSpace(pOut, width-sz);
326 }else{
327 blob_append(pOut, pLine->z, width);
328 }
329 }
330
331
332 /*
333 ** Given a diff context in which the aEdit[] array has been filled
334 ** in, compute a side-by-side diff into pOut.
335 */
336 static void sbsDiff(DContext *p, Blob *pOut, int nContext, int width){
337 DLine *A; /* Left side of the diff */
338 DLine *B; /* Right side of the diff */
339 int a = 0; /* Index of next line in A[] */
340 int b = 0; /* Index of next line in B[] */
341 int *R; /* Array of COPY/DELETE/INSERT triples */
342 int r; /* Index into R[] */
343 int nr; /* Number of COPY/DELETE/INSERT triples to process */
344 int mxr; /* Maximum value for r */
345 int na, nb; /* Number of lines shown from A and B */
346 int i, j; /* Loop counters */
347 int m, ma, mb;/* Number of lines to output */
348 int skip; /* Number of lines to skip */
349 char zFormat[50]; /* Output format */
350
351 sqlite3_snprintf(sizeof(zFormat), zFormat,
352 "%%4d %%%d.%ds %%c %%4d %%.%ds\n",
353 width, width, width);
354 A = p->aFrom;
355 B = p->aTo;
356 R = p->aEdit;
357 mxr = p->nEdit;
358 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
359 for(r=0; r<mxr; r += 3*nr){
360 /* Figure out how many triples to show in a single block */
361 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
362 /* printf("r=%d nr=%d\n", r, nr); */
363
364 /* For the current block comprising nr triples, figure out
365 ** how many lines of A and B are to be displayed
366 */
367 if( R[r]>nContext ){
368 na = nb = nContext;
369 skip = R[r] - nContext;
370 }else{
371 na = nb = R[r];
372 skip = 0;
373 }
374 for(i=0; i<nr; i++){
375 na += R[r+i*3+1];
376 nb += R[r+i*3+2];
377 }
378 if( R[r+nr*3]>nContext ){
379 na += nContext;
380 nb += nContext;
381 }else{
382 na += R[r+nr*3];
383 nb += R[r+nr*3];
384 }
385 for(i=1; i<nr; i++){
386 na += R[r+i*3];
387 nb += R[r+i*3];
388 }
389 /*
390 * If the patch changes an empty file or results in an empty file,
391 * the block header must use 0,0 as position indicator and not 1,0.
392 * Otherwise, patch would be confused and may reject the diff.
393 */
394 blob_appendf(pOut,"@@ -%d,%d +%d,%d @@\n",
395 na ? a+skip+1 : 0, na,
396 nb ? b+skip+1 : 0, nb);
397
398 /* Show the initial common area */
399 a += skip;
400 b += skip;
401 m = R[r] - skip;
402 for(j=0; j<m; j++){
403 blob_appendf(pOut, "%6d ", a+j);
404 appendSbsLine(pOut, &A[a+j], width, 1);
405 blob_appendf(pOut, " %6d ", b+j);
406 appendSbsLine(pOut, &B[b+j], width, 0);
407 blob_append(pOut, "\n", 1);
408 }
409 a += m;
410 b += m;
411
412 /* Show the differences */
413 for(i=0; i<nr; i++){
414 ma = R[r+i*3+1];
415 mb = R[r+i*3+2];
416 m = ma<mb ? ma : mb;
417 for(j=0; j<m; j++){
418 blob_appendf(pOut, "%6d ", a+j);
419 appendSbsLine(pOut, &A[a+j], width, 1);
420 blob_appendf(pOut, " | %6d ", b+j);
421 appendSbsLine(pOut, &B[b+j], width, 0);
422 blob_append(pOut, "\n", 1);
423 }
424 a += m;
425 b += m;
426 ma -= m;
427 mb -= m;
428 for(j=0; j<ma; j++){
429 blob_appendf(pOut, "%6d ", a+j);
430 appendSbsLine(pOut, &A[a+j], width, 1);
431 blob_append(pOut, " <\n", 3);
432 }
433 a += ma;
434 for(j=0; j<mb; j++){
435 appendSpace(pOut, width+7);
436 blob_appendf(pOut, " > %6d", b+j);
437 appendSbsLine(pOut, &B[b+j], width, 0);
438 blob_append(pOut, "\n", 1);
439 }
440 b += mb;
441 if( i<nr-1 ){
442 m = R[r+i*3+3];
443 for(j=0; j<m; j++){
444 blob_appendf(pOut, "%6d ", a+j);
445 appendSbsLine(pOut, &A[a+j], width, 1);
446 blob_appendf(pOut, " %6d ", b+j);
447 appendSbsLine(pOut, &B[b+j], width, 0);
448 blob_append(pOut, "\n", 1);
449 }
450 b += m;
451 a += m;
452 }
453 }
454
455 /* Show the final common area */
456 assert( nr==i );
457 m = R[r+nr*3];
458 if( m>nContext ) m = nContext;
459 for(j=0; j<m; j++){
460 blob_appendf(pOut, "%6d ", a+j);
461 appendSbsLine(pOut, &A[a+j], width, 1);
462 blob_appendf(pOut, " %6d ", b+j);
463 appendSbsLine(pOut, &B[b+j], width, 0);
464 blob_append(pOut, "\n", 1);
465 }
466 }
467 }
468
469 /*
470 ** Compute the optimal longest common subsequence (LCS) using an
471 ** exhaustive search. This version of the LCS is only used for
472 ** shorter input strings since runtime is O(N*N) where N is the
@@ -579,12 +746,18 @@
746
747 /* Compute the difference */
748 diff_all(&c);
749
750 if( pOut ){
751 /* Compute a context or side-by-side diff into pOut */
752 if( diffFlags & DIFF_SIDEBYSIDE ){
753 int width = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
754 if( width==0 ) width = 80;
755 sbsDiff(&c, pOut, nContext, width);
756 }else{
757 contextDiff(&c, pOut, nContext);
758 }
759 free(c.aFrom);
760 free(c.aTo);
761 free(c.aEdit);
762 return 0;
763 }else{
764
+9 -3
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -447,16 +447,17 @@
447447
**
448448
** The "-N" or "--new-file" option causes the complete text of added or
449449
** deleted files to be displayed.
450450
**
451451
** Options:
452
+** --context|-c N Use N lines of context
452453
** --from|-r VERSION select VERSION as source for the diff
453454
** --new-file|-N output complete text of added or deleted files
454455
** -i use internal diff logic
455456
** --to VERSION select VERSION as target for the diff
456
-** --sbs side-by-side diff
457
-** --context|-c N Use N lines of context
457
+** --side-by-side|-y side-by-side diff
458
+** --width|-W N Width of lines in side-by-side diff
458459
*/
459460
void diff_cmd(void){
460461
int isGDiff; /* True for gdiff. False for normal diff */
461462
int isInternDiff; /* True for internal diff */
462463
int hasNFlag; /* True if -N or --new-file flag is used */
@@ -470,14 +471,19 @@
470471
isGDiff = g.argv[1][0]=='g';
471472
isInternDiff = find_option("internal","i",0)!=0;
472473
zFrom = find_option("from", "r", 1);
473474
zTo = find_option("to", 0, 1);
474475
hasNFlag = find_option("new-file","N",0)!=0;
475
- if( find_option("sbs",0,0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
476
+ if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
476477
if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>0 ){
477478
if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
478479
diffFlags |= f;
480
+ }
481
+ if( (z = find_option("width","W",1))!=0 && (f = atoi(z))>0 ){
482
+ f *= DIFF_CONTEXT_MASK+1;
483
+ if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
484
+ diffFlags |= f;
479485
}
480486
481487
482488
if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
483489
if( zTo==0 ){
484490
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -447,16 +447,17 @@
447 **
448 ** The "-N" or "--new-file" option causes the complete text of added or
449 ** deleted files to be displayed.
450 **
451 ** Options:
 
452 ** --from|-r VERSION select VERSION as source for the diff
453 ** --new-file|-N output complete text of added or deleted files
454 ** -i use internal diff logic
455 ** --to VERSION select VERSION as target for the diff
456 ** --sbs side-by-side diff
457 ** --context|-c N Use N lines of context
458 */
459 void diff_cmd(void){
460 int isGDiff; /* True for gdiff. False for normal diff */
461 int isInternDiff; /* True for internal diff */
462 int hasNFlag; /* True if -N or --new-file flag is used */
@@ -470,14 +471,19 @@
470 isGDiff = g.argv[1][0]=='g';
471 isInternDiff = find_option("internal","i",0)!=0;
472 zFrom = find_option("from", "r", 1);
473 zTo = find_option("to", 0, 1);
474 hasNFlag = find_option("new-file","N",0)!=0;
475 if( find_option("sbs",0,0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
476 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>0 ){
477 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
478 diffFlags |= f;
 
 
 
 
 
479 }
480
481
482 if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
483 if( zTo==0 ){
484
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -447,16 +447,17 @@
447 **
448 ** The "-N" or "--new-file" option causes the complete text of added or
449 ** deleted files to be displayed.
450 **
451 ** Options:
452 ** --context|-c N Use N lines of context
453 ** --from|-r VERSION select VERSION as source for the diff
454 ** --new-file|-N output complete text of added or deleted files
455 ** -i use internal diff logic
456 ** --to VERSION select VERSION as target for the diff
457 ** --side-by-side|-y side-by-side diff
458 ** --width|-W N Width of lines in side-by-side diff
459 */
460 void diff_cmd(void){
461 int isGDiff; /* True for gdiff. False for normal diff */
462 int isInternDiff; /* True for internal diff */
463 int hasNFlag; /* True if -N or --new-file flag is used */
@@ -470,14 +471,19 @@
471 isGDiff = g.argv[1][0]=='g';
472 isInternDiff = find_option("internal","i",0)!=0;
473 zFrom = find_option("from", "r", 1);
474 zTo = find_option("to", 0, 1);
475 hasNFlag = find_option("new-file","N",0)!=0;
476 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
477 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>0 ){
478 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
479 diffFlags |= f;
480 }
481 if( (z = find_option("width","W",1))!=0 && (f = atoi(z))>0 ){
482 f *= DIFF_CONTEXT_MASK+1;
483 if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
484 diffFlags |= f;
485 }
486
487
488 if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
489 if( zTo==0 ){
490

Keyboard Shortcuts

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