Fossil SCM

merge trunk

jan.nijtmans 2013-01-15 10:03 UTC allow-backslash-in-card-filename merge
Commit 9a88d1963f17a1fe1367b56ec25cc078cf3cf868
+1 -1
--- src/checkin.c
+++ src/checkin.c
@@ -1527,11 +1527,11 @@
15271527
exit(1);
15281528
}
15291529
db_end_transaction(0);
15301530
15311531
if( !g.markPrivate ){
1532
- autosync(SYNC_PUSH);
1532
+ autosync(SYNC_PUSH|SYNC_PULL);
15331533
}
15341534
if( count_nonbranch_children(vid)>1 ){
15351535
fossil_print("**** warning: a fork has occurred *****\n");
15361536
}
15371537
}
15381538
--- src/checkin.c
+++ src/checkin.c
@@ -1527,11 +1527,11 @@
1527 exit(1);
1528 }
1529 db_end_transaction(0);
1530
1531 if( !g.markPrivate ){
1532 autosync(SYNC_PUSH);
1533 }
1534 if( count_nonbranch_children(vid)>1 ){
1535 fossil_print("**** warning: a fork has occurred *****\n");
1536 }
1537 }
1538
--- src/checkin.c
+++ src/checkin.c
@@ -1527,11 +1527,11 @@
1527 exit(1);
1528 }
1529 db_end_transaction(0);
1530
1531 if( !g.markPrivate ){
1532 autosync(SYNC_PUSH|SYNC_PULL);
1533 }
1534 if( count_nonbranch_children(vid)>1 ){
1535 fossil_print("**** warning: a fork has occurred *****\n");
1536 }
1537 }
1538
+3
--- src/db.c
+++ src/db.c
@@ -1222,10 +1222,13 @@
12221222
void db_create_default_users(int setupUserOnly, const char *zDefaultUser){
12231223
const char *zUser = zDefaultUser;
12241224
if( zUser==0 ){
12251225
zUser = db_get("default-user", 0);
12261226
}
1227
+ if( zUser==0 ){
1228
+ zUser = fossil_getenv("FOSSIL_USER");
1229
+ }
12271230
if( zUser==0 ){
12281231
#if defined(_WIN32)
12291232
zUser = fossil_getenv("USERNAME");
12301233
#else
12311234
zUser = fossil_getenv("USER");
12321235
--- src/db.c
+++ src/db.c
@@ -1222,10 +1222,13 @@
1222 void db_create_default_users(int setupUserOnly, const char *zDefaultUser){
1223 const char *zUser = zDefaultUser;
1224 if( zUser==0 ){
1225 zUser = db_get("default-user", 0);
1226 }
 
 
 
1227 if( zUser==0 ){
1228 #if defined(_WIN32)
1229 zUser = fossil_getenv("USERNAME");
1230 #else
1231 zUser = fossil_getenv("USER");
1232
--- src/db.c
+++ src/db.c
@@ -1222,10 +1222,13 @@
1222 void db_create_default_users(int setupUserOnly, const char *zDefaultUser){
1223 const char *zUser = zDefaultUser;
1224 if( zUser==0 ){
1225 zUser = db_get("default-user", 0);
1226 }
1227 if( zUser==0 ){
1228 zUser = fossil_getenv("FOSSIL_USER");
1229 }
1230 if( zUser==0 ){
1231 #if defined(_WIN32)
1232 zUser = fossil_getenv("USERNAME");
1233 #else
1234 zUser = fossil_getenv("USER");
1235
--- src/descendants.c
+++ src/descendants.c
@@ -348,10 +348,11 @@
348348
** repository database to be recomputed.
349349
**
350350
** Options:
351351
** --all show ALL leaves
352352
** --closed show only closed leaves
353
+** --bybranch order output by branch name
353354
** --recompute recompute the "leaf" table in the repository DB
354355
**
355356
** See also: descendants, finfo, info, branch
356357
*/
357358
void leaves_cmd(void){
@@ -358,10 +359,14 @@
358359
Stmt q;
359360
Blob sql;
360361
int showAll = find_option("all", 0, 0)!=0;
361362
int showClosed = find_option("closed", 0, 0)!=0;
362363
int recomputeFlag = find_option("recompute",0,0)!=0;
364
+ int byBranch = find_option("bybranch",0,0)!=0;
365
+ char *zLastBr = 0;
366
+ int n;
367
+ char zLineNo[10];
363368
364369
db_find_and_open_repository(0,0);
365370
if( recomputeFlag ) leaf_rebuild();
366371
blob_zero(&sql);
367372
blob_append(&sql, timeline_query_for_tty(), -1);
@@ -369,13 +374,39 @@
369374
if( showClosed ){
370375
blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
371376
}else if( !showAll ){
372377
blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
373378
}
374
- db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
379
+ if( byBranch ){
380
+ db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
381
+ " event.mtime DESC",
382
+ blob_str(&sql));
383
+ }else{
384
+ db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
385
+ }
375386
blob_reset(&sql);
376
- print_timeline(&q, 2000, 0);
387
+ n = 0;
388
+ while( db_step(&q)==SQLITE_ROW ){
389
+ const char *zId = db_column_text(&q, 1);
390
+ const char *zDate = db_column_text(&q, 2);
391
+ const char *zCom = db_column_text(&q, 3);
392
+ const char *zBr = db_column_text(&q, 7);
393
+ char *z;
394
+
395
+ if( byBranch && fossil_strcmp(zBr, zLastBr)!=0 ){
396
+ fossil_print("*** %s ***\n", zBr);
397
+ fossil_free(zLastBr);
398
+ zLastBr = fossil_strdup(zBr);
399
+ }
400
+ n++;
401
+ sqlite3_snprintf(sizeof(zLineNo), zLineNo, "(%d)", n);
402
+ fossil_print("%6s ", zLineNo);
403
+ z = mprintf("%s [%.10s] %s", zDate, zId, zCom);
404
+ comment_print(z, 7, 79);
405
+ fossil_free(z);
406
+ }
407
+ fossil_free(zLastBr);
377408
db_finalize(&q);
378409
}
379410
380411
/*
381412
** WEBPAGE: leaves
382413
--- src/descendants.c
+++ src/descendants.c
@@ -348,10 +348,11 @@
348 ** repository database to be recomputed.
349 **
350 ** Options:
351 ** --all show ALL leaves
352 ** --closed show only closed leaves
 
353 ** --recompute recompute the "leaf" table in the repository DB
354 **
355 ** See also: descendants, finfo, info, branch
356 */
357 void leaves_cmd(void){
@@ -358,10 +359,14 @@
358 Stmt q;
359 Blob sql;
360 int showAll = find_option("all", 0, 0)!=0;
361 int showClosed = find_option("closed", 0, 0)!=0;
362 int recomputeFlag = find_option("recompute",0,0)!=0;
 
 
 
 
363
364 db_find_and_open_repository(0,0);
365 if( recomputeFlag ) leaf_rebuild();
366 blob_zero(&sql);
367 blob_append(&sql, timeline_query_for_tty(), -1);
@@ -369,13 +374,39 @@
369 if( showClosed ){
370 blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
371 }else if( !showAll ){
372 blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
373 }
374 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
 
 
 
 
 
 
375 blob_reset(&sql);
376 print_timeline(&q, 2000, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377 db_finalize(&q);
378 }
379
380 /*
381 ** WEBPAGE: leaves
382
--- src/descendants.c
+++ src/descendants.c
@@ -348,10 +348,11 @@
348 ** repository database to be recomputed.
349 **
350 ** Options:
351 ** --all show ALL leaves
352 ** --closed show only closed leaves
353 ** --bybranch order output by branch name
354 ** --recompute recompute the "leaf" table in the repository DB
355 **
356 ** See also: descendants, finfo, info, branch
357 */
358 void leaves_cmd(void){
@@ -358,10 +359,14 @@
359 Stmt q;
360 Blob sql;
361 int showAll = find_option("all", 0, 0)!=0;
362 int showClosed = find_option("closed", 0, 0)!=0;
363 int recomputeFlag = find_option("recompute",0,0)!=0;
364 int byBranch = find_option("bybranch",0,0)!=0;
365 char *zLastBr = 0;
366 int n;
367 char zLineNo[10];
368
369 db_find_and_open_repository(0,0);
370 if( recomputeFlag ) leaf_rebuild();
371 blob_zero(&sql);
372 blob_append(&sql, timeline_query_for_tty(), -1);
@@ -369,13 +374,39 @@
374 if( showClosed ){
375 blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
376 }else if( !showAll ){
377 blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
378 }
379 if( byBranch ){
380 db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
381 " event.mtime DESC",
382 blob_str(&sql));
383 }else{
384 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
385 }
386 blob_reset(&sql);
387 n = 0;
388 while( db_step(&q)==SQLITE_ROW ){
389 const char *zId = db_column_text(&q, 1);
390 const char *zDate = db_column_text(&q, 2);
391 const char *zCom = db_column_text(&q, 3);
392 const char *zBr = db_column_text(&q, 7);
393 char *z;
394
395 if( byBranch && fossil_strcmp(zBr, zLastBr)!=0 ){
396 fossil_print("*** %s ***\n", zBr);
397 fossil_free(zLastBr);
398 zLastBr = fossil_strdup(zBr);
399 }
400 n++;
401 sqlite3_snprintf(sizeof(zLineNo), zLineNo, "(%d)", n);
402 fossil_print("%6s ", zLineNo);
403 z = mprintf("%s [%.10s] %s", zDate, zId, zCom);
404 comment_print(z, 7, 79);
405 fossil_free(z);
406 }
407 fossil_free(zLastBr);
408 db_finalize(&q);
409 }
410
411 /*
412 ** WEBPAGE: leaves
413
-2
--- src/diff.c
+++ src/diff.c
@@ -620,13 +620,11 @@
620620
621621
/* Show the differences */
622622
for(i=0; i<nr; i++){
623623
m = R[r+i*3+1];
624624
for(j=0; j<m; j++){
625
- char cMark = '-';
626625
if( showLn ) appendDiffLineno(pOut, a+j+1, 0, html);
627
- if( pRe && re_dline_match(pRe, &A[a+j], 1)==0 ) cMark = ' ';
628626
appendDiffLine(pOut, '-', &A[a+j], html, pRe);
629627
}
630628
a += m;
631629
m = R[r+i*3+2];
632630
for(j=0; j<m; j++){
633631
--- src/diff.c
+++ src/diff.c
@@ -620,13 +620,11 @@
620
621 /* Show the differences */
622 for(i=0; i<nr; i++){
623 m = R[r+i*3+1];
624 for(j=0; j<m; j++){
625 char cMark = '-';
626 if( showLn ) appendDiffLineno(pOut, a+j+1, 0, html);
627 if( pRe && re_dline_match(pRe, &A[a+j], 1)==0 ) cMark = ' ';
628 appendDiffLine(pOut, '-', &A[a+j], html, pRe);
629 }
630 a += m;
631 m = R[r+i*3+2];
632 for(j=0; j<m; j++){
633
--- src/diff.c
+++ src/diff.c
@@ -620,13 +620,11 @@
620
621 /* Show the differences */
622 for(i=0; i<nr; i++){
623 m = R[r+i*3+1];
624 for(j=0; j<m; j++){
 
625 if( showLn ) appendDiffLineno(pOut, a+j+1, 0, html);
 
626 appendDiffLine(pOut, '-', &A[a+j], html, pRe);
627 }
628 a += m;
629 m = R[r+i*3+2];
630 for(j=0; j<m; j++){
631
+1 -2
--- src/info.c
+++ src/info.c
@@ -1298,11 +1298,10 @@
12981298
char *zV2;
12991299
const char *zRe;
13001300
ReCompiled *pRe = 0;
13011301
u64 diffFlags;
13021302
const char *zStyle = "sbsdiff";
1303
- const char *zReErr = 0;
13041303
13051304
login_check_credentials();
13061305
if( !g.perm.Read ){ login_needed(); return; }
13071306
v1 = name_to_rid_www("v1");
13081307
v2 = name_to_rid_www("v2");
@@ -1325,11 +1324,11 @@
13251324
diffFlags |= DIFF_LINENO;
13261325
zStyle = "udiff";
13271326
}
13281327
}
13291328
zRe = P("regex");
1330
- if( zRe ) zReErr = re_compile(&pRe, zRe, 0);
1329
+ if( zRe ) re_compile(&pRe, zRe, 0);
13311330
content_get(v1, &c1);
13321331
content_get(v2, &c2);
13331332
text_diff(&c1, &c2, pOut, pRe, diffFlags);
13341333
blob_reset(&c1);
13351334
blob_reset(&c2);
13361335
--- src/info.c
+++ src/info.c
@@ -1298,11 +1298,10 @@
1298 char *zV2;
1299 const char *zRe;
1300 ReCompiled *pRe = 0;
1301 u64 diffFlags;
1302 const char *zStyle = "sbsdiff";
1303 const char *zReErr = 0;
1304
1305 login_check_credentials();
1306 if( !g.perm.Read ){ login_needed(); return; }
1307 v1 = name_to_rid_www("v1");
1308 v2 = name_to_rid_www("v2");
@@ -1325,11 +1324,11 @@
1325 diffFlags |= DIFF_LINENO;
1326 zStyle = "udiff";
1327 }
1328 }
1329 zRe = P("regex");
1330 if( zRe ) zReErr = re_compile(&pRe, zRe, 0);
1331 content_get(v1, &c1);
1332 content_get(v2, &c2);
1333 text_diff(&c1, &c2, pOut, pRe, diffFlags);
1334 blob_reset(&c1);
1335 blob_reset(&c2);
1336
--- src/info.c
+++ src/info.c
@@ -1298,11 +1298,10 @@
1298 char *zV2;
1299 const char *zRe;
1300 ReCompiled *pRe = 0;
1301 u64 diffFlags;
1302 const char *zStyle = "sbsdiff";
 
1303
1304 login_check_credentials();
1305 if( !g.perm.Read ){ login_needed(); return; }
1306 v1 = name_to_rid_www("v1");
1307 v2 = name_to_rid_www("v2");
@@ -1325,11 +1324,11 @@
1324 diffFlags |= DIFF_LINENO;
1325 zStyle = "udiff";
1326 }
1327 }
1328 zRe = P("regex");
1329 if( zRe ) re_compile(&pRe, zRe, 0);
1330 content_get(v1, &c1);
1331 content_get(v2, &c2);
1332 text_diff(&c1, &c2, pOut, pRe, diffFlags);
1333 blob_reset(&c1);
1334 blob_reset(&c2);
1335
+70 -8
--- src/merge.c
+++ src/merge.c
@@ -57,19 +57,22 @@
5757
5858
5959
/*
6060
** COMMAND: merge
6161
**
62
-** Usage: %fossil merge ?OPTIONS? VERSION
62
+** Usage: %fossil merge ?OPTIONS? ?VERSION?
6363
**
6464
** The argument VERSION is a version that should be merged into the
6565
** current checkout. All changes from VERSION back to the nearest
6666
** common ancestor are merged. Except, if either of the --cherrypick or
6767
** --backout options are used only the changes associated with the
6868
** single check-in VERSION are merged. The --backout option causes
6969
** the changes associated with VERSION to be removed from the current
7070
** checkout rather than added.
71
+**
72
+** If the VERSION argument is omitted, then Fossil attempts to find
73
+** a recent fork on the current branch to merge.
7174
**
7275
** Only file content is merged. The result continues to use the
7376
** file and directory names from the current checkout even if those
7477
** names might have been changed in the branch being merged in.
7578
**
@@ -131,24 +134,83 @@
131134
zBinGlob = find_option("binary",0,1);
132135
nochangeFlag = find_option("nochange","n",0)!=0;
133136
forceFlag = find_option("force","f",0)!=0;
134137
zPivot = find_option("baseline",0,1);
135138
capture_case_sensitive_option();
136
- if( g.argc!=3 ){
137
- usage("VERSION");
138
- }
139
+ verify_all_options();
139140
db_must_be_within_tree();
140141
caseSensitive = filenames_are_case_sensitive();
141142
if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
142143
vid = db_lget_int("checkout", 0);
143144
if( vid==0 ){
144145
fossil_fatal("nothing is checked out");
145146
}
146
- mid = name_to_typed_rid(g.argv[2], "ci");
147
- if( mid==0 || !is_a_version(mid) ){
148
- fossil_fatal("not a version: %s", g.argv[2]);
147
+
148
+ /* Find mid, the artifactID of the version to be merged into the current
149
+ ** check-out */
150
+ if( g.argc==3 ){
151
+ /* Mid is specified as an argument on the command-line */
152
+ mid = name_to_typed_rid(g.argv[2], "ci");
153
+ if( mid==0 || !is_a_version(mid) ){
154
+ fossil_fatal("not a version: %s", g.argv[2]);
155
+ }
156
+ }else if( g.argc==2 ){
157
+ /* No version specified on the command-line so pick the most recent
158
+ ** leaf that is (1) not the version currently checked out and (2)
159
+ ** has not already been merged into the current checkout and (3)
160
+ ** the leaf is not closed and (4) the leaf is in the same branch
161
+ ** as the current checkout.
162
+ */
163
+ Stmt q;
164
+ if( pickFlag || backoutFlag ){
165
+ fossil_fatal("cannot use --cherrypick or --backout with a fork merge");
166
+ }
167
+ mid = db_int(0,
168
+ "SELECT leaf.rid"
169
+ " FROM leaf, event"
170
+ " WHERE leaf.rid=event.objid"
171
+ " AND leaf.rid!=%d" /* Constraint (1) */
172
+ " AND leaf.rid NOT IN (SELECT merge FROM vmerge)" /* Constraint (2) */
173
+ " AND NOT EXISTS(SELECT 1 FROM tagxref" /* Constraint (3) */
174
+ " WHERE rid=leaf.rid"
175
+ " AND tagid=%d"
176
+ " AND tagtype>0)"
177
+ " AND (SELECT value FROM tagxref" /* Constraint (4) */
178
+ " WHERE tagid=%d AND rid=%d AND tagtype>0) ="
179
+ " (SELECT value FROM tagxref"
180
+ " WHERE tagid=%d AND rid=leaf.rid AND tagtype>0)"
181
+ " ORDER BY event.mtime DESC LIMIT 1",
182
+ vid, TAG_CLOSED, TAG_BRANCH, vid, TAG_BRANCH
183
+ );
184
+ if( mid==0 ){
185
+ fossil_fatal("no unmerged forks of branch \"%s\"",
186
+ db_text(0, "SELECT value FROM tagxref"
187
+ " WHERE tagid=%d AND rid=%d AND tagtype>0",
188
+ TAG_BRANCH, vid)
189
+ );
190
+ }
191
+ db_prepare(&q,
192
+ "SELECT blob.uuid,"
193
+ " datetime(event.mtime,'localtime'),"
194
+ " coalesce(ecomment, comment),"
195
+ " coalesce(euser, user)"
196
+ " FROM event, blob"
197
+ " WHERE event.objid=%d AND blob.rid=%d",
198
+ mid, mid
199
+ );
200
+ if( db_step(&q)==SQLITE_ROW ){
201
+ char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"",
202
+ db_column_text(&q, 0), db_column_text(&q, 1),
203
+ db_column_text(&q, 3), db_column_text(&q, 2));
204
+ comment_print(zCom, 0, 79);
205
+ fossil_free(zCom);
206
+ }
207
+ db_finalize(&q);
208
+ }else{
209
+ usage("?OPTIONS? ?VERSION?");
149210
}
211
+
150212
if( zPivot ){
151213
pid = name_to_typed_rid(zPivot, "ci");
152214
if( pid==0 || !is_a_version(pid) ){
153215
fossil_fatal("not a version: %s", zPivot);
154216
}
@@ -347,11 +409,11 @@
347409
"SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0"
348410
);
349411
while( db_step(&q)==SQLITE_ROW ){
350412
int idm = db_column_int(&q, 0);
351413
char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm);
352
- fossil_warning("WARNING - no common ancestor: %s\n", zName);
414
+ fossil_warning("WARNING - no common ancestor: %s", zName);
353415
free(zName);
354416
db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm);
355417
}
356418
db_finalize(&q);
357419
358420
--- src/merge.c
+++ src/merge.c
@@ -57,19 +57,22 @@
57
58
59 /*
60 ** COMMAND: merge
61 **
62 ** Usage: %fossil merge ?OPTIONS? VERSION
63 **
64 ** The argument VERSION is a version that should be merged into the
65 ** current checkout. All changes from VERSION back to the nearest
66 ** common ancestor are merged. Except, if either of the --cherrypick or
67 ** --backout options are used only the changes associated with the
68 ** single check-in VERSION are merged. The --backout option causes
69 ** the changes associated with VERSION to be removed from the current
70 ** checkout rather than added.
 
 
 
71 **
72 ** Only file content is merged. The result continues to use the
73 ** file and directory names from the current checkout even if those
74 ** names might have been changed in the branch being merged in.
75 **
@@ -131,24 +134,83 @@
131 zBinGlob = find_option("binary",0,1);
132 nochangeFlag = find_option("nochange","n",0)!=0;
133 forceFlag = find_option("force","f",0)!=0;
134 zPivot = find_option("baseline",0,1);
135 capture_case_sensitive_option();
136 if( g.argc!=3 ){
137 usage("VERSION");
138 }
139 db_must_be_within_tree();
140 caseSensitive = filenames_are_case_sensitive();
141 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
142 vid = db_lget_int("checkout", 0);
143 if( vid==0 ){
144 fossil_fatal("nothing is checked out");
145 }
146 mid = name_to_typed_rid(g.argv[2], "ci");
147 if( mid==0 || !is_a_version(mid) ){
148 fossil_fatal("not a version: %s", g.argv[2]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149 }
 
150 if( zPivot ){
151 pid = name_to_typed_rid(zPivot, "ci");
152 if( pid==0 || !is_a_version(pid) ){
153 fossil_fatal("not a version: %s", zPivot);
154 }
@@ -347,11 +409,11 @@
347 "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0"
348 );
349 while( db_step(&q)==SQLITE_ROW ){
350 int idm = db_column_int(&q, 0);
351 char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm);
352 fossil_warning("WARNING - no common ancestor: %s\n", zName);
353 free(zName);
354 db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm);
355 }
356 db_finalize(&q);
357
358
--- src/merge.c
+++ src/merge.c
@@ -57,19 +57,22 @@
57
58
59 /*
60 ** COMMAND: merge
61 **
62 ** Usage: %fossil merge ?OPTIONS? ?VERSION?
63 **
64 ** The argument VERSION is a version that should be merged into the
65 ** current checkout. All changes from VERSION back to the nearest
66 ** common ancestor are merged. Except, if either of the --cherrypick or
67 ** --backout options are used only the changes associated with the
68 ** single check-in VERSION are merged. The --backout option causes
69 ** the changes associated with VERSION to be removed from the current
70 ** checkout rather than added.
71 **
72 ** If the VERSION argument is omitted, then Fossil attempts to find
73 ** a recent fork on the current branch to merge.
74 **
75 ** Only file content is merged. The result continues to use the
76 ** file and directory names from the current checkout even if those
77 ** names might have been changed in the branch being merged in.
78 **
@@ -131,24 +134,83 @@
134 zBinGlob = find_option("binary",0,1);
135 nochangeFlag = find_option("nochange","n",0)!=0;
136 forceFlag = find_option("force","f",0)!=0;
137 zPivot = find_option("baseline",0,1);
138 capture_case_sensitive_option();
139 verify_all_options();
 
 
140 db_must_be_within_tree();
141 caseSensitive = filenames_are_case_sensitive();
142 if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
143 vid = db_lget_int("checkout", 0);
144 if( vid==0 ){
145 fossil_fatal("nothing is checked out");
146 }
147
148 /* Find mid, the artifactID of the version to be merged into the current
149 ** check-out */
150 if( g.argc==3 ){
151 /* Mid is specified as an argument on the command-line */
152 mid = name_to_typed_rid(g.argv[2], "ci");
153 if( mid==0 || !is_a_version(mid) ){
154 fossil_fatal("not a version: %s", g.argv[2]);
155 }
156 }else if( g.argc==2 ){
157 /* No version specified on the command-line so pick the most recent
158 ** leaf that is (1) not the version currently checked out and (2)
159 ** has not already been merged into the current checkout and (3)
160 ** the leaf is not closed and (4) the leaf is in the same branch
161 ** as the current checkout.
162 */
163 Stmt q;
164 if( pickFlag || backoutFlag ){
165 fossil_fatal("cannot use --cherrypick or --backout with a fork merge");
166 }
167 mid = db_int(0,
168 "SELECT leaf.rid"
169 " FROM leaf, event"
170 " WHERE leaf.rid=event.objid"
171 " AND leaf.rid!=%d" /* Constraint (1) */
172 " AND leaf.rid NOT IN (SELECT merge FROM vmerge)" /* Constraint (2) */
173 " AND NOT EXISTS(SELECT 1 FROM tagxref" /* Constraint (3) */
174 " WHERE rid=leaf.rid"
175 " AND tagid=%d"
176 " AND tagtype>0)"
177 " AND (SELECT value FROM tagxref" /* Constraint (4) */
178 " WHERE tagid=%d AND rid=%d AND tagtype>0) ="
179 " (SELECT value FROM tagxref"
180 " WHERE tagid=%d AND rid=leaf.rid AND tagtype>0)"
181 " ORDER BY event.mtime DESC LIMIT 1",
182 vid, TAG_CLOSED, TAG_BRANCH, vid, TAG_BRANCH
183 );
184 if( mid==0 ){
185 fossil_fatal("no unmerged forks of branch \"%s\"",
186 db_text(0, "SELECT value FROM tagxref"
187 " WHERE tagid=%d AND rid=%d AND tagtype>0",
188 TAG_BRANCH, vid)
189 );
190 }
191 db_prepare(&q,
192 "SELECT blob.uuid,"
193 " datetime(event.mtime,'localtime'),"
194 " coalesce(ecomment, comment),"
195 " coalesce(euser, user)"
196 " FROM event, blob"
197 " WHERE event.objid=%d AND blob.rid=%d",
198 mid, mid
199 );
200 if( db_step(&q)==SQLITE_ROW ){
201 char *zCom = mprintf("Merging fork [%S] at %s by %s: \"%s\"",
202 db_column_text(&q, 0), db_column_text(&q, 1),
203 db_column_text(&q, 3), db_column_text(&q, 2));
204 comment_print(zCom, 0, 79);
205 fossil_free(zCom);
206 }
207 db_finalize(&q);
208 }else{
209 usage("?OPTIONS? ?VERSION?");
210 }
211
212 if( zPivot ){
213 pid = name_to_typed_rid(zPivot, "ci");
214 if( pid==0 || !is_a_version(pid) ){
215 fossil_fatal("not a version: %s", zPivot);
216 }
@@ -347,11 +409,11 @@
409 "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0"
410 );
411 while( db_step(&q)==SQLITE_ROW ){
412 int idm = db_column_int(&q, 0);
413 char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm);
414 fossil_warning("WARNING - no common ancestor: %s", zName);
415 free(zName);
416 db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm);
417 }
418 db_finalize(&q);
419
420
+9 -9
--- src/regexp.c
+++ src/regexp.c
@@ -32,11 +32,11 @@
3232
** X$ X occurring at the end of the string
3333
** . Match any single character
3434
** \c Character c where c is one of \{}()[]|*+?.
3535
** \c C-language escapes for c in afnrtv. ex: \t or \n
3636
** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX
37
-** \xXXX Where XXX is any number of hex digits, unicode value XXX
37
+** \xXX Where XX is exactly 2 hex digits, unicode value XX
3838
** [abc] Any single character from the set abc
3939
** [^abc] Any single character not in the set abc
4040
** [a-z] Any single character in the range a-z
4141
** [^a-z] Any single character not in the range a-z
4242
** \b Word boundary
@@ -381,22 +381,21 @@
381381
*pV = (*pV)*16 + (c & 0xff);
382382
return 1;
383383
}
384384
385385
/* A backslash character has been seen, read the next character and
386
-** return its intepretation.
386
+** return its interpretation.
387387
*/
388388
static unsigned re_esc_char(ReCompiled *p){
389389
static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
390390
static const char zTrans[] = "\a\f\n\r\t\v";
391391
int i, v = 0;
392392
char c;
393393
if( p->sIn.i>=p->sIn.mx ) return 0;
394394
c = p->sIn.z[p->sIn.i];
395
- if( c=='u' && p->sIn.i+5<p->sIn.mx ){
395
+ if( c=='u' && p->sIn.i+4<p->sIn.mx ){
396396
const unsigned char *zIn = p->sIn.z + p->sIn.i;
397
- v = 0;
398397
if( re_hex(zIn[1],&v)
399398
&& re_hex(zIn[2],&v)
400399
&& re_hex(zIn[3],&v)
401400
&& re_hex(zIn[4],&v)
402401
){
@@ -403,15 +402,16 @@
403402
p->sIn.i += 5;
404403
return v;
405404
}
406405
}
407406
if( c=='x' ){
408
- v = 0;
409
- for(i=1; p->sIn.i<p->sIn.mx && re_hex(p->sIn.z[p->sIn.i+i], &v); i++){}
410
- if( i>1 ){
411
- p->sIn.i += i;
412
- return v;
407
+ const unsigned char *zIn = p->sIn.z + p->sIn.i;
408
+ if( p->sIn.i+2<p->sIn.mx ){
409
+ if( re_hex(zIn[1],&v) && re_hex(zIn[2],&v) ){
410
+ p->sIn.i += 3;
411
+ return v;
412
+ }
413413
}
414414
}
415415
for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
416416
if( zEsc[i] ){
417417
if( i<6 ) c = zTrans[i];
418418
--- src/regexp.c
+++ src/regexp.c
@@ -32,11 +32,11 @@
32 ** X$ X occurring at the end of the string
33 ** . Match any single character
34 ** \c Character c where c is one of \{}()[]|*+?.
35 ** \c C-language escapes for c in afnrtv. ex: \t or \n
36 ** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX
37 ** \xXXX Where XXX is any number of hex digits, unicode value XXX
38 ** [abc] Any single character from the set abc
39 ** [^abc] Any single character not in the set abc
40 ** [a-z] Any single character in the range a-z
41 ** [^a-z] Any single character not in the range a-z
42 ** \b Word boundary
@@ -381,22 +381,21 @@
381 *pV = (*pV)*16 + (c & 0xff);
382 return 1;
383 }
384
385 /* A backslash character has been seen, read the next character and
386 ** return its intepretation.
387 */
388 static unsigned re_esc_char(ReCompiled *p){
389 static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
390 static const char zTrans[] = "\a\f\n\r\t\v";
391 int i, v = 0;
392 char c;
393 if( p->sIn.i>=p->sIn.mx ) return 0;
394 c = p->sIn.z[p->sIn.i];
395 if( c=='u' && p->sIn.i+5<p->sIn.mx ){
396 const unsigned char *zIn = p->sIn.z + p->sIn.i;
397 v = 0;
398 if( re_hex(zIn[1],&v)
399 && re_hex(zIn[2],&v)
400 && re_hex(zIn[3],&v)
401 && re_hex(zIn[4],&v)
402 ){
@@ -403,15 +402,16 @@
403 p->sIn.i += 5;
404 return v;
405 }
406 }
407 if( c=='x' ){
408 v = 0;
409 for(i=1; p->sIn.i<p->sIn.mx && re_hex(p->sIn.z[p->sIn.i+i], &v); i++){}
410 if( i>1 ){
411 p->sIn.i += i;
412 return v;
 
413 }
414 }
415 for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
416 if( zEsc[i] ){
417 if( i<6 ) c = zTrans[i];
418
--- src/regexp.c
+++ src/regexp.c
@@ -32,11 +32,11 @@
32 ** X$ X occurring at the end of the string
33 ** . Match any single character
34 ** \c Character c where c is one of \{}()[]|*+?.
35 ** \c C-language escapes for c in afnrtv. ex: \t or \n
36 ** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX
37 ** \xXX Where XX is exactly 2 hex digits, unicode value XX
38 ** [abc] Any single character from the set abc
39 ** [^abc] Any single character not in the set abc
40 ** [a-z] Any single character in the range a-z
41 ** [^a-z] Any single character not in the range a-z
42 ** \b Word boundary
@@ -381,22 +381,21 @@
381 *pV = (*pV)*16 + (c & 0xff);
382 return 1;
383 }
384
385 /* A backslash character has been seen, read the next character and
386 ** return its interpretation.
387 */
388 static unsigned re_esc_char(ReCompiled *p){
389 static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
390 static const char zTrans[] = "\a\f\n\r\t\v";
391 int i, v = 0;
392 char c;
393 if( p->sIn.i>=p->sIn.mx ) return 0;
394 c = p->sIn.z[p->sIn.i];
395 if( c=='u' && p->sIn.i+4<p->sIn.mx ){
396 const unsigned char *zIn = p->sIn.z + p->sIn.i;
 
397 if( re_hex(zIn[1],&v)
398 && re_hex(zIn[2],&v)
399 && re_hex(zIn[3],&v)
400 && re_hex(zIn[4],&v)
401 ){
@@ -403,15 +402,16 @@
402 p->sIn.i += 5;
403 return v;
404 }
405 }
406 if( c=='x' ){
407 const unsigned char *zIn = p->sIn.z + p->sIn.i;
408 if( p->sIn.i+2<p->sIn.mx ){
409 if( re_hex(zIn[1],&v) && re_hex(zIn[2],&v) ){
410 p->sIn.i += 3;
411 return v;
412 }
413 }
414 }
415 for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
416 if( zEsc[i] ){
417 if( i<6 ) c = zTrans[i];
418
--- src/schema.c
+++ src/schema.c
@@ -385,10 +385,11 @@
385385
@ CREATE TABLE ticket(
386386
@ -- Do not change any column that begins with tkt_
387387
@ tkt_id INTEGER PRIMARY KEY,
388388
@ tkt_uuid TEXT UNIQUE,
389389
@ tkt_mtime DATE,
390
+@ tkt_ctime DATE,
390391
@ -- Add as many field as required below this line
391392
@ type TEXT,
392393
@ status TEXT,
393394
@ subsystem TEXT,
394395
@ priority TEXT,
@@ -400,10 +401,11 @@
400401
@ comment TEXT
401402
@ );
402403
@ CREATE TABLE ticketchng(
403404
@ -- Do not change any column that begins with tkt_
404405
@ tkt_id INTEGER REFERENCES ticket,
406
+@ tkt_rid INTEGER REFERENCES blob,
405407
@ tkt_mtime DATE,
406408
@ -- Add as many fields as required below this line
407409
@ login TEXT,
408410
@ username TEXT,
409411
@ mimetype TEXT,
410412
--- src/schema.c
+++ src/schema.c
@@ -385,10 +385,11 @@
385 @ CREATE TABLE ticket(
386 @ -- Do not change any column that begins with tkt_
387 @ tkt_id INTEGER PRIMARY KEY,
388 @ tkt_uuid TEXT UNIQUE,
389 @ tkt_mtime DATE,
 
390 @ -- Add as many field as required below this line
391 @ type TEXT,
392 @ status TEXT,
393 @ subsystem TEXT,
394 @ priority TEXT,
@@ -400,10 +401,11 @@
400 @ comment TEXT
401 @ );
402 @ CREATE TABLE ticketchng(
403 @ -- Do not change any column that begins with tkt_
404 @ tkt_id INTEGER REFERENCES ticket,
 
405 @ tkt_mtime DATE,
406 @ -- Add as many fields as required below this line
407 @ login TEXT,
408 @ username TEXT,
409 @ mimetype TEXT,
410
--- src/schema.c
+++ src/schema.c
@@ -385,10 +385,11 @@
385 @ CREATE TABLE ticket(
386 @ -- Do not change any column that begins with tkt_
387 @ tkt_id INTEGER PRIMARY KEY,
388 @ tkt_uuid TEXT UNIQUE,
389 @ tkt_mtime DATE,
390 @ tkt_ctime DATE,
391 @ -- Add as many field as required below this line
392 @ type TEXT,
393 @ status TEXT,
394 @ subsystem TEXT,
395 @ priority TEXT,
@@ -400,10 +401,11 @@
401 @ comment TEXT
402 @ );
403 @ CREATE TABLE ticketchng(
404 @ -- Do not change any column that begins with tkt_
405 @ tkt_id INTEGER REFERENCES ticket,
406 @ tkt_rid INTEGER REFERENCES blob,
407 @ tkt_mtime DATE,
408 @ -- Add as many fields as required below this line
409 @ login TEXT,
410 @ username TEXT,
411 @ mimetype TEXT,
412
+104
--- src/stat.c
+++ src/stat.c
@@ -137,10 +137,114 @@
137137
@ </td></tr>
138138
139139
@ </table>
140140
style_footer();
141141
}
142
+
143
+/*
144
+** COMMAND: dbstat
145
+**
146
+** Show statistics and global information about the repository.
147
+*/
148
+void dbstat_cmd(void){
149
+ i64 t, fsize;
150
+ int n, m;
151
+ int szMax, szAvg;
152
+ const char *zDb;
153
+ int brief;
154
+ char zBuf[100];
155
+ const int colWidth = -20 /* printf alignment/width for left column */;
156
+ brief = find_option("brief", "b",0)!=0;
157
+ db_find_and_open_repository(0,0);
158
+ fsize = file_size(g.zRepositoryName);
159
+ bigSizeName(sizeof(zBuf), zBuf, fsize);
160
+ fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
161
+ if( !brief ){
162
+ n = db_int(0, "SELECT count(*) FROM blob");
163
+ m = db_int(0, "SELECT count(*) FROM delta");
164
+ fossil_print("%*s%d (stored as %d full text and %d delta blobs)\n",
165
+ colWidth, "artifact-count:",
166
+ n, n-m, m);
167
+ if( n>0 ){
168
+ int a, b;
169
+ Stmt q;
170
+ db_prepare(&q, "SELECT total(size), avg(size), max(size)"
171
+ " FROM blob WHERE size>0");
172
+ db_step(&q);
173
+ t = db_column_int64(&q, 0);
174
+ szAvg = db_column_int(&q, 1);
175
+ szMax = db_column_int(&q, 2);
176
+ db_finalize(&q);
177
+ bigSizeName(sizeof(zBuf), zBuf, t);
178
+ fossil_print( "%*s%d bytes average, "
179
+ "%d bytes max, %s total\n",
180
+ colWidth, "artifact-sizes:",
181
+ szAvg, szMax, zBuf);
182
+ if( t/fsize < 5 ){
183
+ b = 10;
184
+ fsize /= 10;
185
+ }else{
186
+ b = 1;
187
+ }
188
+ a = t/fsize;
189
+ fossil_print("%*s%d:%d\n", colWidth, "compression-ratio:", a, b);
190
+ }
191
+ n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'");
192
+ fossil_print("%*s%d\n", colWidth, "checkin-count:", n);
193
+ n = db_int(0, "SELECT count(*) FROM filename /*scan*/");
194
+ /* FIXME/TODO: add the change-count-per-type to each event type,
195
+ ** plus add 'Event' count
196
+ */
197
+#if 0
198
+ m = db_int(0, "SELECT count(distinct mid) FROM mlink /*scan*/");
199
+#endif
200
+ fossil_print("%*s%d"/* (%d changes) */"\n", colWidth, "file-count:",
201
+ n/*, m */);
202
+ n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
203
+ " WHERE tagname GLOB 'wiki-*'");
204
+#if 0
205
+ m = db_int(0, "SELECT COUNT(*) FROM blob b JOIN event e WHERE "
206
+ "b.rid=e.objid AND e.type='w'");
207
+#endif
208
+ fossil_print("%*s%d"/* (%d changes) */"\n", colWidth, "wikipage-count:",
209
+ n/*, m */);
210
+ n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
211
+ " WHERE tagname GLOB 'tkt-*'");
212
+#if 0
213
+ m = db_int(0, "SELECT COUNT(*) FROM blob b JOIN event e WHERE "
214
+ "b.rid=e.objid AND e.type='t'");
215
+#endif
216
+ fossil_print("%*s%d"/* (%d changes)*/"\n", colWidth, "ticket-count:",
217
+ n/* , m */);
218
+ }
219
+ n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
220
+ " + 0.99");
221
+ fossil_print("%*s%d days or approximately %.2f years.\n",
222
+ colWidth, "project-age:", n, n/365.24);
223
+ fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code",""));
224
+ fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code",""));
225
+ fossil_print("%*s%s %s %s (%s)\n",
226
+ colWidth, "fossil-version:",
227
+ RELEASE_VERSION, MANIFEST_DATE, MANIFEST_VERSION,
228
+ COMPILER_NAME);
229
+ fossil_print("%*s%.19s [%.10s] (%s)\n",
230
+ colWidth, "sqlite-version:",
231
+ SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20],
232
+ SQLITE_VERSION);
233
+ zDb = db_name("repository");
234
+ fossil_print("%*s%d pages, %d bytes/page, %d free pages, "
235
+ "%s, %s mode\n",
236
+ colWidth, "database-stats:",
237
+ db_int(0, "PRAGMA %s.page_count", zDb),
238
+ db_int(0, "PRAGMA %s.page_size", zDb),
239
+ db_int(0, "PRAGMA %s.freelist_count", zDb),
240
+ db_text(0, "PRAGMA %s.encoding", zDb),
241
+ db_text(0, "PRAGMA %s.journal_mode", zDb));
242
+
243
+}
244
+
245
+
142246
143247
/*
144248
** WEBPAGE: urllist
145249
**
146250
** Show ways in which this repository has been accessed
147251
--- src/stat.c
+++ src/stat.c
@@ -137,10 +137,114 @@
137 @ </td></tr>
138
139 @ </table>
140 style_footer();
141 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
143 /*
144 ** WEBPAGE: urllist
145 **
146 ** Show ways in which this repository has been accessed
147
--- src/stat.c
+++ src/stat.c
@@ -137,10 +137,114 @@
137 @ </td></tr>
138
139 @ </table>
140 style_footer();
141 }
142
143 /*
144 ** COMMAND: dbstat
145 **
146 ** Show statistics and global information about the repository.
147 */
148 void dbstat_cmd(void){
149 i64 t, fsize;
150 int n, m;
151 int szMax, szAvg;
152 const char *zDb;
153 int brief;
154 char zBuf[100];
155 const int colWidth = -20 /* printf alignment/width for left column */;
156 brief = find_option("brief", "b",0)!=0;
157 db_find_and_open_repository(0,0);
158 fsize = file_size(g.zRepositoryName);
159 bigSizeName(sizeof(zBuf), zBuf, fsize);
160 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
161 if( !brief ){
162 n = db_int(0, "SELECT count(*) FROM blob");
163 m = db_int(0, "SELECT count(*) FROM delta");
164 fossil_print("%*s%d (stored as %d full text and %d delta blobs)\n",
165 colWidth, "artifact-count:",
166 n, n-m, m);
167 if( n>0 ){
168 int a, b;
169 Stmt q;
170 db_prepare(&q, "SELECT total(size), avg(size), max(size)"
171 " FROM blob WHERE size>0");
172 db_step(&q);
173 t = db_column_int64(&q, 0);
174 szAvg = db_column_int(&q, 1);
175 szMax = db_column_int(&q, 2);
176 db_finalize(&q);
177 bigSizeName(sizeof(zBuf), zBuf, t);
178 fossil_print( "%*s%d bytes average, "
179 "%d bytes max, %s total\n",
180 colWidth, "artifact-sizes:",
181 szAvg, szMax, zBuf);
182 if( t/fsize < 5 ){
183 b = 10;
184 fsize /= 10;
185 }else{
186 b = 1;
187 }
188 a = t/fsize;
189 fossil_print("%*s%d:%d\n", colWidth, "compression-ratio:", a, b);
190 }
191 n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'");
192 fossil_print("%*s%d\n", colWidth, "checkin-count:", n);
193 n = db_int(0, "SELECT count(*) FROM filename /*scan*/");
194 /* FIXME/TODO: add the change-count-per-type to each event type,
195 ** plus add 'Event' count
196 */
197 #if 0
198 m = db_int(0, "SELECT count(distinct mid) FROM mlink /*scan*/");
199 #endif
200 fossil_print("%*s%d"/* (%d changes) */"\n", colWidth, "file-count:",
201 n/*, m */);
202 n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
203 " WHERE tagname GLOB 'wiki-*'");
204 #if 0
205 m = db_int(0, "SELECT COUNT(*) FROM blob b JOIN event e WHERE "
206 "b.rid=e.objid AND e.type='w'");
207 #endif
208 fossil_print("%*s%d"/* (%d changes) */"\n", colWidth, "wikipage-count:",
209 n/*, m */);
210 n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
211 " WHERE tagname GLOB 'tkt-*'");
212 #if 0
213 m = db_int(0, "SELECT COUNT(*) FROM blob b JOIN event e WHERE "
214 "b.rid=e.objid AND e.type='t'");
215 #endif
216 fossil_print("%*s%d"/* (%d changes)*/"\n", colWidth, "ticket-count:",
217 n/* , m */);
218 }
219 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
220 " + 0.99");
221 fossil_print("%*s%d days or approximately %.2f years.\n",
222 colWidth, "project-age:", n, n/365.24);
223 fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code",""));
224 fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code",""));
225 fossil_print("%*s%s %s %s (%s)\n",
226 colWidth, "fossil-version:",
227 RELEASE_VERSION, MANIFEST_DATE, MANIFEST_VERSION,
228 COMPILER_NAME);
229 fossil_print("%*s%.19s [%.10s] (%s)\n",
230 colWidth, "sqlite-version:",
231 SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20],
232 SQLITE_VERSION);
233 zDb = db_name("repository");
234 fossil_print("%*s%d pages, %d bytes/page, %d free pages, "
235 "%s, %s mode\n",
236 colWidth, "database-stats:",
237 db_int(0, "PRAGMA %s.page_count", zDb),
238 db_int(0, "PRAGMA %s.page_size", zDb),
239 db_int(0, "PRAGMA %s.freelist_count", zDb),
240 db_text(0, "PRAGMA %s.encoding", zDb),
241 db_text(0, "PRAGMA %s.journal_mode", zDb));
242
243 }
244
245
246
247 /*
248 ** WEBPAGE: urllist
249 **
250 ** Show ways in which this repository has been accessed
251
+11 -3
--- src/timeline.c
+++ src/timeline.c
@@ -1392,10 +1392,12 @@
13921392
** 1. uuid
13931393
** 2. Date/Time
13941394
** 3. Comment string and user
13951395
** 4. Number of non-merge children
13961396
** 5. Number of parents
1397
+** 6. mtime
1398
+** 7. branch
13971399
*/
13981400
void print_timeline(Stmt *q, int mxLine, int showfiles){
13991401
int nLine = 0;
14001402
char zPrevDate[20];
14011403
const char *zCurrentUuid=0;
@@ -1500,15 +1502,21 @@
15001502
@ FROM (SELECT group_concat(substr(tagname,5), ', ') AS x
15011503
@ FROM tag, tagxref
15021504
@ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
15031505
@ AND tagxref.rid=blob.rid AND tagxref.tagtype>0))
15041506
@ || ')' as comment,
1505
- @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim) AS primPlinkCount,
1507
+ @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim)
1508
+ @ AS primPlinkCount,
15061509
@ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
1507
- @ event.mtime AS mtime
1508
- @ FROM event, blob
1510
+ @ event.mtime AS mtime,
1511
+ @ tagxref.value AS branch
1512
+ @ FROM tag CROSS JOIN event CROSS JOIN blob CROSS JOIN tagxref
15091513
@ WHERE blob.rid=event.objid
1514
+ @ AND tag.tagname='branch'
1515
+ @ AND tagxref.tagid=tag.tagid
1516
+ @ AND tagxref.tagtype>0
1517
+ @ AND tagxref.rid=blob.rid
15101518
;
15111519
return zBaseSql;
15121520
}
15131521
15141522
/*
15151523
--- src/timeline.c
+++ src/timeline.c
@@ -1392,10 +1392,12 @@
1392 ** 1. uuid
1393 ** 2. Date/Time
1394 ** 3. Comment string and user
1395 ** 4. Number of non-merge children
1396 ** 5. Number of parents
 
 
1397 */
1398 void print_timeline(Stmt *q, int mxLine, int showfiles){
1399 int nLine = 0;
1400 char zPrevDate[20];
1401 const char *zCurrentUuid=0;
@@ -1500,15 +1502,21 @@
1500 @ FROM (SELECT group_concat(substr(tagname,5), ', ') AS x
1501 @ FROM tag, tagxref
1502 @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
1503 @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0))
1504 @ || ')' as comment,
1505 @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim) AS primPlinkCount,
 
1506 @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
1507 @ event.mtime AS mtime
1508 @ FROM event, blob
 
1509 @ WHERE blob.rid=event.objid
 
 
 
 
1510 ;
1511 return zBaseSql;
1512 }
1513
1514 /*
1515
--- src/timeline.c
+++ src/timeline.c
@@ -1392,10 +1392,12 @@
1392 ** 1. uuid
1393 ** 2. Date/Time
1394 ** 3. Comment string and user
1395 ** 4. Number of non-merge children
1396 ** 5. Number of parents
1397 ** 6. mtime
1398 ** 7. branch
1399 */
1400 void print_timeline(Stmt *q, int mxLine, int showfiles){
1401 int nLine = 0;
1402 char zPrevDate[20];
1403 const char *zCurrentUuid=0;
@@ -1500,15 +1502,21 @@
1502 @ FROM (SELECT group_concat(substr(tagname,5), ', ') AS x
1503 @ FROM tag, tagxref
1504 @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
1505 @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0))
1506 @ || ')' as comment,
1507 @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim)
1508 @ AS primPlinkCount,
1509 @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
1510 @ event.mtime AS mtime,
1511 @ tagxref.value AS branch
1512 @ FROM tag CROSS JOIN event CROSS JOIN blob CROSS JOIN tagxref
1513 @ WHERE blob.rid=event.objid
1514 @ AND tag.tagname='branch'
1515 @ AND tagxref.tagid=tag.tagid
1516 @ AND tagxref.tagtype>0
1517 @ AND tagxref.rid=blob.rid
1518 ;
1519 return zBaseSql;
1520 }
1521
1522 /*
1523
+73 -16
--- src/tkt.c
+++ src/tkt.c
@@ -34,12 +34,15 @@
3434
char *zAppend; /* Value to append */
3535
unsigned mUsed; /* 01: TICKET 02: TICKETCHNG */
3636
} *aField;
3737
#define USEDBY_TICKET 01
3838
#define USEDBY_TICKETCHNG 02
39
-static int haveTicket = 0; /* True if the TICKET table exists */
40
-static int haveTicketChng = 0; /* True if the TICKETCHNG table exists */
39
+#define USEDBY_BOTH 03
40
+static u8 haveTicket = 0; /* True if the TICKET table exists */
41
+static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
42
+static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
43
+static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
4144
4245
/*
4346
** Compare two entries in aField[] for sorting purposes
4447
*/
4548
static int nameCmpr(const void *a, const void *b){
@@ -74,11 +77,14 @@
7477
once = 1;
7578
db_prepare(&q, "PRAGMA table_info(ticket)");
7679
while( db_step(&q)==SQLITE_ROW ){
7780
const char *zFieldName = db_column_text(&q, 1);
7881
haveTicket = 1;
79
- if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
82
+ if( memcmp(zFieldName,"tkt_",4)==0 ){
83
+ if( strcmp(zFieldName, "tkt_ctime")==0 ) haveTicketCTime = 1;
84
+ continue;
85
+ }
8086
if( nField%10==0 ){
8187
aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
8288
}
8389
aField[nField].zName = mprintf("%s", zFieldName);
8490
aField[nField].mUsed = USEDBY_TICKET;
@@ -87,11 +93,14 @@
8793
db_finalize(&q);
8894
db_prepare(&q, "PRAGMA table_info(ticketchng)");
8995
while( db_step(&q)==SQLITE_ROW ){
9096
const char *zFieldName = db_column_text(&q, 1);
9197
haveTicketChng = 1;
92
- if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
98
+ if( memcmp(zFieldName,"tkt_",4)==0 ){
99
+ if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
100
+ continue;
101
+ }
93102
if( (i = fieldId(zFieldName))>=0 ){
94103
aField[i].mUsed |= USEDBY_TICKETCHNG;
95104
continue;
96105
}
97106
if( nField%10==0 ){
@@ -183,10 +192,11 @@
183192
*/
184193
static int ticket_insert(const Manifest *p, int rid, int tktid){
185194
Blob sql1, sql2, sql3;
186195
Stmt q;
187196
int i, j;
197
+ char *aUsed;
188198
189199
if( tktid==0 ){
190200
db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
191201
"VALUES(%Q, 0)", p->zTicketUuid);
192202
tktid = db_last_insert_rowid();
@@ -193,22 +203,25 @@
193203
}
194204
blob_zero(&sql1);
195205
blob_zero(&sql2);
196206
blob_zero(&sql3);
197207
blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
208
+ if( haveTicketCTime ){
209
+ blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
210
+ }
211
+ aUsed = fossil_malloc( nField );
212
+ memset(aUsed, 0, nField);
198213
for(i=0; i<p->nField; i++){
199214
const char *zName = p->aField[i].zName;
200
- if( zName[0]=='+' ){
201
- zName++;
202
- if( (j = fieldId(zName))<0 ) continue;
203
- if( aField[j].mUsed & USEDBY_TICKET ){
215
+ if( (j = fieldId(zName))<0 ) continue;
216
+ aUsed[j] = 1;
217
+ if( aField[j].mUsed & USEDBY_TICKET ){
218
+ if( zName[0]=='+' ){
219
+ zName++;
204220
blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
205221
zName, zName, p->aField[i].zValue);
206
- }
207
- }else{
208
- if( (j = fieldId(zName))<0 ) continue;
209
- if( aField[j].mUsed & USEDBY_TICKET ){
222
+ }else{
210223
blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
211224
}
212225
}
213226
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
214227
blob_appendf(&sql2, ",%s", zName);
@@ -222,20 +235,41 @@
222235
db_prepare(&q, "%s", blob_str(&sql1));
223236
db_bind_double(&q, ":mtime", p->rDate);
224237
db_step(&q);
225238
db_finalize(&q);
226239
blob_reset(&sql1);
227
- if( blob_size(&sql2)>0 ){
228
- db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
229
- "VALUES(%d,:mtime%s)",
230
- blob_str(&sql2), tktid, blob_str(&sql3));
240
+ if( blob_size(&sql2)>0 || haveTicketChngRid ){
241
+ int fromTkt = 0;
242
+ if( haveTicketChngRid ){
243
+ blob_append(&sql2, ",tkt_rid", -1);
244
+ blob_appendf(&sql3, ",%d", rid);
245
+ }
246
+ for(i=0; i<nField; i++){
247
+ if( aUsed[i]==0
248
+ && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
249
+ ){
250
+ fromTkt = 1;
251
+ blob_appendf(&sql2, ",%s", aField[i].zName);
252
+ blob_appendf(&sql3, ",%s", aField[i].zName);
253
+ }
254
+ }
255
+ if( fromTkt ){
256
+ db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
257
+ "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
258
+ blob_str(&sql2), tktid, blob_str(&sql3), tktid);
259
+ }else{
260
+ db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
261
+ "VALUES(%d,:mtime%s)",
262
+ blob_str(&sql2), tktid, blob_str(&sql3));
263
+ }
231264
db_bind_double(&q, ":mtime", p->rDate);
232265
db_step(&q);
233266
db_finalize(&q);
234267
}
235268
blob_reset(&sql2);
236269
blob_reset(&sql3);
270
+ fossil_free(aUsed);
237271
return tktid;
238272
}
239273
240274
/*
241275
** Rebuild an entire entry in the TICKET table
@@ -268,10 +302,11 @@
268302
}
269303
createFlag = 0;
270304
}
271305
db_finalize(&q);
272306
}
307
+
273308
274309
/*
275310
** Create the TH1 interpreter and load the "common" code.
276311
*/
277312
void ticket_init(void){
@@ -328,10 +363,32 @@
328363
ticket_rebuild_entry(zName);
329364
}
330365
db_finalize(&q);
331366
db_end_transaction(0);
332367
}
368
+
369
+/*
370
+** COMMAND: test-ticket-rebuild
371
+**
372
+** Usage: %fossil test-ticket-rebuild TICKETID|all
373
+**
374
+** Rebuild the TICKET and TICKETCHNG tables for the given ticket ID
375
+** or for ALL.
376
+*/
377
+void test_ticket_rebuild(void){
378
+ db_find_and_open_repository(0, 0);
379
+ if( g.argc!=3 ) usage("TICKETID|all");
380
+ if( fossil_strcmp(g.argv[2], "all")==0 ){
381
+ ticket_rebuild();
382
+ }else{
383
+ const char *zUuid;
384
+ zUuid = db_text(0, "SELECT substr(tagname,5) FROM tag"
385
+ " WHERE tagname GLOB 'tkt-%q*'", g.argv[2]);
386
+ if( zUuid==0 ) fossil_fatal("no such ticket: %s", g.argv[2]);
387
+ ticket_rebuild_entry(zUuid);
388
+ }
389
+}
333390
334391
/*
335392
** For trouble-shooting purposes, render a dump of the aField[] table to
336393
** the webpage currently under construction.
337394
*/
338395
--- src/tkt.c
+++ src/tkt.c
@@ -34,12 +34,15 @@
34 char *zAppend; /* Value to append */
35 unsigned mUsed; /* 01: TICKET 02: TICKETCHNG */
36 } *aField;
37 #define USEDBY_TICKET 01
38 #define USEDBY_TICKETCHNG 02
39 static int haveTicket = 0; /* True if the TICKET table exists */
40 static int haveTicketChng = 0; /* True if the TICKETCHNG table exists */
 
 
 
41
42 /*
43 ** Compare two entries in aField[] for sorting purposes
44 */
45 static int nameCmpr(const void *a, const void *b){
@@ -74,11 +77,14 @@
74 once = 1;
75 db_prepare(&q, "PRAGMA table_info(ticket)");
76 while( db_step(&q)==SQLITE_ROW ){
77 const char *zFieldName = db_column_text(&q, 1);
78 haveTicket = 1;
79 if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
 
 
 
80 if( nField%10==0 ){
81 aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
82 }
83 aField[nField].zName = mprintf("%s", zFieldName);
84 aField[nField].mUsed = USEDBY_TICKET;
@@ -87,11 +93,14 @@
87 db_finalize(&q);
88 db_prepare(&q, "PRAGMA table_info(ticketchng)");
89 while( db_step(&q)==SQLITE_ROW ){
90 const char *zFieldName = db_column_text(&q, 1);
91 haveTicketChng = 1;
92 if( memcmp(zFieldName,"tkt_",4)==0 ) continue;
 
 
 
93 if( (i = fieldId(zFieldName))>=0 ){
94 aField[i].mUsed |= USEDBY_TICKETCHNG;
95 continue;
96 }
97 if( nField%10==0 ){
@@ -183,10 +192,11 @@
183 */
184 static int ticket_insert(const Manifest *p, int rid, int tktid){
185 Blob sql1, sql2, sql3;
186 Stmt q;
187 int i, j;
 
188
189 if( tktid==0 ){
190 db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
191 "VALUES(%Q, 0)", p->zTicketUuid);
192 tktid = db_last_insert_rowid();
@@ -193,22 +203,25 @@
193 }
194 blob_zero(&sql1);
195 blob_zero(&sql2);
196 blob_zero(&sql3);
197 blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
 
 
 
 
 
198 for(i=0; i<p->nField; i++){
199 const char *zName = p->aField[i].zName;
200 if( zName[0]=='+' ){
201 zName++;
202 if( (j = fieldId(zName))<0 ) continue;
203 if( aField[j].mUsed & USEDBY_TICKET ){
 
204 blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
205 zName, zName, p->aField[i].zValue);
206 }
207 }else{
208 if( (j = fieldId(zName))<0 ) continue;
209 if( aField[j].mUsed & USEDBY_TICKET ){
210 blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
211 }
212 }
213 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
214 blob_appendf(&sql2, ",%s", zName);
@@ -222,20 +235,41 @@
222 db_prepare(&q, "%s", blob_str(&sql1));
223 db_bind_double(&q, ":mtime", p->rDate);
224 db_step(&q);
225 db_finalize(&q);
226 blob_reset(&sql1);
227 if( blob_size(&sql2)>0 ){
228 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
229 "VALUES(%d,:mtime%s)",
230 blob_str(&sql2), tktid, blob_str(&sql3));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231 db_bind_double(&q, ":mtime", p->rDate);
232 db_step(&q);
233 db_finalize(&q);
234 }
235 blob_reset(&sql2);
236 blob_reset(&sql3);
 
237 return tktid;
238 }
239
240 /*
241 ** Rebuild an entire entry in the TICKET table
@@ -268,10 +302,11 @@
268 }
269 createFlag = 0;
270 }
271 db_finalize(&q);
272 }
 
273
274 /*
275 ** Create the TH1 interpreter and load the "common" code.
276 */
277 void ticket_init(void){
@@ -328,10 +363,32 @@
328 ticket_rebuild_entry(zName);
329 }
330 db_finalize(&q);
331 db_end_transaction(0);
332 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
334 /*
335 ** For trouble-shooting purposes, render a dump of the aField[] table to
336 ** the webpage currently under construction.
337 */
338
--- src/tkt.c
+++ src/tkt.c
@@ -34,12 +34,15 @@
34 char *zAppend; /* Value to append */
35 unsigned mUsed; /* 01: TICKET 02: TICKETCHNG */
36 } *aField;
37 #define USEDBY_TICKET 01
38 #define USEDBY_TICKETCHNG 02
39 #define USEDBY_BOTH 03
40 static u8 haveTicket = 0; /* True if the TICKET table exists */
41 static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
42 static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
43 static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
44
45 /*
46 ** Compare two entries in aField[] for sorting purposes
47 */
48 static int nameCmpr(const void *a, const void *b){
@@ -74,11 +77,14 @@
77 once = 1;
78 db_prepare(&q, "PRAGMA table_info(ticket)");
79 while( db_step(&q)==SQLITE_ROW ){
80 const char *zFieldName = db_column_text(&q, 1);
81 haveTicket = 1;
82 if( memcmp(zFieldName,"tkt_",4)==0 ){
83 if( strcmp(zFieldName, "tkt_ctime")==0 ) haveTicketCTime = 1;
84 continue;
85 }
86 if( nField%10==0 ){
87 aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
88 }
89 aField[nField].zName = mprintf("%s", zFieldName);
90 aField[nField].mUsed = USEDBY_TICKET;
@@ -87,11 +93,14 @@
93 db_finalize(&q);
94 db_prepare(&q, "PRAGMA table_info(ticketchng)");
95 while( db_step(&q)==SQLITE_ROW ){
96 const char *zFieldName = db_column_text(&q, 1);
97 haveTicketChng = 1;
98 if( memcmp(zFieldName,"tkt_",4)==0 ){
99 if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
100 continue;
101 }
102 if( (i = fieldId(zFieldName))>=0 ){
103 aField[i].mUsed |= USEDBY_TICKETCHNG;
104 continue;
105 }
106 if( nField%10==0 ){
@@ -183,10 +192,11 @@
192 */
193 static int ticket_insert(const Manifest *p, int rid, int tktid){
194 Blob sql1, sql2, sql3;
195 Stmt q;
196 int i, j;
197 char *aUsed;
198
199 if( tktid==0 ){
200 db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
201 "VALUES(%Q, 0)", p->zTicketUuid);
202 tktid = db_last_insert_rowid();
@@ -193,22 +203,25 @@
203 }
204 blob_zero(&sql1);
205 blob_zero(&sql2);
206 blob_zero(&sql3);
207 blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
208 if( haveTicketCTime ){
209 blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
210 }
211 aUsed = fossil_malloc( nField );
212 memset(aUsed, 0, nField);
213 for(i=0; i<p->nField; i++){
214 const char *zName = p->aField[i].zName;
215 if( (j = fieldId(zName))<0 ) continue;
216 aUsed[j] = 1;
217 if( aField[j].mUsed & USEDBY_TICKET ){
218 if( zName[0]=='+' ){
219 zName++;
220 blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
221 zName, zName, p->aField[i].zValue);
222 }else{
 
 
 
223 blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
224 }
225 }
226 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
227 blob_appendf(&sql2, ",%s", zName);
@@ -222,20 +235,41 @@
235 db_prepare(&q, "%s", blob_str(&sql1));
236 db_bind_double(&q, ":mtime", p->rDate);
237 db_step(&q);
238 db_finalize(&q);
239 blob_reset(&sql1);
240 if( blob_size(&sql2)>0 || haveTicketChngRid ){
241 int fromTkt = 0;
242 if( haveTicketChngRid ){
243 blob_append(&sql2, ",tkt_rid", -1);
244 blob_appendf(&sql3, ",%d", rid);
245 }
246 for(i=0; i<nField; i++){
247 if( aUsed[i]==0
248 && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
249 ){
250 fromTkt = 1;
251 blob_appendf(&sql2, ",%s", aField[i].zName);
252 blob_appendf(&sql3, ",%s", aField[i].zName);
253 }
254 }
255 if( fromTkt ){
256 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
257 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
258 blob_str(&sql2), tktid, blob_str(&sql3), tktid);
259 }else{
260 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
261 "VALUES(%d,:mtime%s)",
262 blob_str(&sql2), tktid, blob_str(&sql3));
263 }
264 db_bind_double(&q, ":mtime", p->rDate);
265 db_step(&q);
266 db_finalize(&q);
267 }
268 blob_reset(&sql2);
269 blob_reset(&sql3);
270 fossil_free(aUsed);
271 return tktid;
272 }
273
274 /*
275 ** Rebuild an entire entry in the TICKET table
@@ -268,10 +302,11 @@
302 }
303 createFlag = 0;
304 }
305 db_finalize(&q);
306 }
307
308
309 /*
310 ** Create the TH1 interpreter and load the "common" code.
311 */
312 void ticket_init(void){
@@ -328,10 +363,32 @@
363 ticket_rebuild_entry(zName);
364 }
365 db_finalize(&q);
366 db_end_transaction(0);
367 }
368
369 /*
370 ** COMMAND: test-ticket-rebuild
371 **
372 ** Usage: %fossil test-ticket-rebuild TICKETID|all
373 **
374 ** Rebuild the TICKET and TICKETCHNG tables for the given ticket ID
375 ** or for ALL.
376 */
377 void test_ticket_rebuild(void){
378 db_find_and_open_repository(0, 0);
379 if( g.argc!=3 ) usage("TICKETID|all");
380 if( fossil_strcmp(g.argv[2], "all")==0 ){
381 ticket_rebuild();
382 }else{
383 const char *zUuid;
384 zUuid = db_text(0, "SELECT substr(tagname,5) FROM tag"
385 " WHERE tagname GLOB 'tkt-%q*'", g.argv[2]);
386 if( zUuid==0 ) fossil_fatal("no such ticket: %s", g.argv[2]);
387 ticket_rebuild_entry(zUuid);
388 }
389 }
390
391 /*
392 ** For trouble-shooting purposes, render a dump of the aField[] table to
393 ** the webpage currently under construction.
394 */
395
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -67,10 +67,11 @@
6767
@ CREATE TABLE ticket(
6868
@ -- Do not change any column that begins with tkt_
6969
@ tkt_id INTEGER PRIMARY KEY,
7070
@ tkt_uuid TEXT UNIQUE,
7171
@ tkt_mtime DATE,
72
+@ tkt_ctime DATE,
7273
@ -- Add as many fields as required below this line
7374
@ type TEXT,
7475
@ status TEXT,
7576
@ subsystem TEXT,
7677
@ priority TEXT,
@@ -82,10 +83,11 @@
8283
@ comment TEXT
8384
@ );
8485
@ CREATE TABLE ticketchng(
8586
@ -- Do not change any column that begins with tkt_
8687
@ tkt_id INTEGER REFERENCES ticket,
88
+@ tkt_rid INTEGER REFERENCES blob,
8789
@ tkt_mtime DATE,
8890
@ -- Add as many fields as required below this line
8991
@ login TEXT,
9092
@ username TEXT,
9193
@ mimetype TEXT,
9294
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -67,10 +67,11 @@
67 @ CREATE TABLE ticket(
68 @ -- Do not change any column that begins with tkt_
69 @ tkt_id INTEGER PRIMARY KEY,
70 @ tkt_uuid TEXT UNIQUE,
71 @ tkt_mtime DATE,
 
72 @ -- Add as many fields as required below this line
73 @ type TEXT,
74 @ status TEXT,
75 @ subsystem TEXT,
76 @ priority TEXT,
@@ -82,10 +83,11 @@
82 @ comment TEXT
83 @ );
84 @ CREATE TABLE ticketchng(
85 @ -- Do not change any column that begins with tkt_
86 @ tkt_id INTEGER REFERENCES ticket,
 
87 @ tkt_mtime DATE,
88 @ -- Add as many fields as required below this line
89 @ login TEXT,
90 @ username TEXT,
91 @ mimetype TEXT,
92
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -67,10 +67,11 @@
67 @ CREATE TABLE ticket(
68 @ -- Do not change any column that begins with tkt_
69 @ tkt_id INTEGER PRIMARY KEY,
70 @ tkt_uuid TEXT UNIQUE,
71 @ tkt_mtime DATE,
72 @ tkt_ctime DATE,
73 @ -- Add as many fields as required below this line
74 @ type TEXT,
75 @ status TEXT,
76 @ subsystem TEXT,
77 @ priority TEXT,
@@ -82,10 +83,11 @@
83 @ comment TEXT
84 @ );
85 @ CREATE TABLE ticketchng(
86 @ -- Do not change any column that begins with tkt_
87 @ tkt_id INTEGER REFERENCES ticket,
88 @ tkt_rid INTEGER REFERENCES blob,
89 @ tkt_mtime DATE,
90 @ -- Add as many fields as required below this line
91 @ login TEXT,
92 @ username TEXT,
93 @ mimetype TEXT,
94

Keyboard Shortcuts

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