Fossil SCM
Simplified and improved implementation of annotate_file().
Commit
d2b1565b7c112b827e49eeb9f863dc5e7d2b9f01c39c9590fcc8a5d1218d5380
Parent
54c0dab0c6e6c91…
1 file changed
+25
-55
+25
-55
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -2191,104 +2191,74 @@ | ||
| 2191 | 2191 | u64 annFlags /* Flags to alter the annotation */ |
| 2192 | 2192 | ){ |
| 2193 | 2193 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2194 | 2194 | Blob step; /* Text of previous revision */ |
| 2195 | 2195 | Blob treename; /* FILENAME translated to canonical form */ |
| 2196 | - Manifest *pManifest; /* Manifest structure */ | |
| 2197 | - ManifestFile *pFile; /* Manifest file pointer */ | |
| 2198 | 2196 | int cid; /* Selected check-in ID */ |
| 2199 | - int mid; /* Manifest where file was most recently changed */ | |
| 2200 | 2197 | int rid; /* Artifact ID of the file being annotated */ |
| 2201 | 2198 | int fnid; /* Filename ID */ |
| 2202 | 2199 | Stmt q; /* Query returning all ancestor versions */ |
| 2203 | - int cnt = 0; /* Number of versions examined */ | |
| 2200 | + int cnt = 0; /* Number of versions analyzed */ | |
| 2201 | + | |
| 2202 | + if( iLimit<=0 ) iLimit = 1000000000; /* A negative limit means no limit */ | |
| 2203 | + db_begin_transaction(); | |
| 2204 | 2204 | |
| 2205 | - /* Get artifact IDs of selected check-in and file */ | |
| 2205 | + /* Get the artificate ID for the check-in begin analyzed */ | |
| 2206 | 2206 | if( zRevision ){ |
| 2207 | - /* Get artifact ID of selected check-in manifest */ | |
| 2208 | 2207 | cid = name_to_typed_rid(zRevision, "ci"); |
| 2209 | - | |
| 2210 | - /* Get manifest structure for selected check-in */ | |
| 2211 | - pManifest = manifest_get(cid, CFTYPE_MANIFEST, 0); | |
| 2212 | - if( !pManifest ){ | |
| 2213 | - fossil_fatal("could not parse manifest for check-in: %s", zRevision); | |
| 2214 | - } | |
| 2215 | - | |
| 2216 | - /* Get selected file in manifest */ | |
| 2217 | - pFile = manifest_file_find(pManifest, zFilename); | |
| 2218 | - if( !pFile ){ | |
| 2219 | - fossil_fatal("file %s does not exist in check-in %s", zFilename, | |
| 2220 | - zRevision); | |
| 2221 | - } | |
| 2222 | - manifest_destroy(pManifest); | |
| 2223 | - | |
| 2224 | - /* Get file artifact ID from manifest file record */ | |
| 2225 | - rid = fast_uuid_to_rid(pFile->zUuid); | |
| 2226 | 2208 | }else{ |
| 2227 | - /* Get artifact ID of current checkout manifest */ | |
| 2228 | 2209 | db_must_be_within_tree(); |
| 2229 | 2210 | cid = db_lget_int("checkout", 0); |
| 2211 | + } | |
| 2230 | 2212 | |
| 2231 | - /* Get file artifact ID from current checkout file table */ | |
| 2232 | - rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename); | |
| 2233 | - if( rid==0 ){ | |
| 2234 | - fossil_fatal("file %s does not exist in current checkout", zFilename); | |
| 2235 | - } | |
| 2236 | - } | |
| 2213 | + /* Compute all direct ancestors of the check-in being analyzed into | |
| 2214 | + ** the "ancestor" table. */ | |
| 2215 | + compute_direct_ancestors(cid); | |
| 2237 | 2216 | |
| 2238 | 2217 | /* Get filename ID */ |
| 2239 | 2218 | file_tree_name(zFilename, &treename, 0, 1); |
| 2240 | 2219 | zFilename = blob_str(&treename); |
| 2241 | 2220 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2242 | 2221 | |
| 2243 | - /* Get ID of most recent manifest containing a change to the selected file */ | |
| 2244 | - compute_direct_ancestors(cid); | |
| 2245 | - mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor " | |
| 2246 | - " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid" | |
| 2247 | - " ORDER BY ancestor.generation ASC LIMIT 1", | |
| 2248 | - rid, fnid); | |
| 2249 | - if( mid==0 ){ | |
| 2250 | - fossil_fatal("unable to find manifest"); | |
| 2251 | - } | |
| 2252 | - | |
| 2253 | - /* Initialize the annotation */ | |
| 2254 | - if( !content_get(rid, &toAnnotate) ){ | |
| 2255 | - fossil_fatal("unable to retrieve content of artifact #%d", rid); | |
| 2256 | - } | |
| 2257 | - if( iLimit<=0 ) iLimit = 1000000000; | |
| 2258 | - blob_to_utf8_no_bom(&toAnnotate, 0); | |
| 2259 | - annotation_start(p, &toAnnotate, annFlags); | |
| 2260 | - db_begin_transaction(); | |
| 2261 | - | |
| 2262 | 2222 | db_prepare(&q, |
| 2263 | - "SELECT DISTINCT" | |
| 2223 | + "SELECT" | |
| 2264 | 2224 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 2265 | 2225 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 2266 | - " date(event.mtime)," | |
| 2267 | - " coalesce(event.euser,event.user)" | |
| 2226 | + " date(event.mtime)," | |
| 2227 | + " coalesce(event.euser,event.user)," | |
| 2228 | + " mlink.fid" | |
| 2268 | 2229 | " FROM mlink, event, ancestor" |
| 2269 | 2230 | " WHERE mlink.fnid=%d" |
| 2270 | - " AND event.objid=mlink.mid" | |
| 2271 | 2231 | " AND ancestor.rid=mlink.mid" |
| 2232 | + " AND event.objid=mlink.mid" | |
| 2233 | + " AND mlink.mid!=mlink.pid" | |
| 2272 | 2234 | " ORDER BY ancestor.generation;", |
| 2273 | 2235 | fnid |
| 2274 | 2236 | ); |
| 2275 | 2237 | |
| 2276 | 2238 | if( iLimit==0 ) iLimit = 1000000000; |
| 2277 | 2239 | while( iLimit>cnt && db_step(&q)==SQLITE_ROW ){ |
| 2240 | + rid = db_column_int(&q, 4); | |
| 2241 | + if( cnt==0 ){ | |
| 2242 | + if( !content_get(rid, &toAnnotate) ){ | |
| 2243 | + fossil_fatal("unable to retrieve content of artifact #%d", rid); | |
| 2244 | + } | |
| 2245 | + blob_to_utf8_no_bom(&toAnnotate, 0); | |
| 2246 | + annotation_start(p, &toAnnotate, annFlags); | |
| 2247 | + } | |
| 2278 | 2248 | p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); |
| 2279 | 2249 | p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); |
| 2280 | 2250 | p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); |
| 2281 | 2251 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2282 | 2252 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2283 | - if( p->nVers ){ | |
| 2253 | + p->nVers++; | |
| 2254 | + if( cnt>0 ){ | |
| 2284 | 2255 | content_get(rid, &step); |
| 2285 | 2256 | blob_to_utf8_no_bom(&step, 0); |
| 2286 | 2257 | annotation_step(p, &step, p->nVers-1, annFlags); |
| 2287 | 2258 | blob_reset(&step); |
| 2288 | 2259 | } |
| 2289 | - p->nVers++; | |
| 2290 | 2260 | cnt++; |
| 2291 | 2261 | } |
| 2292 | 2262 | p->bLimit = iLimit==cnt; |
| 2293 | 2263 | db_finalize(&q); |
| 2294 | 2264 | db_end_transaction(0); |
| 2295 | 2265 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -2191,104 +2191,74 @@ | |
| 2191 | u64 annFlags /* Flags to alter the annotation */ |
| 2192 | ){ |
| 2193 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2194 | Blob step; /* Text of previous revision */ |
| 2195 | Blob treename; /* FILENAME translated to canonical form */ |
| 2196 | Manifest *pManifest; /* Manifest structure */ |
| 2197 | ManifestFile *pFile; /* Manifest file pointer */ |
| 2198 | int cid; /* Selected check-in ID */ |
| 2199 | int mid; /* Manifest where file was most recently changed */ |
| 2200 | int rid; /* Artifact ID of the file being annotated */ |
| 2201 | int fnid; /* Filename ID */ |
| 2202 | Stmt q; /* Query returning all ancestor versions */ |
| 2203 | int cnt = 0; /* Number of versions examined */ |
| 2204 | |
| 2205 | /* Get artifact IDs of selected check-in and file */ |
| 2206 | if( zRevision ){ |
| 2207 | /* Get artifact ID of selected check-in manifest */ |
| 2208 | cid = name_to_typed_rid(zRevision, "ci"); |
| 2209 | |
| 2210 | /* Get manifest structure for selected check-in */ |
| 2211 | pManifest = manifest_get(cid, CFTYPE_MANIFEST, 0); |
| 2212 | if( !pManifest ){ |
| 2213 | fossil_fatal("could not parse manifest for check-in: %s", zRevision); |
| 2214 | } |
| 2215 | |
| 2216 | /* Get selected file in manifest */ |
| 2217 | pFile = manifest_file_find(pManifest, zFilename); |
| 2218 | if( !pFile ){ |
| 2219 | fossil_fatal("file %s does not exist in check-in %s", zFilename, |
| 2220 | zRevision); |
| 2221 | } |
| 2222 | manifest_destroy(pManifest); |
| 2223 | |
| 2224 | /* Get file artifact ID from manifest file record */ |
| 2225 | rid = fast_uuid_to_rid(pFile->zUuid); |
| 2226 | }else{ |
| 2227 | /* Get artifact ID of current checkout manifest */ |
| 2228 | db_must_be_within_tree(); |
| 2229 | cid = db_lget_int("checkout", 0); |
| 2230 | |
| 2231 | /* Get file artifact ID from current checkout file table */ |
| 2232 | rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename); |
| 2233 | if( rid==0 ){ |
| 2234 | fossil_fatal("file %s does not exist in current checkout", zFilename); |
| 2235 | } |
| 2236 | } |
| 2237 | |
| 2238 | /* Get filename ID */ |
| 2239 | file_tree_name(zFilename, &treename, 0, 1); |
| 2240 | zFilename = blob_str(&treename); |
| 2241 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2242 | |
| 2243 | /* Get ID of most recent manifest containing a change to the selected file */ |
| 2244 | compute_direct_ancestors(cid); |
| 2245 | mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor " |
| 2246 | " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid" |
| 2247 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2248 | rid, fnid); |
| 2249 | if( mid==0 ){ |
| 2250 | fossil_fatal("unable to find manifest"); |
| 2251 | } |
| 2252 | |
| 2253 | /* Initialize the annotation */ |
| 2254 | if( !content_get(rid, &toAnnotate) ){ |
| 2255 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2256 | } |
| 2257 | if( iLimit<=0 ) iLimit = 1000000000; |
| 2258 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2259 | annotation_start(p, &toAnnotate, annFlags); |
| 2260 | db_begin_transaction(); |
| 2261 | |
| 2262 | db_prepare(&q, |
| 2263 | "SELECT DISTINCT" |
| 2264 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 2265 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 2266 | " date(event.mtime)," |
| 2267 | " coalesce(event.euser,event.user)" |
| 2268 | " FROM mlink, event, ancestor" |
| 2269 | " WHERE mlink.fnid=%d" |
| 2270 | " AND event.objid=mlink.mid" |
| 2271 | " AND ancestor.rid=mlink.mid" |
| 2272 | " ORDER BY ancestor.generation;", |
| 2273 | fnid |
| 2274 | ); |
| 2275 | |
| 2276 | if( iLimit==0 ) iLimit = 1000000000; |
| 2277 | while( iLimit>cnt && db_step(&q)==SQLITE_ROW ){ |
| 2278 | p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); |
| 2279 | p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); |
| 2280 | p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); |
| 2281 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2282 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2283 | if( p->nVers ){ |
| 2284 | content_get(rid, &step); |
| 2285 | blob_to_utf8_no_bom(&step, 0); |
| 2286 | annotation_step(p, &step, p->nVers-1, annFlags); |
| 2287 | blob_reset(&step); |
| 2288 | } |
| 2289 | p->nVers++; |
| 2290 | cnt++; |
| 2291 | } |
| 2292 | p->bLimit = iLimit==cnt; |
| 2293 | db_finalize(&q); |
| 2294 | db_end_transaction(0); |
| 2295 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -2191,104 +2191,74 @@ | |
| 2191 | u64 annFlags /* Flags to alter the annotation */ |
| 2192 | ){ |
| 2193 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2194 | Blob step; /* Text of previous revision */ |
| 2195 | Blob treename; /* FILENAME translated to canonical form */ |
| 2196 | int cid; /* Selected check-in ID */ |
| 2197 | int rid; /* Artifact ID of the file being annotated */ |
| 2198 | int fnid; /* Filename ID */ |
| 2199 | Stmt q; /* Query returning all ancestor versions */ |
| 2200 | int cnt = 0; /* Number of versions analyzed */ |
| 2201 | |
| 2202 | if( iLimit<=0 ) iLimit = 1000000000; /* A negative limit means no limit */ |
| 2203 | db_begin_transaction(); |
| 2204 | |
| 2205 | /* Get the artificate ID for the check-in begin analyzed */ |
| 2206 | if( zRevision ){ |
| 2207 | cid = name_to_typed_rid(zRevision, "ci"); |
| 2208 | }else{ |
| 2209 | db_must_be_within_tree(); |
| 2210 | cid = db_lget_int("checkout", 0); |
| 2211 | } |
| 2212 | |
| 2213 | /* Compute all direct ancestors of the check-in being analyzed into |
| 2214 | ** the "ancestor" table. */ |
| 2215 | compute_direct_ancestors(cid); |
| 2216 | |
| 2217 | /* Get filename ID */ |
| 2218 | file_tree_name(zFilename, &treename, 0, 1); |
| 2219 | zFilename = blob_str(&treename); |
| 2220 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2221 | |
| 2222 | db_prepare(&q, |
| 2223 | "SELECT" |
| 2224 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 2225 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 2226 | " date(event.mtime)," |
| 2227 | " coalesce(event.euser,event.user)," |
| 2228 | " mlink.fid" |
| 2229 | " FROM mlink, event, ancestor" |
| 2230 | " WHERE mlink.fnid=%d" |
| 2231 | " AND ancestor.rid=mlink.mid" |
| 2232 | " AND event.objid=mlink.mid" |
| 2233 | " AND mlink.mid!=mlink.pid" |
| 2234 | " ORDER BY ancestor.generation;", |
| 2235 | fnid |
| 2236 | ); |
| 2237 | |
| 2238 | if( iLimit==0 ) iLimit = 1000000000; |
| 2239 | while( iLimit>cnt && db_step(&q)==SQLITE_ROW ){ |
| 2240 | rid = db_column_int(&q, 4); |
| 2241 | if( cnt==0 ){ |
| 2242 | if( !content_get(rid, &toAnnotate) ){ |
| 2243 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2244 | } |
| 2245 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2246 | annotation_start(p, &toAnnotate, annFlags); |
| 2247 | } |
| 2248 | p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); |
| 2249 | p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); |
| 2250 | p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); |
| 2251 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2252 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2253 | p->nVers++; |
| 2254 | if( cnt>0 ){ |
| 2255 | content_get(rid, &step); |
| 2256 | blob_to_utf8_no_bom(&step, 0); |
| 2257 | annotation_step(p, &step, p->nVers-1, annFlags); |
| 2258 | blob_reset(&step); |
| 2259 | } |
| 2260 | cnt++; |
| 2261 | } |
| 2262 | p->bLimit = iLimit==cnt; |
| 2263 | db_finalize(&q); |
| 2264 | db_end_transaction(0); |
| 2265 |