Fossil SCM

Prevent check-ins against a closed leaf. Add the --branch and --bgcolor options to the "ci" and "commit" commands.

drh 2009-01-24 15:47 trunk
Commit 4ac75b9107e129c7393f8c8608d9abb58f903d5c
1 file changed +64 -9
+64 -9
--- src/checkin.c
+++ src/checkin.c
@@ -367,23 +367,40 @@
367367
368368
/*
369369
** COMMAND: ci
370370
** COMMAND: commit
371371
**
372
-** Usage: %fossil commit ?-m COMMENT? ?--nosign? ?FILE...?
372
+** Usage: %fossil commit ?OPTIONS? ?FILE...?
373373
**
374374
** Create a new version containing all of the changes in the current
375375
** checkout. You will be prompted to enter a check-in comment unless
376376
** the "-m" option is used to specify a comment line. You will be
377377
** prompted for your GPG passphrase in order to sign the new manifest
378378
** unless the "--nosign" options is used. All files that have
379379
** changed will be committed unless some subset of files is specified
380380
** on the command line.
381
+**
382
+** The --branch option followed by a branch name cases the new check-in
383
+** to be placed in the named branch. The --bgcolor option can be followed
384
+** by a color name (ex: '#ffc0c0') to specify the background color of
385
+** entries in the new branch when shown in the web timeline interface.
386
+**
387
+** A check-in is not permitted to fork unless the --force or -f
388
+** option appears. A check-in is not allowed against a closed check-in.
389
+**
390
+** Options:
391
+**
392
+** --comment|-m COMMENT-TEXT
393
+** --branch NEW-BRANCH-NAME
394
+** --bgcolor COLOR
395
+** --nosign
396
+** --force|-f
397
+**
381398
*/
382399
void commit_cmd(void){
383400
int rc;
384
- int vid, nrid, nvid, wouldFork=0;
401
+ int vid, nrid, nvid;
385402
Blob comment;
386403
const char *zComment;
387404
Stmt q;
388405
Stmt q2;
389406
char *zUuid, *zDate;
@@ -390,31 +407,35 @@
390407
int noSign = 0; /* True to omit signing the manifest using GPG */
391408
int isAMerge = 0; /* True if checking in a merge */
392409
int forceFlag = 0; /* Force a fork */
393410
char *zManifestFile; /* Name of the manifest file */
394411
int nBasename; /* Length of "g.zLocalRoot/" */
412
+ const char *zBranch; /* Create a new branch with this name */
413
+ const char *zBgColor; /* Set background color when branching */
395414
Blob filename; /* complete filename */
396415
Blob manifest;
397416
Blob muuid; /* Manifest uuid */
398417
Blob mcksum; /* Self-checksum on the manifest */
399418
Blob cksum1, cksum2; /* Before and after commit checksums */
400419
Blob cksum1b; /* Checksum recorded in the manifest */
401420
402421
url_proxy_options();
403
- noSign = find_option("nosign","",0)!=0;
422
+ noSign = find_option("nosign",0,0)!=0;
404423
zComment = find_option("comment","m",1);
405424
forceFlag = find_option("force", "f", 0)!=0;
425
+ zBranch = find_option("branch","b",1);
426
+ zBgColor = find_option("bgcolor",0,1);
406427
db_must_be_within_tree();
407428
noSign = db_get_boolean("omitsign", 0)|noSign;
408429
if( db_get_boolean("clearsign", 1)==0 ){ noSign = 1; }
409430
verify_all_options();
410431
411432
/*
412433
** Autosync if requested.
413434
*/
414435
autosync(AUTOSYNC_PULL);
415
-
436
+
416437
/* There are two ways this command may be executed. If there are
417438
** no arguments following the word "commit", then all modified files
418439
** in the checked out directory are committed. If one or more arguments
419440
** follows "commit", then only those files are committed.
420441
**
@@ -458,16 +479,28 @@
458479
fossil_panic("file %s has not changed", blob_str(&unmodified));
459480
}
460481
}
461482
462483
vid = db_lget_int("checkout", 0);
463
- if( !is_a_leaf(vid) ){
464
- wouldFork=1;
465
- if( forceFlag==0 ){
466
- fossil_fatal("would fork. \"update\" first or use -f or --force.");
467
- }
484
+
485
+ /*
486
+ ** Do not allow a commit that will cause a fork unless the --force flag
487
+ ** is used.
488
+ */
489
+ if( zBranch==0 && forceFlag==0 && !is_a_leaf(vid) ){
490
+ fossil_fatal("would fork. \"update\" first or use -f or --force.");
491
+ }
492
+
493
+ /*
494
+ ** Do not allow a commit against a closed leaf
495
+ */
496
+ if( db_exists("SELECT 1 FROM tagxref"
497
+ " WHERE tagid=%d AND rid=%d AND tagtype>0",
498
+ TAG_CLOSED, vid) ){
499
+ fossil_fatal("cannot commit against a closed leaf");
468500
}
501
+
469502
vfile_aggregate_checksum_disk(vid, &cksum1);
470503
if( zComment ){
471504
blob_zero(&comment);
472505
blob_append(&comment, zComment, -1);
473506
}else{
@@ -565,10 +598,32 @@
565598
}
566599
db_reset(&q2);
567600
568601
blob_appendf(&manifest, "\n");
569602
blob_appendf(&manifest, "R %b\n", &cksum1);
603
+ if( zBranch && zBranch[0] ){
604
+ Stmt q;
605
+ if( zBgColor && zBgColor[0] ){
606
+ blob_appendf(&manifest, "T *bgcolor * %F\n", zBgColor);
607
+ }
608
+ blob_appendf(&manifest, "T *branch * %F\n", zBranch);
609
+ blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
610
+
611
+ /* Cancel all other symbolic tags */
612
+ db_prepare(&q,
613
+ "SELECT tagname FROM tagxref, tag"
614
+ " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
615
+ " AND tagtype>0 AND tagname GLOB 'sym-*'"
616
+ " AND tagname!='sym-'||%Q"
617
+ " ORDER BY tagname",
618
+ vid, zBranch);
619
+ while( db_step(&q)==SQLITE_ROW ){
620
+ const char *zTag = db_column_text(&q, 0);
621
+ blob_appendf(&manifest, "T -%s *\n", zTag);
622
+ }
623
+ db_finalize(&q);
624
+ }
570625
blob_appendf(&manifest, "U %F\n", g.zLogin);
571626
md5sum_blob(&manifest, &mcksum);
572627
blob_appendf(&manifest, "Z %b\n", &mcksum);
573628
zManifestFile = mprintf("%smanifest", g.zLocalRoot);
574629
if( !noSign && clearsign(&manifest, &manifest) ){
575630
--- src/checkin.c
+++ src/checkin.c
@@ -367,23 +367,40 @@
367
368 /*
369 ** COMMAND: ci
370 ** COMMAND: commit
371 **
372 ** Usage: %fossil commit ?-m COMMENT? ?--nosign? ?FILE...?
373 **
374 ** Create a new version containing all of the changes in the current
375 ** checkout. You will be prompted to enter a check-in comment unless
376 ** the "-m" option is used to specify a comment line. You will be
377 ** prompted for your GPG passphrase in order to sign the new manifest
378 ** unless the "--nosign" options is used. All files that have
379 ** changed will be committed unless some subset of files is specified
380 ** on the command line.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381 */
382 void commit_cmd(void){
383 int rc;
384 int vid, nrid, nvid, wouldFork=0;
385 Blob comment;
386 const char *zComment;
387 Stmt q;
388 Stmt q2;
389 char *zUuid, *zDate;
@@ -390,31 +407,35 @@
390 int noSign = 0; /* True to omit signing the manifest using GPG */
391 int isAMerge = 0; /* True if checking in a merge */
392 int forceFlag = 0; /* Force a fork */
393 char *zManifestFile; /* Name of the manifest file */
394 int nBasename; /* Length of "g.zLocalRoot/" */
 
 
395 Blob filename; /* complete filename */
396 Blob manifest;
397 Blob muuid; /* Manifest uuid */
398 Blob mcksum; /* Self-checksum on the manifest */
399 Blob cksum1, cksum2; /* Before and after commit checksums */
400 Blob cksum1b; /* Checksum recorded in the manifest */
401
402 url_proxy_options();
403 noSign = find_option("nosign","",0)!=0;
404 zComment = find_option("comment","m",1);
405 forceFlag = find_option("force", "f", 0)!=0;
 
 
406 db_must_be_within_tree();
407 noSign = db_get_boolean("omitsign", 0)|noSign;
408 if( db_get_boolean("clearsign", 1)==0 ){ noSign = 1; }
409 verify_all_options();
410
411 /*
412 ** Autosync if requested.
413 */
414 autosync(AUTOSYNC_PULL);
415
416 /* There are two ways this command may be executed. If there are
417 ** no arguments following the word "commit", then all modified files
418 ** in the checked out directory are committed. If one or more arguments
419 ** follows "commit", then only those files are committed.
420 **
@@ -458,16 +479,28 @@
458 fossil_panic("file %s has not changed", blob_str(&unmodified));
459 }
460 }
461
462 vid = db_lget_int("checkout", 0);
463 if( !is_a_leaf(vid) ){
464 wouldFork=1;
465 if( forceFlag==0 ){
466 fossil_fatal("would fork. \"update\" first or use -f or --force.");
467 }
 
 
 
 
 
 
 
 
 
 
 
468 }
 
469 vfile_aggregate_checksum_disk(vid, &cksum1);
470 if( zComment ){
471 blob_zero(&comment);
472 blob_append(&comment, zComment, -1);
473 }else{
@@ -565,10 +598,32 @@
565 }
566 db_reset(&q2);
567
568 blob_appendf(&manifest, "\n");
569 blob_appendf(&manifest, "R %b\n", &cksum1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570 blob_appendf(&manifest, "U %F\n", g.zLogin);
571 md5sum_blob(&manifest, &mcksum);
572 blob_appendf(&manifest, "Z %b\n", &mcksum);
573 zManifestFile = mprintf("%smanifest", g.zLocalRoot);
574 if( !noSign && clearsign(&manifest, &manifest) ){
575
--- src/checkin.c
+++ src/checkin.c
@@ -367,23 +367,40 @@
367
368 /*
369 ** COMMAND: ci
370 ** COMMAND: commit
371 **
372 ** Usage: %fossil commit ?OPTIONS? ?FILE...?
373 **
374 ** Create a new version containing all of the changes in the current
375 ** checkout. You will be prompted to enter a check-in comment unless
376 ** the "-m" option is used to specify a comment line. You will be
377 ** prompted for your GPG passphrase in order to sign the new manifest
378 ** unless the "--nosign" options is used. All files that have
379 ** changed will be committed unless some subset of files is specified
380 ** on the command line.
381 **
382 ** The --branch option followed by a branch name cases the new check-in
383 ** to be placed in the named branch. The --bgcolor option can be followed
384 ** by a color name (ex: '#ffc0c0') to specify the background color of
385 ** entries in the new branch when shown in the web timeline interface.
386 **
387 ** A check-in is not permitted to fork unless the --force or -f
388 ** option appears. A check-in is not allowed against a closed check-in.
389 **
390 ** Options:
391 **
392 ** --comment|-m COMMENT-TEXT
393 ** --branch NEW-BRANCH-NAME
394 ** --bgcolor COLOR
395 ** --nosign
396 ** --force|-f
397 **
398 */
399 void commit_cmd(void){
400 int rc;
401 int vid, nrid, nvid;
402 Blob comment;
403 const char *zComment;
404 Stmt q;
405 Stmt q2;
406 char *zUuid, *zDate;
@@ -390,31 +407,35 @@
407 int noSign = 0; /* True to omit signing the manifest using GPG */
408 int isAMerge = 0; /* True if checking in a merge */
409 int forceFlag = 0; /* Force a fork */
410 char *zManifestFile; /* Name of the manifest file */
411 int nBasename; /* Length of "g.zLocalRoot/" */
412 const char *zBranch; /* Create a new branch with this name */
413 const char *zBgColor; /* Set background color when branching */
414 Blob filename; /* complete filename */
415 Blob manifest;
416 Blob muuid; /* Manifest uuid */
417 Blob mcksum; /* Self-checksum on the manifest */
418 Blob cksum1, cksum2; /* Before and after commit checksums */
419 Blob cksum1b; /* Checksum recorded in the manifest */
420
421 url_proxy_options();
422 noSign = find_option("nosign",0,0)!=0;
423 zComment = find_option("comment","m",1);
424 forceFlag = find_option("force", "f", 0)!=0;
425 zBranch = find_option("branch","b",1);
426 zBgColor = find_option("bgcolor",0,1);
427 db_must_be_within_tree();
428 noSign = db_get_boolean("omitsign", 0)|noSign;
429 if( db_get_boolean("clearsign", 1)==0 ){ noSign = 1; }
430 verify_all_options();
431
432 /*
433 ** Autosync if requested.
434 */
435 autosync(AUTOSYNC_PULL);
436
437 /* There are two ways this command may be executed. If there are
438 ** no arguments following the word "commit", then all modified files
439 ** in the checked out directory are committed. If one or more arguments
440 ** follows "commit", then only those files are committed.
441 **
@@ -458,16 +479,28 @@
479 fossil_panic("file %s has not changed", blob_str(&unmodified));
480 }
481 }
482
483 vid = db_lget_int("checkout", 0);
484
485 /*
486 ** Do not allow a commit that will cause a fork unless the --force flag
487 ** is used.
488 */
489 if( zBranch==0 && forceFlag==0 && !is_a_leaf(vid) ){
490 fossil_fatal("would fork. \"update\" first or use -f or --force.");
491 }
492
493 /*
494 ** Do not allow a commit against a closed leaf
495 */
496 if( db_exists("SELECT 1 FROM tagxref"
497 " WHERE tagid=%d AND rid=%d AND tagtype>0",
498 TAG_CLOSED, vid) ){
499 fossil_fatal("cannot commit against a closed leaf");
500 }
501
502 vfile_aggregate_checksum_disk(vid, &cksum1);
503 if( zComment ){
504 blob_zero(&comment);
505 blob_append(&comment, zComment, -1);
506 }else{
@@ -565,10 +598,32 @@
598 }
599 db_reset(&q2);
600
601 blob_appendf(&manifest, "\n");
602 blob_appendf(&manifest, "R %b\n", &cksum1);
603 if( zBranch && zBranch[0] ){
604 Stmt q;
605 if( zBgColor && zBgColor[0] ){
606 blob_appendf(&manifest, "T *bgcolor * %F\n", zBgColor);
607 }
608 blob_appendf(&manifest, "T *branch * %F\n", zBranch);
609 blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
610
611 /* Cancel all other symbolic tags */
612 db_prepare(&q,
613 "SELECT tagname FROM tagxref, tag"
614 " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
615 " AND tagtype>0 AND tagname GLOB 'sym-*'"
616 " AND tagname!='sym-'||%Q"
617 " ORDER BY tagname",
618 vid, zBranch);
619 while( db_step(&q)==SQLITE_ROW ){
620 const char *zTag = db_column_text(&q, 0);
621 blob_appendf(&manifest, "T -%s *\n", zTag);
622 }
623 db_finalize(&q);
624 }
625 blob_appendf(&manifest, "U %F\n", g.zLogin);
626 md5sum_blob(&manifest, &mcksum);
627 blob_appendf(&manifest, "Z %b\n", &mcksum);
628 zManifestFile = mprintf("%smanifest", g.zLocalRoot);
629 if( !noSign && clearsign(&manifest, &manifest) ){
630

Keyboard Shortcuts

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