Fossil SCM
Add the ability to diff to arbitrary versions of a single file.
Commit
fe8bb01d38d17c447c3ebc82ac9ae43e7c9e5446
Parent
149945beea2774a…
1 file changed
+85
-3
+85
-3
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -128,10 +128,63 @@ | ||
| 128 | 128 | unlink(blob_str(&nameFile1)); |
| 129 | 129 | blob_reset(&nameFile1); |
| 130 | 130 | blob_reset(&cmd); |
| 131 | 131 | } |
| 132 | 132 | } |
| 133 | + | |
| 134 | +/* | |
| 135 | +** Show the difference between two files, both in memory. | |
| 136 | +** | |
| 137 | +** The difference is the set of edits needed to transform pFile1 into | |
| 138 | +** pFile2. | |
| 139 | +** | |
| 140 | +** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the | |
| 141 | +** command zDiffCmd to do the diffing. | |
| 142 | +*/ | |
| 143 | +static void diff_file_mem( | |
| 144 | + Blob *pFile1, /* In memory content to compare from */ | |
| 145 | + Blob *pFile2, /* In memory content to compare to */ | |
| 146 | + const char *zName, /* Display name of the file */ | |
| 147 | + const char *zDiffCmd /* Command for comparison */ | |
| 148 | +){ | |
| 149 | + if( zDiffCmd==0 ){ | |
| 150 | + Blob out; /* Diff output text */ | |
| 151 | + | |
| 152 | + blob_zero(&out); | |
| 153 | + text_diff(pFile1, pFile2, &out, 5); | |
| 154 | + printf("--- %s\n+++ %s\n", zName, zName); | |
| 155 | + printf("%s\n", blob_str(&out)); | |
| 156 | + | |
| 157 | + /* Release memory resources */ | |
| 158 | + blob_reset(&out); | |
| 159 | + }else{ | |
| 160 | + Blob cmd; | |
| 161 | + char zTemp1[300]; | |
| 162 | + char zTemp2[300]; | |
| 163 | + | |
| 164 | + /* Construct a temporary file names */ | |
| 165 | + file_tempname(sizeof(zTemp1), zTemp1); | |
| 166 | + file_tempname(sizeof(zTemp2), zTemp2); | |
| 167 | + blob_write_to_file(pFile1, zTemp1); | |
| 168 | + blob_write_to_file(pFile2, zTemp2); | |
| 169 | + | |
| 170 | + /* Construct the external diff command */ | |
| 171 | + blob_zero(&cmd); | |
| 172 | + blob_appendf(&cmd, "%s ", zDiffCmd); | |
| 173 | + shell_escape(&cmd, zTemp1); | |
| 174 | + blob_append(&cmd, " ", 1); | |
| 175 | + shell_escape(&cmd, zTemp2); | |
| 176 | + | |
| 177 | + /* Run the external diff command */ | |
| 178 | + portable_system(blob_str(&cmd)); | |
| 179 | + | |
| 180 | + /* Delete the temporary file and clean up memory used */ | |
| 181 | + unlink(zTemp1); | |
| 182 | + unlink(zTemp2); | |
| 183 | + blob_reset(&cmd); | |
| 184 | + } | |
| 185 | +} | |
| 133 | 186 | |
| 134 | 187 | /* |
| 135 | 188 | ** Do a diff against a single file named in g.argv[2] from version zFrom |
| 136 | 189 | ** against the same file on disk. |
| 137 | 190 | */ |
| @@ -227,11 +280,42 @@ | ||
| 227 | 280 | } |
| 228 | 281 | db_finalize(&q); |
| 229 | 282 | db_end_transaction(1); |
| 230 | 283 | } |
| 231 | 284 | |
| 285 | +/* | |
| 286 | +** Output the differences between two versions of a single file. | |
| 287 | +** zFrom and zTo are the check-ins containing the two file versions. | |
| 288 | +** The filename is contained in g.argv[2]. | |
| 289 | +*/ | |
| 290 | +static void diff_one_two_versions( | |
| 291 | + const char *zFrom, | |
| 292 | + const char *zTo, | |
| 293 | + const char *zDiffCmd | |
| 294 | +){ | |
| 295 | + char *zName; | |
| 296 | + Blob fname; | |
| 297 | + Blob v1, v2; | |
| 298 | + file_tree_name(g.argv[2], &fname, 1); | |
| 299 | + zName = blob_str(&fname); | |
| 300 | + historical_version_of_file(zFrom, zName, &v1); | |
| 301 | + historical_version_of_file(zTo, zName, &v2); | |
| 302 | + diff_file_mem(&v1, &v2, zName, zDiffCmd); | |
| 303 | + blob_reset(&v1); | |
| 304 | + blob_reset(&v2); | |
| 305 | + blob_reset(&fname); | |
| 306 | +} | |
| 232 | 307 | |
| 308 | +/* | |
| 309 | +** Output the differences between two check-ins. | |
| 310 | +*/ | |
| 311 | +static void diff_all_two_versions( | |
| 312 | + const char *zFrom, | |
| 313 | + const char *zTo, | |
| 314 | + const char *zDiffCmd | |
| 315 | +){ | |
| 316 | +} | |
| 233 | 317 | |
| 234 | 318 | /* |
| 235 | 319 | ** COMMAND: diff |
| 236 | 320 | ** COMMAND: gdiff |
| 237 | 321 | ** |
| @@ -285,15 +369,13 @@ | ||
| 285 | 369 | db_find_and_open_repository(1); |
| 286 | 370 | verify_all_options(); |
| 287 | 371 | if( !isInternDiff && g.argc==3 ){ |
| 288 | 372 | zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0); |
| 289 | 373 | } |
| 290 | - fossil_fatal("--to not yet implemented"); | |
| 291 | -#if 0 | |
| 292 | 374 | if( g.argc==3 ){ |
| 293 | 375 | diff_one_two_versions(zFrom, zTo, zDiffCmd); |
| 294 | 376 | }else{ |
| 377 | + fossil_fatal("--to on complete check-ins not yet implemented"); | |
| 295 | 378 | diff_all_two_versions(zFrom, zTo, zDiffCmd); |
| 296 | 379 | } |
| 297 | -#endif | |
| 298 | 380 | } |
| 299 | 381 | } |
| 300 | 382 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -128,10 +128,63 @@ | |
| 128 | unlink(blob_str(&nameFile1)); |
| 129 | blob_reset(&nameFile1); |
| 130 | blob_reset(&cmd); |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | /* |
| 135 | ** Do a diff against a single file named in g.argv[2] from version zFrom |
| 136 | ** against the same file on disk. |
| 137 | */ |
| @@ -227,11 +280,42 @@ | |
| 227 | } |
| 228 | db_finalize(&q); |
| 229 | db_end_transaction(1); |
| 230 | } |
| 231 | |
| 232 | |
| 233 | |
| 234 | /* |
| 235 | ** COMMAND: diff |
| 236 | ** COMMAND: gdiff |
| 237 | ** |
| @@ -285,15 +369,13 @@ | |
| 285 | db_find_and_open_repository(1); |
| 286 | verify_all_options(); |
| 287 | if( !isInternDiff && g.argc==3 ){ |
| 288 | zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0); |
| 289 | } |
| 290 | fossil_fatal("--to not yet implemented"); |
| 291 | #if 0 |
| 292 | if( g.argc==3 ){ |
| 293 | diff_one_two_versions(zFrom, zTo, zDiffCmd); |
| 294 | }else{ |
| 295 | diff_all_two_versions(zFrom, zTo, zDiffCmd); |
| 296 | } |
| 297 | #endif |
| 298 | } |
| 299 | } |
| 300 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -128,10 +128,63 @@ | |
| 128 | unlink(blob_str(&nameFile1)); |
| 129 | blob_reset(&nameFile1); |
| 130 | blob_reset(&cmd); |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | /* |
| 135 | ** Show the difference between two files, both in memory. |
| 136 | ** |
| 137 | ** The difference is the set of edits needed to transform pFile1 into |
| 138 | ** pFile2. |
| 139 | ** |
| 140 | ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the |
| 141 | ** command zDiffCmd to do the diffing. |
| 142 | */ |
| 143 | static void diff_file_mem( |
| 144 | Blob *pFile1, /* In memory content to compare from */ |
| 145 | Blob *pFile2, /* In memory content to compare to */ |
| 146 | const char *zName, /* Display name of the file */ |
| 147 | const char *zDiffCmd /* Command for comparison */ |
| 148 | ){ |
| 149 | if( zDiffCmd==0 ){ |
| 150 | Blob out; /* Diff output text */ |
| 151 | |
| 152 | blob_zero(&out); |
| 153 | text_diff(pFile1, pFile2, &out, 5); |
| 154 | printf("--- %s\n+++ %s\n", zName, zName); |
| 155 | printf("%s\n", blob_str(&out)); |
| 156 | |
| 157 | /* Release memory resources */ |
| 158 | blob_reset(&out); |
| 159 | }else{ |
| 160 | Blob cmd; |
| 161 | char zTemp1[300]; |
| 162 | char zTemp2[300]; |
| 163 | |
| 164 | /* Construct a temporary file names */ |
| 165 | file_tempname(sizeof(zTemp1), zTemp1); |
| 166 | file_tempname(sizeof(zTemp2), zTemp2); |
| 167 | blob_write_to_file(pFile1, zTemp1); |
| 168 | blob_write_to_file(pFile2, zTemp2); |
| 169 | |
| 170 | /* Construct the external diff command */ |
| 171 | blob_zero(&cmd); |
| 172 | blob_appendf(&cmd, "%s ", zDiffCmd); |
| 173 | shell_escape(&cmd, zTemp1); |
| 174 | blob_append(&cmd, " ", 1); |
| 175 | shell_escape(&cmd, zTemp2); |
| 176 | |
| 177 | /* Run the external diff command */ |
| 178 | portable_system(blob_str(&cmd)); |
| 179 | |
| 180 | /* Delete the temporary file and clean up memory used */ |
| 181 | unlink(zTemp1); |
| 182 | unlink(zTemp2); |
| 183 | blob_reset(&cmd); |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /* |
| 188 | ** Do a diff against a single file named in g.argv[2] from version zFrom |
| 189 | ** against the same file on disk. |
| 190 | */ |
| @@ -227,11 +280,42 @@ | |
| 280 | } |
| 281 | db_finalize(&q); |
| 282 | db_end_transaction(1); |
| 283 | } |
| 284 | |
| 285 | /* |
| 286 | ** Output the differences between two versions of a single file. |
| 287 | ** zFrom and zTo are the check-ins containing the two file versions. |
| 288 | ** The filename is contained in g.argv[2]. |
| 289 | */ |
| 290 | static void diff_one_two_versions( |
| 291 | const char *zFrom, |
| 292 | const char *zTo, |
| 293 | const char *zDiffCmd |
| 294 | ){ |
| 295 | char *zName; |
| 296 | Blob fname; |
| 297 | Blob v1, v2; |
| 298 | file_tree_name(g.argv[2], &fname, 1); |
| 299 | zName = blob_str(&fname); |
| 300 | historical_version_of_file(zFrom, zName, &v1); |
| 301 | historical_version_of_file(zTo, zName, &v2); |
| 302 | diff_file_mem(&v1, &v2, zName, zDiffCmd); |
| 303 | blob_reset(&v1); |
| 304 | blob_reset(&v2); |
| 305 | blob_reset(&fname); |
| 306 | } |
| 307 | |
| 308 | /* |
| 309 | ** Output the differences between two check-ins. |
| 310 | */ |
| 311 | static void diff_all_two_versions( |
| 312 | const char *zFrom, |
| 313 | const char *zTo, |
| 314 | const char *zDiffCmd |
| 315 | ){ |
| 316 | } |
| 317 | |
| 318 | /* |
| 319 | ** COMMAND: diff |
| 320 | ** COMMAND: gdiff |
| 321 | ** |
| @@ -285,15 +369,13 @@ | |
| 369 | db_find_and_open_repository(1); |
| 370 | verify_all_options(); |
| 371 | if( !isInternDiff && g.argc==3 ){ |
| 372 | zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0); |
| 373 | } |
| 374 | if( g.argc==3 ){ |
| 375 | diff_one_two_versions(zFrom, zTo, zDiffCmd); |
| 376 | }else{ |
| 377 | fossil_fatal("--to on complete check-ins not yet implemented"); |
| 378 | diff_all_two_versions(zFrom, zTo, zDiffCmd); |
| 379 | } |
| 380 | } |
| 381 | } |
| 382 |