Fossil SCM

Add new command to edit a check-in from the command line similar to editing a check-in from the web UI.

andybradford 2015-07-04 07:17 trunk
Commit b9e0d72e7e6da002fb0da5e4c8bd0657101edcf7
1 file changed +234 -78
+234 -78
--- src/info.c
+++ src/info.c
@@ -2276,10 +2276,125 @@
22762276
}
22772277
while( fossil_isspace(zB[0]) ) zB++;
22782278
while( fossil_isspace(zA[0]) ) zA++;
22792279
return zA[0]==0 && zB[0]==0;
22802280
}
2281
+
2282
+/*
2283
+** The following methods operate on the newtags temporary table
2284
+** that is used to collect various changes to be added to a control
2285
+** artifact for a check-in edit.
2286
+*/
2287
+static void init_newtags(void){
2288
+ db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
2289
+}
2290
+
2291
+static void change_special(
2292
+ const char *zName, /* Name of the special tag */
2293
+ const char *zOp, /* Operation prefix (e.g. +,-,*) */
2294
+ const char *zValue /* Value of the tag */
2295
+){
2296
+ db_multi_exec("REPLACE INTO newtags VALUES(%Q,'%q',%Q)", zName, zOp, zValue);
2297
+}
2298
+
2299
+static void change_sym_tag(const char *zTag, const char *zOp){
2300
+ db_multi_exec("REPLACE INTO newtags VALUES('sym-%q',%Q,NULL)", zTag, zOp);
2301
+}
2302
+
2303
+static void cancel_special(const char *zTag){
2304
+ change_special(zTag,"-",0);
2305
+}
2306
+
2307
+static void add_color(const char *zNewColor, int fPropagateColor){
2308
+ change_special("bgcolor",fPropagateColor ? "*" : "+", zNewColor);
2309
+}
2310
+
2311
+static void cancel_color(void){
2312
+ change_special("color","-",0);
2313
+}
2314
+
2315
+static void add_comment(const char *zNewComment){
2316
+ change_special("comment","+",zNewComment);
2317
+}
2318
+
2319
+static void add_date(const char *zNewDate){
2320
+ change_special("date","+",zNewDate);
2321
+}
2322
+
2323
+static void add_user(const char *zNewUser){
2324
+ change_special("user","+",zNewUser);
2325
+}
2326
+
2327
+static void add_tag(const char *zNewTag){
2328
+ change_sym_tag(zNewTag,"+");
2329
+}
2330
+
2331
+static void cancel_tag(int rid, const char *zCancelTag){
2332
+ if( db_exists("SELECT 1 FROM tagxref, tag"
2333
+ " WHERE tagxref.rid=%d AND tagtype>0"
2334
+ " AND tagxref.tagid=tag.tagid AND tagname='sym-%q'",
2335
+ rid, zCancelTag)
2336
+ ) change_sym_tag(zCancelTag,"-");
2337
+}
2338
+
2339
+static void hide_branch(void){
2340
+ change_special("hidden","*",0);
2341
+}
2342
+
2343
+static void close_leaf(int rid){
2344
+ change_special("closed",is_a_leaf(rid)?"+":"*",0);
2345
+}
2346
+
2347
+static void change_branch(int rid, const char *zNewBranch){
2348
+ db_multi_exec(
2349
+ "REPLACE INTO newtags "
2350
+ " SELECT tagname, '-', NULL FROM tagxref, tag"
2351
+ " WHERE tagxref.rid=%d AND tagtype==2"
2352
+ " AND tagname GLOB 'sym-*'"
2353
+ " AND tag.tagid=tagxref.tagid",
2354
+ rid
2355
+ );
2356
+ change_special("branch","*",zNewBranch);
2357
+ change_sym_tag(zNewBranch,"*");
2358
+}
2359
+
2360
+/*
2361
+** The apply_newtags method is called after all newtags have been added
2362
+** and the control artifact is completed and then written to the DB.
2363
+*/
2364
+static void apply_newtags(Blob *ctrl, int rid, const char *zUuid){
2365
+ Stmt q;
2366
+ int nChng = 0;
2367
+
2368
+ db_prepare(&q, "SELECT tag, prefix, value FROM newtags"
2369
+ " ORDER BY prefix || tag");
2370
+ while( db_step(&q)==SQLITE_ROW ){
2371
+ const char *zTag = db_column_text(&q, 0);
2372
+ const char *zPrefix = db_column_text(&q, 1);
2373
+ const char *zValue = db_column_text(&q, 2);
2374
+ nChng++;
2375
+ if( zValue ){
2376
+ blob_appendf(ctrl, "T %s%F %s %F\n", zPrefix, zTag, zUuid, zValue);
2377
+ }else{
2378
+ blob_appendf(ctrl, "T %s%F %s\n", zPrefix, zTag, zUuid);
2379
+ }
2380
+ }
2381
+ db_finalize(&q);
2382
+ if( nChng>0 ){
2383
+ int nrid;
2384
+ Blob cksum;
2385
+ blob_appendf(ctrl, "U %F\n", login_name());
2386
+ md5sum_blob(ctrl, &cksum);
2387
+ blob_appendf(ctrl, "Z %b\n", &cksum);
2388
+ db_begin_transaction();
2389
+ g.markPrivate = content_is_private(rid);
2390
+ nrid = content_put(ctrl);
2391
+ manifest_crosslink(nrid, ctrl, MC_PERMIT_HOOKS);
2392
+ assert( blob_is_reset(ctrl) );
2393
+ db_end_transaction(0);
2394
+ }
2395
+}
22812396
22822397
/*
22832398
** WEBPAGE: ci_edit
22842399
** URL: /ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
22852400
**
@@ -2360,36 +2475,19 @@
23602475
23612476
login_verify_csrf_secret();
23622477
blob_zero(&ctrl);
23632478
zNow = date_in_standard_format(zChngTime ? zChngTime : "now");
23642479
blob_appendf(&ctrl, "D %s\n", zNow);
2365
- db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
2480
+ init_newtags();
23662481
if( zNewColor[0]
23672482
&& (fPropagateColor!=fNewPropagateColor
23682483
|| fossil_strcmp(zColor,zNewColor)!=0)
2369
- ){
2370
- char *zPrefix = "+";
2371
- if( fNewPropagateColor ){
2372
- zPrefix = "*";
2373
- }
2374
- db_multi_exec("REPLACE INTO newtags VALUES('bgcolor',%Q,%Q)",
2375
- zPrefix, zNewColor);
2376
- }
2377
- if( zNewColor[0]==0 && zColor[0]!=0 ){
2378
- db_multi_exec("REPLACE INTO newtags VALUES('bgcolor','-',NULL)");
2379
- }
2380
- if( comment_compare(zComment,zNewComment)==0 ){
2381
- db_multi_exec("REPLACE INTO newtags VALUES('comment','+',%Q)",
2382
- zNewComment);
2383
- }
2384
- if( fossil_strcmp(zDate,zNewDate)!=0 ){
2385
- db_multi_exec("REPLACE INTO newtags VALUES('date','+',%Q)",
2386
- zNewDate);
2387
- }
2388
- if( fossil_strcmp(zUser,zNewUser)!=0 ){
2389
- db_multi_exec("REPLACE INTO newtags VALUES('user','+',%Q)", zNewUser);
2390
- }
2484
+ ) add_color(zNewColor,fNewPropagateColor);
2485
+ if( zNewColor[0]==0 && zColor[0]!=0 ) cancel_color();
2486
+ if( comment_compare(zComment,zNewComment)==0 ) add_comment(zNewComment);
2487
+ if( fossil_strcmp(zDate,zNewDate)!=0 ) add_date(zNewDate);
2488
+ if( fossil_strcmp(zUser,zNewUser)!=0 ) add_user(zNewUser);
23912489
db_prepare(&q,
23922490
"SELECT tag.tagid, tagname FROM tagxref, tag"
23932491
" WHERE tagxref.rid=%d AND tagtype>0 AND tagxref.tagid=tag.tagid",
23942492
rid
23952493
);
@@ -2396,65 +2494,18 @@
23962494
while( db_step(&q)==SQLITE_ROW ){
23972495
int tagid = db_column_int(&q, 0);
23982496
const char *zTag = db_column_text(&q, 1);
23992497
char zLabel[30];
24002498
sqlite3_snprintf(sizeof(zLabel), zLabel, "c%d", tagid);
2401
- if( P(zLabel) ){
2402
- db_multi_exec("REPLACE INTO newtags VALUES(%Q,'-',NULL)", zTag);
2403
- }
2404
- }
2405
- db_finalize(&q);
2406
- if( zHideFlag[0] ){
2407
- db_multi_exec("REPLACE INTO newtags VALUES('hidden','*',NULL)");
2408
- }
2409
- if( zCloseFlag[0] ){
2410
- db_multi_exec("REPLACE INTO newtags VALUES('closed','%s',NULL)",
2411
- is_a_leaf(rid)?"+":"*");
2412
- }
2413
- if( zNewTagFlag[0] && zNewTag[0] ){
2414
- db_multi_exec("REPLACE INTO newtags VALUES('sym-%q','+',NULL)", zNewTag);
2415
- }
2416
- if( zNewBrFlag[0] && zNewBranch[0] ){
2417
- db_multi_exec(
2418
- "REPLACE INTO newtags "
2419
- " SELECT tagname, '-', NULL FROM tagxref, tag"
2420
- " WHERE tagxref.rid=%d AND tagtype==2"
2421
- " AND tagname GLOB 'sym-*'"
2422
- " AND tag.tagid=tagxref.tagid",
2423
- rid
2424
- );
2425
- db_multi_exec("REPLACE INTO newtags VALUES('branch','*',%Q)", zNewBranch);
2426
- db_multi_exec("REPLACE INTO newtags VALUES('sym-%q','*',NULL)",
2427
- zNewBranch);
2428
- }
2429
- db_prepare(&q, "SELECT tag, prefix, value FROM newtags"
2430
- " ORDER BY prefix || tag");
2431
- while( db_step(&q)==SQLITE_ROW ){
2432
- const char *zTag = db_column_text(&q, 0);
2433
- const char *zPrefix = db_column_text(&q, 1);
2434
- const char *zValue = db_column_text(&q, 2);
2435
- nChng++;
2436
- if( zValue ){
2437
- blob_appendf(&ctrl, "T %s%F %s %F\n", zPrefix, zTag, zUuid, zValue);
2438
- }else{
2439
- blob_appendf(&ctrl, "T %s%F %s\n", zPrefix, zTag, zUuid);
2440
- }
2441
- }
2442
- db_finalize(&q);
2443
- if( nChng>0 ){
2444
- int nrid;
2445
- Blob cksum;
2446
- blob_appendf(&ctrl, "U %F\n", login_name());
2447
- md5sum_blob(&ctrl, &cksum);
2448
- blob_appendf(&ctrl, "Z %b\n", &cksum);
2449
- db_begin_transaction();
2450
- g.markPrivate = content_is_private(rid);
2451
- nrid = content_put(&ctrl);
2452
- manifest_crosslink(nrid, &ctrl, MC_PERMIT_HOOKS);
2453
- assert( blob_is_reset(&ctrl) );
2454
- db_end_transaction(0);
2455
- }
2499
+ if( P(zLabel) ) cancel_special(zTag);
2500
+ }
2501
+ db_finalize(&q);
2502
+ if( zHideFlag[0] ) hide_branch();
2503
+ if( zCloseFlag[0] ) close_leaf(rid);
2504
+ if( zNewTagFlag[0] && zNewTag[0] ) add_tag(zNewTag);
2505
+ if( zNewBrFlag[0] && zNewBranch[0] ) change_branch(rid,zNewBranch);
2506
+ apply_newtags(&ctrl, rid, zUuid);
24562507
cgi_redirectf("ci?name=%s", zUuid);
24572508
}
24582509
blob_zero(&comment);
24592510
blob_append(&comment, zNewComment, -1);
24602511
zUuid[10] = 0;
@@ -2652,5 +2703,110 @@
26522703
@ </td></tr>
26532704
@ </table>
26542705
@ </div></form>
26552706
style_footer();
26562707
}
2708
+
2709
+/*
2710
+** COMMAND: edit
2711
+**
2712
+** Usage: %fossil edit UUID ?OPTIONS?
2713
+**
2714
+** Options:
2715
+**
2716
+** --euser USER Make USER the check-in user
2717
+** --comment COMMENT Make COMMENT the check-in comment
2718
+** --date DATE Make DATE the check-in time
2719
+** --bgcolor COLOR Apply COLOR to this check-in
2720
+** --branchcolor COLOR Apply COLOR to the branch
2721
+** --tag TAG Add new TAG to this check-in
2722
+** --cancel TAG Cancel TAG from this check-in
2723
+** --branch NAME Make this check-in the start of branch NAME
2724
+** --hide Hide branch starting from this check-in
2725
+** --close Mark this "leaf" as closed
2726
+*/
2727
+void ci_edit_cmd(void){
2728
+ int rid;
2729
+ const char *zComment; /* Current comment on the check-in */
2730
+ const char *zNewComment; /* Revised check-in comment */
2731
+ const char *zUser; /* Current user for the check-in */
2732
+ const char *zNewUser; /* Revised user */
2733
+ const char *zDate; /* Current date of the check-in */
2734
+ const char *zNewDate; /* Revised check-in date */
2735
+ const char *zColor;
2736
+ const char *zNewColor;
2737
+ const char *zNewBrColor;
2738
+ const char *zNewTag;
2739
+ const char *zNewBranch;
2740
+ const char *zCancelTag;
2741
+ int fClose; /* True if leaf should be closed */
2742
+ int fHide; /* True if branch should be hidden */
2743
+ int fPropagateColor; /* True if color propagates before edit */
2744
+ int fNewPropagateColor = 0; /* True if color propagates after edit */
2745
+ const char *zChngTime; /* The change time on the control artifact */
2746
+ const char *zUuid;
2747
+ Blob ctrl;
2748
+ char *zNow;
2749
+
2750
+ if( g.argc<3 ) usage("UUID ?OPTIONS?");
2751
+ zNewComment = find_option("comment",0,1);
2752
+ zNewBranch = find_option("branch",0,1);
2753
+ zNewColor = find_option("bgcolor",0,1);
2754
+ zNewBrColor = find_option("branchcolor",0,1);
2755
+ if( zNewBrColor ){
2756
+ zNewColor = zNewBrColor;
2757
+ fNewPropagateColor = 1;
2758
+ }
2759
+ zNewDate = find_option("date",0,1);
2760
+ zNewUser = find_option("euser",0,1);
2761
+ zNewTag = find_option("tag",0,1);
2762
+ zCancelTag = find_option("cancel",0,1);
2763
+ fClose = find_option("close",0,0)!=0;
2764
+ fHide = find_option("hide",0,0)!=0;
2765
+ zChngTime = find_option("chngtime",0,1);
2766
+ db_find_and_open_repository(0,0);
2767
+ user_select();
2768
+ verify_all_options();
2769
+ rid = name_to_typed_rid(g.argv[2], "ci");
2770
+ zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
2771
+ zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
2772
+ " FROM event WHERE objid=%d", rid);
2773
+ if( zComment==0 || zComment[0]==0 ) fossil_fatal("No comment on rid %d", rid);
2774
+ zUser = db_text(0, "SELECT coalesce(euser,user)"
2775
+ " FROM event WHERE objid=%d", rid);
2776
+ if( zUser==0 || zUser[0]==0 ) fossil_fatal("No user on rid %d", rid);
2777
+ zDate = db_text(0, "SELECT datetime(mtime)"
2778
+ " FROM event WHERE objid=%d", rid);
2779
+ if( zDate==0 || zDate[0]==0 ) fossil_fatal("No date on rid %d", rid);
2780
+ zColor = db_text("", "SELECT bgcolor"
2781
+ " FROM event WHERE objid=%d", rid);
2782
+ fPropagateColor = db_int(0, "SELECT tagtype FROM tagxref"
2783
+ " WHERE rid=%d AND tagid=%d",
2784
+ rid, TAG_BGCOLOR)==2;
2785
+ fNewPropagateColor = zNewColor && zNewColor[0]
2786
+ ? fNewPropagateColor : fPropagateColor;
2787
+ blob_zero(&ctrl);
2788
+ zNow = date_in_standard_format(zChngTime && zChngTime[0] ? zChngTime : "now");
2789
+ blob_appendf(&ctrl, "D %s\n", zNow);
2790
+ init_newtags();
2791
+ if( zNewColor && zNewColor[0]
2792
+ && (fPropagateColor!=fNewPropagateColor
2793
+ || fossil_strcmp(zColor,zNewColor)!=0)
2794
+ ) add_color(zNewColor,fNewPropagateColor);
2795
+ if( (zNewColor!=0 && zNewColor[0]==0) && (zColor && zColor[0] ) ){
2796
+ cancel_color();
2797
+ }
2798
+ if( zNewComment && zNewComment[0]
2799
+ && comment_compare(zComment,zNewComment)==0 ) add_comment(zNewComment);
2800
+ if( zNewDate && zNewDate[0] && fossil_strcmp(zDate,zNewDate)!=0 ){
2801
+ add_date(zNewDate);
2802
+ }
2803
+ if( zNewUser && zNewUser[0] && fossil_strcmp(zUser,zNewUser)!=0 ){
2804
+ add_user(zNewUser);
2805
+ }
2806
+ if( zNewTag && zNewTag[0] ) add_tag(zNewTag);
2807
+ if( zCancelTag && zCancelTag[0] ) cancel_tag(rid,zCancelTag);
2808
+ if( fHide ) hide_branch();
2809
+ if( fClose ) close_leaf(rid);
2810
+ if( zNewBranch && zNewBranch[0] ) change_branch(rid,zNewBranch);
2811
+ apply_newtags(&ctrl, rid, zUuid);
2812
+}
26572813
--- src/info.c
+++ src/info.c
@@ -2276,10 +2276,125 @@
2276 }
2277 while( fossil_isspace(zB[0]) ) zB++;
2278 while( fossil_isspace(zA[0]) ) zA++;
2279 return zA[0]==0 && zB[0]==0;
2280 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2281
2282 /*
2283 ** WEBPAGE: ci_edit
2284 ** URL: /ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
2285 **
@@ -2360,36 +2475,19 @@
2360
2361 login_verify_csrf_secret();
2362 blob_zero(&ctrl);
2363 zNow = date_in_standard_format(zChngTime ? zChngTime : "now");
2364 blob_appendf(&ctrl, "D %s\n", zNow);
2365 db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
2366 if( zNewColor[0]
2367 && (fPropagateColor!=fNewPropagateColor
2368 || fossil_strcmp(zColor,zNewColor)!=0)
2369 ){
2370 char *zPrefix = "+";
2371 if( fNewPropagateColor ){
2372 zPrefix = "*";
2373 }
2374 db_multi_exec("REPLACE INTO newtags VALUES('bgcolor',%Q,%Q)",
2375 zPrefix, zNewColor);
2376 }
2377 if( zNewColor[0]==0 && zColor[0]!=0 ){
2378 db_multi_exec("REPLACE INTO newtags VALUES('bgcolor','-',NULL)");
2379 }
2380 if( comment_compare(zComment,zNewComment)==0 ){
2381 db_multi_exec("REPLACE INTO newtags VALUES('comment','+',%Q)",
2382 zNewComment);
2383 }
2384 if( fossil_strcmp(zDate,zNewDate)!=0 ){
2385 db_multi_exec("REPLACE INTO newtags VALUES('date','+',%Q)",
2386 zNewDate);
2387 }
2388 if( fossil_strcmp(zUser,zNewUser)!=0 ){
2389 db_multi_exec("REPLACE INTO newtags VALUES('user','+',%Q)", zNewUser);
2390 }
2391 db_prepare(&q,
2392 "SELECT tag.tagid, tagname FROM tagxref, tag"
2393 " WHERE tagxref.rid=%d AND tagtype>0 AND tagxref.tagid=tag.tagid",
2394 rid
2395 );
@@ -2396,65 +2494,18 @@
2396 while( db_step(&q)==SQLITE_ROW ){
2397 int tagid = db_column_int(&q, 0);
2398 const char *zTag = db_column_text(&q, 1);
2399 char zLabel[30];
2400 sqlite3_snprintf(sizeof(zLabel), zLabel, "c%d", tagid);
2401 if( P(zLabel) ){
2402 db_multi_exec("REPLACE INTO newtags VALUES(%Q,'-',NULL)", zTag);
2403 }
2404 }
2405 db_finalize(&q);
2406 if( zHideFlag[0] ){
2407 db_multi_exec("REPLACE INTO newtags VALUES('hidden','*',NULL)");
2408 }
2409 if( zCloseFlag[0] ){
2410 db_multi_exec("REPLACE INTO newtags VALUES('closed','%s',NULL)",
2411 is_a_leaf(rid)?"+":"*");
2412 }
2413 if( zNewTagFlag[0] && zNewTag[0] ){
2414 db_multi_exec("REPLACE INTO newtags VALUES('sym-%q','+',NULL)", zNewTag);
2415 }
2416 if( zNewBrFlag[0] && zNewBranch[0] ){
2417 db_multi_exec(
2418 "REPLACE INTO newtags "
2419 " SELECT tagname, '-', NULL FROM tagxref, tag"
2420 " WHERE tagxref.rid=%d AND tagtype==2"
2421 " AND tagname GLOB 'sym-*'"
2422 " AND tag.tagid=tagxref.tagid",
2423 rid
2424 );
2425 db_multi_exec("REPLACE INTO newtags VALUES('branch','*',%Q)", zNewBranch);
2426 db_multi_exec("REPLACE INTO newtags VALUES('sym-%q','*',NULL)",
2427 zNewBranch);
2428 }
2429 db_prepare(&q, "SELECT tag, prefix, value FROM newtags"
2430 " ORDER BY prefix || tag");
2431 while( db_step(&q)==SQLITE_ROW ){
2432 const char *zTag = db_column_text(&q, 0);
2433 const char *zPrefix = db_column_text(&q, 1);
2434 const char *zValue = db_column_text(&q, 2);
2435 nChng++;
2436 if( zValue ){
2437 blob_appendf(&ctrl, "T %s%F %s %F\n", zPrefix, zTag, zUuid, zValue);
2438 }else{
2439 blob_appendf(&ctrl, "T %s%F %s\n", zPrefix, zTag, zUuid);
2440 }
2441 }
2442 db_finalize(&q);
2443 if( nChng>0 ){
2444 int nrid;
2445 Blob cksum;
2446 blob_appendf(&ctrl, "U %F\n", login_name());
2447 md5sum_blob(&ctrl, &cksum);
2448 blob_appendf(&ctrl, "Z %b\n", &cksum);
2449 db_begin_transaction();
2450 g.markPrivate = content_is_private(rid);
2451 nrid = content_put(&ctrl);
2452 manifest_crosslink(nrid, &ctrl, MC_PERMIT_HOOKS);
2453 assert( blob_is_reset(&ctrl) );
2454 db_end_transaction(0);
2455 }
2456 cgi_redirectf("ci?name=%s", zUuid);
2457 }
2458 blob_zero(&comment);
2459 blob_append(&comment, zNewComment, -1);
2460 zUuid[10] = 0;
@@ -2652,5 +2703,110 @@
2652 @ </td></tr>
2653 @ </table>
2654 @ </div></form>
2655 style_footer();
2656 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2657
--- src/info.c
+++ src/info.c
@@ -2276,10 +2276,125 @@
2276 }
2277 while( fossil_isspace(zB[0]) ) zB++;
2278 while( fossil_isspace(zA[0]) ) zA++;
2279 return zA[0]==0 && zB[0]==0;
2280 }
2281
2282 /*
2283 ** The following methods operate on the newtags temporary table
2284 ** that is used to collect various changes to be added to a control
2285 ** artifact for a check-in edit.
2286 */
2287 static void init_newtags(void){
2288 db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
2289 }
2290
2291 static void change_special(
2292 const char *zName, /* Name of the special tag */
2293 const char *zOp, /* Operation prefix (e.g. +,-,*) */
2294 const char *zValue /* Value of the tag */
2295 ){
2296 db_multi_exec("REPLACE INTO newtags VALUES(%Q,'%q',%Q)", zName, zOp, zValue);
2297 }
2298
2299 static void change_sym_tag(const char *zTag, const char *zOp){
2300 db_multi_exec("REPLACE INTO newtags VALUES('sym-%q',%Q,NULL)", zTag, zOp);
2301 }
2302
2303 static void cancel_special(const char *zTag){
2304 change_special(zTag,"-",0);
2305 }
2306
2307 static void add_color(const char *zNewColor, int fPropagateColor){
2308 change_special("bgcolor",fPropagateColor ? "*" : "+", zNewColor);
2309 }
2310
2311 static void cancel_color(void){
2312 change_special("color","-",0);
2313 }
2314
2315 static void add_comment(const char *zNewComment){
2316 change_special("comment","+",zNewComment);
2317 }
2318
2319 static void add_date(const char *zNewDate){
2320 change_special("date","+",zNewDate);
2321 }
2322
2323 static void add_user(const char *zNewUser){
2324 change_special("user","+",zNewUser);
2325 }
2326
2327 static void add_tag(const char *zNewTag){
2328 change_sym_tag(zNewTag,"+");
2329 }
2330
2331 static void cancel_tag(int rid, const char *zCancelTag){
2332 if( db_exists("SELECT 1 FROM tagxref, tag"
2333 " WHERE tagxref.rid=%d AND tagtype>0"
2334 " AND tagxref.tagid=tag.tagid AND tagname='sym-%q'",
2335 rid, zCancelTag)
2336 ) change_sym_tag(zCancelTag,"-");
2337 }
2338
2339 static void hide_branch(void){
2340 change_special("hidden","*",0);
2341 }
2342
2343 static void close_leaf(int rid){
2344 change_special("closed",is_a_leaf(rid)?"+":"*",0);
2345 }
2346
2347 static void change_branch(int rid, const char *zNewBranch){
2348 db_multi_exec(
2349 "REPLACE INTO newtags "
2350 " SELECT tagname, '-', NULL FROM tagxref, tag"
2351 " WHERE tagxref.rid=%d AND tagtype==2"
2352 " AND tagname GLOB 'sym-*'"
2353 " AND tag.tagid=tagxref.tagid",
2354 rid
2355 );
2356 change_special("branch","*",zNewBranch);
2357 change_sym_tag(zNewBranch,"*");
2358 }
2359
2360 /*
2361 ** The apply_newtags method is called after all newtags have been added
2362 ** and the control artifact is completed and then written to the DB.
2363 */
2364 static void apply_newtags(Blob *ctrl, int rid, const char *zUuid){
2365 Stmt q;
2366 int nChng = 0;
2367
2368 db_prepare(&q, "SELECT tag, prefix, value FROM newtags"
2369 " ORDER BY prefix || tag");
2370 while( db_step(&q)==SQLITE_ROW ){
2371 const char *zTag = db_column_text(&q, 0);
2372 const char *zPrefix = db_column_text(&q, 1);
2373 const char *zValue = db_column_text(&q, 2);
2374 nChng++;
2375 if( zValue ){
2376 blob_appendf(ctrl, "T %s%F %s %F\n", zPrefix, zTag, zUuid, zValue);
2377 }else{
2378 blob_appendf(ctrl, "T %s%F %s\n", zPrefix, zTag, zUuid);
2379 }
2380 }
2381 db_finalize(&q);
2382 if( nChng>0 ){
2383 int nrid;
2384 Blob cksum;
2385 blob_appendf(ctrl, "U %F\n", login_name());
2386 md5sum_blob(ctrl, &cksum);
2387 blob_appendf(ctrl, "Z %b\n", &cksum);
2388 db_begin_transaction();
2389 g.markPrivate = content_is_private(rid);
2390 nrid = content_put(ctrl);
2391 manifest_crosslink(nrid, ctrl, MC_PERMIT_HOOKS);
2392 assert( blob_is_reset(ctrl) );
2393 db_end_transaction(0);
2394 }
2395 }
2396
2397 /*
2398 ** WEBPAGE: ci_edit
2399 ** URL: /ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
2400 **
@@ -2360,36 +2475,19 @@
2475
2476 login_verify_csrf_secret();
2477 blob_zero(&ctrl);
2478 zNow = date_in_standard_format(zChngTime ? zChngTime : "now");
2479 blob_appendf(&ctrl, "D %s\n", zNow);
2480 init_newtags();
2481 if( zNewColor[0]
2482 && (fPropagateColor!=fNewPropagateColor
2483 || fossil_strcmp(zColor,zNewColor)!=0)
2484 ) add_color(zNewColor,fNewPropagateColor);
2485 if( zNewColor[0]==0 && zColor[0]!=0 ) cancel_color();
2486 if( comment_compare(zComment,zNewComment)==0 ) add_comment(zNewComment);
2487 if( fossil_strcmp(zDate,zNewDate)!=0 ) add_date(zNewDate);
2488 if( fossil_strcmp(zUser,zNewUser)!=0 ) add_user(zNewUser);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2489 db_prepare(&q,
2490 "SELECT tag.tagid, tagname FROM tagxref, tag"
2491 " WHERE tagxref.rid=%d AND tagtype>0 AND tagxref.tagid=tag.tagid",
2492 rid
2493 );
@@ -2396,65 +2494,18 @@
2494 while( db_step(&q)==SQLITE_ROW ){
2495 int tagid = db_column_int(&q, 0);
2496 const char *zTag = db_column_text(&q, 1);
2497 char zLabel[30];
2498 sqlite3_snprintf(sizeof(zLabel), zLabel, "c%d", tagid);
2499 if( P(zLabel) ) cancel_special(zTag);
2500 }
2501 db_finalize(&q);
2502 if( zHideFlag[0] ) hide_branch();
2503 if( zCloseFlag[0] ) close_leaf(rid);
2504 if( zNewTagFlag[0] && zNewTag[0] ) add_tag(zNewTag);
2505 if( zNewBrFlag[0] && zNewBranch[0] ) change_branch(rid,zNewBranch);
2506 apply_newtags(&ctrl, rid, zUuid);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2507 cgi_redirectf("ci?name=%s", zUuid);
2508 }
2509 blob_zero(&comment);
2510 blob_append(&comment, zNewComment, -1);
2511 zUuid[10] = 0;
@@ -2652,5 +2703,110 @@
2703 @ </td></tr>
2704 @ </table>
2705 @ </div></form>
2706 style_footer();
2707 }
2708
2709 /*
2710 ** COMMAND: edit
2711 **
2712 ** Usage: %fossil edit UUID ?OPTIONS?
2713 **
2714 ** Options:
2715 **
2716 ** --euser USER Make USER the check-in user
2717 ** --comment COMMENT Make COMMENT the check-in comment
2718 ** --date DATE Make DATE the check-in time
2719 ** --bgcolor COLOR Apply COLOR to this check-in
2720 ** --branchcolor COLOR Apply COLOR to the branch
2721 ** --tag TAG Add new TAG to this check-in
2722 ** --cancel TAG Cancel TAG from this check-in
2723 ** --branch NAME Make this check-in the start of branch NAME
2724 ** --hide Hide branch starting from this check-in
2725 ** --close Mark this "leaf" as closed
2726 */
2727 void ci_edit_cmd(void){
2728 int rid;
2729 const char *zComment; /* Current comment on the check-in */
2730 const char *zNewComment; /* Revised check-in comment */
2731 const char *zUser; /* Current user for the check-in */
2732 const char *zNewUser; /* Revised user */
2733 const char *zDate; /* Current date of the check-in */
2734 const char *zNewDate; /* Revised check-in date */
2735 const char *zColor;
2736 const char *zNewColor;
2737 const char *zNewBrColor;
2738 const char *zNewTag;
2739 const char *zNewBranch;
2740 const char *zCancelTag;
2741 int fClose; /* True if leaf should be closed */
2742 int fHide; /* True if branch should be hidden */
2743 int fPropagateColor; /* True if color propagates before edit */
2744 int fNewPropagateColor = 0; /* True if color propagates after edit */
2745 const char *zChngTime; /* The change time on the control artifact */
2746 const char *zUuid;
2747 Blob ctrl;
2748 char *zNow;
2749
2750 if( g.argc<3 ) usage("UUID ?OPTIONS?");
2751 zNewComment = find_option("comment",0,1);
2752 zNewBranch = find_option("branch",0,1);
2753 zNewColor = find_option("bgcolor",0,1);
2754 zNewBrColor = find_option("branchcolor",0,1);
2755 if( zNewBrColor ){
2756 zNewColor = zNewBrColor;
2757 fNewPropagateColor = 1;
2758 }
2759 zNewDate = find_option("date",0,1);
2760 zNewUser = find_option("euser",0,1);
2761 zNewTag = find_option("tag",0,1);
2762 zCancelTag = find_option("cancel",0,1);
2763 fClose = find_option("close",0,0)!=0;
2764 fHide = find_option("hide",0,0)!=0;
2765 zChngTime = find_option("chngtime",0,1);
2766 db_find_and_open_repository(0,0);
2767 user_select();
2768 verify_all_options();
2769 rid = name_to_typed_rid(g.argv[2], "ci");
2770 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
2771 zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
2772 " FROM event WHERE objid=%d", rid);
2773 if( zComment==0 || zComment[0]==0 ) fossil_fatal("No comment on rid %d", rid);
2774 zUser = db_text(0, "SELECT coalesce(euser,user)"
2775 " FROM event WHERE objid=%d", rid);
2776 if( zUser==0 || zUser[0]==0 ) fossil_fatal("No user on rid %d", rid);
2777 zDate = db_text(0, "SELECT datetime(mtime)"
2778 " FROM event WHERE objid=%d", rid);
2779 if( zDate==0 || zDate[0]==0 ) fossil_fatal("No date on rid %d", rid);
2780 zColor = db_text("", "SELECT bgcolor"
2781 " FROM event WHERE objid=%d", rid);
2782 fPropagateColor = db_int(0, "SELECT tagtype FROM tagxref"
2783 " WHERE rid=%d AND tagid=%d",
2784 rid, TAG_BGCOLOR)==2;
2785 fNewPropagateColor = zNewColor && zNewColor[0]
2786 ? fNewPropagateColor : fPropagateColor;
2787 blob_zero(&ctrl);
2788 zNow = date_in_standard_format(zChngTime && zChngTime[0] ? zChngTime : "now");
2789 blob_appendf(&ctrl, "D %s\n", zNow);
2790 init_newtags();
2791 if( zNewColor && zNewColor[0]
2792 && (fPropagateColor!=fNewPropagateColor
2793 || fossil_strcmp(zColor,zNewColor)!=0)
2794 ) add_color(zNewColor,fNewPropagateColor);
2795 if( (zNewColor!=0 && zNewColor[0]==0) && (zColor && zColor[0] ) ){
2796 cancel_color();
2797 }
2798 if( zNewComment && zNewComment[0]
2799 && comment_compare(zComment,zNewComment)==0 ) add_comment(zNewComment);
2800 if( zNewDate && zNewDate[0] && fossil_strcmp(zDate,zNewDate)!=0 ){
2801 add_date(zNewDate);
2802 }
2803 if( zNewUser && zNewUser[0] && fossil_strcmp(zUser,zNewUser)!=0 ){
2804 add_user(zNewUser);
2805 }
2806 if( zNewTag && zNewTag[0] ) add_tag(zNewTag);
2807 if( zCancelTag && zCancelTag[0] ) cancel_tag(rid,zCancelTag);
2808 if( fHide ) hide_branch();
2809 if( fClose ) close_leaf(rid);
2810 if( zNewBranch && zNewBranch[0] ) change_branch(rid,zNewBranch);
2811 apply_newtags(&ctrl, rid, zUuid);
2812 }
2813

Keyboard Shortcuts

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