Fossil

Check-in [41f35ca4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Consolidated annotation file and manifest lookup code. This changes the error handling for the annotation web page to report an error rather than redirect to home. It also enables omitting the checkin query parameter when used with a server running within a checkout. (Later, by drh:) Move this code onto a branch because of build errors on Ubuntu.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | annotation-enhancements
Files: files | file ages | folders
SHA3-256:41f35ca4ec6178912c06f46abc9ac01d0769639b2745211b9072d044766e9e4c
User & Date: andygoth 2017-09-23 21:07:03
Original Comment: Consolidated annotation file and manifest lookup code. This changes the error handling for the annotation web page to report an error rather than redirect to home. It also enables omitting the checkin query parameter when used with a server running within a checkout.
Context
2017-09-23
21:18
Correct operation of filevers query parameter to annotate pages check-in: 4b721600 user: andygoth tags: annotation-enhancements
21:07
Consolidated annotation file and manifest lookup code. This changes the error handling for the annotation web page to report an error rather than redirect to home. It also enables omitting the checkin query parameter when used with a server running within a checkout. (Later, by drh:) Move this code onto a branch because of build errors on Ubuntu. check-in: 41f35ca4 user: andygoth tags: annotation-enhancements
19:10
Fix the value of the ANN_FILE_VERS flag so that it no longer overlaps with DIFF_SLOW_SBS. Omit the ANN_FILE_ANCEST flag which was always true. Update the annotator so that it follows check-ins in generation order according to the ancestor table. check-in: d9ef474a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/diff.c.

2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197





2198

2199
2200
2201
2202
2203
2204




























2205
2206

2207


















2208
2209
2210
2211
2212
2213
2214
....
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316

2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333

2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
....
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522

2523
2524
2525
2526
2527
2528
2529
....
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601

  /* Return no errors */
  return 0;
}


/*
** Compute a complete annotation on a file.  The file is identified
** by its filename number (filename.fnid) and check-in (mlink.mid).
*/
static void annotate_file(
  Annotator *p,        /* The annotator */
  int fnid,            /* The name of the file to be annotated */
  int mid,             /* Use the version of the file in this check-in */
  int iLimit,          /* Limit the number of levels if greater than zero */
  u64 annFlags         /* Flags to alter the annotation */
){
  Blob toAnnotate;     /* Text of the final (mid) version of the file */
  Blob step;           /* Text of previous revision */





  int rid;             /* Artifact ID of the file being annotated */

  Stmt q;              /* Query returning all ancestor versions */
  Stmt ins;            /* Inserts into the temporary VSEEN table */
  int cnt = 0;         /* Number of versions examined */

  /* Initialize the annotation */
  rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid);




























  if( rid==0 ){
    fossil_fatal("file #%d is unchanged in manifest #%d", fnid, mid);

  }


















  if( !content_get(rid, &toAnnotate) ){
    fossil_fatal("unable to retrieve content of artifact #%d", rid);
  }
  if( iLimit<=0 ) iLimit = 1000000000;
  blob_to_utf8_no_bom(&toAnnotate, 0);
  annotation_start(p, &toAnnotate, annFlags);
  db_begin_transaction();
................................................................................
**    filevers            Show file versions rather than check-in versions
**    limit=N             Limit the search depth to N ancestors
**    log=BOOLEAN         Show a log of versions analyzed
**    w                   Ignore whitespace
**
*/
void annotation_page(void){
  int mid;
  int fnid;
  int i;
  int iLimit;            /* Depth limit */
  u64 annFlags = DIFF_STRIP_EOLCR;
  int showLog = 0;       /* True to display the log */
  int ignoreWs = 0;      /* Ignore whitespace */
  const char *zFilename; /* Name of file to annotate */

  const char *zCI;       /* The check-in containing zFilename */
  Annotator ann;
  HQuery url;
  struct AnnVers *p;
  unsigned clr1, clr2, clr;
  int bBlame = g.zPath[0]!='a';/* True for BLAME output.  False for ANNOTATE. */

  /* Gather query parameters */
  showLog = atoi(PD("log","1"));
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
  if( exclude_spiders() ) return;
  load_control();
  mid = name_to_typed_rid(PD("checkin","0"),"ci");
  zFilename = P("filename");
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
  if( mid==0 || fnid==0 ){ fossil_redirect_home(); }

  iLimit = atoi(PD("limit","20"));
  if( P("filevers") ) annFlags |= ANN_FILE_VERS;
  ignoreWs = P("w")!=0;
  if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS;
  if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
    fossil_redirect_home();
  }

  /* compute the annotation */
  compute_direct_ancestors(mid);
  annotate_file(&ann, fnid, mid, iLimit, annFlags);
  zCI = ann.aVers[0].zMUuid;

  /* generate the web page */
  style_header("Annotation For %h", zFilename);
  if( bBlame ){
    url_initialize(&url, "blame");
  }else{
................................................................................
**   -n|--limit N                Only look backwards in time by N versions
**   -w|--ignore-all-space       Ignore white space when comparing lines
**   -Z|--ignore-trailing-space  Ignore whitespace at line end
**
** See also: info, finfo, timeline
*/
void annotate_cmd(void){
  int fnid;         /* Filename ID */
  int fid;          /* File instance ID */
  int mid;          /* Manifest where file was checked in */
  int cid;          /* Checkout or selected check-in ID */
  Blob treename;    /* FILENAME translated to canonical form */
  const char *zRev; /* Revision name, or NULL for current check-in */
  char *zFilename;  /* Canonical filename */
  Annotator ann;    /* The annotation of the file */
  int i;            /* Loop counter */
  const char *zLimit; /* The value to the -n|--limit option */
  int iLimit;       /* How far back in time to look */
  int showLog;      /* True to show the log */
  int fileVers;     /* Show file version instead of check-in versions */
  u64 annFlags = 0; /* Flags to control annotation properties */
  int bBlame = 0;   /* True for BLAME output.  False for ANNOTATE. */
  Manifest *pManifest; /* Manifest structure */
  ManifestFile *pFile; /* Manifest file pointer */

  bBlame = g.argv[1][0]!='a';
  zRev = find_option("r","revision",1);
  zLimit = find_option("limit","n",1);
  if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
  iLimit = atoi(zLimit);

  showLog = find_option("log","l",0)!=0;
  if( find_option("ignore-trailing-space","Z",0)!=0 ){
    annFlags = DIFF_IGNORE_EOLWS;
  }
  if( find_option("ignore-all-space","w",0)!=0 ){
    annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
  }
................................................................................
  /* We should be done with options.. */
  verify_all_options();

  if( g.argc<3 ) {
    usage("FILENAME");
  }

  /* Get filename ID */
  file_tree_name(g.argv[2], &treename, 0, 1);
  zFilename = blob_str(&treename);
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
  if( fnid==0 ){
    fossil_fatal("no such file: %s", zFilename);
  }

  /* Get artifact IDs of selected check-in and file */
  if( zRev ){
    /* Get artifact ID of selected check-in manifest */
    cid = name_to_typed_rid(zRev, "ci");

    /* Get manifest structure for selected check-in */
    pManifest = manifest_get(cid, CFTYPE_MANIFEST, 0);
    if( !pManifest ){
      fossil_fatal("could not parse manifest for check-in: %s", zRev);
    }
    
    /* Get selected file in manifest */
    pFile = manifest_file_find(pManifest, zFilename);
    if( !pFile ){
      fossil_fatal("file %s does not exist in check-in %s", zFilename, zRev);
    }
    manifest_destroy(pManifest);

    /* Get file instance ID from manifest file record */
    fid = fast_uuid_to_rid(pFile->zUuid);
  }else{
    /* Get artifact ID of current checkout manifest */
    cid = db_lget_int("checkout", 0);
    if( cid == 0 ){
      fossil_fatal("not in a checkout");
    }

    /* Get file instance ID from current checkout file table */
    fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
    if( fid==0 ){
      fossil_fatal("not part of current checkout: %s", zFilename);
    }
  }

  /* Get ID of most recent manifest containing a change to the selected file */
  compute_direct_ancestors(cid);
  mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
          " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid"
          " ORDER BY ancestor.generation ASC LIMIT 1",
          fid, fnid);
  if( mid==0 ){
    fossil_fatal("unable to find manifest");
  }

  if( iLimit<=0 ) iLimit = 1000000000;
  annFlags |= DIFF_STRIP_EOLCR;
  annotate_file(&ann, fnid, mid, iLimit, annFlags);
  if( showLog ){
    struct AnnVers *p;
    for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
      fossil_print("version %3d: %s %S file %S\n",
                   i+1, p->zDate, p->zMUuid, p->zFUuid);
    }
    fossil_print("---------------------------------------------------\n");







|
|



|
|





>
>
>
>
>

>




<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<






>













<

<
<
>




<
<
|
<

<
|







 







<
<
<
<
<
|
<












|



>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|







2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208


2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237

2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
....
2352
2353
2354
2355
2356
2357
2358


2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378

2379


2380
2381
2382
2383
2384


2385

2386

2387
2388
2389
2390
2391
2392
2393
2394
....
2536
2537
2538
2539
2540
2541
2542





2543

2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
....
2571
2572
2573
2574
2575
2576
2577





















































2578
2579
2580
2581
2582
2583
2584
2585
2586

  /* Return no errors */
  return 0;
}


/*
** Compute a complete annotation on a file.  The file is identified by its
** filename and check-in name (NULL for current check-in).
*/
static void annotate_file(
  Annotator *p,        /* The annotator */
  const char *zFilename,/* The name of the file to be annotated */
  const char *zRevision,/* Use the version of the file in this check-in */
  int iLimit,          /* Limit the number of levels if greater than zero */
  u64 annFlags         /* Flags to alter the annotation */
){
  Blob toAnnotate;     /* Text of the final (mid) version of the file */
  Blob step;           /* Text of previous revision */
  Blob treename;       /* FILENAME translated to canonical form */
  Manifest *pManifest; /* Manifest structure */
  ManifestFile *pFile; /* Manifest file pointer */
  int cid;             /* Selected check-in ID */
  int mid;             /* Manifest where file was most recently changed */
  int rid;             /* Artifact ID of the file being annotated */
  int fnid;            /* Filename ID */
  Stmt q;              /* Query returning all ancestor versions */
  Stmt ins;            /* Inserts into the temporary VSEEN table */
  int cnt = 0;         /* Number of versions examined */



  /* Get artifact IDs of selected check-in and file */
  if( zRevision ){
    /* Get artifact ID of selected check-in manifest */
    cid = name_to_typed_rid(zRevision, "ci");

    /* Get manifest structure for selected check-in */
    pManifest = manifest_get(cid, CFTYPE_MANIFEST, 0);
    if( !pManifest ){
      fossil_fatal("could not parse manifest for check-in: %s", zRevision);
    }
    
    /* Get selected file in manifest */
    pFile = manifest_file_find(pManifest, zFilename);
    if( !pFile ){
      fossil_fatal("file %s does not exist in check-in %s", zFilename,
          zRevision);
    }
    manifest_destroy(pManifest);

    /* Get file artifact ID from manifest file record */
    rid = fast_uuid_to_rid(pFile->zUuid);
  }else{
    /* Get artifact ID of current checkout manifest */
    db_must_be_within_tree();
    cid = db_lget_int("checkout", 0);

    /* Get file artifact ID from current checkout file table */
    rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
    if( rid==0 ){

      fossil_fatal("file %s does not exist in current checkout", zFilename);
    }
  }

  /* Get filename ID */
  file_tree_name(zFilename, &treename, 0, 1);
  zFilename = blob_str(&treename);
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);

  /* Get ID of most recent manifest containing a change to the selected file */
  compute_direct_ancestors(cid);
  mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
          " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid"
          " ORDER BY ancestor.generation ASC LIMIT 1",
          rid, fnid);
  if( mid==0 ){
    fossil_fatal("unable to find manifest");
  }

  /* Initialize the annotation */
  if( !content_get(rid, &toAnnotate) ){
    fossil_fatal("unable to retrieve content of artifact #%d", rid);
  }
  if( iLimit<=0 ) iLimit = 1000000000;
  blob_to_utf8_no_bom(&toAnnotate, 0);
  annotation_start(p, &toAnnotate, annFlags);
  db_begin_transaction();
................................................................................
**    filevers            Show file versions rather than check-in versions
**    limit=N             Limit the search depth to N ancestors
**    log=BOOLEAN         Show a log of versions analyzed
**    w                   Ignore whitespace
**
*/
void annotation_page(void){


  int i;
  int iLimit;            /* Depth limit */
  u64 annFlags = DIFF_STRIP_EOLCR;
  int showLog = 0;       /* True to display the log */
  int ignoreWs = 0;      /* Ignore whitespace */
  const char *zFilename; /* Name of file to annotate */
  const char *zRevision; /* Name of check-in from which to start annotation */
  const char *zCI;       /* The check-in containing zFilename */
  Annotator ann;
  HQuery url;
  struct AnnVers *p;
  unsigned clr1, clr2, clr;
  int bBlame = g.zPath[0]!='a';/* True for BLAME output.  False for ANNOTATE. */

  /* Gather query parameters */
  showLog = atoi(PD("log","1"));
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
  if( exclude_spiders() ) return;
  load_control();

  zFilename = P("filename");


  zRevision = PD("checkin",0);
  iLimit = atoi(PD("limit","20"));
  if( P("filevers") ) annFlags |= ANN_FILE_VERS;
  ignoreWs = P("w")!=0;
  if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS;




  /* compute the annotation */

  annotate_file(&ann, zFilename, zRevision, iLimit, annFlags);
  zCI = ann.aVers[0].zMUuid;

  /* generate the web page */
  style_header("Annotation For %h", zFilename);
  if( bBlame ){
    url_initialize(&url, "blame");
  }else{
................................................................................
**   -n|--limit N                Only look backwards in time by N versions
**   -w|--ignore-all-space       Ignore white space when comparing lines
**   -Z|--ignore-trailing-space  Ignore whitespace at line end
**
** See also: info, finfo, timeline
*/
void annotate_cmd(void){





  const char *zRevision; /* Revision name, or NULL for current check-in */

  Annotator ann;    /* The annotation of the file */
  int i;            /* Loop counter */
  const char *zLimit; /* The value to the -n|--limit option */
  int iLimit;       /* How far back in time to look */
  int showLog;      /* True to show the log */
  int fileVers;     /* Show file version instead of check-in versions */
  u64 annFlags = 0; /* Flags to control annotation properties */
  int bBlame = 0;   /* True for BLAME output.  False for ANNOTATE. */
  Manifest *pManifest; /* Manifest structure */
  ManifestFile *pFile; /* Manifest file pointer */

  bBlame = g.argv[1][0]!='a';
  zRevision = find_option("r","revision",1);
  zLimit = find_option("limit","n",1);
  if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
  iLimit = atoi(zLimit);
  if( iLimit<=0 ) iLimit = 1000000000;
  showLog = find_option("log","l",0)!=0;
  if( find_option("ignore-trailing-space","Z",0)!=0 ){
    annFlags = DIFF_IGNORE_EOLWS;
  }
  if( find_option("ignore-all-space","w",0)!=0 ){
    annFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
  }
................................................................................
  /* We should be done with options.. */
  verify_all_options();

  if( g.argc<3 ) {
    usage("FILENAME");
  }






















































  annFlags |= DIFF_STRIP_EOLCR;
  annotate_file(&ann, g.argv[2], zRevision, iLimit, annFlags);
  if( showLog ){
    struct AnnVers *p;
    for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
      fossil_print("version %3d: %s %S file %S\n",
                   i+1, p->zDate, p->zMUuid, p->zFUuid);
    }
    fossil_print("---------------------------------------------------\n");