Fossil SCM

Modify the check-in command to detect clock skew and abort if found.

drh 2010-02-09 11:57 trunk
Commit 8fdac87b688c3ea0cecc970364632b8ba254004b
1 file changed +25
--- src/checkin.c
+++ src/checkin.c
@@ -432,10 +432,32 @@
432432
@ WHERE tagid=%d AND rid=plink.cid), 'trunk')
433433
;
434434
rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
435435
return rc==0;
436436
}
437
+
438
+/*
439
+** Make sure the current check-in with timestamp zDate is younger than its
440
+** ancestor identified rid and zUuid. Throw a fatal error if not.
441
+*/
442
+static void checkin_verify_younger(
443
+ int rid, /* The record ID of the ancestor */
444
+ const char *zUuid, /* The artifact ID of the ancestor */
445
+ const char *zDate /* Date & time of the current check-in */
446
+){
447
+ int b;
448
+ b = db_exists(
449
+ "SELECT 1 FROM event"
450
+ " WHERE datetime(mtime)>=%Q"
451
+ " AND type='ci' AND objid=%d",
452
+ zDate, rid
453
+ );
454
+ if( b ){
455
+ fossil_fatal("ancestor check-in [%.10s] (%s) is younger (clock skew?)",
456
+ zUuid, zDate);
457
+ }
458
+}
437459
438460
/*
439461
** COMMAND: ci
440462
** COMMAND: commit
441463
**
@@ -661,10 +683,11 @@
661683
}
662684
blob_appendf(&manifest, "C %F\n", blob_str(&comment));
663685
zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
664686
zDate[10] = 'T';
665687
blob_appendf(&manifest, "D %s\n", zDate);
688
+ zDate[10] = ' ';
666689
db_prepare(&q,
667690
"SELECT pathname, uuid, origname, blob.rid"
668691
" FROM vfile JOIN blob ON vfile.mrid=blob.rid"
669692
" WHERE NOT deleted AND vfile.vid=%d"
670693
" ORDER BY 1", vid);
@@ -694,19 +717,21 @@
694717
}
695718
blob_reset(&filename);
696719
db_finalize(&q);
697720
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
698721
blob_appendf(&manifest, "P %s", zUuid);
722
+ checkin_verify_younger(vid, zUuid, zDate);
699723
700724
db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
701725
db_bind_int(&q2, ":id", 0);
702726
while( db_step(&q2)==SQLITE_ROW ){
703727
int mid = db_column_int(&q2, 0);
704728
if( !g.markPrivate && content_is_private(mid) ) continue;
705729
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
706730
if( zUuid ){
707731
blob_appendf(&manifest, " %s", zUuid);
732
+ checkin_verify_younger(mid, zUuid, zDate);
708733
free(zUuid);
709734
}
710735
}
711736
db_reset(&q2);
712737
713738
--- src/checkin.c
+++ src/checkin.c
@@ -432,10 +432,32 @@
432 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
433 ;
434 rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
435 return rc==0;
436 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
438 /*
439 ** COMMAND: ci
440 ** COMMAND: commit
441 **
@@ -661,10 +683,11 @@
661 }
662 blob_appendf(&manifest, "C %F\n", blob_str(&comment));
663 zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
664 zDate[10] = 'T';
665 blob_appendf(&manifest, "D %s\n", zDate);
 
666 db_prepare(&q,
667 "SELECT pathname, uuid, origname, blob.rid"
668 " FROM vfile JOIN blob ON vfile.mrid=blob.rid"
669 " WHERE NOT deleted AND vfile.vid=%d"
670 " ORDER BY 1", vid);
@@ -694,19 +717,21 @@
694 }
695 blob_reset(&filename);
696 db_finalize(&q);
697 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
698 blob_appendf(&manifest, "P %s", zUuid);
 
699
700 db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
701 db_bind_int(&q2, ":id", 0);
702 while( db_step(&q2)==SQLITE_ROW ){
703 int mid = db_column_int(&q2, 0);
704 if( !g.markPrivate && content_is_private(mid) ) continue;
705 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
706 if( zUuid ){
707 blob_appendf(&manifest, " %s", zUuid);
 
708 free(zUuid);
709 }
710 }
711 db_reset(&q2);
712
713
--- src/checkin.c
+++ src/checkin.c
@@ -432,10 +432,32 @@
432 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
433 ;
434 rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
435 return rc==0;
436 }
437
438 /*
439 ** Make sure the current check-in with timestamp zDate is younger than its
440 ** ancestor identified rid and zUuid. Throw a fatal error if not.
441 */
442 static void checkin_verify_younger(
443 int rid, /* The record ID of the ancestor */
444 const char *zUuid, /* The artifact ID of the ancestor */
445 const char *zDate /* Date & time of the current check-in */
446 ){
447 int b;
448 b = db_exists(
449 "SELECT 1 FROM event"
450 " WHERE datetime(mtime)>=%Q"
451 " AND type='ci' AND objid=%d",
452 zDate, rid
453 );
454 if( b ){
455 fossil_fatal("ancestor check-in [%.10s] (%s) is younger (clock skew?)",
456 zUuid, zDate);
457 }
458 }
459
460 /*
461 ** COMMAND: ci
462 ** COMMAND: commit
463 **
@@ -661,10 +683,11 @@
683 }
684 blob_appendf(&manifest, "C %F\n", blob_str(&comment));
685 zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
686 zDate[10] = 'T';
687 blob_appendf(&manifest, "D %s\n", zDate);
688 zDate[10] = ' ';
689 db_prepare(&q,
690 "SELECT pathname, uuid, origname, blob.rid"
691 " FROM vfile JOIN blob ON vfile.mrid=blob.rid"
692 " WHERE NOT deleted AND vfile.vid=%d"
693 " ORDER BY 1", vid);
@@ -694,19 +717,21 @@
717 }
718 blob_reset(&filename);
719 db_finalize(&q);
720 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
721 blob_appendf(&manifest, "P %s", zUuid);
722 checkin_verify_younger(vid, zUuid, zDate);
723
724 db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
725 db_bind_int(&q2, ":id", 0);
726 while( db_step(&q2)==SQLITE_ROW ){
727 int mid = db_column_int(&q2, 0);
728 if( !g.markPrivate && content_is_private(mid) ) continue;
729 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
730 if( zUuid ){
731 blob_appendf(&manifest, " %s", zUuid);
732 checkin_verify_younger(mid, zUuid, zDate);
733 free(zUuid);
734 }
735 }
736 db_reset(&q2);
737
738

Keyboard Shortcuts

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