Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch use-blob_strip_bom Excluding Merge-Ins
This is equivalent to a diff from db0c512767 to b0e05a90b6
2012-11-05
| ||
21:10 | Do not run the graphical merging tool nor leave merge-droppings after a dry-run merge. Also improve the merge summary message at the end of a merge. check-in: cd2c0e4cb5 user: drh tags: trunk | |
13:56 | merge trunk Leaf check-in: b0e05a90b6 user: jan.nijtmans tags: use-blob_strip_bom | |
13:10 | If the committed file has CR/NL or UTF-16 (or both), give the user the possibility to convert it to resp NL or UTF-8 (or both) without committing check-in: c6223a8e2a user: jan.nijtmans tags: convert_before_commit | |
2012-11-04
| ||
18:03 | merge trunk check-in: e86aa2a1e8 user: jan.nijtmans tags: improve_commit_warning | |
17:41 | Merge the "spelling" branch into trunk, fixing a huge number of typos, mostly in comments, but occasionally in error messages or help screens. check-in: db0c512767 user: drh tags: trunk | |
12:59 | Fix typos. Closed-Leaf check-in: 45065c5c28 user: dmitry tags: spelling | |
11:58 | Improvements to the fix for [0ff64b0a5fc88e7e]: (1) Better error message and (2) allow the partial commit of the renamed file as long as its destination files is also part of the partial commit. check-in: c0fe455c78 user: drh tags: trunk | |
2012-11-01
| ||
14:02 | bug-fix: Before preparing a diff, BOM's should not be removed. It might result in a BOM in the middle of UTF-8, which is invalid, but that's how diff works. check-in: cd06b7d8af user: jan.nijtmans tags: use-blob_strip_bom | |
Changes to src/blob.c.
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
....
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
|
*pRight = swap; } /* ** Strip a possible BOM from the blob. On Windows, if there ** is either no BOM at all or an (le/be) UTF-16 BOM, a conversion ** to UTF-8 is done. ** If useMbcs is false and there is no BOM, the input string ** is assumed to be UTF-8 already, so no conversion is done. */ void blob_strip_bom(Blob *pBlob, int useMbcs){ static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF }; #ifdef _WIN32 static const unsigned short ubom = 0xfeff; static const unsigned short urbom = 0xfffe; #endif /* _WIN32 */ char *zUtf8; if( blob_size(pBlob)>2 && memcmp(blob_buffer(pBlob), bom, 3)==0 ) { struct Blob temp; zUtf8 = blob_str(pBlob) + 3; blob_zero(&temp); blob_append(&temp, zUtf8, -1); fossil_mbcs_free(zUtf8); blob_swap(pBlob, &temp); blob_reset(&temp); #ifdef _WIN32 }else if( blob_size(pBlob)>1 && (blob_size(pBlob)&1)==0 && memcmp(blob_buffer(pBlob), &ubom, 2)==0 ) { /* Make sure the blob contains two terminating 0-bytes */ blob_append(pBlob, "", 1); zUtf8 = blob_str(pBlob) + 2; zUtf8 = fossil_unicode_to_utf8(zUtf8); blob_zero(pBlob); blob_append(pBlob, zUtf8, -1); fossil_mbcs_free(zUtf8); }else if( blob_size(pBlob)>1 && (blob_size(pBlob)&1)==0 && memcmp(blob_buffer(pBlob), &urbom, 2)==0 ) { unsigned int i = blob_size(pBlob); zUtf8 = blob_buffer(pBlob); while( i > 0 ){ ................................................................................ zUtf8[--i] = temp; } /* Make sure the blob contains two terminating 0-bytes */ blob_append(pBlob, "", 1); zUtf8 = blob_str(pBlob) + 2; zUtf8 = fossil_unicode_to_utf8(zUtf8); blob_zero(pBlob); blob_append(pBlob, zUtf8, -1); fossil_mbcs_free(zUtf8); }else if (useMbcs) { zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob)); blob_zero(pBlob); blob_append(pBlob, zUtf8, -1); fossil_mbcs_free(zUtf8); #endif /* _WIN32 */ } } |
|
>
>
|
|
|
|
|
|
|
>
>
>
>
>
>
>
|
|
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
....
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
|
*pRight = swap; } /* ** Strip a possible BOM from the blob. On Windows, if there ** is either no BOM at all or an (le/be) UTF-16 BOM, a conversion ** to UTF-8 is done. ** If useMbcs is 0 and there is no BOM, the input string ** is assumed to be UTF-8 already, so no conversion is done. ** If useMbcs is 2, any BOM is replaced by the UTF-8 BOM */ void blob_strip_bom(Blob *pBlob, int useMbcs){ static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF }; #ifdef _WIN32 static const unsigned short ubom = 0xfeff; static const unsigned short urbom = 0xfffe; #endif /* _WIN32 */ char *zUtf8; if( blob_size(pBlob)>2 && memcmp(blob_buffer(pBlob), bom, 3)==0 ) { if( useMbcs<2 ){ struct Blob temp; zUtf8 = blob_str(pBlob) + 3; blob_zero(&temp); blob_append(&temp, zUtf8, -1); fossil_mbcs_free(zUtf8); blob_swap(pBlob, &temp); blob_reset(&temp); } #ifdef _WIN32 }else if( blob_size(pBlob)>1 && (blob_size(pBlob)&1)==0 && memcmp(blob_buffer(pBlob), &ubom, 2)==0 ) { /* Make sure the blob contains two terminating 0-bytes */ blob_append(pBlob, "", 1); zUtf8 = blob_str(pBlob) + 2; zUtf8 = fossil_unicode_to_utf8(zUtf8); blob_zero(pBlob); if( useMbcs>1 ){ blob_append(pBlob, (char*)bom, 3); } blob_append(pBlob, zUtf8, -1); fossil_mbcs_free(zUtf8); }else if( blob_size(pBlob)>1 && (blob_size(pBlob)&1)==0 && memcmp(blob_buffer(pBlob), &urbom, 2)==0 ) { unsigned int i = blob_size(pBlob); zUtf8 = blob_buffer(pBlob); while( i > 0 ){ ................................................................................ zUtf8[--i] = temp; } /* Make sure the blob contains two terminating 0-bytes */ blob_append(pBlob, "", 1); zUtf8 = blob_str(pBlob) + 2; zUtf8 = fossil_unicode_to_utf8(zUtf8); blob_zero(pBlob); if( useMbcs>1 ){ blob_append(pBlob, (char*)bom, 3); } blob_append(pBlob, zUtf8, -1); fossil_mbcs_free(zUtf8); }else if (useMbcs==1) { zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob)); blob_zero(pBlob); blob_append(pBlob, zUtf8, -1); fossil_mbcs_free(zUtf8); #endif /* _WIN32 */ } } |
Changes to src/diff.c.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 ... 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 ... 209 210 211 212 213 214 215 216 217 218 219 220 221 222 ... 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
/* ** These error messages are shared in multiple locations. They are defined ** here for consistency. */ #define DIFF_CANNOT_COMPUTE_BINARY \ "cannot compute difference between binary files\n" #define DIFF_CANNOT_COMPUTE_SYMLINK \ "cannot compute difference between symlink and regular file\n" #define looks_like_binary(blob) (looks_like_utf8((blob)) == 0) #endif /* INTERFACE */ /* ** Maximum length of a line in a text file, in bytes. (8192) */ #define LENGTH_MASK_SZ 13 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1) ................................................................................ ** not be UTF-8. ** ** (0) -- The content appears to be binary because it contains embedded ** NUL characters or an extremely long line. Since this function ** does not understand UTF-16, it may falsely consider UTF-16 text ** to be binary. ** ** (-1) -- The content appears to consist entirely of text, with lines ** delimited by carriage-return, line-feed pairs; however, the ** encoding may not be UTF-8. ** ************************************ WARNING ********************************** ** ** This function does not validate that the blob content is properly formed ** UTF-8. It assumes that all code points are the same size. It does not ................................................................................ /* Check individual lines. */ if( n==0 ) return result; /* Empty file -> text */ c = *z; if( c==0 ) return 0; /* Zero byte in a file -> binary */ j = (c!='\n'); while( --n>0 ){ c = *++z; ++j; if( c==0 ) return 0; /* Zero byte in a file -> binary */ if( c=='\n' ){ int c2 = z[-1]; if( c2=='\r' ){ result = -1; /* Contains CR/NL, continue */ ................................................................................ # define WCHAR_T wchar_t # else # define WCHAR_T unsigned short # endif #endif /* ** Maximum length of a line in a text file, in UTF-16 characters. (4096) ** The number of bytes represented by this value cannot exceed LENGTH_MASK ** bytes, because that is the line buffer size used by the diff engine. */ #define UTF16_LENGTH_MASK_SZ (LENGTH_MASK_SZ-(sizeof(WCHAR_T)-sizeof(char))) #define UTF16_LENGTH_MASK ((1<<UTF16_LENGTH_MASK_SZ)-1) /* ** The carriage-return / line-feed characters in the UTF-16be and UTF-16le ** encodings. */ #define UTF16BE_CR ((WCHAR_T)'\r') #define UTF16BE_LF ((WCHAR_T)'\n') |
> > > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > < | |
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 ... 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 ... 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 ... 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
/* ** These error messages are shared in multiple locations. They are defined ** here for consistency. */ #define DIFF_CANNOT_COMPUTE_BINARY \ "cannot compute difference between binary files\n" #define DIFF_CANNOT_COMPUTE_ENCODING \ "cannot compute difference between files with different encodings\n" #define DIFF_CANNOT_COMPUTE_SYMLINK \ "cannot compute difference between symlink and regular file\n" #define looks_like_text(blob) (looks_like_utf8(blob)&3) #endif /* INTERFACE */ /* ** Maximum length of a line in a text file, in bytes. (8192) */ #define LENGTH_MASK_SZ 13 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1) ................................................................................ ** not be UTF-8. ** ** (0) -- The content appears to be binary because it contains embedded ** NUL characters or an extremely long line. Since this function ** does not understand UTF-16, it may falsely consider UTF-16 text ** to be binary. ** ** (-1,-2) UTF-16 (le/be) ** ** (-3) -- The content appears to consist entirely of text, with lines ** delimited by carriage-return, line-feed pairs; however, the ** encoding may not be UTF-8. ** ************************************ WARNING ********************************** ** ** This function does not validate that the blob content is properly formed ** UTF-8. It assumes that all code points are the same size. It does not ................................................................................ /* Check individual lines. */ if( n==0 ) return result; /* Empty file -> text */ c = *z; if( c==0 ) return 0; /* Zero byte in a file -> binary */ j = (c!='\n'); if ( (n&1)==0 ){ /* UTF-16 must have an even blob length */ if ( (c==0xff) && (z[1]==0xfe) ){ /* UTF-16 LE BOM */ result = -1; while( (n-=2)>0 ){ c = *(z+=2); ++j; if( z[1]==0 ){ /* High-byte must be 0 for further checks */ if( c==0 ) return 0; /* Zero char in a file -> binary */ if( c=='\n' ){ if( j>LENGTH_MASK ){ return 0; /* Very long line -> binary */ } j = 0; } } if( j>LENGTH_MASK ){ return 0; /* Very long line -> binary */ } } return result; } else if ( (c==0xfe) && (z[1]==0xff) ){ /* UTF-16 BE BOM */ result = -2; ++z; while( (n-=2)>0 ){ c = *(z+=2); ++j; if ( z[-1]==0 ){ /* High-byte must be 0 for further checks */ if( c==0 ) return 0; /* Zero char in a file -> binary */ if( c=='\n' ){ if( j>LENGTH_MASK ){ return 0; /* Very long line -> binary */ } j = 0; } } if( j>LENGTH_MASK ){ return 0; /* Very long line -> binary */ } } return result; } } while( --n>0 ){ c = *++z; ++j; if( c==0 ) return 0; /* Zero byte in a file -> binary */ if( c=='\n' ){ int c2 = z[-1]; if( c2=='\r' ){ result = -1; /* Contains CR/NL, continue */ ................................................................................ # define WCHAR_T wchar_t # else # define WCHAR_T unsigned short # endif #endif /* ** Maximum length of a line in a text file, in UTF-16 characters. (2731) ** The number of characters represented by this value cannot exceed ** LENGTH_UTF16_LENGTH_MASK characters, because when converting UTF-16 ** to UTF-8 it could overflow the line buffer used by the diff engine. */ #define UTF16_LENGTH_MASK (LENGTH_MASK/3) /* ** The carriage-return / line-feed characters in the UTF-16be and UTF-16le ** encodings. */ #define UTF16BE_CR ((WCHAR_T)'\r') #define UTF16BE_LF ((WCHAR_T)'\n') |
Changes to src/diffcmd.c.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 ... 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 ... 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ... 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 ... 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 ... 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 ... 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 ... 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 ... 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
** ** When using an external diff program, zBinGlob contains the GLOB patterns ** for file names to treat as binary. If fIncludeBinary is zero, these files ** will be skipped in addition to files that may contain binary content. */ void diff_file( Blob *pFile1, /* In memory content to compare from */ int isBin1, /* Does the 'from' content appear to be binary */ const char *zFile2, /* On disk content to compare to */ const char *zName, /* Display name of the file */ const char *zDiffCmd, /* Command for comparison */ const char *zBinGlob, /* Treat file names matching this as binary */ int fIncludeBinary, /* Include binary files for external diff */ u64 diffFlags /* Flags to control the diff */ ){ if( zDiffCmd==0 ){ Blob out; /* Diff output text */ Blob file2; /* Content of zFile2 */ const char *zName2; /* Name of zFile2 for display */ /* Read content of zFile2 into memory */ blob_zero(&file2); if( file_wd_size(zFile2)<0 ){ zName2 = NULL_DEVICE; }else{ if( file_wd_islink(zFile2) ){ blob_read_link(&file2, zFile2); }else{ blob_read_from_file(&file2, zFile2); } zName2 = zName; } /* Compute and output the differences */ if( diffFlags & DIFF_BRIEF ){ if( blob_compare(pFile1, &file2) ){ fossil_print("CHANGED %s\n", zName); } }else{ blob_zero(&out); text_diff(pFile1, &file2, &out, diffFlags); if( blob_size(&out) ){ diff_print_filenames(zName, zName2, diffFlags); fossil_print("%s\n", blob_str(&out)); } blob_reset(&out); ................................................................................ }else{ int cnt = 0; Blob nameFile1; /* Name of temporary file to old pFile1 content */ Blob cmd; /* Text of command to run */ if( !fIncludeBinary ){ Blob file2; if( isBin1 ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); return; } if( zBinGlob ){ Glob *pBinary = glob_create(zBinGlob); if( glob_match(pBinary, zName) ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); ................................................................................ if( file_wd_size(zFile2)>=0 ){ if( file_wd_islink(zFile2) ){ blob_read_link(&file2, zFile2); }else{ blob_read_from_file(&file2, zFile2); } } if( looks_like_binary(&file2) ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); blob_reset(&file2); return; } blob_reset(&file2); } ................................................................................ ** When using an external diff program, zBinGlob contains the GLOB patterns ** for file names to treat as binary. If fIncludeBinary is zero, these files ** will be skipped in addition to files that may contain binary content. */ void diff_file_mem( Blob *pFile1, /* In memory content to compare from */ Blob *pFile2, /* In memory content to compare to */ int isBin1, /* Does the 'from' content appear to be binary */ int isBin2, /* Does the 'to' content appear to be binary */ const char *zName, /* Display name of the file */ const char *zDiffCmd, /* Command for comparison */ const char *zBinGlob, /* Treat file names matching this as binary */ int fIncludeBinary, /* Include binary files for external diff */ u64 diffFlags /* Diff flags */ ){ if( diffFlags & DIFF_BRIEF ) return; if( zDiffCmd==0 ){ Blob out; /* Diff output text */ blob_zero(&out); text_diff(pFile1, pFile2, &out, diffFlags); diff_print_filenames(zName, zName, diffFlags); fossil_print("%s\n", blob_str(&out)); /* Release memory resources */ blob_reset(&out); }else{ Blob cmd; char zTemp1[300]; char zTemp2[300]; if( !fIncludeBinary ){ if( isBin1 || isBin2 ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); return; } if( zBinGlob ){ Glob *pBinary = glob_create(zBinGlob); if( glob_match(pBinary, zName) ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); ................................................................................ int fIncludeBinary, /* Include binary files for external diff */ u64 diffFlags, /* Diff control flags */ const char *zFileTreeName ){ Blob fname; Blob content; int isLink; int isBin; file_tree_name(zFileTreeName, &fname, 1); historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, fIncludeBinary ? 0 : &isBin, 0); if( !isLink != !file_wd_islink(zFrom) ){ fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); }else{ diff_file(&content, isBin, zFileTreeName, zFileTreeName, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); } blob_reset(&content); blob_reset(&fname); } /* ................................................................................ }else if( isChnged==3 ){ fossil_print("ADDED_BY_MERGE %s\n", zPathname); srcid = 0; if( !asNewFile ){ showDiff = 0; } } if( showDiff ){ Blob content; int isBin; if( !isLink != !file_wd_islink(zFullName) ){ diff_print_index(zPathname, diffFlags); diff_print_filenames(zPathname, zPathname, diffFlags); fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); continue; } if( srcid>0 ){ content_get(srcid, &content); }else{ blob_zero(&content); } isBin = fIncludeBinary ? 0 : looks_like_binary(&content); diff_print_index(zPathname, diffFlags); diff_file(&content, isBin, zFullName, zPathname, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); blob_reset(&content); } free(zToFree); } db_finalize(&q); db_end_transaction(1); /* ROLLBACK */ ................................................................................ u64 diffFlags, const char *zFileTreeName ){ char *zName; Blob fname; Blob v1, v2; int isLink1, isLink2; int isBin1, isBin2; if( diffFlags & DIFF_BRIEF ) return; file_tree_name(zFileTreeName, &fname, 1); zName = blob_str(&fname); historical_version_of_file(zFrom, zName, &v1, &isLink1, 0, fIncludeBinary ? 0 : &isBin1, 0); historical_version_of_file(zTo, zName, &v2, &isLink2, 0, fIncludeBinary ? 0 : &isBin2, 0); if( isLink1 != isLink2 ){ diff_print_filenames(zName, zName, diffFlags); fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); }else{ diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); } blob_reset(&v1); blob_reset(&v2); blob_reset(&fname); } ................................................................................ struct ManifestFile *pTo, const char *zDiffCmd, const char *zBinGlob, int fIncludeBinary, u64 diffFlags ){ Blob f1, f2; int isBin1, isBin2; int rid; const char *zName = pFrom ? pFrom->zName : pTo->zName; if( diffFlags & DIFF_BRIEF ) return; diff_print_index(zName, diffFlags); if( pFrom ){ rid = uuid_to_rid(pFrom->zUuid, 0); content_get(rid, &f1); ................................................................................ } if( pTo ){ rid = uuid_to_rid(pTo->zUuid, 0); content_get(rid, &f2); }else{ blob_zero(&f2); } isBin1 = fIncludeBinary ? 0 : looks_like_binary(&f1); isBin2 = fIncludeBinary ? 0 : looks_like_binary(&f2); diff_file_mem(&f1, &f2, isBin1, isBin2, zName, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); blob_reset(&f1); blob_reset(&f2); } /* ** Output the differences between two check-ins. ** |
| > > > | > > > > | > | > | < > > | | | | | | > > | | | | > > > | | | | > > > > > > | | > |
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 ... 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 ... 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 ... 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 ... 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 ... 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 ... 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 ... 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 ... 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
** ** When using an external diff program, zBinGlob contains the GLOB patterns ** for file names to treat as binary. If fIncludeBinary is zero, these files ** will be skipped in addition to files that may contain binary content. */ void diff_file( Blob *pFile1, /* In memory content to compare from */ int eType1, /* Does the 'from' content appear to be text */ const char *zFile2, /* On disk content to compare to */ const char *zName, /* Display name of the file */ const char *zDiffCmd, /* Command for comparison */ const char *zBinGlob, /* Treat file names matching this as binary */ int fIncludeBinary, /* Include binary files for external diff */ u64 diffFlags /* Flags to control the diff */ ){ if( zDiffCmd==0 ){ Blob out; /* Diff output text */ Blob file2; /* Content of zFile2 */ const char *zName2; /* Name of zFile2 for display */ int eType2 = 0; /* Read content of zFile2 into memory */ blob_zero(&file2); if( file_wd_size(zFile2)<0 ){ zName2 = NULL_DEVICE; }else{ if( file_wd_islink(zFile2) ){ blob_read_link(&file2, zFile2); }else{ blob_read_from_file(&file2, zFile2); } zName2 = zName; } if( !fIncludeBinary ){ eType2 = looks_like_text(&file2); } /* Compute and output the differences */ if( diffFlags & DIFF_BRIEF ){ if( blob_compare(pFile1, &file2) ){ fossil_print("CHANGED %s\n", zName); } }else if( eType1!=eType2 ){ fossil_print(DIFF_CANNOT_COMPUTE_ENCODING); }else{ blob_strip_bom(pFile1, 2); blob_strip_bom(&file2, 2); blob_zero(&out); text_diff(pFile1, &file2, &out, diffFlags); if( blob_size(&out) ){ diff_print_filenames(zName, zName2, diffFlags); fossil_print("%s\n", blob_str(&out)); } blob_reset(&out); ................................................................................ }else{ int cnt = 0; Blob nameFile1; /* Name of temporary file to old pFile1 content */ Blob cmd; /* Text of command to run */ if( !fIncludeBinary ){ Blob file2; int eType2; if( eType1!=1 ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); return; } if( zBinGlob ){ Glob *pBinary = glob_create(zBinGlob); if( glob_match(pBinary, zName) ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); ................................................................................ if( file_wd_size(zFile2)>=0 ){ if( file_wd_islink(zFile2) ){ blob_read_link(&file2, zFile2); }else{ blob_read_from_file(&file2, zFile2); } } eType2 = looks_like_text(&file2); if( eType2!=1 ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); blob_reset(&file2); return; } blob_reset(&file2); } ................................................................................ ** When using an external diff program, zBinGlob contains the GLOB patterns ** for file names to treat as binary. If fIncludeBinary is zero, these files ** will be skipped in addition to files that may contain binary content. */ void diff_file_mem( Blob *pFile1, /* In memory content to compare from */ Blob *pFile2, /* In memory content to compare to */ int eType, /* Does the content appear to be text */ const char *zName, /* Display name of the file */ const char *zDiffCmd, /* Command for comparison */ const char *zBinGlob, /* Treat file names matching this as binary */ int fIncludeBinary, /* Include binary files for external diff */ u64 diffFlags /* Diff flags */ ){ if( diffFlags & DIFF_BRIEF ) return; if( zDiffCmd==0 ){ Blob out; /* Diff output text */ blob_zero(&out); blob_strip_bom(pFile1, 2); blob_strip_bom(pFile2, 2); text_diff(pFile1, pFile2, &out, diffFlags); diff_print_filenames(zName, zName, diffFlags); fossil_print("%s\n", blob_str(&out)); /* Release memory resources */ blob_reset(&out); }else{ Blob cmd; char zTemp1[300]; char zTemp2[300]; if( !fIncludeBinary ){ if( eType==0 ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); return; } if( zBinGlob ){ Glob *pBinary = glob_create(zBinGlob); if( glob_match(pBinary, zName) ){ fossil_print(DIFF_CANNOT_COMPUTE_BINARY); ................................................................................ int fIncludeBinary, /* Include binary files for external diff */ u64 diffFlags, /* Diff control flags */ const char *zFileTreeName ){ Blob fname; Blob content; int isLink; int eType = 0; file_tree_name(zFileTreeName, &fname, 1); historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, fIncludeBinary ? 0 : &eType, 0); if( !isLink != !file_wd_islink(zFrom) ){ fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); }else{ diff_file(&content, eType, zFileTreeName, zFileTreeName, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); } blob_reset(&content); blob_reset(&fname); } /* ................................................................................ }else if( isChnged==3 ){ fossil_print("ADDED_BY_MERGE %s\n", zPathname); srcid = 0; if( !asNewFile ){ showDiff = 0; } } if( showDiff ){ Blob content; int eType = 0; if( !isLink != !file_wd_islink(zFullName) ){ diff_print_index(zPathname, diffFlags); diff_print_filenames(zPathname, zPathname, diffFlags); fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); continue; } if( srcid>0 ){ content_get(srcid, &content); }else{ blob_zero(&content); } if( !fIncludeBinary ){ eType = looks_like_text(&content); } diff_print_index(zPathname, diffFlags); diff_file(&content, eType, zFullName, zPathname, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); blob_reset(&content); } free(zToFree); } db_finalize(&q); db_end_transaction(1); /* ROLLBACK */ ................................................................................ u64 diffFlags, const char *zFileTreeName ){ char *zName; Blob fname; Blob v1, v2; int isLink1, isLink2; int eType = 0, eType2 = 0; if( diffFlags & DIFF_BRIEF ) return; file_tree_name(zFileTreeName, &fname, 1); zName = blob_str(&fname); historical_version_of_file(zFrom, zName, &v1, &isLink1, 0, fIncludeBinary ? 0 : &eType, 0); historical_version_of_file(zTo, zName, &v2, &isLink2, 0, fIncludeBinary ? 0 : &eType2, 0); if( isLink1 != isLink2 ){ diff_print_filenames(zName, zName, diffFlags); fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK); }else if( eType!=eType2 ){ diff_print_filenames(zName, zName, diffFlags); fossil_print(DIFF_CANNOT_COMPUTE_ENCODING); }else{ diff_file_mem(&v1, &v2, eType, zName, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); } blob_reset(&v1); blob_reset(&v2); blob_reset(&fname); } ................................................................................ struct ManifestFile *pTo, const char *zDiffCmd, const char *zBinGlob, int fIncludeBinary, u64 diffFlags ){ Blob f1, f2; int eType = 0, eType2 = 0; int rid; const char *zName = pFrom ? pFrom->zName : pTo->zName; if( diffFlags & DIFF_BRIEF ) return; diff_print_index(zName, diffFlags); if( pFrom ){ rid = uuid_to_rid(pFrom->zUuid, 0); content_get(rid, &f1); ................................................................................ } if( pTo ){ rid = uuid_to_rid(pTo->zUuid, 0); content_get(rid, &f2); }else{ blob_zero(&f2); } if ( !fIncludeBinary ){ eType = looks_like_text(&f1); eType2 = looks_like_text(&f2); } if( eType!=eType2 ){ diff_print_filenames(zName, zName, diffFlags); fossil_print(DIFF_CANNOT_COMPUTE_ENCODING); }else{ diff_file_mem(&f1, &f2, eType, zName, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); } blob_reset(&f1); blob_reset(&f2); } /* ** Output the differences between two check-ins. ** |
Changes to src/stash.c.
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
|
" FROM stashfile WHERE stashid=%d", stashid ); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); int isRemoved = db_column_int(&q, 1); int isLink = db_column_int(&q, 3); int isBin1, isBin2; const char *zOrig = db_column_text(&q, 4); const char *zNew = db_column_text(&q, 5); char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); Blob delta, a, b, disk; if( rid==0 ){ db_ephemeral_blob(&q, 6, &a); fossil_print("ADDED %s\n", zNew); diff_print_index(zNew, diffFlags); isBin1 = 0; isBin2 = fIncludeBinary ? 0 : looks_like_binary(&a); diff_file_mem(&empty, &a, isBin1, isBin2, zNew, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); }else if( isRemoved ){ fossil_print("DELETE %s\n", zOrig); if( fBaseline==0 ){ if( file_wd_islink(zOPath) ){ blob_read_link(&a, zOPath); }else{ blob_read_from_file(&a, zOPath); } }else{ content_get(rid, &a); } diff_print_index(zNew, diffFlags); isBin1 = fIncludeBinary ? 0 : looks_like_binary(&a); isBin2 = 0; diff_file_mem(&a, &empty, isBin1, isBin2, zOrig, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); }else{ int isOrigLink = file_wd_islink(zOPath); db_ephemeral_blob(&q, 6, &delta); if( fBaseline==0 ){ if( isOrigLink ){ blob_read_link(&disk, zOPath); ................................................................................ diff_print_index(zNew, diffFlags); diff_print_filenames(zOrig, zNew, diffFlags); printf(DIFF_CANNOT_COMPUTE_SYMLINK); }else{ Blob *pBase = fBaseline ? &a : &disk; content_get(rid, &a); blob_delta_apply(&a, &delta, &b); isBin1 = fIncludeBinary ? 0 : looks_like_binary(pBase); isBin2 = fIncludeBinary ? 0 : looks_like_binary(&b); diff_file_mem(fBaseline? &a : &disk, &b, isBin1, isBin2, zNew, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); blob_reset(&a); blob_reset(&b); } if( !fBaseline ) blob_reset(&disk); } blob_reset(&delta); } db_finalize(&q); } /* ** Drop the indicated stash */ static void stash_drop(int stashid){ |
|
|
|
>
|
|
|
>
|
|
|
|
>
>
>
>
>
>
>
|
>
|
|
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
|
" FROM stashfile WHERE stashid=%d", stashid ); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); int isRemoved = db_column_int(&q, 1); int isLink = db_column_int(&q, 3); int eType = 0; const char *zOrig = db_column_text(&q, 4); const char *zNew = db_column_text(&q, 5); char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); Blob delta, a, b, disk; if( rid==0 ){ db_ephemeral_blob(&q, 6, &a); fossil_print("ADDED %s\n", zNew); diff_print_index(zNew, diffFlags); if( !fIncludeBinary ){ eType = looks_like_text(&a); } diff_file_mem(&empty, &a, eType, zNew, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); }else if( isRemoved ){ fossil_print("DELETE %s\n", zOrig); if( fBaseline==0 ){ if( file_wd_islink(zOPath) ){ blob_read_link(&a, zOPath); }else{ blob_read_from_file(&a, zOPath); } }else{ content_get(rid, &a); } diff_print_index(zNew, diffFlags); if( !fIncludeBinary){ eType = looks_like_text(&a); } diff_file_mem(&a, &empty, eType, zOrig, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); }else{ int isOrigLink = file_wd_islink(zOPath); db_ephemeral_blob(&q, 6, &delta); if( fBaseline==0 ){ if( isOrigLink ){ blob_read_link(&disk, zOPath); ................................................................................ diff_print_index(zNew, diffFlags); diff_print_filenames(zOrig, zNew, diffFlags); printf(DIFF_CANNOT_COMPUTE_SYMLINK); }else{ Blob *pBase = fBaseline ? &a : &disk; content_get(rid, &a); blob_delta_apply(&a, &delta, &b); int eType2 = 0; if( !fIncludeBinary ){ eType = looks_like_text(pBase); eType2 = looks_like_text(&b); } if( eType!=eType2 ){ diff_print_filenames(zOrig, zNew, diffFlags); printf(DIFF_CANNOT_COMPUTE_ENCODING); }else{ diff_file_mem(pBase, &b, eType, zNew, zDiffCmd, zBinGlob, fIncludeBinary, diffFlags); } blob_reset(&a); blob_reset(&b); } if( !fBaseline ) blob_reset(&disk); } blob_reset(&delta); } db_finalize(&q); } /* ** Drop the indicated stash */ static void stash_drop(int stashid){ |
Changes to src/update.c.
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
|
*/ int historical_version_of_file( const char *revision, /* The checkin containing the file */ const char *file, /* Full treename of the file */ Blob *content, /* Put the content here */ int *pIsLink, /* Set to true if file is link. */ int *pIsExe, /* Set to true if file is executable */ int *pIsBin, /* Set to true if file is binary */ int errCode /* Error code if file not found. Panic if 0. */ ){ Manifest *pManifest; ManifestFile *pFile; int rid=0; if( revision ){ ................................................................................ if( pFile ){ int rc; rid = uuid_to_rid(pFile->zUuid, 0); if( pIsExe ) *pIsExe = ( manifest_file_mperm(pFile)==PERM_EXE ); if( pIsLink ) *pIsLink = ( manifest_file_mperm(pFile)==PERM_LNK ); manifest_destroy(pManifest); rc = content_get(rid, content); if( rc && pIsBin ){ *pIsBin = looks_like_binary(content); } return rc; } manifest_destroy(pManifest); if( errCode<=0 ){ fossil_fatal("file %s does not exist in checkin: %s", file, revision); } |
|
|
|
|
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
|
*/ int historical_version_of_file( const char *revision, /* The checkin containing the file */ const char *file, /* Full treename of the file */ Blob *content, /* Put the content here */ int *pIsLink, /* Set to true if file is link. */ int *pIsExe, /* Set to true if file is executable */ int *pEType, /* Set to file type, look_like_text()&3 */ int errCode /* Error code if file not found. Panic if 0. */ ){ Manifest *pManifest; ManifestFile *pFile; int rid=0; if( revision ){ ................................................................................ if( pFile ){ int rc; rid = uuid_to_rid(pFile->zUuid, 0); if( pIsExe ) *pIsExe = ( manifest_file_mperm(pFile)==PERM_EXE ); if( pIsLink ) *pIsLink = ( manifest_file_mperm(pFile)==PERM_LNK ); manifest_destroy(pManifest); rc = content_get(rid, content); if( rc && pEType ){ *pEType = looks_like_text(content); } return rc; } manifest_destroy(pManifest); if( errCode<=0 ){ fossil_fatal("file %s does not exist in checkin: %s", file, revision); } |