Fossil SCM

Work towards including full text of deleted and added files in a diff when the -N or --new-file option is used. Ticket [e90d38c2054e9b44792eb]

drh 2010-10-14 18:38 trunk
Commit 585360b47dad7384b7d5c5b7926d1beb77e9e5cd
3 files changed +1 -1 +4 +47 -12
+1 -1
--- src/blob.c
+++ src/blob.c
@@ -612,11 +612,11 @@
612612
return blob_read_from_channel(pBlob, stdin, -1);
613613
}
614614
size = file_size(zFilename);
615615
blob_zero(pBlob);
616616
if( size<0 ){
617
- fossil_panic("no such file: %s", zFilename);
617
+ fossil_fatal("no such file: %s", zFilename);
618618
}
619619
if( size==0 ){
620620
return 0;
621621
}
622622
blob_resize(pBlob, size);
623623
--- src/blob.c
+++ src/blob.c
@@ -612,11 +612,11 @@
612 return blob_read_from_channel(pBlob, stdin, -1);
613 }
614 size = file_size(zFilename);
615 blob_zero(pBlob);
616 if( size<0 ){
617 fossil_panic("no such file: %s", zFilename);
618 }
619 if( size==0 ){
620 return 0;
621 }
622 blob_resize(pBlob, size);
623
--- src/blob.c
+++ src/blob.c
@@ -612,11 +612,11 @@
612 return blob_read_from_channel(pBlob, stdin, -1);
613 }
614 size = file_size(zFilename);
615 blob_zero(pBlob);
616 if( size<0 ){
617 fossil_fatal("no such file: %s", zFilename);
618 }
619 if( size==0 ){
620 return 0;
621 }
622 blob_resize(pBlob, size);
623
+4
--- src/diff.c
+++ src/diff.c
@@ -99,10 +99,14 @@
9999
return 0;
100100
}
101101
a = malloc( nLine*sizeof(a[0]) );
102102
if( a==0 ) fossil_panic("out of memory");
103103
memset(a, 0, nLine*sizeof(a[0]) );
104
+ if( n==0 ){
105
+ *pnLine = 0;
106
+ return a;
107
+ }
104108
105109
/* Fill in the array */
106110
for(i=0; i<nLine; i++){
107111
a[i].z = z;
108112
for(j=0; z[j] && z[j]!='\n'; j++){}
109113
--- src/diff.c
+++ src/diff.c
@@ -99,10 +99,14 @@
99 return 0;
100 }
101 a = malloc( nLine*sizeof(a[0]) );
102 if( a==0 ) fossil_panic("out of memory");
103 memset(a, 0, nLine*sizeof(a[0]) );
 
 
 
 
104
105 /* Fill in the array */
106 for(i=0; i<nLine; i++){
107 a[i].z = z;
108 for(j=0; z[j] && z[j]!='\n'; j++){}
109
--- src/diff.c
+++ src/diff.c
@@ -99,10 +99,14 @@
99 return 0;
100 }
101 a = malloc( nLine*sizeof(a[0]) );
102 if( a==0 ) fossil_panic("out of memory");
103 memset(a, 0, nLine*sizeof(a[0]) );
104 if( n==0 ){
105 *pnLine = 0;
106 return a;
107 }
108
109 /* Fill in the array */
110 for(i=0; i<nLine; i++){
111 a[i].z = z;
112 for(j=0; z[j] && z[j]!='\n'; j++){}
113
+47 -12
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -19,10 +19,16 @@
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
+
2430
/*
2531
** This function implements a cross-platform "system()" interface.
2632
*/
2733
int portable_system(const char *zOrigCmd){
2834
int rc;
@@ -53,24 +59,30 @@
5359
static void diff_file(
5460
Blob *pFile1, /* In memory content to compare from */
5561
const char *zFile2, /* On disk content to compare to */
5662
const char *zName, /* Display name of the file */
5763
const char *zDiffCmd, /* Command for comparison */
58
- int ignoreEolWs /* Ignore whitespace at end of lines */
64
+ int ignoreEolWs /* Ignore whitespace at end of line */
5965
){
6066
if( zDiffCmd==0 ){
61
- Blob out; /* Diff output text */
62
- Blob file2; /* Content of zFile2 */
67
+ Blob out; /* Diff output text */
68
+ Blob file2; /* Content of zFile2 */
69
+ const char *zName2; /* Name of zFile2 for display */
6370
6471
/* Read content of zFile2 into memory */
6572
blob_zero(&file2);
66
- blob_read_from_file(&file2, zFile2);
73
+ if( file_size(zFile2)<0 ){
74
+ zName2 = "/dev/null";
75
+ }else{
76
+ blob_read_from_file(&file2, zFile2);
77
+ zName2 = zName;
78
+ }
6779
6880
/* Compute and output the differences */
6981
blob_zero(&out);
7082
text_diff(pFile1, &file2, &out, 5, ignoreEolWs);
71
- printf("--- %s\n+++ %s\n", zName, zName);
83
+ printf("--- %s\n+++ %s\n", zName, zName2);
7284
printf("%s\n", blob_str(&out));
7385
7486
/* Release memory resources */
7587
blob_reset(&file2);
7688
blob_reset(&out);
@@ -183,16 +195,20 @@
183195
** files on disk and the check-out on which they are based.
184196
*/
185197
static void diff_all_against_disk(
186198
const char *zFrom, /* Version to difference from */
187199
const char *zDiffCmd, /* Use this diff command. NULL for built-in */
188
- int ignoreEolWs /* Ignore end-of-line whitespace */
200
+ int diffFlags /* Flags controlling diff output */
189201
){
190202
int vid;
191203
Blob sql;
192204
Stmt q;
205
+ int ignoreEolWs; /* Ignore end-of-line whitespace */
206
+ int asNewFile; /* Treat non-existant files as empty files */
193207
208
+ ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
209
+ asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
194210
vid = db_lget_int("checkout", 0);
195211
vfile_check_signature(vid, 1);
196212
blob_zero(&sql);
197213
db_begin_transaction();
198214
if( zFrom ){
@@ -235,23 +251,35 @@
235251
while( db_step(&q)==SQLITE_ROW ){
236252
const char *zPathname = db_column_text(&q,0);
237253
int isDeleted = db_column_int(&q, 1);
238254
int isChnged = db_column_int(&q,2);
239255
int isNew = db_column_int(&q,3);
256
+ int srcid = db_column_int(&q, 4);
240257
char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
258
+ int showDiff = 1;
241259
if( isDeleted ){
242260
printf("DELETED %s\n", zPathname);
261
+ if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; }
243262
}else if( access(zFullName, 0) ){
244263
printf("MISSING %s\n", zPathname);
264
+ if( !asNewFile ){ showDiff = 0; }
245265
}else if( isNew ){
246266
printf("ADDED %s\n", zPathname);
267
+ srcid = 0;
268
+ if( !asNewFile ){ showDiff = 0; }
247269
}else if( isChnged==3 ){
248270
printf("ADDED_BY_MERGE %s\n", zPathname);
249
- }else{
250
- int srcid = db_column_int(&q, 4);
271
+ srcid = 0;
272
+ if( !asNewFile ){ showDiff = 0; }
273
+ }
274
+ if( showDiff ){
251275
Blob content;
252
- content_get(srcid, &content);
276
+ if( srcid>0 ){
277
+ content_get(srcid, &content);
278
+ }else{
279
+ blob_zero(&content);
280
+ }
253281
printf("Index: %s\n======================================="
254282
"============================\n",
255283
zPathname
256284
);
257285
diff_file(&content, zFullName, zPathname, zDiffCmd, ignoreEolWs);
@@ -292,14 +320,16 @@
292320
*/
293321
static void diff_all_two_versions(
294322
const char *zFrom,
295323
const char *zTo,
296324
const char *zDiffCmd,
297
- int ignoreEolWs
325
+ int diffFlags
298326
){
299327
Manifest mFrom, mTo;
300328
int iFrom, iTo;
329
+ int ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0 ? 1 : 0;
330
+ /* int asNewFlag = (diffFlags & DIFF_NEWFILE)!=0 ? 1 : 0; */
301331
302332
manifest_from_name(zFrom, &mFrom);
303333
manifest_from_name(zTo, &mTo);
304334
iFrom = iTo = 0;
305335
while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
@@ -370,29 +400,34 @@
370400
** the "-i" option is a no-op. The "-i" option converts "gdiff" into "diff".
371401
*/
372402
void diff_cmd(void){
373403
int isGDiff; /* True for gdiff. False for normal diff */
374404
int isInternDiff; /* True for internal diff */
405
+ int hasNFlag; /* True if -N or --new-file flag is used */
375406
const char *zFrom; /* Source version number */
376407
const char *zTo; /* Target version number */
377408
const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
409
+ int diffFlags = 0; /* Flags to control the DIFF */
378410
379411
isGDiff = g.argv[1][0]=='g';
380412
isInternDiff = find_option("internal","i",0)!=0;
381413
zFrom = find_option("from", "r", 1);
382414
zTo = find_option("to", 0, 1);
415
+ hasNFlag = find_option("new-file","N",0)!=0;
416
+
383417
418
+ if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
384419
if( zTo==0 ){
385420
db_must_be_within_tree();
386421
verify_all_options();
387422
if( !isInternDiff ){
388423
zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
389424
}
390425
if( g.argc==3 ){
391426
diff_one_against_disk(zFrom, zDiffCmd, 0);
392427
}else{
393
- diff_all_against_disk(zFrom, zDiffCmd, 0);
428
+ diff_all_against_disk(zFrom, zDiffCmd, diffFlags);
394429
}
395430
}else if( zFrom==0 ){
396431
fossil_fatal("must use --from if --to is present");
397432
}else{
398433
db_find_and_open_repository(1);
@@ -401,9 +436,9 @@
401436
zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
402437
}
403438
if( g.argc==3 ){
404439
diff_one_two_versions(zFrom, zTo, zDiffCmd, 0);
405440
}else{
406
- diff_all_two_versions(zFrom, zTo, zDiffCmd, 0);
441
+ diff_all_two_versions(zFrom, zTo, zDiffCmd, diffFlags);
407442
}
408443
}
409444
}
410445
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -19,10 +19,16 @@
19 */
20 #include "config.h"
21 #include "diffcmd.h"
22 #include <assert.h>
23
 
 
 
 
 
 
24 /*
25 ** This function implements a cross-platform "system()" interface.
26 */
27 int portable_system(const char *zOrigCmd){
28 int rc;
@@ -53,24 +59,30 @@
53 static void diff_file(
54 Blob *pFile1, /* In memory content to compare from */
55 const char *zFile2, /* On disk content to compare to */
56 const char *zName, /* Display name of the file */
57 const char *zDiffCmd, /* Command for comparison */
58 int ignoreEolWs /* Ignore whitespace at end of lines */
59 ){
60 if( zDiffCmd==0 ){
61 Blob out; /* Diff output text */
62 Blob file2; /* Content of zFile2 */
 
63
64 /* Read content of zFile2 into memory */
65 blob_zero(&file2);
66 blob_read_from_file(&file2, zFile2);
 
 
 
 
 
67
68 /* Compute and output the differences */
69 blob_zero(&out);
70 text_diff(pFile1, &file2, &out, 5, ignoreEolWs);
71 printf("--- %s\n+++ %s\n", zName, zName);
72 printf("%s\n", blob_str(&out));
73
74 /* Release memory resources */
75 blob_reset(&file2);
76 blob_reset(&out);
@@ -183,16 +195,20 @@
183 ** files on disk and the check-out on which they are based.
184 */
185 static void diff_all_against_disk(
186 const char *zFrom, /* Version to difference from */
187 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
188 int ignoreEolWs /* Ignore end-of-line whitespace */
189 ){
190 int vid;
191 Blob sql;
192 Stmt q;
 
 
193
 
 
194 vid = db_lget_int("checkout", 0);
195 vfile_check_signature(vid, 1);
196 blob_zero(&sql);
197 db_begin_transaction();
198 if( zFrom ){
@@ -235,23 +251,35 @@
235 while( db_step(&q)==SQLITE_ROW ){
236 const char *zPathname = db_column_text(&q,0);
237 int isDeleted = db_column_int(&q, 1);
238 int isChnged = db_column_int(&q,2);
239 int isNew = db_column_int(&q,3);
 
240 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
 
241 if( isDeleted ){
242 printf("DELETED %s\n", zPathname);
 
243 }else if( access(zFullName, 0) ){
244 printf("MISSING %s\n", zPathname);
 
245 }else if( isNew ){
246 printf("ADDED %s\n", zPathname);
 
 
247 }else if( isChnged==3 ){
248 printf("ADDED_BY_MERGE %s\n", zPathname);
249 }else{
250 int srcid = db_column_int(&q, 4);
 
 
251 Blob content;
252 content_get(srcid, &content);
 
 
 
 
253 printf("Index: %s\n======================================="
254 "============================\n",
255 zPathname
256 );
257 diff_file(&content, zFullName, zPathname, zDiffCmd, ignoreEolWs);
@@ -292,14 +320,16 @@
292 */
293 static void diff_all_two_versions(
294 const char *zFrom,
295 const char *zTo,
296 const char *zDiffCmd,
297 int ignoreEolWs
298 ){
299 Manifest mFrom, mTo;
300 int iFrom, iTo;
 
 
301
302 manifest_from_name(zFrom, &mFrom);
303 manifest_from_name(zTo, &mTo);
304 iFrom = iTo = 0;
305 while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
@@ -370,29 +400,34 @@
370 ** the "-i" option is a no-op. The "-i" option converts "gdiff" into "diff".
371 */
372 void diff_cmd(void){
373 int isGDiff; /* True for gdiff. False for normal diff */
374 int isInternDiff; /* True for internal diff */
 
375 const char *zFrom; /* Source version number */
376 const char *zTo; /* Target version number */
377 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
 
378
379 isGDiff = g.argv[1][0]=='g';
380 isInternDiff = find_option("internal","i",0)!=0;
381 zFrom = find_option("from", "r", 1);
382 zTo = find_option("to", 0, 1);
 
 
383
 
384 if( zTo==0 ){
385 db_must_be_within_tree();
386 verify_all_options();
387 if( !isInternDiff ){
388 zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
389 }
390 if( g.argc==3 ){
391 diff_one_against_disk(zFrom, zDiffCmd, 0);
392 }else{
393 diff_all_against_disk(zFrom, zDiffCmd, 0);
394 }
395 }else if( zFrom==0 ){
396 fossil_fatal("must use --from if --to is present");
397 }else{
398 db_find_and_open_repository(1);
@@ -401,9 +436,9 @@
401 zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
402 }
403 if( g.argc==3 ){
404 diff_one_two_versions(zFrom, zTo, zDiffCmd, 0);
405 }else{
406 diff_all_two_versions(zFrom, zTo, zDiffCmd, 0);
407 }
408 }
409 }
410
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -19,10 +19,16 @@
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 ** This function implements a cross-platform "system()" interface.
32 */
33 int portable_system(const char *zOrigCmd){
34 int rc;
@@ -53,24 +59,30 @@
59 static void diff_file(
60 Blob *pFile1, /* In memory content to compare from */
61 const char *zFile2, /* On disk content to compare to */
62 const char *zName, /* Display name of the file */
63 const char *zDiffCmd, /* Command for comparison */
64 int ignoreEolWs /* Ignore whitespace at end of line */
65 ){
66 if( zDiffCmd==0 ){
67 Blob out; /* Diff output text */
68 Blob file2; /* Content of zFile2 */
69 const char *zName2; /* Name of zFile2 for display */
70
71 /* Read content of zFile2 into memory */
72 blob_zero(&file2);
73 if( file_size(zFile2)<0 ){
74 zName2 = "/dev/null";
75 }else{
76 blob_read_from_file(&file2, zFile2);
77 zName2 = zName;
78 }
79
80 /* Compute and output the differences */
81 blob_zero(&out);
82 text_diff(pFile1, &file2, &out, 5, ignoreEolWs);
83 printf("--- %s\n+++ %s\n", zName, zName2);
84 printf("%s\n", blob_str(&out));
85
86 /* Release memory resources */
87 blob_reset(&file2);
88 blob_reset(&out);
@@ -183,16 +195,20 @@
195 ** files on disk and the check-out on which they are based.
196 */
197 static void diff_all_against_disk(
198 const char *zFrom, /* Version to difference from */
199 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
200 int diffFlags /* Flags controlling diff output */
201 ){
202 int vid;
203 Blob sql;
204 Stmt q;
205 int ignoreEolWs; /* Ignore end-of-line whitespace */
206 int asNewFile; /* Treat non-existant files as empty files */
207
208 ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
209 asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
210 vid = db_lget_int("checkout", 0);
211 vfile_check_signature(vid, 1);
212 blob_zero(&sql);
213 db_begin_transaction();
214 if( zFrom ){
@@ -235,23 +251,35 @@
251 while( db_step(&q)==SQLITE_ROW ){
252 const char *zPathname = db_column_text(&q,0);
253 int isDeleted = db_column_int(&q, 1);
254 int isChnged = db_column_int(&q,2);
255 int isNew = db_column_int(&q,3);
256 int srcid = db_column_int(&q, 4);
257 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
258 int showDiff = 1;
259 if( isDeleted ){
260 printf("DELETED %s\n", zPathname);
261 if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; }
262 }else if( access(zFullName, 0) ){
263 printf("MISSING %s\n", zPathname);
264 if( !asNewFile ){ showDiff = 0; }
265 }else if( isNew ){
266 printf("ADDED %s\n", zPathname);
267 srcid = 0;
268 if( !asNewFile ){ showDiff = 0; }
269 }else if( isChnged==3 ){
270 printf("ADDED_BY_MERGE %s\n", zPathname);
271 srcid = 0;
272 if( !asNewFile ){ showDiff = 0; }
273 }
274 if( showDiff ){
275 Blob content;
276 if( srcid>0 ){
277 content_get(srcid, &content);
278 }else{
279 blob_zero(&content);
280 }
281 printf("Index: %s\n======================================="
282 "============================\n",
283 zPathname
284 );
285 diff_file(&content, zFullName, zPathname, zDiffCmd, ignoreEolWs);
@@ -292,14 +320,16 @@
320 */
321 static void diff_all_two_versions(
322 const char *zFrom,
323 const char *zTo,
324 const char *zDiffCmd,
325 int diffFlags
326 ){
327 Manifest mFrom, mTo;
328 int iFrom, iTo;
329 int ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0 ? 1 : 0;
330 /* int asNewFlag = (diffFlags & DIFF_NEWFILE)!=0 ? 1 : 0; */
331
332 manifest_from_name(zFrom, &mFrom);
333 manifest_from_name(zTo, &mTo);
334 iFrom = iTo = 0;
335 while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
@@ -370,29 +400,34 @@
400 ** the "-i" option is a no-op. The "-i" option converts "gdiff" into "diff".
401 */
402 void diff_cmd(void){
403 int isGDiff; /* True for gdiff. False for normal diff */
404 int isInternDiff; /* True for internal diff */
405 int hasNFlag; /* True if -N or --new-file flag is used */
406 const char *zFrom; /* Source version number */
407 const char *zTo; /* Target version number */
408 const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */
409 int diffFlags = 0; /* Flags to control the DIFF */
410
411 isGDiff = g.argv[1][0]=='g';
412 isInternDiff = find_option("internal","i",0)!=0;
413 zFrom = find_option("from", "r", 1);
414 zTo = find_option("to", 0, 1);
415 hasNFlag = find_option("new-file","N",0)!=0;
416
417
418 if( hasNFlag ) diffFlags |= DIFF_NEWFILE;
419 if( zTo==0 ){
420 db_must_be_within_tree();
421 verify_all_options();
422 if( !isInternDiff ){
423 zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
424 }
425 if( g.argc==3 ){
426 diff_one_against_disk(zFrom, zDiffCmd, 0);
427 }else{
428 diff_all_against_disk(zFrom, zDiffCmd, diffFlags);
429 }
430 }else if( zFrom==0 ){
431 fossil_fatal("must use --from if --to is present");
432 }else{
433 db_find_and_open_repository(1);
@@ -401,9 +436,9 @@
436 zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
437 }
438 if( g.argc==3 ){
439 diff_one_two_versions(zFrom, zTo, zDiffCmd, 0);
440 }else{
441 diff_all_two_versions(zFrom, zTo, zDiffCmd, diffFlags);
442 }
443 }
444 }
445

Keyboard Shortcuts

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