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