Fossil SCM

The "fossil diff" command now accepts options --from and --to in order to do a diff between two arbitrary check-ins.

drh 2010-08-07 16:10 trunk
Commit 296b90a25bfbd3fc93bc9e6125284559108a0717
+43 -2
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -271,11 +271,11 @@
271271
blob_reset(&content);
272272
}
273273
free(zFullName);
274274
}
275275
db_finalize(&q);
276
- db_end_transaction(1);
276
+ db_end_transaction(1); /* ROLLBACK */
277277
}
278278
279279
/*
280280
** Output the differences between two versions of a single file.
281281
** zFrom and zTo are the check-ins containing the two file versions.
@@ -305,10 +305,52 @@
305305
static void diff_all_two_versions(
306306
const char *zFrom,
307307
const char *zTo,
308308
const char *zDiffCmd
309309
){
310
+ Manifest mFrom, mTo;
311
+ int iFrom, iTo;
312
+
313
+ manifest_from_name(zFrom, &mFrom);
314
+ manifest_from_name(zTo, &mTo);
315
+ iFrom = iTo = 0;
316
+ while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
317
+ int cmp;
318
+ if( iFrom>=mFrom.nFile ){
319
+ cmp = +1;
320
+ }else if( iTo>=mTo.nFile ){
321
+ cmp = -1;
322
+ }else{
323
+ cmp = strcmp(mFrom.aFile[iFrom].zName, mTo.aFile[iTo].zName);
324
+ }
325
+ if( cmp<0 ){
326
+ printf("DELETED %s\n", mFrom.aFile[iFrom].zName);
327
+ iFrom++;
328
+ }else if( cmp>0 ){
329
+ printf("ADDED %s\n", mTo.aFile[iTo].zName);
330
+ iTo++;
331
+ }else if( strcmp(mFrom.aFile[iFrom].zUuid, mTo.aFile[iTo].zUuid)==0 ){
332
+ /* No changes */
333
+ iFrom++;
334
+ iTo++;
335
+ }else{
336
+ Blob f1, f2;
337
+ int rid;
338
+ printf("CHANGED %s\n", mFrom.aFile[iFrom].zName);
339
+ rid = uuid_to_rid(mFrom.aFile[iFrom].zUuid, 0);
340
+ content_get(rid, &f1);
341
+ rid = uuid_to_rid(mTo.aFile[iTo].zUuid, 0);
342
+ content_get(rid, &f2);
343
+ diff_file_mem(&f1, &f2, mFrom.aFile[iFrom].zName, zDiffCmd);
344
+ blob_reset(&f1);
345
+ blob_reset(&f2);
346
+ iFrom++;
347
+ iTo++;
348
+ }
349
+ }
350
+ manifest_clear(&mFrom);
351
+ manifest_clear(&mTo);
310352
}
311353
312354
/*
313355
** COMMAND: diff
314356
** COMMAND: gdiff
@@ -366,10 +408,9 @@
366408
zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
367409
}
368410
if( g.argc==3 ){
369411
diff_one_two_versions(zFrom, zTo, zDiffCmd);
370412
}else{
371
- fossil_fatal("--to on complete check-ins not yet implemented");
372413
diff_all_two_versions(zFrom, zTo, zDiffCmd);
373414
}
374415
}
375416
}
376417
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -271,11 +271,11 @@
271 blob_reset(&content);
272 }
273 free(zFullName);
274 }
275 db_finalize(&q);
276 db_end_transaction(1);
277 }
278
279 /*
280 ** Output the differences between two versions of a single file.
281 ** zFrom and zTo are the check-ins containing the two file versions.
@@ -305,10 +305,52 @@
305 static void diff_all_two_versions(
306 const char *zFrom,
307 const char *zTo,
308 const char *zDiffCmd
309 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310 }
311
312 /*
313 ** COMMAND: diff
314 ** COMMAND: gdiff
@@ -366,10 +408,9 @@
366 zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
367 }
368 if( g.argc==3 ){
369 diff_one_two_versions(zFrom, zTo, zDiffCmd);
370 }else{
371 fossil_fatal("--to on complete check-ins not yet implemented");
372 diff_all_two_versions(zFrom, zTo, zDiffCmd);
373 }
374 }
375 }
376
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -271,11 +271,11 @@
271 blob_reset(&content);
272 }
273 free(zFullName);
274 }
275 db_finalize(&q);
276 db_end_transaction(1); /* ROLLBACK */
277 }
278
279 /*
280 ** Output the differences between two versions of a single file.
281 ** zFrom and zTo are the check-ins containing the two file versions.
@@ -305,10 +305,52 @@
305 static void diff_all_two_versions(
306 const char *zFrom,
307 const char *zTo,
308 const char *zDiffCmd
309 ){
310 Manifest mFrom, mTo;
311 int iFrom, iTo;
312
313 manifest_from_name(zFrom, &mFrom);
314 manifest_from_name(zTo, &mTo);
315 iFrom = iTo = 0;
316 while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
317 int cmp;
318 if( iFrom>=mFrom.nFile ){
319 cmp = +1;
320 }else if( iTo>=mTo.nFile ){
321 cmp = -1;
322 }else{
323 cmp = strcmp(mFrom.aFile[iFrom].zName, mTo.aFile[iTo].zName);
324 }
325 if( cmp<0 ){
326 printf("DELETED %s\n", mFrom.aFile[iFrom].zName);
327 iFrom++;
328 }else if( cmp>0 ){
329 printf("ADDED %s\n", mTo.aFile[iTo].zName);
330 iTo++;
331 }else if( strcmp(mFrom.aFile[iFrom].zUuid, mTo.aFile[iTo].zUuid)==0 ){
332 /* No changes */
333 iFrom++;
334 iTo++;
335 }else{
336 Blob f1, f2;
337 int rid;
338 printf("CHANGED %s\n", mFrom.aFile[iFrom].zName);
339 rid = uuid_to_rid(mFrom.aFile[iFrom].zUuid, 0);
340 content_get(rid, &f1);
341 rid = uuid_to_rid(mTo.aFile[iTo].zUuid, 0);
342 content_get(rid, &f2);
343 diff_file_mem(&f1, &f2, mFrom.aFile[iFrom].zName, zDiffCmd);
344 blob_reset(&f1);
345 blob_reset(&f2);
346 iFrom++;
347 iTo++;
348 }
349 }
350 manifest_clear(&mFrom);
351 manifest_clear(&mTo);
352 }
353
354 /*
355 ** COMMAND: diff
356 ** COMMAND: gdiff
@@ -366,10 +408,9 @@
408 zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0);
409 }
410 if( g.argc==3 ){
411 diff_one_two_versions(zFrom, zTo, zDiffCmd);
412 }else{
 
413 diff_all_two_versions(zFrom, zTo, zDiffCmd);
414 }
415 }
416 }
417
--- src/manifest.c
+++ src/manifest.c
@@ -1174,5 +1174,26 @@
11741174
}
11751175
db_end_transaction(0);
11761176
manifest_clear(&m);
11771177
return 1;
11781178
}
1179
+
1180
+/*
1181
+** Given a checkin name, load and parse the manifest for that checkin.
1182
+** Throw a fatal error if anything goes wrong.
1183
+*/
1184
+void manifest_from_name(
1185
+ const char *zName,
1186
+ Manifest *pM
1187
+){
1188
+ int rid;
1189
+ Blob content;
1190
+
1191
+ rid = name_to_rid(zName);
1192
+ if( !is_a_version(rid) ){
1193
+ fossil_fatal("no such checkin: %s", zName);
1194
+ }
1195
+ content_get(rid, &content);
1196
+ if( !manifest_parse(pM, &content) ){
1197
+ fossil_fatal("cannot parse manifest for checkin: %s", zName);
1198
+ }
1199
+}
11791200
--- src/manifest.c
+++ src/manifest.c
@@ -1174,5 +1174,26 @@
1174 }
1175 db_end_transaction(0);
1176 manifest_clear(&m);
1177 return 1;
1178 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1179
--- src/manifest.c
+++ src/manifest.c
@@ -1174,5 +1174,26 @@
1174 }
1175 db_end_transaction(0);
1176 manifest_clear(&m);
1177 return 1;
1178 }
1179
1180 /*
1181 ** Given a checkin name, load and parse the manifest for that checkin.
1182 ** Throw a fatal error if anything goes wrong.
1183 */
1184 void manifest_from_name(
1185 const char *zName,
1186 Manifest *pM
1187 ){
1188 int rid;
1189 Blob content;
1190
1191 rid = name_to_rid(zName);
1192 if( !is_a_version(rid) ){
1193 fossil_fatal("no such checkin: %s", zName);
1194 }
1195 content_get(rid, &content);
1196 if( !manifest_parse(pM, &content) ){
1197 fossil_fatal("cannot parse manifest for checkin: %s", zName);
1198 }
1199 }
1200
+8 -5
--- src/update.c
+++ src/update.c
@@ -292,14 +292,15 @@
292292
}
293293
}
294294
295295
296296
/*
297
-** Get the contents of a file within a given revision.
297
+** Get the contents of a file within the checking "revision". If
298
+** revision==NULL then get the file content for the current checkout.
298299
*/
299300
int historical_version_of_file(
300
- const char *revision, /* The baseline name containing the file */
301
+ const char *revision, /* The checkin containing the file */
301302
const char *file, /* Full treename of the file */
302303
Blob *content, /* Put the content here */
303304
int errCode /* Error code if file not found. Panic if 0. */
304305
){
305306
Blob mfile;
@@ -311,26 +312,28 @@
311312
}else{
312313
rid = db_lget_int("checkout", 0);
313314
}
314315
if( !is_a_version(rid) ){
315316
if( errCode>0 ) return errCode;
316
- fossil_fatal("no such check-out: %s", revision);
317
+ fossil_fatal("no such checkin: %s", revision);
317318
}
318319
content_get(rid, &mfile);
319320
320321
if( manifest_parse(&m, &mfile) ){
321322
for(i=0; i<m.nFile; i++){
322323
if( strcmp(m.aFile[i].zName, file)==0 ){
323324
rid = uuid_to_rid(m.aFile[i].zUuid, 0);
325
+ manifest_clear(&m);
324326
return content_get(rid, content);
325327
}
326328
}
329
+ manifest_clear(&m);
327330
if( errCode<=0 ){
328
- fossil_fatal("file %s does not exist in baseline: %s", file, revision);
331
+ fossil_fatal("file %s does not exist in checkin: %s", file, revision);
329332
}
330333
}else if( errCode<=0 ){
331
- fossil_panic("could not parse manifest for baseline: %s", revision);
334
+ fossil_panic("could not parse manifest for checkin: %s", revision);
332335
}
333336
return errCode;
334337
}
335338
336339
337340
--- src/update.c
+++ src/update.c
@@ -292,14 +292,15 @@
292 }
293 }
294
295
296 /*
297 ** Get the contents of a file within a given revision.
 
298 */
299 int historical_version_of_file(
300 const char *revision, /* The baseline name containing the file */
301 const char *file, /* Full treename of the file */
302 Blob *content, /* Put the content here */
303 int errCode /* Error code if file not found. Panic if 0. */
304 ){
305 Blob mfile;
@@ -311,26 +312,28 @@
311 }else{
312 rid = db_lget_int("checkout", 0);
313 }
314 if( !is_a_version(rid) ){
315 if( errCode>0 ) return errCode;
316 fossil_fatal("no such check-out: %s", revision);
317 }
318 content_get(rid, &mfile);
319
320 if( manifest_parse(&m, &mfile) ){
321 for(i=0; i<m.nFile; i++){
322 if( strcmp(m.aFile[i].zName, file)==0 ){
323 rid = uuid_to_rid(m.aFile[i].zUuid, 0);
 
324 return content_get(rid, content);
325 }
326 }
 
327 if( errCode<=0 ){
328 fossil_fatal("file %s does not exist in baseline: %s", file, revision);
329 }
330 }else if( errCode<=0 ){
331 fossil_panic("could not parse manifest for baseline: %s", revision);
332 }
333 return errCode;
334 }
335
336
337
--- src/update.c
+++ src/update.c
@@ -292,14 +292,15 @@
292 }
293 }
294
295
296 /*
297 ** Get the contents of a file within the checking "revision". If
298 ** revision==NULL then get the file content for the current checkout.
299 */
300 int historical_version_of_file(
301 const char *revision, /* The checkin containing the file */
302 const char *file, /* Full treename of the file */
303 Blob *content, /* Put the content here */
304 int errCode /* Error code if file not found. Panic if 0. */
305 ){
306 Blob mfile;
@@ -311,26 +312,28 @@
312 }else{
313 rid = db_lget_int("checkout", 0);
314 }
315 if( !is_a_version(rid) ){
316 if( errCode>0 ) return errCode;
317 fossil_fatal("no such checkin: %s", revision);
318 }
319 content_get(rid, &mfile);
320
321 if( manifest_parse(&m, &mfile) ){
322 for(i=0; i<m.nFile; i++){
323 if( strcmp(m.aFile[i].zName, file)==0 ){
324 rid = uuid_to_rid(m.aFile[i].zUuid, 0);
325 manifest_clear(&m);
326 return content_get(rid, content);
327 }
328 }
329 manifest_clear(&m);
330 if( errCode<=0 ){
331 fossil_fatal("file %s does not exist in checkin: %s", file, revision);
332 }
333 }else if( errCode<=0 ){
334 fossil_panic("could not parse manifest for checkin: %s", revision);
335 }
336 return errCode;
337 }
338
339
340

Keyboard Shortcuts

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