Fossil SCM

Begin improvement efforts on the "diff" functions by adding the --context option to the "diff" command.

drh 2011-10-21 20:24 UTC trunk
Commit 3bbbbdfd7d032f0655b6c56a28ee3c9a0c55178d
+32 -8
--- src/diff.c
+++ src/diff.c
@@ -21,10 +21,21 @@
2121
#include "config.h"
2222
#include "diff.h"
2323
#include <assert.h>
2424
2525
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
+
2637
/*
2738
** Maximum length of a line in a text file. (8192)
2839
*/
2940
#define LENGTH_MASK_SZ 13
3041
#define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
@@ -538,16 +549,21 @@
538549
** text "cannot compute difference between binary files".
539550
*/
540551
int *text_diff(
541552
Blob *pA_Blob, /* FROM file */
542553
Blob *pB_Blob, /* TO file */
543
- Blob *pOut, /* Write unified diff here if not NULL */
544
- int nContext, /* Amount of context to unified diff */
545
- int ignoreEolWs /* Ignore whitespace at the end of lines */
554
+ Blob *pOut, /* Write diff here if not NULL */
555
+ int diffFlags /* DIFF_* flags defined above */
546556
){
557
+ int ignoreEolWs; /* Ignore whitespace at the end of lines */
558
+ int nContext; /* Amount of context to display */
547559
DContext c;
548
-
560
+
561
+ nContext = diffFlags & DIFF_CONTEXT_MASK;
562
+ if( nContext==0 ) nContext = 5;
563
+ ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
564
+
549565
/* Prepare the input files */
550566
memset(&c, 0, sizeof(c));
551567
c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
552568
&c.nFrom, ignoreEolWs);
553569
c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
@@ -660,11 +676,11 @@
660676
while( i<c.nEdit ){
661677
int j;
662678
/* Copied lines */
663679
for( j=0; j<c.aEdit[i]; j++){
664680
/* Hide lines which are copied and are further away from block boundaries
665
- ** than nConext lines. For each block with hidden lines, show a row
681
+ ** than nContext lines. For each block with hidden lines, show a row
666682
** notifying the user about the hidden rows.
667683
*/
668684
if( j<nContext || j>c.aEdit[i]-nContext-1 ){
669685
@ <tr>
670686
}else if( j==nContext && j<c.aEdit[i]-nContext-1 ){
@@ -776,11 +792,11 @@
776792
if( g.argc<4 ) usage("FILE1 FILE2 ...");
777793
blob_read_from_file(&a, g.argv[2]);
778794
for(i=3; i<g.argc; i++){
779795
if( i>3 ) fossil_print("-------------------------------\n");
780796
blob_read_from_file(&b, g.argv[i]);
781
- R = text_diff(&a, &b, 0, 0, 0);
797
+ R = text_diff(&a, &b, 0, 0);
782798
for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
783799
fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
784800
}
785801
/* free(R); */
786802
blob_reset(&b);
@@ -790,15 +806,23 @@
790806
/*
791807
** COMMAND: test-udiff
792808
*/
793809
void test_udiff_cmd(void){
794810
Blob a, b, out;
795
- if( g.argc!=4 ) usage("FILE1 FILE2");
811
+ int diffFlag = find_option("sbs",0,0)!=0 ? DIFF_SIDEBYSIDE : 0;
812
+ int nContext = 5;
813
+ const char *z;
814
+ if( (z = find_option("context","c",1))!=0 && atoi(z)>0 ){
815
+ nContext = atoi(z);
816
+ }
817
+ if( nContext<=0 ) nContext = 5;
818
+ if( (nContext&DIFF_CONTEXT_MASK)!=nContext ) nContext = DIFF_CONTEXT_MASK;
819
+ if( g.argc!=4 ) usage("[--sbs] [--context N] FILE1 FILE2");
796820
blob_read_from_file(&a, g.argv[2]);
797821
blob_read_from_file(&b, g.argv[3]);
798822
blob_zero(&out);
799
- text_diff(&a, &b, &out, 3, 0);
823
+ text_diff(&a, &b, &out, nContext | diffFlag);
800824
blob_write_to_file(&out, "-");
801825
}
802826
803827
/**************************************************************************
804828
** The basic difference engine is above. What follows is the annotation
805829
--- src/diff.c
+++ src/diff.c
@@ -21,10 +21,21 @@
21 #include "config.h"
22 #include "diff.h"
23 #include <assert.h>
24
25
 
 
 
 
 
 
 
 
 
 
 
26 /*
27 ** Maximum length of a line in a text file. (8192)
28 */
29 #define LENGTH_MASK_SZ 13
30 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
@@ -538,16 +549,21 @@
538 ** text "cannot compute difference between binary files".
539 */
540 int *text_diff(
541 Blob *pA_Blob, /* FROM file */
542 Blob *pB_Blob, /* TO file */
543 Blob *pOut, /* Write unified diff here if not NULL */
544 int nContext, /* Amount of context to unified diff */
545 int ignoreEolWs /* Ignore whitespace at the end of lines */
546 ){
 
 
547 DContext c;
548
 
 
 
 
549 /* Prepare the input files */
550 memset(&c, 0, sizeof(c));
551 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
552 &c.nFrom, ignoreEolWs);
553 c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
@@ -660,11 +676,11 @@
660 while( i<c.nEdit ){
661 int j;
662 /* Copied lines */
663 for( j=0; j<c.aEdit[i]; j++){
664 /* Hide lines which are copied and are further away from block boundaries
665 ** than nConext lines. For each block with hidden lines, show a row
666 ** notifying the user about the hidden rows.
667 */
668 if( j<nContext || j>c.aEdit[i]-nContext-1 ){
669 @ <tr>
670 }else if( j==nContext && j<c.aEdit[i]-nContext-1 ){
@@ -776,11 +792,11 @@
776 if( g.argc<4 ) usage("FILE1 FILE2 ...");
777 blob_read_from_file(&a, g.argv[2]);
778 for(i=3; i<g.argc; i++){
779 if( i>3 ) fossil_print("-------------------------------\n");
780 blob_read_from_file(&b, g.argv[i]);
781 R = text_diff(&a, &b, 0, 0, 0);
782 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
783 fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
784 }
785 /* free(R); */
786 blob_reset(&b);
@@ -790,15 +806,23 @@
790 /*
791 ** COMMAND: test-udiff
792 */
793 void test_udiff_cmd(void){
794 Blob a, b, out;
795 if( g.argc!=4 ) usage("FILE1 FILE2");
 
 
 
 
 
 
 
 
796 blob_read_from_file(&a, g.argv[2]);
797 blob_read_from_file(&b, g.argv[3]);
798 blob_zero(&out);
799 text_diff(&a, &b, &out, 3, 0);
800 blob_write_to_file(&out, "-");
801 }
802
803 /**************************************************************************
804 ** The basic difference engine is above. What follows is the annotation
805
--- src/diff.c
+++ src/diff.c
@@ -21,10 +21,21 @@
21 #include "config.h"
22 #include "diff.h"
23 #include <assert.h>
24
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)
39 */
40 #define LENGTH_MASK_SZ 13
41 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
@@ -538,16 +549,21 @@
549 ** text "cannot compute difference between binary files".
550 */
551 int *text_diff(
552 Blob *pA_Blob, /* FROM file */
553 Blob *pB_Blob, /* TO file */
554 Blob *pOut, /* Write diff here if not NULL */
555 int diffFlags /* DIFF_* flags defined above */
 
556 ){
557 int ignoreEolWs; /* Ignore whitespace at the end of lines */
558 int nContext; /* Amount of context to display */
559 DContext c;
560
561 nContext = diffFlags & DIFF_CONTEXT_MASK;
562 if( nContext==0 ) nContext = 5;
563 ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
564
565 /* Prepare the input files */
566 memset(&c, 0, sizeof(c));
567 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
568 &c.nFrom, ignoreEolWs);
569 c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
@@ -660,11 +676,11 @@
676 while( i<c.nEdit ){
677 int j;
678 /* Copied lines */
679 for( j=0; j<c.aEdit[i]; j++){
680 /* Hide lines which are copied and are further away from block boundaries
681 ** than nContext lines. For each block with hidden lines, show a row
682 ** notifying the user about the hidden rows.
683 */
684 if( j<nContext || j>c.aEdit[i]-nContext-1 ){
685 @ <tr>
686 }else if( j==nContext && j<c.aEdit[i]-nContext-1 ){
@@ -776,11 +792,11 @@
792 if( g.argc<4 ) usage("FILE1 FILE2 ...");
793 blob_read_from_file(&a, g.argv[2]);
794 for(i=3; i<g.argc; i++){
795 if( i>3 ) fossil_print("-------------------------------\n");
796 blob_read_from_file(&b, g.argv[i]);
797 R = text_diff(&a, &b, 0, 0);
798 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
799 fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
800 }
801 /* free(R); */
802 blob_reset(&b);
@@ -790,15 +806,23 @@
806 /*
807 ** COMMAND: test-udiff
808 */
809 void test_udiff_cmd(void){
810 Blob a, b, out;
811 int diffFlag = find_option("sbs",0,0)!=0 ? DIFF_SIDEBYSIDE : 0;
812 int nContext = 5;
813 const char *z;
814 if( (z = find_option("context","c",1))!=0 && atoi(z)>0 ){
815 nContext = atoi(z);
816 }
817 if( nContext<=0 ) nContext = 5;
818 if( (nContext&DIFF_CONTEXT_MASK)!=nContext ) nContext = DIFF_CONTEXT_MASK;
819 if( g.argc!=4 ) usage("[--sbs] [--context N] FILE1 FILE2");
820 blob_read_from_file(&a, g.argv[2]);
821 blob_read_from_file(&b, g.argv[3]);
822 blob_zero(&out);
823 text_diff(&a, &b, &out, nContext | diffFlag);
824 blob_write_to_file(&out, "-");
825 }
826
827 /**************************************************************************
828 ** The basic difference engine is above. What follows is the annotation
829
+22 -23
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -19,16 +19,10 @@
1919
*/
2020
#include "config.h"
2121
#include "diffcmd.h"
2222
#include <assert.h>
2323
24
-/*
25
-** Diff option flags
26
-*/
27
-#define DIFF_NEWFILE 0x01 /* Treat non-existing fails as empty files */
28
-#define DIFF_NOEOLWS 0x02 /* Ignore whitespace at the end of lines */
29
-
3024
/*
3125
** Output the results of a diff. Output goes to stdout for command-line
3226
** or to the CGI/HTTP result buffer for web pages.
3327
*/
3428
static void diff_printf(const char *zFormat, ...){
@@ -62,11 +56,11 @@
6256
void diff_file(
6357
Blob *pFile1, /* In memory content to compare from */
6458
const char *zFile2, /* On disk content to compare to */
6559
const char *zName, /* Display name of the file */
6660
const char *zDiffCmd, /* Command for comparison */
67
- int ignoreEolWs /* Ignore whitespace at end of line */
61
+ int diffFlags /* Flags to control the diff */
6862
){
6963
if( zDiffCmd==0 ){
7064
Blob out; /* Diff output text */
7165
Blob file2; /* Content of zFile2 */
7266
const char *zName2; /* Name of zFile2 for display */
@@ -84,11 +78,11 @@
8478
zName2 = zName;
8579
}
8680
8781
/* Compute and output the differences */
8882
blob_zero(&out);
89
- text_diff(pFile1, &file2, &out, 5, ignoreEolWs);
83
+ text_diff(pFile1, &file2, &out, diffFlags);
9084
if( blob_size(&out) ){
9185
diff_printf("--- %s\n+++ %s\n", zName, zName2);
9286
diff_printf("%s\n", blob_str(&out));
9387
}
9488
@@ -138,17 +132,17 @@
138132
void diff_file_mem(
139133
Blob *pFile1, /* In memory content to compare from */
140134
Blob *pFile2, /* In memory content to compare to */
141135
const char *zName, /* Display name of the file */
142136
const char *zDiffCmd, /* Command for comparison */
143
- int ignoreEolWs /* Ignore whitespace at end of lines */
137
+ int diffFlags /* Diff flags */
144138
){
145139
if( zDiffCmd==0 ){
146140
Blob out; /* Diff output text */
147141
148142
blob_zero(&out);
149
- text_diff(pFile1, pFile2, &out, 5, ignoreEolWs);
143
+ text_diff(pFile1, pFile2, &out, diffFlags);
150144
diff_printf("--- %s\n+++ %s\n", zName, zName);
151145
diff_printf("%s\n", blob_str(&out));
152146
153147
/* Release memory resources */
154148
blob_reset(&out);
@@ -185,11 +179,11 @@
185179
** against the same file on disk.
186180
*/
187181
static void diff_one_against_disk(
188182
const char *zFrom, /* Name of file */
189183
const char *zDiffCmd, /* Use this "diff" command */
190
- int ignoreEolWs, /* Ignore whitespace changes at end of lines */
184
+ int diffFlags, /* Diff control flags */
191185
const char *zFileTreeName
192186
){
193187
Blob fname;
194188
Blob content;
195189
int isLink;
@@ -196,11 +190,11 @@
196190
file_tree_name(zFileTreeName, &fname, 1);
197191
historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0);
198192
if( !isLink != !file_wd_islink(zFrom) ){
199193
diff_printf("cannot compute difference between symlink and regular file\n");
200194
}else{
201
- diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, ignoreEolWs);
195
+ diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, diffFlags);
202196
}
203197
blob_reset(&content);
204198
blob_reset(&fname);
205199
}
206200
@@ -215,14 +209,12 @@
215209
int diffFlags /* Flags controlling diff output */
216210
){
217211
int vid;
218212
Blob sql;
219213
Stmt q;
220
- int ignoreEolWs; /* Ignore end-of-line whitespace */
221214
int asNewFile; /* Treat non-existant files as empty files */
222215
223
- ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
224216
asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
225217
vid = db_lget_int("checkout", 0);
226218
vfile_check_signature(vid, 1, 0);
227219
blob_zero(&sql);
228220
db_begin_transaction();
@@ -300,11 +292,11 @@
300292
content_get(srcid, &content);
301293
}else{
302294
blob_zero(&content);
303295
}
304296
diff_print_index(zPathname);
305
- diff_file(&content, zFullName, zPathname, zDiffCmd, ignoreEolWs);
297
+ diff_file(&content, zFullName, zPathname, zDiffCmd, diffFlags);
306298
blob_reset(&content);
307299
}
308300
free(zToFree);
309301
}
310302
db_finalize(&q);
@@ -317,11 +309,11 @@
317309
*/
318310
static void diff_one_two_versions(
319311
const char *zFrom,
320312
const char *zTo,
321313
const char *zDiffCmd,
322
- int ignoreEolWs,
314
+ int diffFlags,
323315
const char *zFileTreeName
324316
){
325317
char *zName;
326318
Blob fname;
327319
Blob v1, v2;
@@ -332,11 +324,11 @@
332324
historical_version_of_file(zTo, zName, &v2, &isLink2, 0, 0);
333325
if( isLink1 != isLink2 ){
334326
diff_printf("--- %s\n+++ %s\n", zName, zName);
335327
diff_printf("cannot compute difference between symlink and regular file\n");
336328
}else{
337
- diff_file_mem(&v1, &v2, zName, zDiffCmd, ignoreEolWs);
329
+ diff_file_mem(&v1, &v2, zName, zDiffCmd, diffFlags);
338330
}
339331
blob_reset(&v1);
340332
blob_reset(&v2);
341333
blob_reset(&fname);
342334
}
@@ -347,11 +339,11 @@
347339
*/
348340
static void diff_manifest_entry(
349341
struct ManifestFile *pFrom,
350342
struct ManifestFile *pTo,
351343
const char *zDiffCmd,
352
- int ignoreEolWs
344
+ int diffFlags
353345
){
354346
Blob f1, f2;
355347
int rid;
356348
const char *zName = pFrom ? pFrom->zName : pTo->zName;
357349
diff_print_index(zName);
@@ -365,11 +357,11 @@
365357
rid = uuid_to_rid(pTo->zUuid, 0);
366358
content_get(rid, &f2);
367359
}else{
368360
blob_zero(&f2);
369361
}
370
- diff_file_mem(&f1, &f2, zName, zDiffCmd, ignoreEolWs);
362
+ diff_file_mem(&f1, &f2, zName, zDiffCmd, diffFlags);
371363
blob_reset(&f1);
372364
blob_reset(&f2);
373365
}
374366
375367
/*
@@ -381,11 +373,10 @@
381373
const char *zDiffCmd,
382374
int diffFlags
383375
){
384376
Manifest *pFrom, *pTo;
385377
ManifestFile *pFromFile, *pToFile;
386
- int ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0 ? 1 : 0;
387378
int asNewFlag = (diffFlags & DIFF_NEWFILE)!=0 ? 1 : 0;
388379
389380
pFrom = manifest_get_by_name(zFrom, 0);
390381
manifest_file_rewind(pFrom);
391382
pFromFile = manifest_file_next(pFrom,0);
@@ -403,26 +394,26 @@
403394
cmp = fossil_strcmp(pFromFile->zName, pToFile->zName);
404395
}
405396
if( cmp<0 ){
406397
diff_printf("DELETED %s\n", pFromFile->zName);
407398
if( asNewFlag ){
408
- diff_manifest_entry(pFromFile, 0, zDiffCmd, ignoreEolWs);
399
+ diff_manifest_entry(pFromFile, 0, zDiffCmd, diffFlags);
409400
}
410401
pFromFile = manifest_file_next(pFrom,0);
411402
}else if( cmp>0 ){
412403
diff_printf("ADDED %s\n", pToFile->zName);
413404
if( asNewFlag ){
414
- diff_manifest_entry(0, pToFile, zDiffCmd, ignoreEolWs);
405
+ diff_manifest_entry(0, pToFile, zDiffCmd, diffFlags);
415406
}
416407
pToFile = manifest_file_next(pTo,0);
417408
}else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){
418409
/* No changes */
419410
pFromFile = manifest_file_next(pFrom,0);
420411
pToFile = manifest_file_next(pTo,0);
421412
}else{
422413
/* diff_printf("CHANGED %s\n", pFromFile->zName); */
423
- diff_manifest_entry(pFromFile, pToFile, zDiffCmd, ignoreEolWs);
414
+ diff_manifest_entry(pFromFile, pToFile, zDiffCmd, diffFlags);
424415
pFromFile = manifest_file_next(pFrom,0);
425416
pToFile = manifest_file_next(pTo,0);
426417
}
427418
}
428419
manifest_destroy(pFrom);
@@ -460,26 +451,34 @@
460451
** Options:
461452
** --from|-r VERSION select VERSION as source for the diff
462453
** --new-file|-N output complete text of added or deleted files
463454
** -i use internal diff logic
464455
** --to VERSION select VERSION as target for the diff
456
+** --sbs side-by-side diff
457
+** --context|-c N Use N lines of context
465458
*/
466459
void diff_cmd(void){
467460
int isGDiff; /* True for gdiff. False for normal diff */
468461
int isInternDiff; /* True for internal diff */
469462
int hasNFlag; /* True if -N or --new-file flag is used */
470463
const char *zFrom; /* Source version number */
471464
const char *zTo; /* Target version number */
472465
const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
473466
int diffFlags = 0; /* Flags to control the DIFF */
467
+ const char *z;
474468
int f;
475469
476470
isGDiff = g.argv[1][0]=='g';
477471
isInternDiff = find_option("internal","i",0)!=0;
478472
zFrom = find_option("from", "r", 1);
479473
zTo = find_option("to", 0, 1);
480474
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
+ }
481480
482481
483482
if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
484483
if( zTo==0 ){
485484
db_must_be_within_tree();
486485
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -19,16 +19,10 @@
19 */
20 #include "config.h"
21 #include "diffcmd.h"
22 #include <assert.h>
23
24 /*
25 ** Diff option flags
26 */
27 #define DIFF_NEWFILE 0x01 /* Treat non-existing fails as empty files */
28 #define DIFF_NOEOLWS 0x02 /* Ignore whitespace at the end of lines */
29
30 /*
31 ** Output the results of a diff. Output goes to stdout for command-line
32 ** or to the CGI/HTTP result buffer for web pages.
33 */
34 static void diff_printf(const char *zFormat, ...){
@@ -62,11 +56,11 @@
62 void diff_file(
63 Blob *pFile1, /* In memory content to compare from */
64 const char *zFile2, /* On disk content to compare to */
65 const char *zName, /* Display name of the file */
66 const char *zDiffCmd, /* Command for comparison */
67 int ignoreEolWs /* Ignore whitespace at end of line */
68 ){
69 if( zDiffCmd==0 ){
70 Blob out; /* Diff output text */
71 Blob file2; /* Content of zFile2 */
72 const char *zName2; /* Name of zFile2 for display */
@@ -84,11 +78,11 @@
84 zName2 = zName;
85 }
86
87 /* Compute and output the differences */
88 blob_zero(&out);
89 text_diff(pFile1, &file2, &out, 5, ignoreEolWs);
90 if( blob_size(&out) ){
91 diff_printf("--- %s\n+++ %s\n", zName, zName2);
92 diff_printf("%s\n", blob_str(&out));
93 }
94
@@ -138,17 +132,17 @@
138 void diff_file_mem(
139 Blob *pFile1, /* In memory content to compare from */
140 Blob *pFile2, /* In memory content to compare to */
141 const char *zName, /* Display name of the file */
142 const char *zDiffCmd, /* Command for comparison */
143 int ignoreEolWs /* Ignore whitespace at end of lines */
144 ){
145 if( zDiffCmd==0 ){
146 Blob out; /* Diff output text */
147
148 blob_zero(&out);
149 text_diff(pFile1, pFile2, &out, 5, ignoreEolWs);
150 diff_printf("--- %s\n+++ %s\n", zName, zName);
151 diff_printf("%s\n", blob_str(&out));
152
153 /* Release memory resources */
154 blob_reset(&out);
@@ -185,11 +179,11 @@
185 ** against the same file on disk.
186 */
187 static void diff_one_against_disk(
188 const char *zFrom, /* Name of file */
189 const char *zDiffCmd, /* Use this "diff" command */
190 int ignoreEolWs, /* Ignore whitespace changes at end of lines */
191 const char *zFileTreeName
192 ){
193 Blob fname;
194 Blob content;
195 int isLink;
@@ -196,11 +190,11 @@
196 file_tree_name(zFileTreeName, &fname, 1);
197 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0);
198 if( !isLink != !file_wd_islink(zFrom) ){
199 diff_printf("cannot compute difference between symlink and regular file\n");
200 }else{
201 diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, ignoreEolWs);
202 }
203 blob_reset(&content);
204 blob_reset(&fname);
205 }
206
@@ -215,14 +209,12 @@
215 int diffFlags /* Flags controlling diff output */
216 ){
217 int vid;
218 Blob sql;
219 Stmt q;
220 int ignoreEolWs; /* Ignore end-of-line whitespace */
221 int asNewFile; /* Treat non-existant files as empty files */
222
223 ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
224 asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
225 vid = db_lget_int("checkout", 0);
226 vfile_check_signature(vid, 1, 0);
227 blob_zero(&sql);
228 db_begin_transaction();
@@ -300,11 +292,11 @@
300 content_get(srcid, &content);
301 }else{
302 blob_zero(&content);
303 }
304 diff_print_index(zPathname);
305 diff_file(&content, zFullName, zPathname, zDiffCmd, ignoreEolWs);
306 blob_reset(&content);
307 }
308 free(zToFree);
309 }
310 db_finalize(&q);
@@ -317,11 +309,11 @@
317 */
318 static void diff_one_two_versions(
319 const char *zFrom,
320 const char *zTo,
321 const char *zDiffCmd,
322 int ignoreEolWs,
323 const char *zFileTreeName
324 ){
325 char *zName;
326 Blob fname;
327 Blob v1, v2;
@@ -332,11 +324,11 @@
332 historical_version_of_file(zTo, zName, &v2, &isLink2, 0, 0);
333 if( isLink1 != isLink2 ){
334 diff_printf("--- %s\n+++ %s\n", zName, zName);
335 diff_printf("cannot compute difference between symlink and regular file\n");
336 }else{
337 diff_file_mem(&v1, &v2, zName, zDiffCmd, ignoreEolWs);
338 }
339 blob_reset(&v1);
340 blob_reset(&v2);
341 blob_reset(&fname);
342 }
@@ -347,11 +339,11 @@
347 */
348 static void diff_manifest_entry(
349 struct ManifestFile *pFrom,
350 struct ManifestFile *pTo,
351 const char *zDiffCmd,
352 int ignoreEolWs
353 ){
354 Blob f1, f2;
355 int rid;
356 const char *zName = pFrom ? pFrom->zName : pTo->zName;
357 diff_print_index(zName);
@@ -365,11 +357,11 @@
365 rid = uuid_to_rid(pTo->zUuid, 0);
366 content_get(rid, &f2);
367 }else{
368 blob_zero(&f2);
369 }
370 diff_file_mem(&f1, &f2, zName, zDiffCmd, ignoreEolWs);
371 blob_reset(&f1);
372 blob_reset(&f2);
373 }
374
375 /*
@@ -381,11 +373,10 @@
381 const char *zDiffCmd,
382 int diffFlags
383 ){
384 Manifest *pFrom, *pTo;
385 ManifestFile *pFromFile, *pToFile;
386 int ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0 ? 1 : 0;
387 int asNewFlag = (diffFlags & DIFF_NEWFILE)!=0 ? 1 : 0;
388
389 pFrom = manifest_get_by_name(zFrom, 0);
390 manifest_file_rewind(pFrom);
391 pFromFile = manifest_file_next(pFrom,0);
@@ -403,26 +394,26 @@
403 cmp = fossil_strcmp(pFromFile->zName, pToFile->zName);
404 }
405 if( cmp<0 ){
406 diff_printf("DELETED %s\n", pFromFile->zName);
407 if( asNewFlag ){
408 diff_manifest_entry(pFromFile, 0, zDiffCmd, ignoreEolWs);
409 }
410 pFromFile = manifest_file_next(pFrom,0);
411 }else if( cmp>0 ){
412 diff_printf("ADDED %s\n", pToFile->zName);
413 if( asNewFlag ){
414 diff_manifest_entry(0, pToFile, zDiffCmd, ignoreEolWs);
415 }
416 pToFile = manifest_file_next(pTo,0);
417 }else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){
418 /* No changes */
419 pFromFile = manifest_file_next(pFrom,0);
420 pToFile = manifest_file_next(pTo,0);
421 }else{
422 /* diff_printf("CHANGED %s\n", pFromFile->zName); */
423 diff_manifest_entry(pFromFile, pToFile, zDiffCmd, ignoreEolWs);
424 pFromFile = manifest_file_next(pFrom,0);
425 pToFile = manifest_file_next(pTo,0);
426 }
427 }
428 manifest_destroy(pFrom);
@@ -460,26 +451,34 @@
460 ** Options:
461 ** --from|-r VERSION select VERSION as source for the diff
462 ** --new-file|-N output complete text of added or deleted files
463 ** -i use internal diff logic
464 ** --to VERSION select VERSION as target for the diff
 
 
465 */
466 void diff_cmd(void){
467 int isGDiff; /* True for gdiff. False for normal diff */
468 int isInternDiff; /* True for internal diff */
469 int hasNFlag; /* True if -N or --new-file flag is used */
470 const char *zFrom; /* Source version number */
471 const char *zTo; /* Target version number */
472 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
473 int diffFlags = 0; /* Flags to control the DIFF */
 
474 int f;
475
476 isGDiff = g.argv[1][0]=='g';
477 isInternDiff = find_option("internal","i",0)!=0;
478 zFrom = find_option("from", "r", 1);
479 zTo = find_option("to", 0, 1);
480 hasNFlag = find_option("new-file","N",0)!=0;
 
 
 
 
 
481
482
483 if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
484 if( zTo==0 ){
485 db_must_be_within_tree();
486
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -19,16 +19,10 @@
19 */
20 #include "config.h"
21 #include "diffcmd.h"
22 #include <assert.h>
23
 
 
 
 
 
 
24 /*
25 ** Output the results of a diff. Output goes to stdout for command-line
26 ** or to the CGI/HTTP result buffer for web pages.
27 */
28 static void diff_printf(const char *zFormat, ...){
@@ -62,11 +56,11 @@
56 void diff_file(
57 Blob *pFile1, /* In memory content to compare from */
58 const char *zFile2, /* On disk content to compare to */
59 const char *zName, /* Display name of the file */
60 const char *zDiffCmd, /* Command for comparison */
61 int diffFlags /* Flags to control the diff */
62 ){
63 if( zDiffCmd==0 ){
64 Blob out; /* Diff output text */
65 Blob file2; /* Content of zFile2 */
66 const char *zName2; /* Name of zFile2 for display */
@@ -84,11 +78,11 @@
78 zName2 = zName;
79 }
80
81 /* Compute and output the differences */
82 blob_zero(&out);
83 text_diff(pFile1, &file2, &out, diffFlags);
84 if( blob_size(&out) ){
85 diff_printf("--- %s\n+++ %s\n", zName, zName2);
86 diff_printf("%s\n", blob_str(&out));
87 }
88
@@ -138,17 +132,17 @@
132 void diff_file_mem(
133 Blob *pFile1, /* In memory content to compare from */
134 Blob *pFile2, /* In memory content to compare to */
135 const char *zName, /* Display name of the file */
136 const char *zDiffCmd, /* Command for comparison */
137 int diffFlags /* Diff flags */
138 ){
139 if( zDiffCmd==0 ){
140 Blob out; /* Diff output text */
141
142 blob_zero(&out);
143 text_diff(pFile1, pFile2, &out, diffFlags);
144 diff_printf("--- %s\n+++ %s\n", zName, zName);
145 diff_printf("%s\n", blob_str(&out));
146
147 /* Release memory resources */
148 blob_reset(&out);
@@ -185,11 +179,11 @@
179 ** against the same file on disk.
180 */
181 static void diff_one_against_disk(
182 const char *zFrom, /* Name of file */
183 const char *zDiffCmd, /* Use this "diff" command */
184 int diffFlags, /* Diff control flags */
185 const char *zFileTreeName
186 ){
187 Blob fname;
188 Blob content;
189 int isLink;
@@ -196,11 +190,11 @@
190 file_tree_name(zFileTreeName, &fname, 1);
191 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0);
192 if( !isLink != !file_wd_islink(zFrom) ){
193 diff_printf("cannot compute difference between symlink and regular file\n");
194 }else{
195 diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, diffFlags);
196 }
197 blob_reset(&content);
198 blob_reset(&fname);
199 }
200
@@ -215,14 +209,12 @@
209 int diffFlags /* Flags controlling diff output */
210 ){
211 int vid;
212 Blob sql;
213 Stmt q;
 
214 int asNewFile; /* Treat non-existant files as empty files */
215
 
216 asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
217 vid = db_lget_int("checkout", 0);
218 vfile_check_signature(vid, 1, 0);
219 blob_zero(&sql);
220 db_begin_transaction();
@@ -300,11 +292,11 @@
292 content_get(srcid, &content);
293 }else{
294 blob_zero(&content);
295 }
296 diff_print_index(zPathname);
297 diff_file(&content, zFullName, zPathname, zDiffCmd, diffFlags);
298 blob_reset(&content);
299 }
300 free(zToFree);
301 }
302 db_finalize(&q);
@@ -317,11 +309,11 @@
309 */
310 static void diff_one_two_versions(
311 const char *zFrom,
312 const char *zTo,
313 const char *zDiffCmd,
314 int diffFlags,
315 const char *zFileTreeName
316 ){
317 char *zName;
318 Blob fname;
319 Blob v1, v2;
@@ -332,11 +324,11 @@
324 historical_version_of_file(zTo, zName, &v2, &isLink2, 0, 0);
325 if( isLink1 != isLink2 ){
326 diff_printf("--- %s\n+++ %s\n", zName, zName);
327 diff_printf("cannot compute difference between symlink and regular file\n");
328 }else{
329 diff_file_mem(&v1, &v2, zName, zDiffCmd, diffFlags);
330 }
331 blob_reset(&v1);
332 blob_reset(&v2);
333 blob_reset(&fname);
334 }
@@ -347,11 +339,11 @@
339 */
340 static void diff_manifest_entry(
341 struct ManifestFile *pFrom,
342 struct ManifestFile *pTo,
343 const char *zDiffCmd,
344 int diffFlags
345 ){
346 Blob f1, f2;
347 int rid;
348 const char *zName = pFrom ? pFrom->zName : pTo->zName;
349 diff_print_index(zName);
@@ -365,11 +357,11 @@
357 rid = uuid_to_rid(pTo->zUuid, 0);
358 content_get(rid, &f2);
359 }else{
360 blob_zero(&f2);
361 }
362 diff_file_mem(&f1, &f2, zName, zDiffCmd, diffFlags);
363 blob_reset(&f1);
364 blob_reset(&f2);
365 }
366
367 /*
@@ -381,11 +373,10 @@
373 const char *zDiffCmd,
374 int diffFlags
375 ){
376 Manifest *pFrom, *pTo;
377 ManifestFile *pFromFile, *pToFile;
 
378 int asNewFlag = (diffFlags & DIFF_NEWFILE)!=0 ? 1 : 0;
379
380 pFrom = manifest_get_by_name(zFrom, 0);
381 manifest_file_rewind(pFrom);
382 pFromFile = manifest_file_next(pFrom,0);
@@ -403,26 +394,26 @@
394 cmp = fossil_strcmp(pFromFile->zName, pToFile->zName);
395 }
396 if( cmp<0 ){
397 diff_printf("DELETED %s\n", pFromFile->zName);
398 if( asNewFlag ){
399 diff_manifest_entry(pFromFile, 0, zDiffCmd, diffFlags);
400 }
401 pFromFile = manifest_file_next(pFrom,0);
402 }else if( cmp>0 ){
403 diff_printf("ADDED %s\n", pToFile->zName);
404 if( asNewFlag ){
405 diff_manifest_entry(0, pToFile, zDiffCmd, diffFlags);
406 }
407 pToFile = manifest_file_next(pTo,0);
408 }else if( fossil_strcmp(pFromFile->zUuid, pToFile->zUuid)==0 ){
409 /* No changes */
410 pFromFile = manifest_file_next(pFrom,0);
411 pToFile = manifest_file_next(pTo,0);
412 }else{
413 /* diff_printf("CHANGED %s\n", pFromFile->zName); */
414 diff_manifest_entry(pFromFile, pToFile, zDiffCmd, diffFlags);
415 pFromFile = manifest_file_next(pFrom,0);
416 pToFile = manifest_file_next(pTo,0);
417 }
418 }
419 manifest_destroy(pFrom);
@@ -460,26 +451,34 @@
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 */
463 const char *zFrom; /* Source version number */
464 const char *zTo; /* Target version number */
465 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
466 int diffFlags = 0; /* Flags to control the DIFF */
467 const char *z;
468 int f;
469
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 db_must_be_within_tree();
485
+2 -2
--- src/info.c
+++ src/info.c
@@ -270,11 +270,11 @@
270270
content_get(toid, &to);
271271
}else{
272272
blob_zero(&to);
273273
}
274274
blob_zero(&out);
275
- text_diff(&from, &to, &out, 5, 1);
275
+ text_diff(&from, &to, &out, DIFF_IGNORE_EOLWS | 5);
276276
@ %h(blob_str(&out))
277277
blob_reset(&from);
278278
blob_reset(&to);
279279
blob_reset(&out);
280280
}
@@ -1091,11 +1091,11 @@
10911091
pOut = &diff;
10921092
}
10931093
if( !sideBySide || isPatch ){
10941094
content_get(v1, &c1);
10951095
content_get(v2, &c2);
1096
- text_diff(&c1, &c2, pOut, 4, 1);
1096
+ text_diff(&c1, &c2, pOut, 4 | 0);
10971097
blob_reset(&c1);
10981098
blob_reset(&c2);
10991099
}
11001100
if( !isPatch ){
11011101
style_header("Diff");
11021102
--- src/info.c
+++ src/info.c
@@ -270,11 +270,11 @@
270 content_get(toid, &to);
271 }else{
272 blob_zero(&to);
273 }
274 blob_zero(&out);
275 text_diff(&from, &to, &out, 5, 1);
276 @ %h(blob_str(&out))
277 blob_reset(&from);
278 blob_reset(&to);
279 blob_reset(&out);
280 }
@@ -1091,11 +1091,11 @@
1091 pOut = &diff;
1092 }
1093 if( !sideBySide || isPatch ){
1094 content_get(v1, &c1);
1095 content_get(v2, &c2);
1096 text_diff(&c1, &c2, pOut, 4, 1);
1097 blob_reset(&c1);
1098 blob_reset(&c2);
1099 }
1100 if( !isPatch ){
1101 style_header("Diff");
1102
--- src/info.c
+++ src/info.c
@@ -270,11 +270,11 @@
270 content_get(toid, &to);
271 }else{
272 blob_zero(&to);
273 }
274 blob_zero(&out);
275 text_diff(&from, &to, &out, DIFF_IGNORE_EOLWS | 5);
276 @ %h(blob_str(&out))
277 blob_reset(&from);
278 blob_reset(&to);
279 blob_reset(&out);
280 }
@@ -1091,11 +1091,11 @@
1091 pOut = &diff;
1092 }
1093 if( !sideBySide || isPatch ){
1094 content_get(v1, &c1);
1095 content_get(v2, &c2);
1096 text_diff(&c1, &c2, pOut, 4 | 0);
1097 blob_reset(&c1);
1098 blob_reset(&c2);
1099 }
1100 if( !isPatch ){
1101 style_header("Diff");
1102
+2 -2
--- src/merge3.c
+++ src/merge3.c
@@ -171,12 +171,12 @@
171171
** is the number of lines of text to copy directly from the pivot,
172172
** the second integer is the number of lines of text to omit from the
173173
** pivot, and the third integer is the number of lines of text that are
174174
** inserted. The edit array ends with a triple of 0,0,0.
175175
*/
176
- aC1 = text_diff(pPivot, pV1, 0, 0, 0);
177
- aC2 = text_diff(pPivot, pV2, 0, 0, 0);
176
+ aC1 = text_diff(pPivot, pV1, 0, 0);
177
+ aC2 = text_diff(pPivot, pV2, 0, 0);
178178
if( aC1==0 || aC2==0 ){
179179
free(aC1);
180180
free(aC2);
181181
return -1;
182182
}
183183
--- src/merge3.c
+++ src/merge3.c
@@ -171,12 +171,12 @@
171 ** is the number of lines of text to copy directly from the pivot,
172 ** the second integer is the number of lines of text to omit from the
173 ** pivot, and the third integer is the number of lines of text that are
174 ** inserted. The edit array ends with a triple of 0,0,0.
175 */
176 aC1 = text_diff(pPivot, pV1, 0, 0, 0);
177 aC2 = text_diff(pPivot, pV2, 0, 0, 0);
178 if( aC1==0 || aC2==0 ){
179 free(aC1);
180 free(aC2);
181 return -1;
182 }
183
--- src/merge3.c
+++ src/merge3.c
@@ -171,12 +171,12 @@
171 ** is the number of lines of text to copy directly from the pivot,
172 ** the second integer is the number of lines of text to omit from the
173 ** pivot, and the third integer is the number of lines of text that are
174 ** inserted. The edit array ends with a triple of 0,0,0.
175 */
176 aC1 = text_diff(pPivot, pV1, 0, 0);
177 aC2 = text_diff(pPivot, pV2, 0, 0);
178 if( aC1==0 || aC2==0 ){
179 free(aC1);
180 free(aC2);
181 return -1;
182 }
183
+1 -1
--- src/wiki.c
+++ src/wiki.c
@@ -621,11 +621,11 @@
621621
blob_zero(&w2);
622622
if( rid2 && (pW2 = manifest_get(rid2, CFTYPE_WIKI))!=0 ){
623623
blob_init(&w2, pW2->zWiki, -1);
624624
}
625625
blob_zero(&d);
626
- text_diff(&w2, &w1, &d, 5, 1);
626
+ text_diff(&w2, &w1, &d, 5 | DIFF_IGNORE_EOLWS);
627627
@ <pre>
628628
@ %h(blob_str(&d))
629629
@ </pre>
630630
manifest_destroy(pW1);
631631
manifest_destroy(pW2);
632632
--- src/wiki.c
+++ src/wiki.c
@@ -621,11 +621,11 @@
621 blob_zero(&w2);
622 if( rid2 && (pW2 = manifest_get(rid2, CFTYPE_WIKI))!=0 ){
623 blob_init(&w2, pW2->zWiki, -1);
624 }
625 blob_zero(&d);
626 text_diff(&w2, &w1, &d, 5, 1);
627 @ <pre>
628 @ %h(blob_str(&d))
629 @ </pre>
630 manifest_destroy(pW1);
631 manifest_destroy(pW2);
632
--- src/wiki.c
+++ src/wiki.c
@@ -621,11 +621,11 @@
621 blob_zero(&w2);
622 if( rid2 && (pW2 = manifest_get(rid2, CFTYPE_WIKI))!=0 ){
623 blob_init(&w2, pW2->zWiki, -1);
624 }
625 blob_zero(&d);
626 text_diff(&w2, &w1, &d, 5 | DIFF_IGNORE_EOLWS);
627 @ <pre>
628 @ %h(blob_str(&d))
629 @ </pre>
630 manifest_destroy(pW1);
631 manifest_destroy(pW2);
632

Keyboard Shortcuts

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