Fossil SCM

Prototype for one approach to linking forum posts to other artifacts (initially check-ins). Adds the --forumpost HASH flag to the ci command, which adds a forumpost/FULL-HASH tag to the checkin for later use in /info and forum post views. For ease of use, this probably needs to be adapted to map only to the first version of a forum post, as is done in the forumpost-locking branch, once that branch is merged with trunk.

stephan 2023-03-02 14:10 trunk
Commit 3e5d23daec90eb93de3f21ed79f5284b98caa63b1edc3c125fe3c0c9a3d68ebd
1 file changed +32 -11
+32 -11
--- src/checkin.c
+++ src/checkin.c
@@ -1817,12 +1817,12 @@
18171817
18181818
if( p->azTag ){
18191819
for(i=0; p->azTag[i]; i++){
18201820
/* Add a symbolic tag to this check-in. The tag names have already
18211821
** been sorted and converted using the %F format */
1822
- assert( i==0 || strcmp(p->azTag[i-1], p->azTag[i])<=0 );
1823
- blob_appendf(pOut, "T +sym-%s *\n", p->azTag[i]);
1822
+ assert( i==0 || fossil_strcmp(p->azTag[i-1], p->azTag[i])<=0 );
1823
+ blob_appendf(pOut, "T +%s *\n", p->azTag[i]);
18241824
}
18251825
}
18261826
if( p->zBranch && p->zBranch[0] ){
18271827
/* For a new branch, cancel all prior propagating tags */
18281828
db_prepare(&q,
@@ -2088,10 +2088,22 @@
20882088
static int tagCmp(const void *a, const void *b){
20892089
char **pA = (char**)a;
20902090
char **pB = (char**)b;
20912091
return fossil_strcmp(pA[0], pB[0]);
20922092
}
2093
+
2094
+/*
2095
+** Append zTag at pCi->azTag[*pNTag] (reallocating as needed),
2096
+** increment *pNTag, then set pCi->azTag[*pNTag] to 0.
2097
+*/
2098
+static void ci_append_tag(CheckinInfo *pCi, int *pNTag,
2099
+ const char *zTag){
2100
+ pCi->azTag = fossil_realloc((void*)pCi->azTag,
2101
+ sizeof(char*)*(*pNTag+2));
2102
+ pCi->azTag[(*pNTag)++] = zTag;
2103
+ pCi->azTag[*pNTag] = 0;
2104
+}
20932105
20942106
/*
20952107
** COMMAND: ci#
20962108
** COMMAND: commit
20972109
**
@@ -2161,10 +2173,12 @@
21612173
** ("auto" lets Fossil choose it automatically,
21622174
** even for private branches)
21632175
** --close Close the branch being committed
21642176
** --date-override DATETIME DATE to use instead of 'now'
21652177
** --delta Use a delta manifest in the commit process
2178
+** --forumpost HASH Adds a tag linking the given forum post to
2179
+** this check-in. May be given multiple times.
21662180
** --hash Verify file status using hashing rather
21672181
** than relying on file mtimes
21682182
** --ignore-clock-skew If a clock skew is detected, ignore it and
21692183
** behave as if the user had entered 'yes' to
21702184
** the question of whether to proceed despite
@@ -2182,11 +2196,12 @@
21822196
** --no-warnings Omit all warnings about file contents
21832197
** --no-verify Do not run before-commit hooks
21842198
** --nosign Do not attempt to sign this commit with gpg
21852199
** --override-lock Allow a check-in even though parent is locked
21862200
** --private Do not sync changes and their descendants
2187
-** --tag TAG-NAME Assign given tag TAG-NAME to the check-in
2201
+** --tag TAG-NAME Assign given tag TAG-NAME to the check-in. May
2202
+** be given multiple times.
21882203
** --trace Debug tracing
21892204
** --user-override USER USER to use instead of the current default
21902205
**
21912206
** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
21922207
** year-month-day form, it may be truncated, the "T" may be replaced by
@@ -2292,14 +2307,23 @@
22922307
sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
22932308
sCiInfo.zMimetype = find_option("mimetype",0,1);
22942309
sCiInfo.verboseFlag = find_option("verbose", "v", 0)!=0;
22952310
while( (zTag = find_option("tag",0,1))!=0 ){
22962311
if( zTag[0]==0 ) continue;
2297
- sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag,
2298
- sizeof(char*)*(nTag+2));
2299
- sCiInfo.azTag[nTag++] = zTag;
2300
- sCiInfo.azTag[nTag] = 0;
2312
+ ci_append_tag(&sCiInfo, &nTag, mprintf("sym-%F",zTag));
2313
+ }
2314
+ while( (zTag = find_option("forumpost",0,1))!=0 ){
2315
+ int forumRid;
2316
+ if( zTag[0]==0 ) continue;
2317
+ forumRid = symbolic_name_to_rid(zTag, "f");
2318
+ if( forumRid==0 ){
2319
+ fossil_fatal("Not a forum post: %s", zTag);
2320
+ }else if( forumRid<0 ){
2321
+ fossil_fatal("Ambiguous symbolic name: %s", zTag);
2322
+ }
2323
+ ci_append_tag(&sCiInfo, &nTag,
2324
+ mprintf("forumpost/%z", rid_to_uuid(forumRid)));
23012325
}
23022326
zComFile = find_option("message-file", "M", 1);
23032327
sCiInfo.zDateOvrd = find_option("date-override",0,1);
23042328
sCiInfo.zUserOvrd = find_option("user-override",0,1);
23052329
noSign = db_get_boolean("omitsign", 0)|noSign;
@@ -2345,12 +2369,10 @@
23452369
" to override", sCiInfo.zBranch);
23462370
}
23472371
23482372
/* Escape special characters in tags and put all tags in sorted order */
23492373
if( nTag ){
2350
- int i;
2351
- for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]);
23522374
qsort((void*)sCiInfo.azTag, nTag, sizeof(sCiInfo.azTag[0]), tagCmp);
23532375
}
23542376
23552377
/*
23562378
** Autosync if autosync is enabled and this is not a private check-in.
@@ -2511,11 +2533,11 @@
25112533
}else{
25122534
fossil_fatal("Would fork. \"update\" first or use --branch or "
25132535
"--allow-fork.");
25142536
}
25152537
}
2516
-
2538
+
25172539
/*
25182540
** Do not allow a commit against a closed leaf unless the commit
25192541
** ends up on a different branch.
25202542
*/
25212543
if(
@@ -2532,11 +2554,10 @@
25322554
}
25332555
25342556
/* Always exit the loop on the second pass */
25352557
if( bRecheck ) break;
25362558
2537
-
25382559
/* Get the check-in comment. This might involve prompting the
25392560
** user for the check-in comment, in which case we should resync
25402561
** to renew the check-in lock and repeat the checks for conflicts.
25412562
*/
25422563
if( zComment ){
25432564
--- src/checkin.c
+++ src/checkin.c
@@ -1817,12 +1817,12 @@
1817
1818 if( p->azTag ){
1819 for(i=0; p->azTag[i]; i++){
1820 /* Add a symbolic tag to this check-in. The tag names have already
1821 ** been sorted and converted using the %F format */
1822 assert( i==0 || strcmp(p->azTag[i-1], p->azTag[i])<=0 );
1823 blob_appendf(pOut, "T +sym-%s *\n", p->azTag[i]);
1824 }
1825 }
1826 if( p->zBranch && p->zBranch[0] ){
1827 /* For a new branch, cancel all prior propagating tags */
1828 db_prepare(&q,
@@ -2088,10 +2088,22 @@
2088 static int tagCmp(const void *a, const void *b){
2089 char **pA = (char**)a;
2090 char **pB = (char**)b;
2091 return fossil_strcmp(pA[0], pB[0]);
2092 }
 
 
 
 
 
 
 
 
 
 
 
 
2093
2094 /*
2095 ** COMMAND: ci#
2096 ** COMMAND: commit
2097 **
@@ -2161,10 +2173,12 @@
2161 ** ("auto" lets Fossil choose it automatically,
2162 ** even for private branches)
2163 ** --close Close the branch being committed
2164 ** --date-override DATETIME DATE to use instead of 'now'
2165 ** --delta Use a delta manifest in the commit process
 
 
2166 ** --hash Verify file status using hashing rather
2167 ** than relying on file mtimes
2168 ** --ignore-clock-skew If a clock skew is detected, ignore it and
2169 ** behave as if the user had entered 'yes' to
2170 ** the question of whether to proceed despite
@@ -2182,11 +2196,12 @@
2182 ** --no-warnings Omit all warnings about file contents
2183 ** --no-verify Do not run before-commit hooks
2184 ** --nosign Do not attempt to sign this commit with gpg
2185 ** --override-lock Allow a check-in even though parent is locked
2186 ** --private Do not sync changes and their descendants
2187 ** --tag TAG-NAME Assign given tag TAG-NAME to the check-in
 
2188 ** --trace Debug tracing
2189 ** --user-override USER USER to use instead of the current default
2190 **
2191 ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
2192 ** year-month-day form, it may be truncated, the "T" may be replaced by
@@ -2292,14 +2307,23 @@
2292 sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
2293 sCiInfo.zMimetype = find_option("mimetype",0,1);
2294 sCiInfo.verboseFlag = find_option("verbose", "v", 0)!=0;
2295 while( (zTag = find_option("tag",0,1))!=0 ){
2296 if( zTag[0]==0 ) continue;
2297 sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag,
2298 sizeof(char*)*(nTag+2));
2299 sCiInfo.azTag[nTag++] = zTag;
2300 sCiInfo.azTag[nTag] = 0;
 
 
 
 
 
 
 
 
 
2301 }
2302 zComFile = find_option("message-file", "M", 1);
2303 sCiInfo.zDateOvrd = find_option("date-override",0,1);
2304 sCiInfo.zUserOvrd = find_option("user-override",0,1);
2305 noSign = db_get_boolean("omitsign", 0)|noSign;
@@ -2345,12 +2369,10 @@
2345 " to override", sCiInfo.zBranch);
2346 }
2347
2348 /* Escape special characters in tags and put all tags in sorted order */
2349 if( nTag ){
2350 int i;
2351 for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]);
2352 qsort((void*)sCiInfo.azTag, nTag, sizeof(sCiInfo.azTag[0]), tagCmp);
2353 }
2354
2355 /*
2356 ** Autosync if autosync is enabled and this is not a private check-in.
@@ -2511,11 +2533,11 @@
2511 }else{
2512 fossil_fatal("Would fork. \"update\" first or use --branch or "
2513 "--allow-fork.");
2514 }
2515 }
2516
2517 /*
2518 ** Do not allow a commit against a closed leaf unless the commit
2519 ** ends up on a different branch.
2520 */
2521 if(
@@ -2532,11 +2554,10 @@
2532 }
2533
2534 /* Always exit the loop on the second pass */
2535 if( bRecheck ) break;
2536
2537
2538 /* Get the check-in comment. This might involve prompting the
2539 ** user for the check-in comment, in which case we should resync
2540 ** to renew the check-in lock and repeat the checks for conflicts.
2541 */
2542 if( zComment ){
2543
--- src/checkin.c
+++ src/checkin.c
@@ -1817,12 +1817,12 @@
1817
1818 if( p->azTag ){
1819 for(i=0; p->azTag[i]; i++){
1820 /* Add a symbolic tag to this check-in. The tag names have already
1821 ** been sorted and converted using the %F format */
1822 assert( i==0 || fossil_strcmp(p->azTag[i-1], p->azTag[i])<=0 );
1823 blob_appendf(pOut, "T +%s *\n", p->azTag[i]);
1824 }
1825 }
1826 if( p->zBranch && p->zBranch[0] ){
1827 /* For a new branch, cancel all prior propagating tags */
1828 db_prepare(&q,
@@ -2088,10 +2088,22 @@
2088 static int tagCmp(const void *a, const void *b){
2089 char **pA = (char**)a;
2090 char **pB = (char**)b;
2091 return fossil_strcmp(pA[0], pB[0]);
2092 }
2093
2094 /*
2095 ** Append zTag at pCi->azTag[*pNTag] (reallocating as needed),
2096 ** increment *pNTag, then set pCi->azTag[*pNTag] to 0.
2097 */
2098 static void ci_append_tag(CheckinInfo *pCi, int *pNTag,
2099 const char *zTag){
2100 pCi->azTag = fossil_realloc((void*)pCi->azTag,
2101 sizeof(char*)*(*pNTag+2));
2102 pCi->azTag[(*pNTag)++] = zTag;
2103 pCi->azTag[*pNTag] = 0;
2104 }
2105
2106 /*
2107 ** COMMAND: ci#
2108 ** COMMAND: commit
2109 **
@@ -2161,10 +2173,12 @@
2173 ** ("auto" lets Fossil choose it automatically,
2174 ** even for private branches)
2175 ** --close Close the branch being committed
2176 ** --date-override DATETIME DATE to use instead of 'now'
2177 ** --delta Use a delta manifest in the commit process
2178 ** --forumpost HASH Adds a tag linking the given forum post to
2179 ** this check-in. May be given multiple times.
2180 ** --hash Verify file status using hashing rather
2181 ** than relying on file mtimes
2182 ** --ignore-clock-skew If a clock skew is detected, ignore it and
2183 ** behave as if the user had entered 'yes' to
2184 ** the question of whether to proceed despite
@@ -2182,11 +2196,12 @@
2196 ** --no-warnings Omit all warnings about file contents
2197 ** --no-verify Do not run before-commit hooks
2198 ** --nosign Do not attempt to sign this commit with gpg
2199 ** --override-lock Allow a check-in even though parent is locked
2200 ** --private Do not sync changes and their descendants
2201 ** --tag TAG-NAME Assign given tag TAG-NAME to the check-in. May
2202 ** be given multiple times.
2203 ** --trace Debug tracing
2204 ** --user-override USER USER to use instead of the current default
2205 **
2206 ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
2207 ** year-month-day form, it may be truncated, the "T" may be replaced by
@@ -2292,14 +2307,23 @@
2307 sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
2308 sCiInfo.zMimetype = find_option("mimetype",0,1);
2309 sCiInfo.verboseFlag = find_option("verbose", "v", 0)!=0;
2310 while( (zTag = find_option("tag",0,1))!=0 ){
2311 if( zTag[0]==0 ) continue;
2312 ci_append_tag(&sCiInfo, &nTag, mprintf("sym-%F",zTag));
2313 }
2314 while( (zTag = find_option("forumpost",0,1))!=0 ){
2315 int forumRid;
2316 if( zTag[0]==0 ) continue;
2317 forumRid = symbolic_name_to_rid(zTag, "f");
2318 if( forumRid==0 ){
2319 fossil_fatal("Not a forum post: %s", zTag);
2320 }else if( forumRid<0 ){
2321 fossil_fatal("Ambiguous symbolic name: %s", zTag);
2322 }
2323 ci_append_tag(&sCiInfo, &nTag,
2324 mprintf("forumpost/%z", rid_to_uuid(forumRid)));
2325 }
2326 zComFile = find_option("message-file", "M", 1);
2327 sCiInfo.zDateOvrd = find_option("date-override",0,1);
2328 sCiInfo.zUserOvrd = find_option("user-override",0,1);
2329 noSign = db_get_boolean("omitsign", 0)|noSign;
@@ -2345,12 +2369,10 @@
2369 " to override", sCiInfo.zBranch);
2370 }
2371
2372 /* Escape special characters in tags and put all tags in sorted order */
2373 if( nTag ){
 
 
2374 qsort((void*)sCiInfo.azTag, nTag, sizeof(sCiInfo.azTag[0]), tagCmp);
2375 }
2376
2377 /*
2378 ** Autosync if autosync is enabled and this is not a private check-in.
@@ -2511,11 +2533,11 @@
2533 }else{
2534 fossil_fatal("Would fork. \"update\" first or use --branch or "
2535 "--allow-fork.");
2536 }
2537 }
2538
2539 /*
2540 ** Do not allow a commit against a closed leaf unless the commit
2541 ** ends up on a different branch.
2542 */
2543 if(
@@ -2532,11 +2554,10 @@
2554 }
2555
2556 /* Always exit the loop on the second pass */
2557 if( bRecheck ) break;
2558
 
2559 /* Get the check-in comment. This might involve prompting the
2560 ** user for the check-in comment, in which case we should resync
2561 ** to renew the check-in lock and repeat the checks for conflicts.
2562 */
2563 if( zComment ){
2564

Keyboard Shortcuts

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