Fossil SCM

Add the ability to edit check-in comments and users from the web interface.

drh 2008-07-19 18:18 trunk
Commit f0474b87b0128227dfd60be6f4f8ddeb5be03ba9
1 file changed +116 -6
+116 -6
--- src/info.c
+++ src/info.c
@@ -303,11 +303,11 @@
303303
304304
login_check_credentials();
305305
if( !g.okRead ){ login_needed(); return; }
306306
rid = name_to_rid(PD("name","0"));
307307
if( rid==0 ){
308
- style_header("Version Information Error");
308
+ style_header("Baseline Information Error");
309309
@ No such object: %h(g.argv[2])
310310
style_footer();
311311
return;
312312
}
313313
isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
@@ -319,23 +319,43 @@
319319
rid, rid
320320
);
321321
if( db_step(&q)==SQLITE_ROW ){
322322
const char *zUuid = db_column_text(&q, 0);
323323
char *zTitle = mprintf("Baseline [%.10s]", zUuid);
324
+ char *zEUser, *zEComment;
325
+ const char *zUser;
326
+ const char *zComment;
324327
style_header(zTitle);
325328
login_anonymous_available();
326329
free(zTitle);
327
- /*@ <h2>Version %s(zUuid)</h2>*/
330
+ zEUser = db_text(0,
331
+ "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
332
+ TAG_USER, rid);
333
+ zEComment = db_text(0,
334
+ "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
335
+ TAG_COMMENT, rid);
336
+ zUser = db_column_text(&q, 2);
337
+ zComment = db_column_text(&q, 3);
328338
@ <div class="section">Overview</div>
329339
@ <p><table class="label-value">
330
- @ <tr><th>Version:</th><td>%s(zUuid)</td></tr>
340
+ @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)</td></tr>
331341
@ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr>
332342
if( g.okSetup ){
333343
@ <tr><th>Record ID:</th><td>%d(rid)</td></tr>
334344
}
335
- @ <tr><th>Original&nbsp;User:</th><td>%h(db_column_text(&q, 2))</td></tr>
336
- @ <tr><th>Original&nbsp;Comment:</th><td>%w(db_column_text(&q,3))</td></tr>
345
+ if( zEUser ){
346
+ @ <tr><th>Edited&nbsp;User:</td><td>%h(zEUser)</td></tr>
347
+ @ <tr><th>Original&nbsp;User:</th><td>%h(zUser)</td></tr>
348
+ }else{
349
+ @ <tr><th>User:</td><td>%h(zUser)</td></tr>
350
+ }
351
+ if( zEComment ){
352
+ @ <tr><th>Edited&nbsp;Comment:</th><td>%w(zEComment)</td></tr>
353
+ @ <tr><th>Original&nbsp;Comment:</th><td>%w(zComment)</td></tr>
354
+ }else{
355
+ @ <tr><th>Comment:</th><td>%w(zComment)</td></tr>
356
+ }
337357
@ </td></tr>
338358
if( g.okHistory ){
339359
@ <tr><th>Timelines:</th><td>
340360
@ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a>
341361
@ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a>
@@ -344,10 +364,13 @@
344364
@ <tr><th>Commands:</th>
345365
@ <td>
346366
@ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a>
347367
@ | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a>
348368
@ | <a href="%s(g.zBaseURL)/artifact/%d(rid)">manifest</a>
369
+ if( g.okWrite ){
370
+ @ | <a href="%s(g.zBaseURL)/vedit?r=%d(rid)">edit</a>
371
+ }
349372
@ </td>
350373
@ </tr>
351374
}
352375
@ </table></p>
353376
}else{
@@ -354,11 +377,11 @@
354377
style_header("Baseline Information");
355378
login_anonymous_available();
356379
}
357380
db_finalize(&q);
358381
showTags(rid, "");
359
- @ <div class="section">Changes</div>
382
+ @ <div class="section">Files Changed</div>
360383
@ <ul>
361384
db_prepare(&q,
362385
"SELECT name, pid, fid"
363386
" FROM mlink, filename"
364387
" WHERE mid=%d"
@@ -925,5 +948,92 @@
925948
}else
926949
{
927950
artifact_page();
928951
}
929952
}
953
+
954
+/*
955
+** WEBPAGE: vedit
956
+** URL: vedit?r=RID&c=NEWCOMMENT&u=NEWUSER
957
+**
958
+** Present a dialog for updating properties of a baseline:
959
+**
960
+** * The check-in user
961
+** * The check-in comment
962
+** * The background color.
963
+*/
964
+void vedit_page(void){
965
+ int rid;
966
+ const char *zComment;
967
+ const char *zNewComment;
968
+ const char *zUser;
969
+ const char *zNewUser;
970
+ char *zUuid;
971
+ Blob comment;
972
+
973
+ login_check_credentials();
974
+ if( !g.okWrite ){ login_needed(); return; }
975
+ rid = atoi(PD("r","0"));
976
+ zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
977
+ " FROM event WHERE objid=%d", rid);
978
+ if( zComment==0 ) fossil_redirect_home();
979
+ zNewComment = PD("c",zComment);
980
+ zUser = db_text(0, "SELECT coalesce(euser,user)"
981
+ " FROM event WHERE objid=%d", rid);
982
+ if( zUser==0 ) fossil_redirect_home();
983
+ zNewUser = PD("u",zUser);
984
+ zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
985
+ if( P("cancel") ){
986
+ cgi_redirectf("vinfo?name=%d", rid);
987
+ }
988
+ if( P("apply") ){
989
+ Blob ctrl;
990
+ char *zDate;
991
+ int nChng = 0;
992
+
993
+ blob_zero(&ctrl);
994
+ zDate = db_text(0, "SELECT datetime('now')");
995
+ zDate[10] = 'T';
996
+ blob_appendf(&ctrl, "D %s\n", zDate);
997
+ if( strcmp(zComment,zNewComment)!=0 ){
998
+ nChng++;
999
+ blob_appendf(&ctrl, "T +comment %s %F\n", zUuid, zNewComment);
1000
+ }
1001
+ if( strcmp(zUser,zNewUser)!=0 ){
1002
+ nChng++;
1003
+ blob_appendf(&ctrl, "T +user %s %F\n", zUuid, zNewUser);
1004
+ }
1005
+ if( nChng>0 ){
1006
+ int nrid;
1007
+ Blob cksum;
1008
+ blob_appendf(&ctrl, "U %F\n", g.zLogin);
1009
+ md5sum_blob(&ctrl, &cksum);
1010
+ blob_appendf(&ctrl, "Z %b\n", &cksum);
1011
+ db_begin_transaction();
1012
+ nrid = content_put(&ctrl, 0, 0);
1013
+ manifest_crosslink(nrid, &ctrl);
1014
+ db_end_transaction(0);
1015
+ }
1016
+ cgi_redirectf("vinfo?name=%d", rid);
1017
+ }
1018
+ blob_init(&comment, zNewComment, -1);
1019
+ zUuid[10] = 0;
1020
+ style_header("Edit Baseline [%s]", zUuid);
1021
+ @ <p>Make changes to the User and Comment for baseline
1022
+ @ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>] then press the
1023
+ @ "Apply Changes" button.</p>
1024
+ @ <form action="%s(g.zBaseURL)/vedit" method="POST">
1025
+ @ <input type="hidden" name="r" value="%d(rid)">
1026
+ @ <p>
1027
+ @ <b>User:</b> <input type="text" name="u" size="20" value="%h(zNewUser)">
1028
+ @ </p>
1029
+ @ <p><b>Comment:</b></b><br />
1030
+ wiki_convert(&comment, 0, WIKI_INLINE);
1031
+ @ <br /><textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea></p>
1032
+ @ <blockquote>
1033
+ @ <input type="submit" name="preview" value="Preview">
1034
+ @ <input type="submit" name="apply" value="Apply Changes">
1035
+ @ <input type="submit" name="cancel" value="Cancel">
1036
+ @ </blockquote>
1037
+ @ </form>
1038
+ style_footer();
1039
+}
9301040
--- src/info.c
+++ src/info.c
@@ -303,11 +303,11 @@
303
304 login_check_credentials();
305 if( !g.okRead ){ login_needed(); return; }
306 rid = name_to_rid(PD("name","0"));
307 if( rid==0 ){
308 style_header("Version Information Error");
309 @ No such object: %h(g.argv[2])
310 style_footer();
311 return;
312 }
313 isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
@@ -319,23 +319,43 @@
319 rid, rid
320 );
321 if( db_step(&q)==SQLITE_ROW ){
322 const char *zUuid = db_column_text(&q, 0);
323 char *zTitle = mprintf("Baseline [%.10s]", zUuid);
 
 
 
324 style_header(zTitle);
325 login_anonymous_available();
326 free(zTitle);
327 /*@ <h2>Version %s(zUuid)</h2>*/
 
 
 
 
 
 
 
328 @ <div class="section">Overview</div>
329 @ <p><table class="label-value">
330 @ <tr><th>Version:</th><td>%s(zUuid)</td></tr>
331 @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr>
332 if( g.okSetup ){
333 @ <tr><th>Record ID:</th><td>%d(rid)</td></tr>
334 }
335 @ <tr><th>Original&nbsp;User:</th><td>%h(db_column_text(&q, 2))</td></tr>
336 @ <tr><th>Original&nbsp;Comment:</th><td>%w(db_column_text(&q,3))</td></tr>
 
 
 
 
 
 
 
 
 
 
337 @ </td></tr>
338 if( g.okHistory ){
339 @ <tr><th>Timelines:</th><td>
340 @ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a>
341 @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a>
@@ -344,10 +364,13 @@
344 @ <tr><th>Commands:</th>
345 @ <td>
346 @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a>
347 @ | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a>
348 @ | <a href="%s(g.zBaseURL)/artifact/%d(rid)">manifest</a>
 
 
 
349 @ </td>
350 @ </tr>
351 }
352 @ </table></p>
353 }else{
@@ -354,11 +377,11 @@
354 style_header("Baseline Information");
355 login_anonymous_available();
356 }
357 db_finalize(&q);
358 showTags(rid, "");
359 @ <div class="section">Changes</div>
360 @ <ul>
361 db_prepare(&q,
362 "SELECT name, pid, fid"
363 " FROM mlink, filename"
364 " WHERE mid=%d"
@@ -925,5 +948,92 @@
925 }else
926 {
927 artifact_page();
928 }
929 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
930
--- src/info.c
+++ src/info.c
@@ -303,11 +303,11 @@
303
304 login_check_credentials();
305 if( !g.okRead ){ login_needed(); return; }
306 rid = name_to_rid(PD("name","0"));
307 if( rid==0 ){
308 style_header("Baseline Information Error");
309 @ No such object: %h(g.argv[2])
310 style_footer();
311 return;
312 }
313 isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
@@ -319,23 +319,43 @@
319 rid, rid
320 );
321 if( db_step(&q)==SQLITE_ROW ){
322 const char *zUuid = db_column_text(&q, 0);
323 char *zTitle = mprintf("Baseline [%.10s]", zUuid);
324 char *zEUser, *zEComment;
325 const char *zUser;
326 const char *zComment;
327 style_header(zTitle);
328 login_anonymous_available();
329 free(zTitle);
330 zEUser = db_text(0,
331 "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
332 TAG_USER, rid);
333 zEComment = db_text(0,
334 "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
335 TAG_COMMENT, rid);
336 zUser = db_column_text(&q, 2);
337 zComment = db_column_text(&q, 3);
338 @ <div class="section">Overview</div>
339 @ <p><table class="label-value">
340 @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)</td></tr>
341 @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr>
342 if( g.okSetup ){
343 @ <tr><th>Record ID:</th><td>%d(rid)</td></tr>
344 }
345 if( zEUser ){
346 @ <tr><th>Edited&nbsp;User:</td><td>%h(zEUser)</td></tr>
347 @ <tr><th>Original&nbsp;User:</th><td>%h(zUser)</td></tr>
348 }else{
349 @ <tr><th>User:</td><td>%h(zUser)</td></tr>
350 }
351 if( zEComment ){
352 @ <tr><th>Edited&nbsp;Comment:</th><td>%w(zEComment)</td></tr>
353 @ <tr><th>Original&nbsp;Comment:</th><td>%w(zComment)</td></tr>
354 }else{
355 @ <tr><th>Comment:</th><td>%w(zComment)</td></tr>
356 }
357 @ </td></tr>
358 if( g.okHistory ){
359 @ <tr><th>Timelines:</th><td>
360 @ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a>
361 @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a>
@@ -344,10 +364,13 @@
364 @ <tr><th>Commands:</th>
365 @ <td>
366 @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a>
367 @ | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a>
368 @ | <a href="%s(g.zBaseURL)/artifact/%d(rid)">manifest</a>
369 if( g.okWrite ){
370 @ | <a href="%s(g.zBaseURL)/vedit?r=%d(rid)">edit</a>
371 }
372 @ </td>
373 @ </tr>
374 }
375 @ </table></p>
376 }else{
@@ -354,11 +377,11 @@
377 style_header("Baseline Information");
378 login_anonymous_available();
379 }
380 db_finalize(&q);
381 showTags(rid, "");
382 @ <div class="section">Files Changed</div>
383 @ <ul>
384 db_prepare(&q,
385 "SELECT name, pid, fid"
386 " FROM mlink, filename"
387 " WHERE mid=%d"
@@ -925,5 +948,92 @@
948 }else
949 {
950 artifact_page();
951 }
952 }
953
954 /*
955 ** WEBPAGE: vedit
956 ** URL: vedit?r=RID&c=NEWCOMMENT&u=NEWUSER
957 **
958 ** Present a dialog for updating properties of a baseline:
959 **
960 ** * The check-in user
961 ** * The check-in comment
962 ** * The background color.
963 */
964 void vedit_page(void){
965 int rid;
966 const char *zComment;
967 const char *zNewComment;
968 const char *zUser;
969 const char *zNewUser;
970 char *zUuid;
971 Blob comment;
972
973 login_check_credentials();
974 if( !g.okWrite ){ login_needed(); return; }
975 rid = atoi(PD("r","0"));
976 zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
977 " FROM event WHERE objid=%d", rid);
978 if( zComment==0 ) fossil_redirect_home();
979 zNewComment = PD("c",zComment);
980 zUser = db_text(0, "SELECT coalesce(euser,user)"
981 " FROM event WHERE objid=%d", rid);
982 if( zUser==0 ) fossil_redirect_home();
983 zNewUser = PD("u",zUser);
984 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
985 if( P("cancel") ){
986 cgi_redirectf("vinfo?name=%d", rid);
987 }
988 if( P("apply") ){
989 Blob ctrl;
990 char *zDate;
991 int nChng = 0;
992
993 blob_zero(&ctrl);
994 zDate = db_text(0, "SELECT datetime('now')");
995 zDate[10] = 'T';
996 blob_appendf(&ctrl, "D %s\n", zDate);
997 if( strcmp(zComment,zNewComment)!=0 ){
998 nChng++;
999 blob_appendf(&ctrl, "T +comment %s %F\n", zUuid, zNewComment);
1000 }
1001 if( strcmp(zUser,zNewUser)!=0 ){
1002 nChng++;
1003 blob_appendf(&ctrl, "T +user %s %F\n", zUuid, zNewUser);
1004 }
1005 if( nChng>0 ){
1006 int nrid;
1007 Blob cksum;
1008 blob_appendf(&ctrl, "U %F\n", g.zLogin);
1009 md5sum_blob(&ctrl, &cksum);
1010 blob_appendf(&ctrl, "Z %b\n", &cksum);
1011 db_begin_transaction();
1012 nrid = content_put(&ctrl, 0, 0);
1013 manifest_crosslink(nrid, &ctrl);
1014 db_end_transaction(0);
1015 }
1016 cgi_redirectf("vinfo?name=%d", rid);
1017 }
1018 blob_init(&comment, zNewComment, -1);
1019 zUuid[10] = 0;
1020 style_header("Edit Baseline [%s]", zUuid);
1021 @ <p>Make changes to the User and Comment for baseline
1022 @ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>] then press the
1023 @ "Apply Changes" button.</p>
1024 @ <form action="%s(g.zBaseURL)/vedit" method="POST">
1025 @ <input type="hidden" name="r" value="%d(rid)">
1026 @ <p>
1027 @ <b>User:</b> <input type="text" name="u" size="20" value="%h(zNewUser)">
1028 @ </p>
1029 @ <p><b>Comment:</b></b><br />
1030 wiki_convert(&comment, 0, WIKI_INLINE);
1031 @ <br /><textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea></p>
1032 @ <blockquote>
1033 @ <input type="submit" name="preview" value="Preview">
1034 @ <input type="submit" name="apply" value="Apply Changes">
1035 @ <input type="submit" name="cancel" value="Cancel">
1036 @ </blockquote>
1037 @ </form>
1038 style_footer();
1039 }
1040

Keyboard Shortcuts

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