| | @@ -106,22 +106,27 @@ |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | /* |
| 109 | 109 | ** Print the "Index:" message that patches wants to see at the top of a diff. |
| 110 | 110 | */ |
| 111 | | -void diff_print_index(const char *zFile, u64 diffFlags){ |
| 111 | +void diff_print_index(const char *zFile, u64 diffFlags, Blob *diffBlob){ |
| 112 | 112 | if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT))==0 ){ |
| 113 | 113 | 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); |
| 118 | + } |
| 115 | 119 | fossil_free(z); |
| 116 | 120 | } |
| 117 | 121 | } |
| 118 | 122 | |
| 119 | 123 | /* |
| 120 | 124 | ** Print the +++/--- filename lines for a diff operation. |
| 121 | 125 | */ |
| 122 | | -void diff_print_filenames(const char *zLeft, const char *zRight, u64 diffFlags){ |
| 126 | +void diff_print_filenames(const char *zLeft, const char *zRight, |
| 127 | + u64 diffFlags, Blob *diffBlob){ |
| 123 | 128 | char *z = 0; |
| 124 | 129 | if( diffFlags & DIFF_BRIEF ){ |
| 125 | 130 | /* no-op */ |
| 126 | 131 | }else if( diffFlags & DIFF_SIDEBYSIDE ){ |
| 127 | 132 | int w = diff_width(diffFlags); |
| | @@ -142,11 +147,15 @@ |
| 142 | 147 | (w-n2)/2, '=', n2, zRight, (w-n2+1)/2, '='); |
| 143 | 148 | } |
| 144 | 149 | }else{ |
| 145 | 150 | z = mprintf("--- %s\n+++ %s\n", zLeft, zRight); |
| 146 | 151 | } |
| 147 | | - fossil_print("%s", z); |
| 152 | + if( !diffBlob ){ |
| 153 | + fossil_print("%s", z); |
| 154 | + }else{ |
| 155 | + blob_appendf(diffBlob, "%s", z); |
| 156 | + } |
| 148 | 157 | fossil_free(z); |
| 149 | 158 | } |
| 150 | 159 | |
| 151 | 160 | /* |
| 152 | 161 | ** Show the difference between two files, one in memory and one on disk. |
| | @@ -171,11 +180,12 @@ |
| 171 | 180 | const char *zName, /* Display name of the file */ |
| 172 | 181 | const char *zDiffCmd, /* Command for comparison */ |
| 173 | 182 | const char *zBinGlob, /* Treat file names matching this as binary */ |
| 174 | 183 | int fIncludeBinary, /* Include binary files for external diff */ |
| 175 | 184 | u64 diffFlags, /* Flags to control the diff */ |
| 176 | | - int fSwapDiff /* Diff from Zfile2 to Pfile1 */ |
| 185 | + int fSwapDiff, /* Diff from Zfile2 to Pfile1 */ |
| 186 | + Blob *diffBlob /* Blob to store diff output */ |
| 177 | 187 | ){ |
| 178 | 188 | if( zDiffCmd==0 ){ |
| 179 | 189 | Blob out; /* Diff output text */ |
| 180 | 190 | Blob file2; /* Content of zFile2 */ |
| 181 | 191 | const char *zName2; /* Name of zFile2 for display */ |
| | @@ -201,14 +211,23 @@ |
| 201 | 211 | }else{ |
| 202 | 212 | text_diff(pFile1, &file2, &out, 0, diffFlags); |
| 203 | 213 | } |
| 204 | 214 | if( blob_size(&out) ){ |
| 205 | 215 | if( diffFlags & DIFF_NUMSTAT ){ |
| 206 | | - fossil_print("%s %s\n", blob_str(&out), zName); |
| 216 | + if( !diffBlob ){ |
| 217 | + fossil_print("%s %s\n", blob_str(&out), zName); |
| 218 | + }else{ |
| 219 | + blob_appendf(diffBlob, "%s %s\n", blob_str(&out), zName); |
| 220 | + } |
| 207 | 221 | }else{ |
| 208 | | - diff_print_filenames(zName, zName2, diffFlags); |
| 209 | | - fossil_print("%s\n", blob_str(&out)); |
| 222 | + if( !diffBlob ){ |
| 223 | + diff_print_filenames(zName, zName2, diffFlags, 0); |
| 224 | + fossil_print("%s\n", blob_str(&out)); |
| 225 | + }else{ |
| 226 | + diff_print_filenames(zName, zName2, diffFlags, diffBlob); |
| 227 | + blob_appendf(diffBlob, "%s\n", blob_str(&out)); |
| 228 | + } |
| 210 | 229 | } |
| 211 | 230 | } |
| 212 | 231 | blob_reset(&out); |
| 213 | 232 | } |
| 214 | 233 | |
| | @@ -302,11 +321,11 @@ |
| 302 | 321 | blob_zero(&out); |
| 303 | 322 | text_diff(pFile1, pFile2, &out, 0, diffFlags); |
| 304 | 323 | if( diffFlags & DIFF_NUMSTAT ){ |
| 305 | 324 | fossil_print("%s %s\n", blob_str(&out), zName); |
| 306 | 325 | }else{ |
| 307 | | - diff_print_filenames(zName, zName, diffFlags); |
| 326 | + diff_print_filenames(zName, zName, diffFlags, 0); |
| 308 | 327 | fossil_print("%s\n", blob_str(&out)); |
| 309 | 328 | } |
| 310 | 329 | |
| 311 | 330 | /* Release memory resources */ |
| 312 | 331 | blob_reset(&out); |
| | @@ -366,17 +385,18 @@ |
| 366 | 385 | ** |
| 367 | 386 | ** When using an external diff program, zBinGlob contains the GLOB patterns |
| 368 | 387 | ** for file names to treat as binary. If fIncludeBinary is zero, these files |
| 369 | 388 | ** will be skipped in addition to files that may contain binary content. |
| 370 | 389 | */ |
| 371 | | -static void diff_against_disk( |
| 390 | +void diff_against_disk( |
| 372 | 391 | const char *zFrom, /* Version to difference from */ |
| 373 | 392 | const char *zDiffCmd, /* Use this diff command. NULL for built-in */ |
| 374 | 393 | const char *zBinGlob, /* Treat file names matching this as binary */ |
| 375 | 394 | int fIncludeBinary, /* Treat file names matching this as binary */ |
| 376 | 395 | u64 diffFlags, /* Flags controlling diff output */ |
| 377 | | - FileDirList *pFileDir /* Which files to diff */ |
| 396 | + FileDirList *pFileDir, /* Which files to diff */ |
| 397 | + Blob *diffBlob /* Blob to output diff instead of stdout */ |
| 378 | 398 | ){ |
| 379 | 399 | int vid; |
| 380 | 400 | Blob sql; |
| 381 | 401 | Stmt q; |
| 382 | 402 | int asNewFile; /* Treat non-existant files as empty files */ |
| | @@ -467,24 +487,24 @@ |
| 467 | 487 | } |
| 468 | 488 | if( showDiff ){ |
| 469 | 489 | Blob content; |
| 470 | 490 | int isBin; |
| 471 | 491 | if( !isLink != !file_islink(zFullName) ){ |
| 472 | | - diff_print_index(zPathname, diffFlags); |
| 473 | | - diff_print_filenames(zPathname, zPathname, diffFlags); |
| 492 | + diff_print_index(zPathname, diffFlags, 0); |
| 493 | + diff_print_filenames(zPathname, zPathname, diffFlags, 0); |
| 474 | 494 | fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK); |
| 475 | 495 | continue; |
| 476 | 496 | } |
| 477 | 497 | if( srcid>0 ){ |
| 478 | 498 | content_get(srcid, &content); |
| 479 | 499 | }else{ |
| 480 | 500 | blob_zero(&content); |
| 481 | 501 | } |
| 482 | 502 | isBin = fIncludeBinary ? 0 : looks_like_binary(&content); |
| 483 | | - diff_print_index(zPathname, diffFlags); |
| 503 | + diff_print_index(zPathname, diffFlags, diffBlob); |
| 484 | 504 | diff_file(&content, isBin, zFullName, zPathname, zDiffCmd, |
| 485 | | - zBinGlob, fIncludeBinary, diffFlags, 0); |
| 505 | + zBinGlob, fIncludeBinary, diffFlags, 0, diffBlob); |
| 486 | 506 | blob_reset(&content); |
| 487 | 507 | } |
| 488 | 508 | blob_reset(&fname); |
| 489 | 509 | } |
| 490 | 510 | db_finalize(&q); |
| | @@ -517,11 +537,11 @@ |
| 517 | 537 | const char *zFile = (const char*)db_column_text(&q, 0); |
| 518 | 538 | if( !file_dir_match(pFileDir, zFile) ) continue; |
| 519 | 539 | zFullName = mprintf("%s%s", g.zLocalRoot, zFile); |
| 520 | 540 | db_column_blob(&q, 1, &content); |
| 521 | 541 | diff_file(&content, 0, zFullName, zFile, |
| 522 | | - zDiffCmd, zBinGlob, fIncludeBinary, diffFlags, 0); |
| 542 | + zDiffCmd, zBinGlob, fIncludeBinary, diffFlags, 0, 0); |
| 523 | 543 | fossil_free(zFullName); |
| 524 | 544 | blob_reset(&content); |
| 525 | 545 | } |
| 526 | 546 | db_finalize(&q); |
| 527 | 547 | } |
| | @@ -555,11 +575,11 @@ |
| 555 | 575 | zName = pTo->zName; |
| 556 | 576 | }else{ |
| 557 | 577 | zName = DIFF_NO_NAME; |
| 558 | 578 | } |
| 559 | 579 | if( diffFlags & DIFF_BRIEF ) return; |
| 560 | | - diff_print_index(zName, diffFlags); |
| 580 | + diff_print_index(zName, diffFlags, 0); |
| 561 | 581 | if( pFrom ){ |
| 562 | 582 | rid = uuid_to_rid(pFrom->zUuid, 0); |
| 563 | 583 | content_get(rid, &f1); |
| 564 | 584 | }else{ |
| 565 | 585 | blob_zero(&f1); |
| | @@ -941,11 +961,11 @@ |
| 941 | 961 | } |
| 942 | 962 | diff_against_undo(zDiffCmd, zBinGlob, fIncludeBinary, |
| 943 | 963 | diffFlags, pFileDir); |
| 944 | 964 | }else if( zTo==0 ){ |
| 945 | 965 | diff_against_disk(zFrom, zDiffCmd, zBinGlob, fIncludeBinary, |
| 946 | | - diffFlags, pFileDir); |
| 966 | + diffFlags, pFileDir, 0); |
| 947 | 967 | }else{ |
| 948 | 968 | diff_two_versions(zFrom, zTo, zDiffCmd, zBinGlob, fIncludeBinary, |
| 949 | 969 | diffFlags, pFileDir); |
| 950 | 970 | } |
| 951 | 971 | if( pFileDir ){ |
| 952 | 972 | |