Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | As a late-stage step in the checkin process, ensure that vfile.isexe and vfile.islink match what the new manifest says. This has been a long-missing step which fossil(1) does but libfossil noted in a TODO comment but never implemented. This completes, hopefully, the fix started in [4243008e112140], but it's difficult to _really_ test without doing a genuine checkin (not a dry-run). |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
404f376c0eeebaa1b4d2392b313b998f |
User & Date: | stephan 2024-09-03 16:44:27 |
Context
2024-09-12
| ||
12:13 | Update to latest upstream fnc. check-in: 25a3a7ceea user: stephan tags: trunk | |
2024-09-03
| ||
16:44 | As a late-stage step in the checkin process, ensure that vfile.isexe and vfile.islink match what the new manifest says. This has been a long-missing step which fossil(1) does but libfossil noted in a TODO comment but never implemented. This completes, hopefully, the fix started in [4243008e112140], but it's difficult to _really_ test without doing a genuine checkin (not a dry-run). check-in: 404f376c0e user: stephan tags: trunk | |
15:25 | latest upstream autosetup. check-in: 21a48eac26 user: stephan tags: trunk | |
Changes
Changes to include/fossil-scm/db.h.
︙ | ︙ | |||
1822 1823 1824 1825 1826 1827 1828 | /** The elipsis counterpart of fsl_stmt_bind_fmtv(). */ FSL_EXPORT int fsl_stmt_bind_fmt( fsl_stmt * const st, char const * fmt, ... ); /** Binds a series of values using a formatting string. | | | | | | | | | | | | | 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 | /** The elipsis counterpart of fsl_stmt_bind_fmtv(). */ FSL_EXPORT int fsl_stmt_bind_fmt( fsl_stmt * const st, char const * fmt, ... ); /** Binds a series of values using a formatting string. The string may contain the following characters, each of which refers to the next argument in the args list: '-': binds a NULL and expects a NULL placeholder in the argument list (for consistency's sake). 'i': binds an int32 'I': binds an int64 'R': binds a fsl_id_t ('R' as in 'RID') 'f': binds a double 's': binds a (char const *) as text or NULL. 'S': binds a (char const *) as a blob or NULL. 'b': binds a (fsl_buffer const *) as text or NULL. 'B': binds a (fsl_buffer const *) as a blob or NULL. ' ': spaces are allowed for readability and are ignored. Returns 0 on success, any number of other FSL_RC_xxx codes on error. ACHTUNG: the "sSbB" bindings assume, because of how this API is normally used, that the memory pointed to by the given argument |
︙ | ︙ |
Changes to src/checkin.c.
︙ | ︙ | |||
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 | "SELECT 1 FROM tagxref" " WHERE tagid=%d AND rid=%"FSL_ID_T_PFMT " AND tagtype>0" " AND value=%Q", FSL_TAGID_BRANCH, vid, name); } int fsl_checkin_commit(fsl_cx * f, fsl_checkin_opt const * opt, fsl_id_t * newRid, fsl_uuid_str * newUuid ){ int rc; fsl_deck deck = fsl_deck_empty; fsl_deck *d = &deck; fsl_db * dbC; fsl_db * dbR; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 | "SELECT 1 FROM tagxref" " WHERE tagid=%d AND rid=%"FSL_ID_T_PFMT " AND tagtype>0" " AND value=%Q", FSL_TAGID_BRANCH, vid, name); } /** Interal helper for fsl_checkin_commit(). Update vfile.isexe and vfile.islink to match d's F-cards. We should arguably do this while calculating the F-cards, as that would not require iterating over d's F-cards again, but having it here is currently simpler (and incidentally matches how fossil(1) does it). */ static int fsl__commit_update_exelink( fsl_cx * const f, fsl_db * const dbC, fsl_deck * const d ) { int rc = 0; fsl_stmt q = fsl_stmt_empty; fsl_card_F const * pFile = NULL; assert( dbC ); assert( d->rid ); /* For reference's sake, the fossil(1) counterpart code: // Update the isexe and islink columns of the vfile table db_prepare(&q, "UPDATE vfile SET isexe=:exec, islink=:link" " WHERE vid=:vid AND pathname=:path AND (isexe!=:exec OR islink!=:link)" ); db_bind_int(&q, ":vid", nvid); pManifest = manifest_get(nvid, CFTYPE_MANIFEST, 0); manifest_file_rewind(pManifest); while( (pFile = manifest_file_next(pManifest, 0)) ){ db_bind_int(&q, ":exec", pFile->zPerm && strstr(pFile->zPerm, "x")); db_bind_int(&q, ":link", pFile->zPerm && strstr(pFile->zPerm, "l")); db_bind_text(&q, ":path", pFile->zName); db_step(&q); db_reset(&q); } db_finalize(&q); */ rc = fsl_db_prepare( dbC, &q, "UPDATE vfile SET isexe=?1, islink=?2 " "WHERE vid=?4 AND pathname=?3 AND (isexe!=?1 OR islink!=?2)" /* yes, ?4 and ?3 are intentionally out of order to simplify code below */ ); if(rc){ fsl_cx_uplift_db_error(f, dbC); return rc; } fsl_stmt_bind_id(&q, 4, d->rid); rc = fsl_deck_F_rewind(d); while( 0==rc ){ rc = fsl_deck_F_next(d, &pFile); if(rc || !pFile) break; rc = fsl_stmt_bind_fmt( &q, "iis", FSL_FILE_PERM_EXE==pFile->perm, FSL_FILE_PERM_LINK==pFile->perm, pFile->name ); if(0==rc){ if( FSL_RC_STEP_DONE==(rc = fsl_stmt_step(&q)) ){ rc = 0; } } fsl_stmt_reset(&q); } fsl_stmt_finalize(&q); return rc; }/* vfile.isexe/islink updates */ int fsl_checkin_commit(fsl_cx * f, fsl_checkin_opt const * opt, fsl_id_t * newRid, fsl_uuid_str * newUuid ){ int rc; fsl_deck deck = fsl_deck_empty; fsl_deck *d = &deck; fsl_db * dbC; fsl_db * dbR; |
︙ | ︙ | |||
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 | if(!rc) rc = fsl__ckout_version_write(f, d->rid, NULL); RC; assert(d->f == f); rc = fsl_checkin_add_unsent(f, d->rid); RC; rc = fsl__ckout_clear_merge_state(f, true); RC; /* todo(?) from fossil(1) follows. Most of this seems to be what the vfile handling does (above). db_multi_exec("PRAGMA %s.application_id=252006673;", db_name("repository")); db_multi_exec("PRAGMA %s.application_id=252006674;", db_name("localdb")); // Update the vfile and vmerge tables db_multi_exec( "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND is_selected(id);" "DELETE FROM vmerge;" "UPDATE vfile SET vid=%d;" "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL" " WHERE is_selected(id);" , vid, nvid ); db_lset_int("checkout", nvid); | > > < < < < < < < < < < < < < < < < < < | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 | if(!rc) rc = fsl__ckout_version_write(f, d->rid, NULL); RC; assert(d->f == f); rc = fsl_checkin_add_unsent(f, d->rid); RC; rc = fsl__ckout_clear_merge_state(f, true); RC; rc = fsl__commit_update_exelink(f, dbC, d); RC; /* todo(?) from fossil(1) follows. Most of this seems to be what the vfile handling does (above). db_multi_exec("PRAGMA %s.application_id=252006673;", db_name("repository")); db_multi_exec("PRAGMA %s.application_id=252006674;", db_name("localdb")); // Update the vfile and vmerge tables db_multi_exec( "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND is_selected(id);" "DELETE FROM vmerge;" "UPDATE vfile SET vid=%d;" "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL" " WHERE is_selected(id);" , vid, nvid ); db_lset_int("checkout", nvid); */ if(opt->dumpManifestFile){ FILE * out; /* MARKER(("Dumping generated manifest to file [%s]:\n", opt->dumpManifestFile)); */ out = fsl_fopen(opt->dumpManifestFile, "w"); if(out){ |
︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 | if(rc && !f->error.code){ if(f->dbMain->error.code) fsl_cx_uplift_db_error(f, f->dbMain); else f->error.code = rc; } fsl_checkin_discard(f); fsl_deck_finalize(d); return rc; | | | 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 | if(rc && !f->error.code){ if(f->dbMain->error.code) fsl_cx_uplift_db_error(f, f->dbMain); else f->error.code = rc; } fsl_checkin_discard(f); fsl_deck_finalize(d); return rc; }/*fsl_checkin_commit()*/ #undef MARKER |
Changes to src/deck.c.
︙ | ︙ | |||
1437 1438 1439 1440 1441 1442 1443 | while( !rc && !(rc=fsl_deck_F_next(d, &fc)) && fc) { rc = cb( fc, visitorState ); } return (FSL_RC_BREAK==rc) ? 0 : rc; } } | < | 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 | while( !rc && !(rc=fsl_deck_F_next(d, &fc)) && fc) { rc = cb( fc, visitorState ); } return (FSL_RC_BREAK==rc) ? 0 : rc; } } /** Output state for fsl_output_f_mf() and friends. Used for managing the output of a fsl_deck. */ struct fsl_deck_out_state { /** The set of cards being output. We use this to delegate certain |
︙ | ︙ | |||
2468 2469 2470 2471 2472 2473 2474 | } rc = fsl_deck_unshuffle(d, (FSL_CX_F_CALC_R_CARD & f->flags) ? ((d->F.used && !d->R) ? 1 : 0) : 0); /* ^^^^ unshuffling might install an R-card, so we have to do that before checking whether all required cards are | | > | 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 | } rc = fsl_deck_unshuffle(d, (FSL_CX_F_CALC_R_CARD & f->flags) ? ((d->F.used && !d->R) ? 1 : 0) : 0); /* ^^^^ unshuffling might install an R-card, so we have to do that before checking whether all required cards are set... */ if( !rc ) rc = fsl_deck_F_rewind(d); if(rc) return rc; else if(!fsl_deck_has_required_cards(d)){ return FSL_RC_SYNTAX; } os->d = d; os->out = out; |
︙ | ︙ | |||
3304 3305 3306 3307 3308 3309 3310 | isPrimary, pParentFile->perm); } } if(rc) goto end; } fsl__cx_mcache_insert(f, &dOther); | | | 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 | isPrimary, pParentFile->perm); } } if(rc) goto end; } fsl__cx_mcache_insert(f, &dOther); /* If pParent is the primary parent of pChild, also run this analysis ** for all merge parents of pChild */ if( pmid && isPrimary ){ for(i=1; i<pChild->P.used; i++){ pmid = fsl_uuid_to_rid(f, (char const*)pChild->P.list[i]); if( pmid<=0 ) continue; rc = fsl_mlink_add(f, pmid, 0, cid, pChild, false); |
︙ | ︙ |