Fossil SCM

Add new --verbose option to 'fossil commit' to display a unified diff of all changes to be committed in the editor. Only tested on OpenBSD 6.8 and preliminary testing on macOS 10.15.7 (Catalina); needs to be tested on Linux and Windows.

jamsek 2021-01-29 16:10 trunk
Commit a713e1e6c22c5d283c651b48a41161d4b0d7532c443055cec6805806d1d2ee66
--- src/checkin.c
+++ src/checkin.c
@@ -1237,10 +1237,14 @@
12371237
int i, n;
12381238
char *z;
12391239
n = blob_size(&line);
12401240
z = blob_buffer(&line);
12411241
for(i=0; i<n && fossil_isspace(z[i]); i++){}
1242
+ if (!fossil_strncmp(
1243
+ "# NOTE: The below diff is not inserted into the commit message.\n",
1244
+ z, n))
1245
+ break;
12421246
if( i<n && z[i]=='#' ) continue;
12431247
if( i<n || blob_size(pComment)>0 ){
12441248
blob_appendf(pComment, "%b", &line);
12451249
}
12461250
}
@@ -1324,10 +1328,41 @@
13241328
blob_append(&prompt,
13251329
"#\n"
13261330
"# All merged-in branches will be closed due to the --integrate flag\n"
13271331
"#\n", -1
13281332
);
1333
+ }
1334
+ if (p->verboseFlag) {
1335
+ FileDirList *diffFiles;
1336
+ if( g.aCommitFile ){
1337
+ int i = 0;
1338
+ diffFiles = fossil_malloc_zero((g.argc - 1) * sizeof(*diffFiles));
1339
+ for (i = 0; g.aCommitFile[i] != 0; ++i) {
1340
+ diffFiles[i].zName = db_text(0,
1341
+ "SELECT pathname FROM vfile WHERE id=%d", g.aCommitFile[i]);
1342
+ if (!strcmp(diffFiles[i].zName , ".")) {
1343
+ diffFiles[0].zName[0] = '.';
1344
+ diffFiles[0].zName[1] = 0;
1345
+ break;
1346
+ }
1347
+ diffFiles[i].nName = strlen(diffFiles[i].zName);
1348
+ diffFiles[i].nUsed = 0;
1349
+ }
1350
+ }
1351
+ blob_append_full(&prompt, "#\n"
1352
+ "# NOTE: The below diff is not inserted into the commit message.\n\n",
1353
+ -1);
1354
+ diff_against_disk(0, 0, diff_get_binary_glob(),
1355
+ db_get_boolean("diff-binary", 1), 0,
1356
+ g.aCommitFile ? diffFiles : 0, &prompt
1357
+ );
1358
+ if (g.aCommitFile && diffFiles) {
1359
+ int i;
1360
+ for (i = 0; diffFiles[i].zName; ++i)
1361
+ fossil_free(diffFiles[i].zName);
1362
+ fossil_free(diffFiles);
1363
+ }
13291364
}
13301365
prompt_for_user_comment(pComment, &prompt);
13311366
blob_reset(&prompt);
13321367
}
13331368
@@ -1543,10 +1578,11 @@
15431578
Blob *pComment; /* Check-in comment text */
15441579
const char *zMimetype; /* Mimetype of check-in command. May be NULL */
15451580
int verifyDate; /* Verify that child is younger */
15461581
int closeFlag; /* Close the branch being committed */
15471582
int integrateFlag; /* Close merged-in branches */
1583
+ int verboseFlag; /* Show diff in editor for check-in comment */
15481584
Blob *pCksum; /* Repository checksum. May be 0 */
15491585
const char *zDateOvrd; /* Date override. If 0 then use 'now' */
15501586
const char *zUserOvrd; /* User override. If 0 then use login_name() */
15511587
const char *zBranch; /* Branch name. May be 0 */
15521588
const char *zColor; /* One-time background color. May be 0 */
@@ -2090,10 +2126,12 @@
20902126
** --integrate close all merged-in branches
20912127
** -m|--comment COMMENT-TEXT use COMMENT-TEXT as commit comment
20922128
** -M|--message-file FILE read the commit comment from given file
20932129
** --mimetype MIMETYPE mimetype of check-in comment
20942130
** -n|--dry-run If given, display instead of run actions
2131
+** -v|--verbose Display in the editor a unified diff of the
2132
+** changes to be committed with this check-in
20952133
** --no-prompt This option disables prompting the user for
20962134
** input and assumes an answer of 'No' for every
20972135
** question.
20982136
** --no-warnings omit all warnings about file contents
20992137
** --no-verify do not run before-commit hooks
@@ -2194,10 +2232,11 @@
21942232
sCiInfo.zColor = find_option("bgcolor",0,1);
21952233
sCiInfo.zBrClr = find_option("branchcolor",0,1);
21962234
sCiInfo.closeFlag = find_option("close",0,0)!=0;
21972235
sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
21982236
sCiInfo.zMimetype = find_option("mimetype",0,1);
2237
+ sCiInfo.verboseFlag = find_option("verbose", "v", 0) != 0;
21992238
while( (zTag = find_option("tag",0,1))!=0 ){
22002239
if( zTag[0]==0 ) continue;
22012240
sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag,
22022241
sizeof(char*)*(nTag+2));
22032242
sCiInfo.azTag[nTag++] = zTag;
22042243
--- src/checkin.c
+++ src/checkin.c
@@ -1237,10 +1237,14 @@
1237 int i, n;
1238 char *z;
1239 n = blob_size(&line);
1240 z = blob_buffer(&line);
1241 for(i=0; i<n && fossil_isspace(z[i]); i++){}
 
 
 
 
1242 if( i<n && z[i]=='#' ) continue;
1243 if( i<n || blob_size(pComment)>0 ){
1244 blob_appendf(pComment, "%b", &line);
1245 }
1246 }
@@ -1324,10 +1328,41 @@
1324 blob_append(&prompt,
1325 "#\n"
1326 "# All merged-in branches will be closed due to the --integrate flag\n"
1327 "#\n", -1
1328 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1329 }
1330 prompt_for_user_comment(pComment, &prompt);
1331 blob_reset(&prompt);
1332 }
1333
@@ -1543,10 +1578,11 @@
1543 Blob *pComment; /* Check-in comment text */
1544 const char *zMimetype; /* Mimetype of check-in command. May be NULL */
1545 int verifyDate; /* Verify that child is younger */
1546 int closeFlag; /* Close the branch being committed */
1547 int integrateFlag; /* Close merged-in branches */
 
1548 Blob *pCksum; /* Repository checksum. May be 0 */
1549 const char *zDateOvrd; /* Date override. If 0 then use 'now' */
1550 const char *zUserOvrd; /* User override. If 0 then use login_name() */
1551 const char *zBranch; /* Branch name. May be 0 */
1552 const char *zColor; /* One-time background color. May be 0 */
@@ -2090,10 +2126,12 @@
2090 ** --integrate close all merged-in branches
2091 ** -m|--comment COMMENT-TEXT use COMMENT-TEXT as commit comment
2092 ** -M|--message-file FILE read the commit comment from given file
2093 ** --mimetype MIMETYPE mimetype of check-in comment
2094 ** -n|--dry-run If given, display instead of run actions
 
 
2095 ** --no-prompt This option disables prompting the user for
2096 ** input and assumes an answer of 'No' for every
2097 ** question.
2098 ** --no-warnings omit all warnings about file contents
2099 ** --no-verify do not run before-commit hooks
@@ -2194,10 +2232,11 @@
2194 sCiInfo.zColor = find_option("bgcolor",0,1);
2195 sCiInfo.zBrClr = find_option("branchcolor",0,1);
2196 sCiInfo.closeFlag = find_option("close",0,0)!=0;
2197 sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
2198 sCiInfo.zMimetype = find_option("mimetype",0,1);
 
2199 while( (zTag = find_option("tag",0,1))!=0 ){
2200 if( zTag[0]==0 ) continue;
2201 sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag,
2202 sizeof(char*)*(nTag+2));
2203 sCiInfo.azTag[nTag++] = zTag;
2204
--- src/checkin.c
+++ src/checkin.c
@@ -1237,10 +1237,14 @@
1237 int i, n;
1238 char *z;
1239 n = blob_size(&line);
1240 z = blob_buffer(&line);
1241 for(i=0; i<n && fossil_isspace(z[i]); i++){}
1242 if (!fossil_strncmp(
1243 "# NOTE: The below diff is not inserted into the commit message.\n",
1244 z, n))
1245 break;
1246 if( i<n && z[i]=='#' ) continue;
1247 if( i<n || blob_size(pComment)>0 ){
1248 blob_appendf(pComment, "%b", &line);
1249 }
1250 }
@@ -1324,10 +1328,41 @@
1328 blob_append(&prompt,
1329 "#\n"
1330 "# All merged-in branches will be closed due to the --integrate flag\n"
1331 "#\n", -1
1332 );
1333 }
1334 if (p->verboseFlag) {
1335 FileDirList *diffFiles;
1336 if( g.aCommitFile ){
1337 int i = 0;
1338 diffFiles = fossil_malloc_zero((g.argc - 1) * sizeof(*diffFiles));
1339 for (i = 0; g.aCommitFile[i] != 0; ++i) {
1340 diffFiles[i].zName = db_text(0,
1341 "SELECT pathname FROM vfile WHERE id=%d", g.aCommitFile[i]);
1342 if (!strcmp(diffFiles[i].zName , ".")) {
1343 diffFiles[0].zName[0] = '.';
1344 diffFiles[0].zName[1] = 0;
1345 break;
1346 }
1347 diffFiles[i].nName = strlen(diffFiles[i].zName);
1348 diffFiles[i].nUsed = 0;
1349 }
1350 }
1351 blob_append_full(&prompt, "#\n"
1352 "# NOTE: The below diff is not inserted into the commit message.\n\n",
1353 -1);
1354 diff_against_disk(0, 0, diff_get_binary_glob(),
1355 db_get_boolean("diff-binary", 1), 0,
1356 g.aCommitFile ? diffFiles : 0, &prompt
1357 );
1358 if (g.aCommitFile && diffFiles) {
1359 int i;
1360 for (i = 0; diffFiles[i].zName; ++i)
1361 fossil_free(diffFiles[i].zName);
1362 fossil_free(diffFiles);
1363 }
1364 }
1365 prompt_for_user_comment(pComment, &prompt);
1366 blob_reset(&prompt);
1367 }
1368
@@ -1543,10 +1578,11 @@
1578 Blob *pComment; /* Check-in comment text */
1579 const char *zMimetype; /* Mimetype of check-in command. May be NULL */
1580 int verifyDate; /* Verify that child is younger */
1581 int closeFlag; /* Close the branch being committed */
1582 int integrateFlag; /* Close merged-in branches */
1583 int verboseFlag; /* Show diff in editor for check-in comment */
1584 Blob *pCksum; /* Repository checksum. May be 0 */
1585 const char *zDateOvrd; /* Date override. If 0 then use 'now' */
1586 const char *zUserOvrd; /* User override. If 0 then use login_name() */
1587 const char *zBranch; /* Branch name. May be 0 */
1588 const char *zColor; /* One-time background color. May be 0 */
@@ -2090,10 +2126,12 @@
2126 ** --integrate close all merged-in branches
2127 ** -m|--comment COMMENT-TEXT use COMMENT-TEXT as commit comment
2128 ** -M|--message-file FILE read the commit comment from given file
2129 ** --mimetype MIMETYPE mimetype of check-in comment
2130 ** -n|--dry-run If given, display instead of run actions
2131 ** -v|--verbose Display in the editor a unified diff of the
2132 ** changes to be committed with this check-in
2133 ** --no-prompt This option disables prompting the user for
2134 ** input and assumes an answer of 'No' for every
2135 ** question.
2136 ** --no-warnings omit all warnings about file contents
2137 ** --no-verify do not run before-commit hooks
@@ -2194,10 +2232,11 @@
2232 sCiInfo.zColor = find_option("bgcolor",0,1);
2233 sCiInfo.zBrClr = find_option("branchcolor",0,1);
2234 sCiInfo.closeFlag = find_option("close",0,0)!=0;
2235 sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
2236 sCiInfo.zMimetype = find_option("mimetype",0,1);
2237 sCiInfo.verboseFlag = find_option("verbose", "v", 0) != 0;
2238 while( (zTag = find_option("tag",0,1))!=0 ){
2239 if( zTag[0]==0 ) continue;
2240 sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag,
2241 sizeof(char*)*(nTag+2));
2242 sCiInfo.azTag[nTag++] = zTag;
2243
+1 -1
--- src/diff.c
+++ src/diff.c
@@ -2090,11 +2090,11 @@
20902090
if( zErr ) fossil_fatal("regex error: %s", zErr);
20912091
}
20922092
diffFlag = diff_options();
20932093
verify_all_options();
20942094
if( g.argc!=4 ) usage("FILE1 FILE2");
2095
- diff_print_filenames(g.argv[2], g.argv[3], diffFlag);
2095
+ diff_print_filenames(g.argv[2], g.argv[3], diffFlag, 0);
20962096
blob_read_from_file(&a, g.argv[2], ExtFILE);
20972097
blob_read_from_file(&b, g.argv[3], ExtFILE);
20982098
blob_zero(&out);
20992099
text_diff(&a, &b, &out, pRe, diffFlag);
21002100
blob_write_to_file(&out, "-");
21012101
--- src/diff.c
+++ src/diff.c
@@ -2090,11 +2090,11 @@
2090 if( zErr ) fossil_fatal("regex error: %s", zErr);
2091 }
2092 diffFlag = diff_options();
2093 verify_all_options();
2094 if( g.argc!=4 ) usage("FILE1 FILE2");
2095 diff_print_filenames(g.argv[2], g.argv[3], diffFlag);
2096 blob_read_from_file(&a, g.argv[2], ExtFILE);
2097 blob_read_from_file(&b, g.argv[3], ExtFILE);
2098 blob_zero(&out);
2099 text_diff(&a, &b, &out, pRe, diffFlag);
2100 blob_write_to_file(&out, "-");
2101
--- src/diff.c
+++ src/diff.c
@@ -2090,11 +2090,11 @@
2090 if( zErr ) fossil_fatal("regex error: %s", zErr);
2091 }
2092 diffFlag = diff_options();
2093 verify_all_options();
2094 if( g.argc!=4 ) usage("FILE1 FILE2");
2095 diff_print_filenames(g.argv[2], g.argv[3], diffFlag, 0);
2096 blob_read_from_file(&a, g.argv[2], ExtFILE);
2097 blob_read_from_file(&b, g.argv[3], ExtFILE);
2098 blob_zero(&out);
2099 text_diff(&a, &b, &out, pRe, diffFlag);
2100 blob_write_to_file(&out, "-");
2101
+35 -18
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -106,22 +106,26 @@
106106
}
107107
108108
/*
109109
** Print the "Index:" message that patches wants to see at the top of a diff.
110110
*/
111
-void diff_print_index(const char *zFile, u64 diffFlags){
111
+void diff_print_index(const char *zFile, u64 diffFlags, Blob *diffBlob){
112112
if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT))==0 ){
113113
char *z = mprintf("Index: %s\n%.66c\n", zFile, '=');
114
- fossil_print("%s", z);
114
+ if (!diffBlob)
115
+ fossil_print("%s", z);
116
+ else
117
+ blob_appendf(diffBlob, "%s", z);
115118
fossil_free(z);
116119
}
117120
}
118121
119122
/*
120123
** Print the +++/--- filename lines for a diff operation.
121124
*/
122
-void diff_print_filenames(const char *zLeft, const char *zRight, u64 diffFlags){
125
+void diff_print_filenames(const char *zLeft, const char *zRight,
126
+ u64 diffFlags, Blob *diffBlob){
123127
char *z = 0;
124128
if( diffFlags & DIFF_BRIEF ){
125129
/* no-op */
126130
}else if( diffFlags & DIFF_SIDEBYSIDE ){
127131
int w = diff_width(diffFlags);
@@ -142,11 +146,14 @@
142146
(w-n2)/2, '=', n2, zRight, (w-n2+1)/2, '=');
143147
}
144148
}else{
145149
z = mprintf("--- %s\n+++ %s\n", zLeft, zRight);
146150
}
147
- fossil_print("%s", z);
151
+ if (!diffBlob)
152
+ fossil_print("%s", z);
153
+ else
154
+ blob_appendf(diffBlob, "%s", z);
148155
fossil_free(z);
149156
}
150157
151158
/*
152159
** Show the difference between two files, one in memory and one on disk.
@@ -171,11 +178,12 @@
171178
const char *zName, /* Display name of the file */
172179
const char *zDiffCmd, /* Command for comparison */
173180
const char *zBinGlob, /* Treat file names matching this as binary */
174181
int fIncludeBinary, /* Include binary files for external diff */
175182
u64 diffFlags, /* Flags to control the diff */
176
- int fSwapDiff /* Diff from Zfile2 to Pfile1 */
183
+ int fSwapDiff, /* Diff from Zfile2 to Pfile1 */
184
+ Blob *diffBlob /* Blob to store diff output */
177185
){
178186
if( zDiffCmd==0 ){
179187
Blob out; /* Diff output text */
180188
Blob file2; /* Content of zFile2 */
181189
const char *zName2; /* Name of zFile2 for display */
@@ -201,14 +209,22 @@
201209
}else{
202210
text_diff(pFile1, &file2, &out, 0, diffFlags);
203211
}
204212
if( blob_size(&out) ){
205213
if( diffFlags & DIFF_NUMSTAT ){
206
- fossil_print("%s %s\n", blob_str(&out), zName);
214
+ if (!diffBlob)
215
+ fossil_print("%s %s\n", blob_str(&out), zName);
216
+ else
217
+ blob_appendf(diffBlob, "%s %s\n", blob_str(&out), zName);
207218
}else{
208
- diff_print_filenames(zName, zName2, diffFlags);
209
- fossil_print("%s\n", blob_str(&out));
219
+ if (!diffBlob) {
220
+ diff_print_filenames(zName, zName2, diffFlags, 0);
221
+ fossil_print("%s\n", blob_str(&out));
222
+ } else {
223
+ diff_print_filenames(zName, zName2, diffFlags, diffBlob);
224
+ blob_appendf(diffBlob, "%s\n", blob_str(&out));
225
+ }
210226
}
211227
}
212228
blob_reset(&out);
213229
}
214230
@@ -302,11 +318,11 @@
302318
blob_zero(&out);
303319
text_diff(pFile1, pFile2, &out, 0, diffFlags);
304320
if( diffFlags & DIFF_NUMSTAT ){
305321
fossil_print("%s %s\n", blob_str(&out), zName);
306322
}else{
307
- diff_print_filenames(zName, zName, diffFlags);
323
+ diff_print_filenames(zName, zName, diffFlags, 0);
308324
fossil_print("%s\n", blob_str(&out));
309325
}
310326
311327
/* Release memory resources */
312328
blob_reset(&out);
@@ -366,17 +382,18 @@
366382
**
367383
** When using an external diff program, zBinGlob contains the GLOB patterns
368384
** for file names to treat as binary. If fIncludeBinary is zero, these files
369385
** will be skipped in addition to files that may contain binary content.
370386
*/
371
-static void diff_against_disk(
387
+void diff_against_disk(
372388
const char *zFrom, /* Version to difference from */
373389
const char *zDiffCmd, /* Use this diff command. NULL for built-in */
374390
const char *zBinGlob, /* Treat file names matching this as binary */
375391
int fIncludeBinary, /* Treat file names matching this as binary */
376392
u64 diffFlags, /* Flags controlling diff output */
377
- FileDirList *pFileDir /* Which files to diff */
393
+ FileDirList *pFileDir, /* Which files to diff */
394
+ Blob *diffBlob /* Blob to output diff instead of stdout */
378395
){
379396
int vid;
380397
Blob sql;
381398
Stmt q;
382399
int asNewFile; /* Treat non-existant files as empty files */
@@ -467,24 +484,24 @@
467484
}
468485
if( showDiff ){
469486
Blob content;
470487
int isBin;
471488
if( !isLink != !file_islink(zFullName) ){
472
- diff_print_index(zPathname, diffFlags);
473
- diff_print_filenames(zPathname, zPathname, diffFlags);
489
+ diff_print_index(zPathname, diffFlags, 0);
490
+ diff_print_filenames(zPathname, zPathname, diffFlags, 0);
474491
fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
475492
continue;
476493
}
477494
if( srcid>0 ){
478495
content_get(srcid, &content);
479496
}else{
480497
blob_zero(&content);
481498
}
482499
isBin = fIncludeBinary ? 0 : looks_like_binary(&content);
483
- diff_print_index(zPathname, diffFlags);
500
+ diff_print_index(zPathname, diffFlags, diffBlob);
484501
diff_file(&content, isBin, zFullName, zPathname, zDiffCmd,
485
- zBinGlob, fIncludeBinary, diffFlags, 0);
502
+ zBinGlob, fIncludeBinary, diffFlags, 0, diffBlob);
486503
blob_reset(&content);
487504
}
488505
blob_reset(&fname);
489506
}
490507
db_finalize(&q);
@@ -517,11 +534,11 @@
517534
const char *zFile = (const char*)db_column_text(&q, 0);
518535
if( !file_dir_match(pFileDir, zFile) ) continue;
519536
zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
520537
db_column_blob(&q, 1, &content);
521538
diff_file(&content, 0, zFullName, zFile,
522
- zDiffCmd, zBinGlob, fIncludeBinary, diffFlags, 0);
539
+ zDiffCmd, zBinGlob, fIncludeBinary, diffFlags, 0, 0);
523540
fossil_free(zFullName);
524541
blob_reset(&content);
525542
}
526543
db_finalize(&q);
527544
}
@@ -555,11 +572,11 @@
555572
zName = pTo->zName;
556573
}else{
557574
zName = DIFF_NO_NAME;
558575
}
559576
if( diffFlags & DIFF_BRIEF ) return;
560
- diff_print_index(zName, diffFlags);
577
+ diff_print_index(zName, diffFlags, 0);
561578
if( pFrom ){
562579
rid = uuid_to_rid(pFrom->zUuid, 0);
563580
content_get(rid, &f1);
564581
}else{
565582
blob_zero(&f1);
@@ -941,11 +958,11 @@
941958
}
942959
diff_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
943960
diffFlags, pFileDir);
944961
}else if( zTo==0 ){
945962
diff_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
946
- diffFlags, pFileDir);
963
+ diffFlags, pFileDir, 0);
947964
}else{
948965
diff_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
949966
diffFlags, pFileDir);
950967
}
951968
if( pFileDir ){
952969
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -106,22 +106,26 @@
106 }
107
108 /*
109 ** Print the "Index:" message that patches wants to see at the top of a diff.
110 */
111 void diff_print_index(const char *zFile, u64 diffFlags){
112 if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT))==0 ){
113 char *z = mprintf("Index: %s\n%.66c\n", zFile, '=');
114 fossil_print("%s", z);
 
 
 
115 fossil_free(z);
116 }
117 }
118
119 /*
120 ** Print the +++/--- filename lines for a diff operation.
121 */
122 void diff_print_filenames(const char *zLeft, const char *zRight, u64 diffFlags){
 
123 char *z = 0;
124 if( diffFlags & DIFF_BRIEF ){
125 /* no-op */
126 }else if( diffFlags & DIFF_SIDEBYSIDE ){
127 int w = diff_width(diffFlags);
@@ -142,11 +146,14 @@
142 (w-n2)/2, '=', n2, zRight, (w-n2+1)/2, '=');
143 }
144 }else{
145 z = mprintf("--- %s\n+++ %s\n", zLeft, zRight);
146 }
147 fossil_print("%s", z);
 
 
 
148 fossil_free(z);
149 }
150
151 /*
152 ** Show the difference between two files, one in memory and one on disk.
@@ -171,11 +178,12 @@
171 const char *zName, /* Display name of the file */
172 const char *zDiffCmd, /* Command for comparison */
173 const char *zBinGlob, /* Treat file names matching this as binary */
174 int fIncludeBinary, /* Include binary files for external diff */
175 u64 diffFlags, /* Flags to control the diff */
176 int fSwapDiff /* Diff from Zfile2 to Pfile1 */
 
177 ){
178 if( zDiffCmd==0 ){
179 Blob out; /* Diff output text */
180 Blob file2; /* Content of zFile2 */
181 const char *zName2; /* Name of zFile2 for display */
@@ -201,14 +209,22 @@
201 }else{
202 text_diff(pFile1, &file2, &out, 0, diffFlags);
203 }
204 if( blob_size(&out) ){
205 if( diffFlags & DIFF_NUMSTAT ){
206 fossil_print("%s %s\n", blob_str(&out), zName);
 
 
 
207 }else{
208 diff_print_filenames(zName, zName2, diffFlags);
209 fossil_print("%s\n", blob_str(&out));
 
 
 
 
 
210 }
211 }
212 blob_reset(&out);
213 }
214
@@ -302,11 +318,11 @@
302 blob_zero(&out);
303 text_diff(pFile1, pFile2, &out, 0, diffFlags);
304 if( diffFlags & DIFF_NUMSTAT ){
305 fossil_print("%s %s\n", blob_str(&out), zName);
306 }else{
307 diff_print_filenames(zName, zName, diffFlags);
308 fossil_print("%s\n", blob_str(&out));
309 }
310
311 /* Release memory resources */
312 blob_reset(&out);
@@ -366,17 +382,18 @@
366 **
367 ** When using an external diff program, zBinGlob contains the GLOB patterns
368 ** for file names to treat as binary. If fIncludeBinary is zero, these files
369 ** will be skipped in addition to files that may contain binary content.
370 */
371 static void diff_against_disk(
372 const char *zFrom, /* Version to difference from */
373 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
374 const char *zBinGlob, /* Treat file names matching this as binary */
375 int fIncludeBinary, /* Treat file names matching this as binary */
376 u64 diffFlags, /* Flags controlling diff output */
377 FileDirList *pFileDir /* Which files to diff */
 
378 ){
379 int vid;
380 Blob sql;
381 Stmt q;
382 int asNewFile; /* Treat non-existant files as empty files */
@@ -467,24 +484,24 @@
467 }
468 if( showDiff ){
469 Blob content;
470 int isBin;
471 if( !isLink != !file_islink(zFullName) ){
472 diff_print_index(zPathname, diffFlags);
473 diff_print_filenames(zPathname, zPathname, diffFlags);
474 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
475 continue;
476 }
477 if( srcid>0 ){
478 content_get(srcid, &content);
479 }else{
480 blob_zero(&content);
481 }
482 isBin = fIncludeBinary ? 0 : looks_like_binary(&content);
483 diff_print_index(zPathname, diffFlags);
484 diff_file(&content, isBin, zFullName, zPathname, zDiffCmd,
485 zBinGlob, fIncludeBinary, diffFlags, 0);
486 blob_reset(&content);
487 }
488 blob_reset(&fname);
489 }
490 db_finalize(&q);
@@ -517,11 +534,11 @@
517 const char *zFile = (const char*)db_column_text(&q, 0);
518 if( !file_dir_match(pFileDir, zFile) ) continue;
519 zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
520 db_column_blob(&q, 1, &content);
521 diff_file(&content, 0, zFullName, zFile,
522 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags, 0);
523 fossil_free(zFullName);
524 blob_reset(&content);
525 }
526 db_finalize(&q);
527 }
@@ -555,11 +572,11 @@
555 zName = pTo->zName;
556 }else{
557 zName = DIFF_NO_NAME;
558 }
559 if( diffFlags & DIFF_BRIEF ) return;
560 diff_print_index(zName, diffFlags);
561 if( pFrom ){
562 rid = uuid_to_rid(pFrom->zUuid, 0);
563 content_get(rid, &f1);
564 }else{
565 blob_zero(&f1);
@@ -941,11 +958,11 @@
941 }
942 diff_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
943 diffFlags, pFileDir);
944 }else if( zTo==0 ){
945 diff_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
946 diffFlags, pFileDir);
947 }else{
948 diff_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
949 diffFlags, pFileDir);
950 }
951 if( pFileDir ){
952
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -106,22 +106,26 @@
106 }
107
108 /*
109 ** Print the "Index:" message that patches wants to see at the top of a diff.
110 */
111 void diff_print_index(const char *zFile, u64 diffFlags, Blob *diffBlob){
112 if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT))==0 ){
113 char *z = mprintf("Index: %s\n%.66c\n", zFile, '=');
114 if (!diffBlob)
115 fossil_print("%s", z);
116 else
117 blob_appendf(diffBlob, "%s", z);
118 fossil_free(z);
119 }
120 }
121
122 /*
123 ** Print the +++/--- filename lines for a diff operation.
124 */
125 void diff_print_filenames(const char *zLeft, const char *zRight,
126 u64 diffFlags, Blob *diffBlob){
127 char *z = 0;
128 if( diffFlags & DIFF_BRIEF ){
129 /* no-op */
130 }else if( diffFlags & DIFF_SIDEBYSIDE ){
131 int w = diff_width(diffFlags);
@@ -142,11 +146,14 @@
146 (w-n2)/2, '=', n2, zRight, (w-n2+1)/2, '=');
147 }
148 }else{
149 z = mprintf("--- %s\n+++ %s\n", zLeft, zRight);
150 }
151 if (!diffBlob)
152 fossil_print("%s", z);
153 else
154 blob_appendf(diffBlob, "%s", z);
155 fossil_free(z);
156 }
157
158 /*
159 ** Show the difference between two files, one in memory and one on disk.
@@ -171,11 +178,12 @@
178 const char *zName, /* Display name of the file */
179 const char *zDiffCmd, /* Command for comparison */
180 const char *zBinGlob, /* Treat file names matching this as binary */
181 int fIncludeBinary, /* Include binary files for external diff */
182 u64 diffFlags, /* Flags to control the diff */
183 int fSwapDiff, /* Diff from Zfile2 to Pfile1 */
184 Blob *diffBlob /* Blob to store diff output */
185 ){
186 if( zDiffCmd==0 ){
187 Blob out; /* Diff output text */
188 Blob file2; /* Content of zFile2 */
189 const char *zName2; /* Name of zFile2 for display */
@@ -201,14 +209,22 @@
209 }else{
210 text_diff(pFile1, &file2, &out, 0, diffFlags);
211 }
212 if( blob_size(&out) ){
213 if( diffFlags & DIFF_NUMSTAT ){
214 if (!diffBlob)
215 fossil_print("%s %s\n", blob_str(&out), zName);
216 else
217 blob_appendf(diffBlob, "%s %s\n", blob_str(&out), zName);
218 }else{
219 if (!diffBlob) {
220 diff_print_filenames(zName, zName2, diffFlags, 0);
221 fossil_print("%s\n", blob_str(&out));
222 } else {
223 diff_print_filenames(zName, zName2, diffFlags, diffBlob);
224 blob_appendf(diffBlob, "%s\n", blob_str(&out));
225 }
226 }
227 }
228 blob_reset(&out);
229 }
230
@@ -302,11 +318,11 @@
318 blob_zero(&out);
319 text_diff(pFile1, pFile2, &out, 0, diffFlags);
320 if( diffFlags & DIFF_NUMSTAT ){
321 fossil_print("%s %s\n", blob_str(&out), zName);
322 }else{
323 diff_print_filenames(zName, zName, diffFlags, 0);
324 fossil_print("%s\n", blob_str(&out));
325 }
326
327 /* Release memory resources */
328 blob_reset(&out);
@@ -366,17 +382,18 @@
382 **
383 ** When using an external diff program, zBinGlob contains the GLOB patterns
384 ** for file names to treat as binary. If fIncludeBinary is zero, these files
385 ** will be skipped in addition to files that may contain binary content.
386 */
387 void diff_against_disk(
388 const char *zFrom, /* Version to difference from */
389 const char *zDiffCmd, /* Use this diff command. NULL for built-in */
390 const char *zBinGlob, /* Treat file names matching this as binary */
391 int fIncludeBinary, /* Treat file names matching this as binary */
392 u64 diffFlags, /* Flags controlling diff output */
393 FileDirList *pFileDir, /* Which files to diff */
394 Blob *diffBlob /* Blob to output diff instead of stdout */
395 ){
396 int vid;
397 Blob sql;
398 Stmt q;
399 int asNewFile; /* Treat non-existant files as empty files */
@@ -467,24 +484,24 @@
484 }
485 if( showDiff ){
486 Blob content;
487 int isBin;
488 if( !isLink != !file_islink(zFullName) ){
489 diff_print_index(zPathname, diffFlags, 0);
490 diff_print_filenames(zPathname, zPathname, diffFlags, 0);
491 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
492 continue;
493 }
494 if( srcid>0 ){
495 content_get(srcid, &content);
496 }else{
497 blob_zero(&content);
498 }
499 isBin = fIncludeBinary ? 0 : looks_like_binary(&content);
500 diff_print_index(zPathname, diffFlags, diffBlob);
501 diff_file(&content, isBin, zFullName, zPathname, zDiffCmd,
502 zBinGlob, fIncludeBinary, diffFlags, 0, diffBlob);
503 blob_reset(&content);
504 }
505 blob_reset(&fname);
506 }
507 db_finalize(&q);
@@ -517,11 +534,11 @@
534 const char *zFile = (const char*)db_column_text(&q, 0);
535 if( !file_dir_match(pFileDir, zFile) ) continue;
536 zFullName = mprintf("%s%s", g.zLocalRoot, zFile);
537 db_column_blob(&q, 1, &content);
538 diff_file(&content, 0, zFullName, zFile,
539 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags, 0, 0);
540 fossil_free(zFullName);
541 blob_reset(&content);
542 }
543 db_finalize(&q);
544 }
@@ -555,11 +572,11 @@
572 zName = pTo->zName;
573 }else{
574 zName = DIFF_NO_NAME;
575 }
576 if( diffFlags & DIFF_BRIEF ) return;
577 diff_print_index(zName, diffFlags, 0);
578 if( pFrom ){
579 rid = uuid_to_rid(pFrom->zUuid, 0);
580 content_get(rid, &f1);
581 }else{
582 blob_zero(&f1);
@@ -941,11 +958,11 @@
958 }
959 diff_against_undo(zDiffCmd, zBinGlob, fIncludeBinary,
960 diffFlags, pFileDir);
961 }else if( zTo==0 ){
962 diff_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary,
963 diffFlags, pFileDir, 0);
964 }else{
965 diff_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary,
966 diffFlags, pFileDir);
967 }
968 if( pFileDir ){
969
+5 -5
--- src/stash.c
+++ src/stash.c
@@ -428,18 +428,18 @@
428428
char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig);
429429
Blob a, b;
430430
if( rid==0 ){
431431
db_ephemeral_blob(&q, 6, &a);
432432
fossil_print("ADDED %s\n", zNew);
433
- diff_print_index(zNew, diffFlags);
433
+ diff_print_index(zNew, diffFlags, 0);
434434
isBin1 = 0;
435435
isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a);
436436
diff_file_mem(&empty, &a, isBin1, isBin2, zNew, zDiffCmd,
437437
zBinGlob, fIncludeBinary, diffFlags);
438438
}else if( isRemoved ){
439439
fossil_print("DELETE %s\n", zOrig);
440
- diff_print_index(zNew, diffFlags);
440
+ diff_print_index(zNew, diffFlags, 0);
441441
isBin2 = 0;
442442
if( fBaseline ){
443443
content_get(rid, &a);
444444
isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
445445
diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd,
@@ -450,12 +450,12 @@
450450
Blob delta;
451451
int isOrigLink = file_islink(zOPath);
452452
db_ephemeral_blob(&q, 6, &delta);
453453
fossil_print("CHANGED %s\n", zNew);
454454
if( !isOrigLink != !isLink ){
455
- diff_print_index(zNew, diffFlags);
456
- diff_print_filenames(zOrig, zNew, diffFlags);
455
+ diff_print_index(zNew, diffFlags, 0);
456
+ diff_print_filenames(zOrig, zNew, diffFlags, 0);
457457
printf(DIFF_CANNOT_COMPUTE_SYMLINK);
458458
}else{
459459
content_get(rid, &a);
460460
blob_delta_apply(&a, &delta, &b);
461461
isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
@@ -465,11 +465,11 @@
465465
zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
466466
}else{
467467
/*Diff with file on disk using fSwapDiff=1 to show the diff in the
468468
same direction as if fBaseline=1.*/
469469
diff_file(&b, isBin2, zOPath, zNew, zDiffCmd,
470
- zBinGlob, fIncludeBinary, diffFlags, 1);
470
+ zBinGlob, fIncludeBinary, diffFlags, 1, 0);
471471
}
472472
blob_reset(&a);
473473
blob_reset(&b);
474474
}
475475
blob_reset(&delta);
476476
--- src/stash.c
+++ src/stash.c
@@ -428,18 +428,18 @@
428 char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig);
429 Blob a, b;
430 if( rid==0 ){
431 db_ephemeral_blob(&q, 6, &a);
432 fossil_print("ADDED %s\n", zNew);
433 diff_print_index(zNew, diffFlags);
434 isBin1 = 0;
435 isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a);
436 diff_file_mem(&empty, &a, isBin1, isBin2, zNew, zDiffCmd,
437 zBinGlob, fIncludeBinary, diffFlags);
438 }else if( isRemoved ){
439 fossil_print("DELETE %s\n", zOrig);
440 diff_print_index(zNew, diffFlags);
441 isBin2 = 0;
442 if( fBaseline ){
443 content_get(rid, &a);
444 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
445 diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd,
@@ -450,12 +450,12 @@
450 Blob delta;
451 int isOrigLink = file_islink(zOPath);
452 db_ephemeral_blob(&q, 6, &delta);
453 fossil_print("CHANGED %s\n", zNew);
454 if( !isOrigLink != !isLink ){
455 diff_print_index(zNew, diffFlags);
456 diff_print_filenames(zOrig, zNew, diffFlags);
457 printf(DIFF_CANNOT_COMPUTE_SYMLINK);
458 }else{
459 content_get(rid, &a);
460 blob_delta_apply(&a, &delta, &b);
461 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
@@ -465,11 +465,11 @@
465 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
466 }else{
467 /*Diff with file on disk using fSwapDiff=1 to show the diff in the
468 same direction as if fBaseline=1.*/
469 diff_file(&b, isBin2, zOPath, zNew, zDiffCmd,
470 zBinGlob, fIncludeBinary, diffFlags, 1);
471 }
472 blob_reset(&a);
473 blob_reset(&b);
474 }
475 blob_reset(&delta);
476
--- src/stash.c
+++ src/stash.c
@@ -428,18 +428,18 @@
428 char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig);
429 Blob a, b;
430 if( rid==0 ){
431 db_ephemeral_blob(&q, 6, &a);
432 fossil_print("ADDED %s\n", zNew);
433 diff_print_index(zNew, diffFlags, 0);
434 isBin1 = 0;
435 isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a);
436 diff_file_mem(&empty, &a, isBin1, isBin2, zNew, zDiffCmd,
437 zBinGlob, fIncludeBinary, diffFlags);
438 }else if( isRemoved ){
439 fossil_print("DELETE %s\n", zOrig);
440 diff_print_index(zNew, diffFlags, 0);
441 isBin2 = 0;
442 if( fBaseline ){
443 content_get(rid, &a);
444 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
445 diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd,
@@ -450,12 +450,12 @@
450 Blob delta;
451 int isOrigLink = file_islink(zOPath);
452 db_ephemeral_blob(&q, 6, &delta);
453 fossil_print("CHANGED %s\n", zNew);
454 if( !isOrigLink != !isLink ){
455 diff_print_index(zNew, diffFlags, 0);
456 diff_print_filenames(zOrig, zNew, diffFlags, 0);
457 printf(DIFF_CANNOT_COMPUTE_SYMLINK);
458 }else{
459 content_get(rid, &a);
460 blob_delta_apply(&a, &delta, &b);
461 isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a);
@@ -465,11 +465,11 @@
465 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
466 }else{
467 /*Diff with file on disk using fSwapDiff=1 to show the diff in the
468 same direction as if fBaseline=1.*/
469 diff_file(&b, isBin2, zOPath, zNew, zDiffCmd,
470 zBinGlob, fIncludeBinary, diffFlags, 1, 0);
471 }
472 blob_reset(&a);
473 blob_reset(&b);
474 }
475 blob_reset(&delta);
476

Keyboard Shortcuts

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