Changes On Branch declined
Not logged in

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

Changes In Branch declined Excluding Merge-Ins

This is equivalent to a diff from fff43ebb5b to a942086390

2011-10-20
02:03
Sorry, wrong branch! started changelog for 1.20 release. Closed-Leaf check-in: a942086390 user: stephan tags: declined
2011-10-15
10:17
A very simple fix to the annotate memory leak problem. check-in: 9929bab702 user: drh tags: trunk
2011-10-14
22:20
Making 'fossil merge' also report a conflict for extra files overwritten. Like [60c6197c8a], but for the merge operation. Related to ticket [953031915f]. check-in: bb49278a8a user: viriketo tags: declined
16:11
Merging the annotate_noleak changes, about removing an important memory leak in the annotate operation.    It also fixes some blob behaviour in blob.c and content.c.    Update: Removed from trunk. Replaced by the must simpler fix at [9929bab702f99839ee] check-in: 409f370a6d user: viriketo tags: declined
00:06
Add /*sort*/ marks to some SQL queries to disable warnings about sorting without an index. check-in: fff43ebb5b user: drh tags: trunk
2011-10-13
23:47
Provide an option to enable the /test_env URL for all users. Optionally display cookie values in the /test_env URL. check-in: 4d32db8ef8 user: drh tags: trunk

Changes to src/blob.c.

   918    918   **
   919    919   ** pOut must be either uninitialized or the same as pIn.
   920    920   */
   921    921   int blob_uncompress(Blob *pIn, Blob *pOut){
   922    922     unsigned int nOut;
   923    923     unsigned char *inBuf;
   924    924     unsigned int nIn = blob_size(pIn);
   925         -  Blob temp;
          925  +  Blob temp = empty_blob;
   926    926     int rc;
   927    927     unsigned long int nOut2;
   928    928     if( nIn<=4 ){
   929    929       return 0;
   930    930     }
   931    931     inBuf = (unsigned char*)blob_buffer(pIn);
   932    932     nOut = (inBuf[0]<<24) + (inBuf[1]<<16) + (inBuf[2]<<8) + inBuf[3];

Changes to src/content.c.

    93     93                                contentCache.nAlloc*sizeof(contentCache.a[0]));
    94     94     }
    95     95     p = &contentCache.a[contentCache.n++];
    96     96     p->rid = rid;
    97     97     p->age = contentCache.nextAge++;
    98     98     contentCache.szTotal += blob_size(pBlob);
    99     99     p->content = *pBlob;
   100         -  blob_zero(pBlob);
          100  +  *pBlob = empty_blob;
   101    101     bag_insert(&contentCache.inCache, rid);
   102    102   }
   103    103   
   104    104   /*
   105    105   ** Clear the content cache.
   106    106   */
   107    107   void content_clear_cache(void){
................................................................................
   257    257     if( nextRid==0 ){
   258    258       rc = content_of_blob(rid, pBlob);
   259    259     }else{
   260    260       int n = 1;
   261    261       int nAlloc = 10;
   262    262       int *a = 0;
   263    263       int mx;
   264         -    Blob delta, next;
          264  +    Blob delta = empty_blob, next = empty_blob;
   265    265   
   266    266       a = fossil_malloc( sizeof(a[0])*nAlloc );
   267    267       a[0] = rid;
   268    268       a[1] = nextRid;
   269    269       n = 1;
   270    270       while( !bag_find(&contentCache.inCache, nextRid)
   271    271           && (nextRid = findSrcid(nextRid))>0 ){

Changes to src/db.c.

   209    209   ** Prepare a Stmt.  Assume that the Stmt is previously uninitialized.
   210    210   ** If the input string contains multiple SQL statements, only the first
   211    211   ** one is processed.  All statements beyond the first are silently ignored.
   212    212   */
   213    213   int db_vprepare(Stmt *pStmt, int errOk, const char *zFormat, va_list ap){
   214    214     int rc;
   215    215     char *zSql;
   216         -  blob_zero(&pStmt->sql);
          216  +  pStmt->sql = empty_blob;
   217    217     blob_vappendf(&pStmt->sql, zFormat, ap);
   218    218     va_end(ap);
   219    219     zSql = blob_str(&pStmt->sql);
   220    220     nPrepare++;
   221    221     rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt->pStmt, 0);
   222    222     if( rc!=0 && !errOk ){
   223    223       db_err("%s\n%s", sqlite3_errmsg(g.db), zSql);

Changes to src/deltacmd.c.

    75     75   **
    76     76   ** It works ok for pTarget and pOriginal to be the same blob.
    77     77   **
    78     78   ** Return the length of the target.  Return -1 if there is an error.
    79     79   */
    80     80   int blob_delta_apply(Blob *pOriginal, Blob *pDelta, Blob *pTarget){
    81     81     int len, n;
    82         -  Blob out;
           82  +  Blob out = empty_blob;
    83     83   
    84     84     n = delta_output_size(blob_buffer(pDelta), blob_size(pDelta));
    85     85     blob_zero(&out);
    86     86     if( n<0 ) return -1;
    87     87     blob_resize(&out, n);
    88     88     len = delta_apply(
    89     89        blob_buffer(pOriginal), blob_size(pOriginal),

Changes to src/diff.c.

   617    617   }
   618    618   
   619    619   /**************************************************************************
   620    620   ** The basic difference engine is above.  What follows is the annotation
   621    621   ** engine.  Both are in the same file since they share many components.
   622    622   */
   623    623   
          624  +/*
          625  +** Linked list of strings, labels used in the annotator code.
          626  +** The elements of the list and the pointed string (str)
          627  +** will be freed once they become totally unreferenced
          628  +** (nref == 0).
          629  +*/
          630  +struct Label
          631  +{
          632  +    struct Label *prev;   /* previous element */
          633  +    struct Label *next;   /* next element */
          634  +    char *str;            /* The label string */
          635  +    int nref;             /* Number of references to the string */
          636  +};
          637  +
   624    638   /*
   625    639   ** The status of an annotation operation is recorded by an instance
   626    640   ** of the following structure.
   627    641   */
   628    642   typedef struct Annotator Annotator;
   629    643   struct Annotator {
   630    644     DContext c;       /* The diff-engine context */
   631    645     struct AnnLine {  /* Lines of the original files... */
   632    646       const char *z;       /* The text of the line */
   633    647       short int n;         /* Number of bytes (omitting trailing space and \n) */
   634    648       short int iLevel;    /* Level at which tag was set */
   635         -    const char *zSrc;    /* Tag showing origin of this line */
          649  +    struct Label *zSrc;    /* Tag showing origin of this line */
   636    650     } *aOrig;
   637    651     int nOrig;        /* Number of elements in aOrig[] */
   638    652     int nNoSrc;       /* Number of entries where aOrig[].zSrc==NULL */
   639    653     int iLevel;       /* Current level */
   640    654     int nVers;        /* Number of versions analyzed */
   641         -  char **azVers;    /* Names of versions analyzed */
          655  +  struct Label **azVers;    /* Names of versions analyzed */
          656  +  Blob toAnnotate;
          657  +  struct Label *firstLabel;
   642    658   };
   643    659   
   644    660   /*
   645    661   ** Initialize the annotation process by specifying the file that is
   646    662   ** to be annotated.  The annotator takes control of the input Blob and
   647    663   ** will release it when it is finished with it.
   648    664   */
   649         -static int annotation_start(Annotator *p, Blob *pInput){
          665  +static int annotation_start(Annotator *p){
   650    666     int i;
   651    667   
   652         -  memset(p, 0, sizeof(*p));
   653         -  p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,1);
          668  +  p->c.aTo = break_into_lines(blob_str(&p->toAnnotate),
          669  +          blob_size(&p->toAnnotate),&p->c.nTo,1);
   654    670     if( p->c.aTo==0 ){
   655    671       return 1;
   656    672     }
   657    673     p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
   658    674     for(i=0; i<p->c.nTo; i++){
   659    675       p->aOrig[i].z = p->c.aTo[i].z;
   660    676       p->aOrig[i].n = p->c.aTo[i].h & LENGTH_MASK;
................................................................................
   667    683   /*
   668    684   ** The input pParent is the next most recent ancestor of the file
   669    685   ** being annotated.  Do another step of the annotation.  Return true
   670    686   ** if additional annotation is required.  zPName is the tag to insert
   671    687   ** on each line of the file being annotated that was contributed by
   672    688   ** pParent.  Memory to hold zPName is leaked.
   673    689   */
   674         -static int annotation_step(Annotator *p, Blob *pParent, char *zPName){
          690  +static int annotation_step(Annotator *p, Blob *pParent, struct Label *zPName){
   675    691     int i, j;
   676    692     int lnTo;
   677    693     int iPrevLevel;
   678    694     int iThisLevel;
   679    695   
   680    696     /* Prepare the parent file to be diffed */
   681    697     p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
   682    698                                   &p->c.nFrom, 1);
   683    699     if( p->c.aFrom==0 ){
          700  +    free(p->c.aFrom);
   684    701       return 1;
   685    702     }
   686    703   
   687    704     /* Compute the differences going from pParent to the file being
   688    705     ** annotated. */
   689    706     diff_all(&p->c);
   690    707   
................................................................................
   694    711     iPrevLevel = p->iLevel;
   695    712     p->iLevel++;
   696    713     iThisLevel = p->iLevel;
   697    714     for(i=lnTo=0; i<p->c.nEdit; i+=3){
   698    715       struct AnnLine *x = &p->aOrig[lnTo];
   699    716       for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
   700    717         if( x->zSrc==0 || x->iLevel==iPrevLevel ){
          718  +         if (x->zSrc!=0)
          719  +         {
          720  +           if(--x->zSrc->nref == 0)
          721  +           {
          722  +             free(x->zSrc->str);
          723  +             if (x->zSrc->prev)
          724  +               x->zSrc->prev->next = x->zSrc->next;
          725  +             if (x->zSrc->next)
          726  +               x->zSrc->next->prev = x->zSrc->prev;
          727  +             free(x->zSrc);
          728  +           }
          729  +         }
   701    730            x->zSrc = zPName;
          731  +         ++zPName->nref;
   702    732            x->iLevel = iThisLevel;
   703    733         }
   704    734       }
   705    735       lnTo += p->c.aEdit[i+2];
   706    736     }
   707    737   
   708    738     /* Clear out the diff results */
................................................................................
   709    739     free(p->c.aEdit);
   710    740     p->c.aEdit = 0;
   711    741     p->c.nEdit = 0;
   712    742     p->c.nEditAlloc = 0;
   713    743   
   714    744     /* Clear out the from file */
   715    745     free(p->c.aFrom);    
   716         -  blob_zero(pParent);
          746  +  blob_reset(pParent);
   717    747   
   718    748     /* Return no errors */
   719    749     return 0;
   720    750   }
   721    751   
   722    752   
   723    753   /*
   724    754   ** COMMAND: test-annotate-step
   725    755   */
   726    756   void test_annotate_step_cmd(void){
   727         -  Blob orig, b;
          757  +  Blob b = empty_blob;
   728    758     Annotator x;
   729    759     int i;
   730    760   
   731    761     if( g.argc<4 ) usage("RID1 RID2 ...");
   732    762     db_must_be_within_tree();
   733         -  blob_zero(&b);
   734         -  content_get(name_to_rid(g.argv[2]), &orig);
   735         -  if( annotation_start(&x, &orig) ){
          763  +  memset(&x, 0, sizeof(x));
          764  +  x.toAnnotate = empty_blob;
          765  +  content_get(name_to_rid(g.argv[2]), &x.toAnnotate);
          766  +  if( annotation_start(&x) ){
   736    767       fossil_fatal("binary file");
   737    768     }
   738    769     for(i=3; i<g.argc; i++){
          770  +    struct Label *l;
   739    771       blob_zero(&b);
   740    772       content_get(name_to_rid(g.argv[i]), &b);
   741         -    if( annotation_step(&x, &b, g.argv[i-1]) ){
          773  +    l = fossil_malloc(sizeof(*l));
          774  +    l->str = g.argv[i-1];
          775  +    l->nref = 0;
          776  +    l->next = x.firstLabel;
          777  +    if (x.firstLabel)
          778  +      x.firstLabel->prev = l;
          779  +    x.firstLabel = l;
          780  +    if( annotation_step(&x, &b, l) ){
   742    781         fossil_fatal("binary file");
   743    782       }
   744    783     }
   745    784     for(i=0; i<x.nOrig; i++){
   746         -    const char *zSrc = x.aOrig[i].zSrc;
          785  +    const char *zSrc = x.aOrig[i].zSrc->str;
   747    786       if( zSrc==0 ) zSrc = g.argv[g.argc-1];
   748    787       fossil_print("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z);
          788  +  }
          789  +  while(x.firstLabel) {
          790  +    struct Label *l;
          791  +    l = x.firstLabel->next;
          792  +    assert(x.firstLabel->nref > 0);
          793  +    free(x.firstLabel->str);
          794  +    free(x.firstLabel);
          795  +    x.firstLabel = l;
   749    796     }
   750    797   }
   751    798   
   752    799   /* Annotation flags */
   753    800   #define ANN_FILE_VERS  0x001  /* Show file version rather than commit version */
   754    801   
   755    802   /*
................................................................................
   761    808     Annotator *p,        /* The annotator */
   762    809     int fnid,            /* The name of the file to be annotated */
   763    810     int mid,             /* Use the version of the file in this check-in */
   764    811     int webLabel,        /* Use web-style annotations if true */
   765    812     int iLimit,          /* Limit the number of levels if greater than zero */
   766    813     int annFlags         /* Flags to alter the annotation */
   767    814   ){
   768         -  Blob toAnnotate;     /* Text of the final (mid) version of the file */
   769         -  Blob step;           /* Text of previous revision */
          815  +  Blob step = empty_blob;           /* Text of previous revision */
   770    816     int rid;             /* Artifact ID of the file being annotated */
   771         -  char *zLabel;        /* Label to apply to a line */
   772    817     Stmt q;              /* Query returning all ancestor versions */
   773    818   
   774    819     /* Initialize the annotation */
   775    820     rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid);
   776    821     if( rid==0 ){
   777    822       fossil_panic("file #%d is unchanged in manifest #%d", fnid, mid);
   778    823     }
   779         -  if( !content_get(rid, &toAnnotate) ){
          824  +  memset(p, 0, sizeof(*p));
          825  +  p->toAnnotate = empty_blob;
          826  +  if( !content_get(rid, &p->toAnnotate) ){
   780    827       fossil_panic("unable to retrieve content of artifact #%d", rid);
   781    828     }
   782    829     db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
   783    830     if( iLimit<=0 ) iLimit = 1000000000;
   784    831     compute_direct_ancestors(mid, iLimit);
   785         -  annotation_start(p, &toAnnotate);
          832  +  annotation_start(p);
   786    833   
   787    834     db_prepare(&q, 
   788    835       "SELECT mlink.fid,"
   789    836       "       (SELECT uuid FROM blob WHERE rid=mlink.%s),"
   790    837       "       date(event.mtime), "
   791    838       "       coalesce(event.euser,event.user) "
   792    839       "  FROM ancestor, mlink, event"
................................................................................
   800    847       iLimit>0 ? iLimit : 10000000
   801    848     );
   802    849     while( db_step(&q)==SQLITE_ROW ){
   803    850       int pid = db_column_int(&q, 0);
   804    851       const char *zUuid = db_column_text(&q, 1);
   805    852       const char *zDate = db_column_text(&q, 2);
   806    853       const char *zUser = db_column_text(&q, 3);
          854  +    struct Label *l = fossil_malloc(sizeof(*l));
          855  +    l->nref = 0;
          856  +    l->next = p->firstLabel;
          857  +    l->prev = 0;
          858  +    if (p->firstLabel)
          859  +      p->firstLabel->prev = l;
   807    860       if( webLabel ){
   808         -      zLabel = mprintf(
          861  +      l->str = mprintf(
   809    862             "<a href='%s/info/%s' target='infowindow'>%.10s</a> %s %9.9s", 
   810    863             g.zTop, zUuid, zUuid, zDate, zUser
   811    864         );
   812    865       }else{
   813         -      zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
          866  +      l->str = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
   814    867       }
          868  +    p->firstLabel = l;
   815    869       p->nVers++;
   816    870       p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
   817         -    p->azVers[p->nVers-1] = zLabel;
          871  +    p->azVers[p->nVers-1] = l;
   818    872       content_get(pid, &step);
   819         -    annotation_step(p, &step, zLabel);
          873  +    annotation_step(p, &step, l);
          874  +    if (l->nref == 0)
          875  +    {
          876  +      free(l->str);
          877  +      p->firstLabel = l->next;
          878  +      if (l->next)
          879  +        l->next->prev = 0;
          880  +      free(l);
          881  +    }
   820    882       blob_reset(&step);
   821    883     }
   822    884     db_finalize(&q);
          885  +  free(p->c.aTo);
   823    886   }
   824    887   
   825    888   /*
   826    889   ** WEBPAGE: annotate
   827    890   **
   828    891   ** Query parameters:
   829    892   **
................................................................................
   851    914     if( P("filevers") ) annFlags |= ANN_FILE_VERS;
   852    915     annotate_file(&ann, fnid, mid, g.perm.History, iLimit, annFlags);
   853    916     if( P("log") ){
   854    917       int i;
   855    918       @ <h2>Versions analyzed:</h2>
   856    919       @ <ol>
   857    920       for(i=0; i<ann.nVers; i++){
   858         -      @ <li><tt>%s(ann.azVers[i])</tt></li>
          921  +      @ <li><tt>%s(ann.azVers[i]->str)</tt></li>
   859    922       }
   860    923       @ </ol>
   861    924       @ <hr>
   862    925       @ <h2>Annotation:</h2>
   863    926     }
   864    927     @ <pre>
   865    928     for(i=0; i<ann.nOrig; i++){
   866    929       ((char*)ann.aOrig[i].z)[ann.aOrig[i].n] = 0;
   867         -    @ %s(ann.aOrig[i].zSrc): %h(ann.aOrig[i].z)
          930  +    @ %s(ann.aOrig[i].zSrc->str): %h(ann.aOrig[i].z)
   868    931     }
   869    932     @ </pre>
   870    933     style_footer();
          934  +
          935  +  free(ann.azVers);
          936  +  free(ann.aOrig);
          937  +  blob_reset(&ann.toAnnotate);
          938  +  while(ann.firstLabel) {
          939  +    struct Label *l;
          940  +    l = ann.firstLabel->next;
          941  +    assert(ann.firstLabel->nref > 0);
          942  +    free(ann.firstLabel->str);
          943  +    free(ann.firstLabel);
          944  +    ann.firstLabel = l;
          945  +  }
   871    946   }
   872    947   
   873    948   /*
   874    949   ** COMMAND: annotate
   875    950   **
   876    951   ** %fossil annotate ?OPTIONS? FILENAME
   877    952   **
................................................................................
   883    958   **   --log           List all versions analyzed
   884    959   **   --filevers      Show file version numbers rather than check-in versions
   885    960   */
   886    961   void annotate_cmd(void){
   887    962     int fnid;         /* Filename ID */
   888    963     int fid;          /* File instance ID */
   889    964     int mid;          /* Manifest where file was checked in */
   890         -  Blob treename;    /* FILENAME translated to canonical form */
          965  +  Blob treename = empty_blob;    /* FILENAME translated to canonical form */
   891    966     char *zFilename;  /* Cannonical filename */
   892    967     Annotator ann;    /* The annotation of the file */
   893    968     int i;            /* Loop counter */
   894    969     const char *zLimit; /* The value to the --limit option */
   895    970     int iLimit;       /* How far back in time to look */
   896    971     int showLog;      /* True to show the log */
   897    972     int fileVers;     /* Show file version instead of check-in versions */
................................................................................
   912    987     if( fnid==0 ){
   913    988       fossil_fatal("no such file: %s", zFilename);
   914    989     }
   915    990     fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
   916    991     if( fid==0 ){
   917    992       fossil_fatal("not part of current checkout: %s", zFilename);
   918    993     }
          994  +  blob_reset(&treename);
   919    995     mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
   920    996     if( mid==0 ){
   921    997       fossil_panic("unable to find manifest");
   922    998     }
   923    999     if( fileVers ) annFlags |= ANN_FILE_VERS;
   924   1000     annotate_file(&ann, fnid, mid, 0, iLimit, annFlags);
   925   1001     if( showLog ){
   926   1002       for(i=0; i<ann.nVers; i++){
   927         -      printf("version %3d: %s\n", i+1, ann.azVers[i]);
         1003  +      printf("version %3d: %s\n", i+1, ann.azVers[i]->str);
   928   1004       }
   929   1005       printf("---------------------------------------------------\n");
   930   1006     }
   931   1007     for(i=0; i<ann.nOrig; i++){
   932   1008       fossil_print("%s: %.*s\n", 
   933         -                 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
         1009  +                 ann.aOrig[i].zSrc->str, ann.aOrig[i].n, ann.aOrig[i].z);
         1010  +  }
         1011  +  free(ann.azVers);
         1012  +  free(ann.aOrig);
         1013  +  blob_reset(&ann.toAnnotate);
         1014  +  while(ann.firstLabel) {
         1015  +    struct Label *l;
         1016  +    l = ann.firstLabel->next;
         1017  +    assert(ann.firstLabel->nref > 0);
         1018  +    free(ann.firstLabel->str);
         1019  +    free(ann.firstLabel);
         1020  +    ann.firstLabel = l;
   934   1021     }
   935   1022   }

Changes to src/diffcmd.c.

   181    181   }
   182    182   
   183    183   /*
   184    184   ** Do a diff against a single file named in zFileTreeName from version zFrom
   185    185   ** against the same file on disk.
   186    186   */
   187    187   static void diff_one_against_disk(
   188         -  const char *zFrom,        /* Name of file */
          188  +  const char *zFrom,        /* Version to difference from */
   189    189     const char *zDiffCmd,     /* Use this "diff" command */
   190    190     int ignoreEolWs,          /* Ignore whitespace changes at end of lines */
   191         -  const char *zFileTreeName
          191  +  const char *zFileTreeName /* Name of file */
   192    192   ){
   193    193     Blob fname;
   194    194     Blob content;
   195    195     int isLink;
   196    196     file_tree_name(zFileTreeName, &fname, 1);
   197    197     historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0);
   198    198     if( !isLink != !file_wd_islink(zFrom) ){
................................................................................
   223    223     ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
   224    224     asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
   225    225     vid = db_lget_int("checkout", 0);
   226    226     vfile_check_signature(vid, 1, 0);
   227    227     blob_zero(&sql);
   228    228     db_begin_transaction();
   229    229     if( zFrom ){
   230         -    int rid = name_to_typed_rid(zFrom, "ci");
          230  +    int rid = extended_ci_name_to_rid(zFrom);
   231    231       if( !is_a_version(rid) ){
   232    232         fossil_fatal("no such check-in: %s", zFrom);
   233    233       }
   234    234       load_vfile_from_rid(rid);
   235    235       blob_appendf(&sql,
   236    236         "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
   237    237         "  FROM vfile v1, vfile v2 "

Changes to src/file.c.

   755    755   ** message and quit if the errFatal flag is true.  If errFatal is
   756    756   ** false, then simply return 0.
   757    757   **
   758    758   ** The root of the tree is defined by the g.zLocalRoot variable.
   759    759   */
   760    760   int file_tree_name(const char *zOrigName, Blob *pOut, int errFatal){
   761    761     int n;
   762         -  Blob full;
          762  +  Blob full = empty_blob;
   763    763     int nFull;
   764    764     char *zFull;
   765    765   
   766    766     blob_zero(pOut);
   767    767     db_must_be_within_tree();
   768    768     file_canonical_name(zOrigName, &full);
   769    769     n = strlen(g.zLocalRoot);

Changes to src/manifest.c.

   936    936   ** Given a checkin name, load and parse the manifest for that checkin.
   937    937   ** Throw a fatal error if anything goes wrong.
   938    938   */
   939    939   Manifest *manifest_get_by_name(const char *zName, int *pRid){
   940    940     int rid;
   941    941     Manifest *p;
   942    942   
   943         -  rid = name_to_typed_rid(zName, "ci");
          943  +  rid = extended_ci_name_to_rid(zName);
   944    944     if( !is_a_version(rid) ){
   945    945       fossil_fatal("no such checkin: %s", zName);
   946    946     }
   947    947     if( pRid ) *pRid = rid;
   948    948     p = manifest_get(rid, CFTYPE_MANIFEST);
   949    949     if( p==0 ){
   950    950       fossil_fatal("cannot parse manifest for checkin: %s", zName);

Changes to src/merge.c.

   326    326         "  SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
   327    327         vid, idm
   328    328       );
   329    329       idv = db_last_insert_rowid();
   330    330       db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
   331    331       zName = db_column_text(&q, 2);
   332    332       fossil_print("ADDED %s\n", zName);
          333  +    if ( file_wd_isfile_or_link(zName) ) {
          334  +      fossil_print("***** The extra file %s has been overwritten\n", zName);
          335  +      nConflict++;
          336  +    }
   333    337       if( !nochangeFlag ){
   334    338         undo_save(zName);
   335    339         vfile_to_disk(0, idm, 0, 0);
   336    340       }
   337    341     }
   338    342     db_finalize(&q);
   339    343     
................................................................................
   495    499     db_finalize(&q);
   496    500   
   497    501   
   498    502     /* Report on conflicts
   499    503     */
   500    504     if( nConflict && !nochangeFlag ){
   501    505       fossil_warning(
   502         -       "WARNING: merge conflicts - see messages above for details.\n");
          506  +       "WARNING: %d merge conflicts - see messages above for details.\n",
          507  +       nConflict);
   503    508     }
   504    509   
   505    510     /*
   506    511     ** Clean up the mid and pid VFILE entries.  Then commit the changes.
   507    512     */
   508    513     db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid);
   509    514     if( !pickFlag ){
   510    515       db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
   511    516     }
   512    517     undo_finish();
   513    518     db_end_transaction(nochangeFlag);
   514    519   }

Changes to src/name.c.

   385    385     }else if( rc==2 ){
   386    386       cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath);
   387    387       return 0;
   388    388     }else{
   389    389       rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name);
   390    390       blob_reset(&name);
   391    391     }
          392  +  return rid;
          393  +}
          394  +
          395  +
          396  +/*
          397  +** Similar to name_to_typed_rid(zName, "ci"), 
          398  +** but it accepts more variants for the name. The additional variants are:
          399  +**
          400  +**   checkout        The current checkout
          401  +**   parent          The parent of the current checkout
          402  +**   pivot:id1:id2   The pivot between id1 and id2
          403  +**
          404  +** It should allow easier naming of checkins, both in 'diff' and 'update'
          405  +** commands for example.
          406  +*/
          407  +int extended_ci_name_to_rid(const char *zName){
          408  +  int rid;
          409  +
          410  +  rid = db_lget_int("checkout", 0);
          411  +
          412  +  if( fossil_strcmp(zName, "checkout")==0 ){
          413  +    rid = db_lget_int("checkout", 0);
          414  +  }
          415  +  else if( fossil_strcmp(zName, "parent")==0 ){
          416  +    int cid;
          417  +    cid = db_lget_int("checkout", 0);
          418  +    if (cid == 0)
          419  +      fossil_fatal("cannot find current checkout version");
          420  +    rid = db_int(0, "SELECT pid FROM plink WHERE cid=%d", cid);
          421  +    if (rid == 0)
          422  +      fossil_fatal("cannot find the parent of the current checkout version");
          423  +  }
          424  +  else if( strlen(zName) > 6 && memcmp(zName, "pivot:", 6)==0 ){
          425  +    /* This conflicts with 'tag:', but I don't know a better char than : */
          426  +    const char *zPair = zName + 6;
          427  +    char *zIdName;
          428  +    int rid1, rid2;
          429  +    char *zPair2 = strdup(zPair); /* Just for constness and strtok */
          430  +
          431  +    zIdName = strtok(zPair2,":");
          432  +
          433  +    if (!zIdName)
          434  +      fossil_fatal("Cannot parse pivot#checkin1#checkin2");
          435  +    rid1 = name_to_typed_rid(zIdName, "ci");
          436  +    if (rid1 == 0)
          437  +      fossil_fatal("Cannot find the check-in %s", zIdName);
          438  +
          439  +    zIdName = strtok(NULL,":");
          440  +    rid2 = name_to_typed_rid(zIdName, "ci");
          441  +
          442  +    pivot_set_primary(rid1);
          443  +    pivot_set_secondary(rid2);
          444  +    rid = pivot_find();
          445  +
          446  +    if (rid == 0)
          447  +      fossil_fatal("Cannot find the pivot of %s", zName);
          448  +
          449  +    free(zPair2);
          450  +  }
          451  +  else{
          452  +    rid = name_to_typed_rid(zName, "ci");
          453  +  }
          454  +
   392    455     return rid;
   393    456   }

Changes to src/update.c.

   129    129         ** target as if VERSION were omitted. */
   130    130       }else if( fossil_strcmp(g.argv[2], "latest")==0 ){
   131    131         /* If VERSION is "latest", then use the same algorithm to find the
   132    132         ** target as if VERSION were omitted and the --latest flag is present.
   133    133         */
   134    134         latestFlag = 1;
   135    135       }else{
   136         -      tid = name_to_typed_rid(g.argv[2],"ci");
          136  +      tid = extended_ci_name_to_rid(g.argv[2]);
   137    137         if( tid==0 ){
   138    138           fossil_fatal("no such version: %s", g.argv[2]);
   139    139         }else if( !is_a_version(tid) ){
   140    140           fossil_fatal("no such version: %s", g.argv[2]);
   141    141         }
   142    142       }
   143    143     }
................................................................................
   358    358         ** but also exists in the target checkout.  Use the current version.
   359    359         */
   360    360         fossil_print("CONFLICT %s\n", zName);
   361    361         nConflict++;
   362    362       }else if( idt>0 && idv==0 ){
   363    363         /* File added in the target. */
   364    364         fossil_print("ADD %s\n", zName);
          365  +      if ( file_wd_isfile_or_link(zName) ) {
          366  +        fossil_print("***** The extra file %s has been overwritten\n", zName);
          367  +        nConflict++;
          368  +      }
   365    369         undo_save(zName);
   366    370         if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
   367    371       }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
   368    372         /* The file is unedited.  Change it to the target version */
   369    373         undo_save(zName);
   370    374         fossil_print("UPDATE %s\n", zName);
   371    375         if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
................................................................................
   551    555     int errCode              /* Error code if file not found.  Panic if 0. */
   552    556   ){
   553    557     Manifest *pManifest;
   554    558     ManifestFile *pFile;
   555    559     int rid=0;
   556    560     
   557    561     if( revision ){
   558         -    rid = name_to_typed_rid(revision,"ci");
          562  +    rid = extended_ci_name_to_rid(revision);
   559    563     }else{
   560    564       rid = db_lget_int("checkout", 0);
   561    565     }
   562    566     if( !is_a_version(rid) ){
   563    567       if( errCode>0 ) return errCode;
   564    568       fossil_fatal("no such checkin: %s", revision);
   565    569     }

Changes to test/merge5.test.

    36     36     } else {
    37     37       test merge5-$testid 1
    38     38     }    
    39     39   }
    40     40   
    41     41   catch {exec $::fossilexe info} res
    42     42   puts res=$res
    43         -if {![regexp {not within an open checkout} $res]} {
           43  +if {![regexp {use --repository} $res]} {
    44     44     puts stderr "Cannot run this test within an open checkout"
    45     45     return
    46     46   }
           47  +#
           48  +# Fossil will write data on $HOME, running 'fossil open' here.
           49  +# We need not to clutter the $HOME of the test caller.
           50  +set env(HOME) [pwd]
    47     51   
    48     52   # Construct a test repository
    49     53   #
    50     54   exec sqlite3 m5.fossil <$testdir/${testfile}_repo.sql
    51     55   fossil rebuild m5.fossil
    52     56   fossil open m5.fossil
    53     57   fossil update baseline

Changes to test/merge_renames.test.

     5      5   
     6      6   catch {exec $::fossilexe info} res
     7      7   puts res=$res
     8      8   if {![regexp {use --repository} $res]} {
     9      9     puts stderr "Cannot run this test within an open checkout"
    10     10     return
    11     11   }
           12  +
           13  +
           14  +# Fossil will write data on $HOME, running 'fossil new' here.
           15  +# We need not to clutter the $HOME of the test caller.
           16  +set env(HOME) [pwd]
           17  +
    12     18   
    13     19   ######################################
    14     20   #  Test 1                            #
    15     21   #  Reported: Ticket [554f44ee74e3d]  #
    16     22   ######################################
    17     23   
    18     24   fossil new rep.fossil

Changes to www/changes.wiki.

     1      1   <title>Change Log</title>
     2      2   
            3  +<h2>Changes For Version 1.20 (upcoming)</h2>
            4  +  *  Added side-by-side diffs in HTML interface
            5  +  *  Fixed annotate to show "more relevant" versions of lines in some cases.
            6  +  *  Timeline now shows tag changes (requires rebuild)
            7  +  *  Added support for symlinks.
            8  +  *  New command: ticket history
            9  +  *  Several SSL improvements. Disabled SSLv2 in HTTPS client.
           10  +  *  Added -R REPOFILE support to several more CLI commands.
           11  +  *  Updated sqlite3 to 3.7.9.
           12  +  *  Generated tarfiles now have constant timestamps, to avoid them having a new checksum each time they are generated.
           13  +  *  A number of minor HTML-related tweaks and fixes.
           14  +  *  Added --args FILENAME global CLI argument to import arbitrary CLI arguments from a file (e.g. long file lists).
           15  +  *  Fixed significant memory leak in annotation of files with long histories.
           16  +  *  Added warnings when a merge operation overwrites local copies (UNDO is available, but previously this condition normally went silently unnoticed).
           17  +
     3     18   <h2>Changes For Version 1.19 (2011-09-02)</h2>
     4     19   
     5     20     *  Added a ./configure script based on autosetup.
     6     21     *  Added the "[/help/winsrv | fossil winsrv]" command
     7     22        for creating a Fossil service on windows systems.
     8     23     *  Added "versionable settings" where settings that affect
     9     24        the local tree can be stored in versioned files in the