Fossil SCM
Combine ANN flags and DIFF flags into a single 64-bit variable, where appropriate. Make DIFF_STRIP_EOLCR a separate flag, as this flag does more than the other whitespace-related flags. Merge trunk.
Commit
da205cf44b32d8253f8aeb970882906da6ad48f2
Parent
4514910a5f820e4…
8 files changed
+32
-29
+32
-29
+1
-1
+1
-1
+2
-2
+2
-2
+32
-29
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -28,12 +28,11 @@ | ||
| 28 | 28 | ** Flag parameters to the text_diff() routine used to control the formatting |
| 29 | 29 | ** of the diff output. |
| 30 | 30 | */ |
| 31 | 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | -#define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */ | |
| 34 | -#define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */ | |
| 33 | +#define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ | |
| 35 | 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 36 | 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 37 | 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 38 | 37 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 39 | 38 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -41,10 +40,11 @@ | ||
| 41 | 40 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 42 | 41 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 43 | 42 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 44 | 43 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 45 | 44 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 45 | +#define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ | |
| 46 | 46 | |
| 47 | 47 | /* |
| 48 | 48 | ** These error messages are shared in multiple locations. They are defined |
| 49 | 49 | ** here for consistency. |
| 50 | 50 | */ |
| @@ -168,16 +168,17 @@ | ||
| 168 | 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | 169 | k = j; |
| 170 | 170 | s = 0; |
| 171 | 171 | extent = 0; /* number of spaces ignored from start/end */ |
| 172 | 172 | numws = 0; /* number of spaces ignored in between */ |
| 173 | - if( diffFlags & DIFF_IGNORE_EOLWS ){ | |
| 174 | - while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} | |
| 175 | - }else if( diffFlags & DIFF_STRIP_EOLCR ){ | |
| 173 | + if( diffFlags & DIFF_STRIP_EOLCR ){ | |
| 176 | 174 | /* Don't do "extend++" here, because the CR needs to be stripped! */ |
| 177 | 175 | if( k>0 && z[k-1]=='\r' ){ k--; } |
| 178 | 176 | } |
| 177 | + if( diffFlags & DIFF_IGNORE_ALLWS ){ | |
| 178 | + while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} | |
| 179 | + } | |
| 179 | 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 180 | 181 | while( s<k && fossil_isspace(z[s]) ){s++; extent++;} |
| 181 | 182 | for(h=0, x=s; x<k; x++){ |
| 182 | 183 | if( fossil_isspace(z[x]) ){ |
| 183 | 184 | ++numws; |
| @@ -1786,11 +1787,11 @@ | ||
| 1786 | 1787 | if( diffFlags & DIFF_INVERT ){ |
| 1787 | 1788 | Blob *pTemp = pA_Blob; |
| 1788 | 1789 | pA_Blob = pB_Blob; |
| 1789 | 1790 | pB_Blob = pTemp; |
| 1790 | 1791 | } |
| 1791 | - ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0; | |
| 1792 | + ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0; | |
| 1792 | 1793 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1793 | 1794 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1794 | 1795 | |
| 1795 | 1796 | /* Prepare the input files */ |
| 1796 | 1797 | memset(&c, 0, sizeof(c)); |
| @@ -1873,18 +1874,18 @@ | ||
| 1873 | 1874 | */ |
| 1874 | 1875 | u64 diff_options(void){ |
| 1875 | 1876 | u64 diffFlags = 0; |
| 1876 | 1877 | const char *z; |
| 1877 | 1878 | int f; |
| 1878 | - if( find_option("strip-trailing-cr",0,0)!=0 ){ | |
| 1879 | - diffFlags = DIFF_STRIP_EOLCR; | |
| 1880 | - } | |
| 1881 | 1879 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1882 | - diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */ | |
| 1880 | + diffFlags = DIFF_IGNORE_EOLWS; | |
| 1883 | 1881 | } |
| 1884 | 1882 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 1885 | 1883 | diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 1884 | + } | |
| 1885 | + if( find_option("strip-trailing-cr",0,0)!=0 ){ | |
| 1886 | + diffFlags |= DIFF_STRIP_EOLCR; | |
| 1886 | 1887 | } |
| 1887 | 1888 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1888 | 1889 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1889 | 1890 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1890 | 1891 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| @@ -2065,13 +2066,13 @@ | ||
| 2065 | 2066 | /* Return no errors */ |
| 2066 | 2067 | return 0; |
| 2067 | 2068 | } |
| 2068 | 2069 | |
| 2069 | 2070 | |
| 2070 | -/* Annotation flags */ | |
| 2071 | -#define ANN_FILE_VERS 0x01 /* Show file vers rather than commit vers */ | |
| 2072 | -#define ANN_FILE_ANCEST 0x02 /* Prefer check-ins in the ANCESTOR table */ | |
| 2071 | +/* Annotation flags. Cannot overlap with DIFF flags */ | |
| 2072 | +#define ANN_FILE_VERS (((u64)0x40)<<32) /* Show file vers rather than commit vers */ | |
| 2073 | +#define ANN_FILE_ANCEST (((u64)0x80)<<32) /* Prefer check-ins in the ANCESTOR table */ | |
| 2073 | 2074 | |
| 2074 | 2075 | /* |
| 2075 | 2076 | ** Compute a complete annotation on a file. The file is identified |
| 2076 | 2077 | ** by its filename number (filename.fnid) and the baseline in which |
| 2077 | 2078 | ** it was checked in (mlink.mid). |
| @@ -2079,12 +2080,11 @@ | ||
| 2079 | 2080 | static void annotate_file( |
| 2080 | 2081 | Annotator *p, /* The annotator */ |
| 2081 | 2082 | int fnid, /* The name of the file to be annotated */ |
| 2082 | 2083 | int mid, /* Use the version of the file in this check-in */ |
| 2083 | 2084 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 2084 | - int annFlags, /* Flags to alter the annotation */ | |
| 2085 | - u64 diffFlags /* Flags to alter the whitespace handling */ | |
| 2085 | + u64 flags /* Flags to alter the annotation/whitespace handling */ | |
| 2086 | 2086 | ){ |
| 2087 | 2087 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2088 | 2088 | Blob step; /* Text of previous revision */ |
| 2089 | 2089 | int rid; /* Artifact ID of the file being annotated */ |
| 2090 | 2090 | Stmt q; /* Query returning all ancestor versions */ |
| @@ -2099,11 +2099,11 @@ | ||
| 2099 | 2099 | if( !content_get(rid, &toAnnotate) ){ |
| 2100 | 2100 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2101 | 2101 | } |
| 2102 | 2102 | if( iLimit<=0 ) iLimit = 1000000000; |
| 2103 | 2103 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2104 | - annotation_start(p, &toAnnotate, diffFlags); | |
| 2104 | + annotation_start(p, &toAnnotate, flags); | |
| 2105 | 2105 | db_begin_transaction(); |
| 2106 | 2106 | db_multi_exec( |
| 2107 | 2107 | "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);" |
| 2108 | 2108 | "DELETE FROM vseen;" |
| 2109 | 2109 | ); |
| @@ -2118,11 +2118,11 @@ | ||
| 2118 | 2118 | " FROM mlink, event" |
| 2119 | 2119 | " WHERE mlink.fid=:rid" |
| 2120 | 2120 | " AND event.objid=mlink.mid" |
| 2121 | 2121 | " AND mlink.pid NOT IN vseen" |
| 2122 | 2122 | " ORDER BY %s event.mtime", |
| 2123 | - (annFlags & ANN_FILE_ANCEST)!=0 ? | |
| 2123 | + (flags & ANN_FILE_ANCEST)!=0 ? | |
| 2124 | 2124 | "(mlink.mid IN (SELECT rid FROM ancestor)) DESC,":"" |
| 2125 | 2125 | ); |
| 2126 | 2126 | |
| 2127 | 2127 | db_bind_int(&q, ":rid", rid); |
| 2128 | 2128 | if( iLimit==0 ) iLimit = 1000000000; |
| @@ -2134,11 +2134,11 @@ | ||
| 2134 | 2134 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2135 | 2135 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2136 | 2136 | if( p->nVers ){ |
| 2137 | 2137 | content_get(rid, &step); |
| 2138 | 2138 | blob_to_utf8_no_bom(&step, 0); |
| 2139 | - annotation_step(p, &step, p->nVers-1, diffFlags); | |
| 2139 | + annotation_step(p, &step, p->nVers-1, flags); | |
| 2140 | 2140 | blob_reset(&step); |
| 2141 | 2141 | } |
| 2142 | 2142 | p->nVers++; |
| 2143 | 2143 | db_bind_int(&ins, ":rid", rid); |
| 2144 | 2144 | db_step(&ins); |
| @@ -2189,14 +2189,14 @@ | ||
| 2189 | 2189 | void annotation_page(void){ |
| 2190 | 2190 | int mid; |
| 2191 | 2191 | int fnid; |
| 2192 | 2192 | int i; |
| 2193 | 2193 | int iLimit; /* Depth limit */ |
| 2194 | - int annFlags = ANN_FILE_ANCEST; | |
| 2194 | + u64 flags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); | |
| 2195 | 2195 | int showLog = 0; /* True to display the log */ |
| 2196 | 2196 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2197 | - u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */ | |
| 2197 | + u64 diffFlags; /* diff flags for ignore whitespace */ | |
| 2198 | 2198 | const char *zFilename; /* Name of file to annotate */ |
| 2199 | 2199 | const char *zCI; /* The check-in containing zFilename */ |
| 2200 | 2200 | Annotator ann; |
| 2201 | 2201 | HQuery url; |
| 2202 | 2202 | struct AnnVers *p; |
| @@ -2211,20 +2211,20 @@ | ||
| 2211 | 2211 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2212 | 2212 | zFilename = P("filename"); |
| 2213 | 2213 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2214 | 2214 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 2215 | 2215 | iLimit = atoi(PD("limit","20")); |
| 2216 | - if( P("filevers") ) annFlags |= ANN_FILE_VERS; | |
| 2216 | + if( P("filevers") ) flags |= ANN_FILE_VERS; | |
| 2217 | 2217 | ignoreWs = P("w")!=0; |
| 2218 | - if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS; | |
| 2218 | + if( ignoreWs ) flags |= DIFF_IGNORE_ALLWS; | |
| 2219 | 2219 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 2220 | 2220 | fossil_redirect_home(); |
| 2221 | 2221 | } |
| 2222 | 2222 | |
| 2223 | 2223 | /* compute the annotation */ |
| 2224 | 2224 | compute_direct_ancestors(mid, 10000000); |
| 2225 | - annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); | |
| 2225 | + annotate_file(&ann, fnid, mid, iLimit, flags); | |
| 2226 | 2226 | zCI = ann.aVers[0].zMUuid; |
| 2227 | 2227 | |
| 2228 | 2228 | /* generate the web page */ |
| 2229 | 2229 | style_header("Annotation For %h", zFilename); |
| 2230 | 2230 | if( bBlame ){ |
| @@ -2386,22 +2386,25 @@ | ||
| 2386 | 2386 | Annotator ann; /* The annotation of the file */ |
| 2387 | 2387 | int i; /* Loop counter */ |
| 2388 | 2388 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2389 | 2389 | int iLimit; /* How far back in time to look */ |
| 2390 | 2390 | int showLog; /* True to show the log */ |
| 2391 | - u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */ | |
| 2391 | + u64 flags = 0; /* Flags to control annotation/whitespace handling */ | |
| 2392 | 2392 | int fileVers; /* Show file version instead of check-in versions */ |
| 2393 | - int annFlags = 0; /* Flags to control annotation properties */ | |
| 2394 | 2393 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 2395 | 2394 | |
| 2396 | 2395 | bBlame = g.argv[1][0]!='a'; |
| 2397 | 2396 | zLimit = find_option("limit","n",1); |
| 2398 | 2397 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2399 | 2398 | iLimit = atoi(zLimit); |
| 2400 | 2399 | showLog = find_option("log","l",0)!=0; |
| 2401 | - if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS; | |
| 2402 | - if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS; | |
| 2400 | + if( find_option("ignore-trailing-space","Z",0)!=0 ){ | |
| 2401 | + flags |= DIFF_IGNORE_EOLWS; | |
| 2402 | + } | |
| 2403 | + if( find_option("ignore-all-space","w",0)!=0 ){ | |
| 2404 | + flags |= DIFF_IGNORE_ALLWS; | |
| 2405 | + } | |
| 2403 | 2406 | fileVers = find_option("filevers",0,0)!=0; |
| 2404 | 2407 | db_must_be_within_tree(); |
| 2405 | 2408 | if( g.argc<3 ) { |
| 2406 | 2409 | usage("FILENAME"); |
| 2407 | 2410 | } |
| @@ -2426,12 +2429,12 @@ | ||
| 2426 | 2429 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2427 | 2430 | fid, fnid); |
| 2428 | 2431 | if( mid==0 ){ |
| 2429 | 2432 | fossil_fatal("unable to find manifest"); |
| 2430 | 2433 | } |
| 2431 | - annFlags |= ANN_FILE_ANCEST; | |
| 2432 | - annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); | |
| 2434 | + flags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); | |
| 2435 | + annotate_file(&ann, fnid, mid, iLimit, flags); | |
| 2433 | 2436 | if( showLog ){ |
| 2434 | 2437 | struct AnnVers *p; |
| 2435 | 2438 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2436 | 2439 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2437 | 2440 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2438 | 2441 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -28,12 +28,11 @@ | |
| 28 | ** Flag parameters to the text_diff() routine used to control the formatting |
| 29 | ** of the diff output. |
| 30 | */ |
| 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | #define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */ |
| 34 | #define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */ |
| 35 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 36 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 37 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 38 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 39 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -41,10 +40,11 @@ | |
| 41 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 42 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 43 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 44 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 45 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 46 | |
| 47 | /* |
| 48 | ** These error messages are shared in multiple locations. They are defined |
| 49 | ** here for consistency. |
| 50 | */ |
| @@ -168,16 +168,17 @@ | |
| 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | k = j; |
| 170 | s = 0; |
| 171 | extent = 0; /* number of spaces ignored from start/end */ |
| 172 | numws = 0; /* number of spaces ignored in between */ |
| 173 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 174 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} |
| 175 | }else if( diffFlags & DIFF_STRIP_EOLCR ){ |
| 176 | /* Don't do "extend++" here, because the CR needs to be stripped! */ |
| 177 | if( k>0 && z[k-1]=='\r' ){ k--; } |
| 178 | } |
| 179 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 180 | while( s<k && fossil_isspace(z[s]) ){s++; extent++;} |
| 181 | for(h=0, x=s; x<k; x++){ |
| 182 | if( fossil_isspace(z[x]) ){ |
| 183 | ++numws; |
| @@ -1786,11 +1787,11 @@ | |
| 1786 | if( diffFlags & DIFF_INVERT ){ |
| 1787 | Blob *pTemp = pA_Blob; |
| 1788 | pA_Blob = pB_Blob; |
| 1789 | pB_Blob = pTemp; |
| 1790 | } |
| 1791 | ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0; |
| 1792 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1793 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1794 | |
| 1795 | /* Prepare the input files */ |
| 1796 | memset(&c, 0, sizeof(c)); |
| @@ -1873,18 +1874,18 @@ | |
| 1873 | */ |
| 1874 | u64 diff_options(void){ |
| 1875 | u64 diffFlags = 0; |
| 1876 | const char *z; |
| 1877 | int f; |
| 1878 | if( find_option("strip-trailing-cr",0,0)!=0 ){ |
| 1879 | diffFlags = DIFF_STRIP_EOLCR; |
| 1880 | } |
| 1881 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1882 | diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */ |
| 1883 | } |
| 1884 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 1885 | diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 1886 | } |
| 1887 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1888 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1889 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1890 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| @@ -2065,13 +2066,13 @@ | |
| 2065 | /* Return no errors */ |
| 2066 | return 0; |
| 2067 | } |
| 2068 | |
| 2069 | |
| 2070 | /* Annotation flags */ |
| 2071 | #define ANN_FILE_VERS 0x01 /* Show file vers rather than commit vers */ |
| 2072 | #define ANN_FILE_ANCEST 0x02 /* Prefer check-ins in the ANCESTOR table */ |
| 2073 | |
| 2074 | /* |
| 2075 | ** Compute a complete annotation on a file. The file is identified |
| 2076 | ** by its filename number (filename.fnid) and the baseline in which |
| 2077 | ** it was checked in (mlink.mid). |
| @@ -2079,12 +2080,11 @@ | |
| 2079 | static void annotate_file( |
| 2080 | Annotator *p, /* The annotator */ |
| 2081 | int fnid, /* The name of the file to be annotated */ |
| 2082 | int mid, /* Use the version of the file in this check-in */ |
| 2083 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 2084 | int annFlags, /* Flags to alter the annotation */ |
| 2085 | u64 diffFlags /* Flags to alter the whitespace handling */ |
| 2086 | ){ |
| 2087 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2088 | Blob step; /* Text of previous revision */ |
| 2089 | int rid; /* Artifact ID of the file being annotated */ |
| 2090 | Stmt q; /* Query returning all ancestor versions */ |
| @@ -2099,11 +2099,11 @@ | |
| 2099 | if( !content_get(rid, &toAnnotate) ){ |
| 2100 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2101 | } |
| 2102 | if( iLimit<=0 ) iLimit = 1000000000; |
| 2103 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2104 | annotation_start(p, &toAnnotate, diffFlags); |
| 2105 | db_begin_transaction(); |
| 2106 | db_multi_exec( |
| 2107 | "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);" |
| 2108 | "DELETE FROM vseen;" |
| 2109 | ); |
| @@ -2118,11 +2118,11 @@ | |
| 2118 | " FROM mlink, event" |
| 2119 | " WHERE mlink.fid=:rid" |
| 2120 | " AND event.objid=mlink.mid" |
| 2121 | " AND mlink.pid NOT IN vseen" |
| 2122 | " ORDER BY %s event.mtime", |
| 2123 | (annFlags & ANN_FILE_ANCEST)!=0 ? |
| 2124 | "(mlink.mid IN (SELECT rid FROM ancestor)) DESC,":"" |
| 2125 | ); |
| 2126 | |
| 2127 | db_bind_int(&q, ":rid", rid); |
| 2128 | if( iLimit==0 ) iLimit = 1000000000; |
| @@ -2134,11 +2134,11 @@ | |
| 2134 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2135 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2136 | if( p->nVers ){ |
| 2137 | content_get(rid, &step); |
| 2138 | blob_to_utf8_no_bom(&step, 0); |
| 2139 | annotation_step(p, &step, p->nVers-1, diffFlags); |
| 2140 | blob_reset(&step); |
| 2141 | } |
| 2142 | p->nVers++; |
| 2143 | db_bind_int(&ins, ":rid", rid); |
| 2144 | db_step(&ins); |
| @@ -2189,14 +2189,14 @@ | |
| 2189 | void annotation_page(void){ |
| 2190 | int mid; |
| 2191 | int fnid; |
| 2192 | int i; |
| 2193 | int iLimit; /* Depth limit */ |
| 2194 | int annFlags = ANN_FILE_ANCEST; |
| 2195 | int showLog = 0; /* True to display the log */ |
| 2196 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2197 | u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */ |
| 2198 | const char *zFilename; /* Name of file to annotate */ |
| 2199 | const char *zCI; /* The check-in containing zFilename */ |
| 2200 | Annotator ann; |
| 2201 | HQuery url; |
| 2202 | struct AnnVers *p; |
| @@ -2211,20 +2211,20 @@ | |
| 2211 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2212 | zFilename = P("filename"); |
| 2213 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2214 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 2215 | iLimit = atoi(PD("limit","20")); |
| 2216 | if( P("filevers") ) annFlags |= ANN_FILE_VERS; |
| 2217 | ignoreWs = P("w")!=0; |
| 2218 | if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS; |
| 2219 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 2220 | fossil_redirect_home(); |
| 2221 | } |
| 2222 | |
| 2223 | /* compute the annotation */ |
| 2224 | compute_direct_ancestors(mid, 10000000); |
| 2225 | annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); |
| 2226 | zCI = ann.aVers[0].zMUuid; |
| 2227 | |
| 2228 | /* generate the web page */ |
| 2229 | style_header("Annotation For %h", zFilename); |
| 2230 | if( bBlame ){ |
| @@ -2386,22 +2386,25 @@ | |
| 2386 | Annotator ann; /* The annotation of the file */ |
| 2387 | int i; /* Loop counter */ |
| 2388 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2389 | int iLimit; /* How far back in time to look */ |
| 2390 | int showLog; /* True to show the log */ |
| 2391 | u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */ |
| 2392 | int fileVers; /* Show file version instead of check-in versions */ |
| 2393 | int annFlags = 0; /* Flags to control annotation properties */ |
| 2394 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 2395 | |
| 2396 | bBlame = g.argv[1][0]!='a'; |
| 2397 | zLimit = find_option("limit","n",1); |
| 2398 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2399 | iLimit = atoi(zLimit); |
| 2400 | showLog = find_option("log","l",0)!=0; |
| 2401 | if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS; |
| 2402 | if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS; |
| 2403 | fileVers = find_option("filevers",0,0)!=0; |
| 2404 | db_must_be_within_tree(); |
| 2405 | if( g.argc<3 ) { |
| 2406 | usage("FILENAME"); |
| 2407 | } |
| @@ -2426,12 +2429,12 @@ | |
| 2426 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2427 | fid, fnid); |
| 2428 | if( mid==0 ){ |
| 2429 | fossil_fatal("unable to find manifest"); |
| 2430 | } |
| 2431 | annFlags |= ANN_FILE_ANCEST; |
| 2432 | annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); |
| 2433 | if( showLog ){ |
| 2434 | struct AnnVers *p; |
| 2435 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2436 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2437 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2438 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -28,12 +28,11 @@ | |
| 28 | ** Flag parameters to the text_diff() routine used to control the formatting |
| 29 | ** of the diff output. |
| 30 | */ |
| 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ |
| 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 37 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 38 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -41,10 +40,11 @@ | |
| 40 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 41 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 42 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 43 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 44 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 45 | #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ |
| 46 | |
| 47 | /* |
| 48 | ** These error messages are shared in multiple locations. They are defined |
| 49 | ** here for consistency. |
| 50 | */ |
| @@ -168,16 +168,17 @@ | |
| 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | k = j; |
| 170 | s = 0; |
| 171 | extent = 0; /* number of spaces ignored from start/end */ |
| 172 | numws = 0; /* number of spaces ignored in between */ |
| 173 | if( diffFlags & DIFF_STRIP_EOLCR ){ |
| 174 | /* Don't do "extend++" here, because the CR needs to be stripped! */ |
| 175 | if( k>0 && z[k-1]=='\r' ){ k--; } |
| 176 | } |
| 177 | if( diffFlags & DIFF_IGNORE_ALLWS ){ |
| 178 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} |
| 179 | } |
| 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 181 | while( s<k && fossil_isspace(z[s]) ){s++; extent++;} |
| 182 | for(h=0, x=s; x<k; x++){ |
| 183 | if( fossil_isspace(z[x]) ){ |
| 184 | ++numws; |
| @@ -1786,11 +1787,11 @@ | |
| 1787 | if( diffFlags & DIFF_INVERT ){ |
| 1788 | Blob *pTemp = pA_Blob; |
| 1789 | pA_Blob = pB_Blob; |
| 1790 | pB_Blob = pTemp; |
| 1791 | } |
| 1792 | ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0; |
| 1793 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1794 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1795 | |
| 1796 | /* Prepare the input files */ |
| 1797 | memset(&c, 0, sizeof(c)); |
| @@ -1873,18 +1874,18 @@ | |
| 1874 | */ |
| 1875 | u64 diff_options(void){ |
| 1876 | u64 diffFlags = 0; |
| 1877 | const char *z; |
| 1878 | int f; |
| 1879 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1880 | diffFlags = DIFF_IGNORE_EOLWS; |
| 1881 | } |
| 1882 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 1883 | diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 1884 | } |
| 1885 | if( find_option("strip-trailing-cr",0,0)!=0 ){ |
| 1886 | diffFlags |= DIFF_STRIP_EOLCR; |
| 1887 | } |
| 1888 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1889 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1890 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1891 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| @@ -2065,13 +2066,13 @@ | |
| 2066 | /* Return no errors */ |
| 2067 | return 0; |
| 2068 | } |
| 2069 | |
| 2070 | |
| 2071 | /* Annotation flags. Cannot overlap with DIFF flags */ |
| 2072 | #define ANN_FILE_VERS (((u64)0x40)<<32) /* Show file vers rather than commit vers */ |
| 2073 | #define ANN_FILE_ANCEST (((u64)0x80)<<32) /* Prefer check-ins in the ANCESTOR table */ |
| 2074 | |
| 2075 | /* |
| 2076 | ** Compute a complete annotation on a file. The file is identified |
| 2077 | ** by its filename number (filename.fnid) and the baseline in which |
| 2078 | ** it was checked in (mlink.mid). |
| @@ -2079,12 +2080,11 @@ | |
| 2080 | static void annotate_file( |
| 2081 | Annotator *p, /* The annotator */ |
| 2082 | int fnid, /* The name of the file to be annotated */ |
| 2083 | int mid, /* Use the version of the file in this check-in */ |
| 2084 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 2085 | u64 flags /* Flags to alter the annotation/whitespace handling */ |
| 2086 | ){ |
| 2087 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2088 | Blob step; /* Text of previous revision */ |
| 2089 | int rid; /* Artifact ID of the file being annotated */ |
| 2090 | Stmt q; /* Query returning all ancestor versions */ |
| @@ -2099,11 +2099,11 @@ | |
| 2099 | if( !content_get(rid, &toAnnotate) ){ |
| 2100 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2101 | } |
| 2102 | if( iLimit<=0 ) iLimit = 1000000000; |
| 2103 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2104 | annotation_start(p, &toAnnotate, flags); |
| 2105 | db_begin_transaction(); |
| 2106 | db_multi_exec( |
| 2107 | "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);" |
| 2108 | "DELETE FROM vseen;" |
| 2109 | ); |
| @@ -2118,11 +2118,11 @@ | |
| 2118 | " FROM mlink, event" |
| 2119 | " WHERE mlink.fid=:rid" |
| 2120 | " AND event.objid=mlink.mid" |
| 2121 | " AND mlink.pid NOT IN vseen" |
| 2122 | " ORDER BY %s event.mtime", |
| 2123 | (flags & ANN_FILE_ANCEST)!=0 ? |
| 2124 | "(mlink.mid IN (SELECT rid FROM ancestor)) DESC,":"" |
| 2125 | ); |
| 2126 | |
| 2127 | db_bind_int(&q, ":rid", rid); |
| 2128 | if( iLimit==0 ) iLimit = 1000000000; |
| @@ -2134,11 +2134,11 @@ | |
| 2134 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2135 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2136 | if( p->nVers ){ |
| 2137 | content_get(rid, &step); |
| 2138 | blob_to_utf8_no_bom(&step, 0); |
| 2139 | annotation_step(p, &step, p->nVers-1, flags); |
| 2140 | blob_reset(&step); |
| 2141 | } |
| 2142 | p->nVers++; |
| 2143 | db_bind_int(&ins, ":rid", rid); |
| 2144 | db_step(&ins); |
| @@ -2189,14 +2189,14 @@ | |
| 2189 | void annotation_page(void){ |
| 2190 | int mid; |
| 2191 | int fnid; |
| 2192 | int i; |
| 2193 | int iLimit; /* Depth limit */ |
| 2194 | u64 flags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2195 | int showLog = 0; /* True to display the log */ |
| 2196 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2197 | u64 diffFlags; /* diff flags for ignore whitespace */ |
| 2198 | const char *zFilename; /* Name of file to annotate */ |
| 2199 | const char *zCI; /* The check-in containing zFilename */ |
| 2200 | Annotator ann; |
| 2201 | HQuery url; |
| 2202 | struct AnnVers *p; |
| @@ -2211,20 +2211,20 @@ | |
| 2211 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2212 | zFilename = P("filename"); |
| 2213 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2214 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 2215 | iLimit = atoi(PD("limit","20")); |
| 2216 | if( P("filevers") ) flags |= ANN_FILE_VERS; |
| 2217 | ignoreWs = P("w")!=0; |
| 2218 | if( ignoreWs ) flags |= DIFF_IGNORE_ALLWS; |
| 2219 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 2220 | fossil_redirect_home(); |
| 2221 | } |
| 2222 | |
| 2223 | /* compute the annotation */ |
| 2224 | compute_direct_ancestors(mid, 10000000); |
| 2225 | annotate_file(&ann, fnid, mid, iLimit, flags); |
| 2226 | zCI = ann.aVers[0].zMUuid; |
| 2227 | |
| 2228 | /* generate the web page */ |
| 2229 | style_header("Annotation For %h", zFilename); |
| 2230 | if( bBlame ){ |
| @@ -2386,22 +2386,25 @@ | |
| 2386 | Annotator ann; /* The annotation of the file */ |
| 2387 | int i; /* Loop counter */ |
| 2388 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2389 | int iLimit; /* How far back in time to look */ |
| 2390 | int showLog; /* True to show the log */ |
| 2391 | u64 flags = 0; /* Flags to control annotation/whitespace handling */ |
| 2392 | int fileVers; /* Show file version instead of check-in versions */ |
| 2393 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 2394 | |
| 2395 | bBlame = g.argv[1][0]!='a'; |
| 2396 | zLimit = find_option("limit","n",1); |
| 2397 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2398 | iLimit = atoi(zLimit); |
| 2399 | showLog = find_option("log","l",0)!=0; |
| 2400 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 2401 | flags |= DIFF_IGNORE_EOLWS; |
| 2402 | } |
| 2403 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 2404 | flags |= DIFF_IGNORE_ALLWS; |
| 2405 | } |
| 2406 | fileVers = find_option("filevers",0,0)!=0; |
| 2407 | db_must_be_within_tree(); |
| 2408 | if( g.argc<3 ) { |
| 2409 | usage("FILENAME"); |
| 2410 | } |
| @@ -2426,12 +2429,12 @@ | |
| 2429 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2430 | fid, fnid); |
| 2431 | if( mid==0 ){ |
| 2432 | fossil_fatal("unable to find manifest"); |
| 2433 | } |
| 2434 | flags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2435 | annotate_file(&ann, fnid, mid, iLimit, flags); |
| 2436 | if( showLog ){ |
| 2437 | struct AnnVers *p; |
| 2438 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2439 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2440 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2441 |
+32
-29
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -28,12 +28,11 @@ | ||
| 28 | 28 | ** Flag parameters to the text_diff() routine used to control the formatting |
| 29 | 29 | ** of the diff output. |
| 30 | 30 | */ |
| 31 | 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | -#define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */ | |
| 34 | -#define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */ | |
| 33 | +#define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ | |
| 35 | 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 36 | 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 37 | 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 38 | 37 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 39 | 38 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -41,10 +40,11 @@ | ||
| 41 | 40 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 42 | 41 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 43 | 42 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 44 | 43 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 45 | 44 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 45 | +#define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ | |
| 46 | 46 | |
| 47 | 47 | /* |
| 48 | 48 | ** These error messages are shared in multiple locations. They are defined |
| 49 | 49 | ** here for consistency. |
| 50 | 50 | */ |
| @@ -168,16 +168,17 @@ | ||
| 168 | 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | 169 | k = j; |
| 170 | 170 | s = 0; |
| 171 | 171 | extent = 0; /* number of spaces ignored from start/end */ |
| 172 | 172 | numws = 0; /* number of spaces ignored in between */ |
| 173 | - if( diffFlags & DIFF_IGNORE_EOLWS ){ | |
| 174 | - while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} | |
| 175 | - }else if( diffFlags & DIFF_STRIP_EOLCR ){ | |
| 173 | + if( diffFlags & DIFF_STRIP_EOLCR ){ | |
| 176 | 174 | /* Don't do "extend++" here, because the CR needs to be stripped! */ |
| 177 | 175 | if( k>0 && z[k-1]=='\r' ){ k--; } |
| 178 | 176 | } |
| 177 | + if( diffFlags & DIFF_IGNORE_ALLWS ){ | |
| 178 | + while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} | |
| 179 | + } | |
| 179 | 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 180 | 181 | while( s<k && fossil_isspace(z[s]) ){s++; extent++;} |
| 181 | 182 | for(h=0, x=s; x<k; x++){ |
| 182 | 183 | if( fossil_isspace(z[x]) ){ |
| 183 | 184 | ++numws; |
| @@ -1786,11 +1787,11 @@ | ||
| 1786 | 1787 | if( diffFlags & DIFF_INVERT ){ |
| 1787 | 1788 | Blob *pTemp = pA_Blob; |
| 1788 | 1789 | pA_Blob = pB_Blob; |
| 1789 | 1790 | pB_Blob = pTemp; |
| 1790 | 1791 | } |
| 1791 | - ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0; | |
| 1792 | + ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0; | |
| 1792 | 1793 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1793 | 1794 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1794 | 1795 | |
| 1795 | 1796 | /* Prepare the input files */ |
| 1796 | 1797 | memset(&c, 0, sizeof(c)); |
| @@ -1873,18 +1874,18 @@ | ||
| 1873 | 1874 | */ |
| 1874 | 1875 | u64 diff_options(void){ |
| 1875 | 1876 | u64 diffFlags = 0; |
| 1876 | 1877 | const char *z; |
| 1877 | 1878 | int f; |
| 1878 | - if( find_option("strip-trailing-cr",0,0)!=0 ){ | |
| 1879 | - diffFlags = DIFF_STRIP_EOLCR; | |
| 1880 | - } | |
| 1881 | 1879 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1882 | - diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */ | |
| 1880 | + diffFlags = DIFF_IGNORE_EOLWS; | |
| 1883 | 1881 | } |
| 1884 | 1882 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 1885 | 1883 | diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 1884 | + } | |
| 1885 | + if( find_option("strip-trailing-cr",0,0)!=0 ){ | |
| 1886 | + diffFlags |= DIFF_STRIP_EOLCR; | |
| 1886 | 1887 | } |
| 1887 | 1888 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1888 | 1889 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1889 | 1890 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1890 | 1891 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| @@ -2065,13 +2066,13 @@ | ||
| 2065 | 2066 | /* Return no errors */ |
| 2066 | 2067 | return 0; |
| 2067 | 2068 | } |
| 2068 | 2069 | |
| 2069 | 2070 | |
| 2070 | -/* Annotation flags */ | |
| 2071 | -#define ANN_FILE_VERS 0x01 /* Show file vers rather than commit vers */ | |
| 2072 | -#define ANN_FILE_ANCEST 0x02 /* Prefer check-ins in the ANCESTOR table */ | |
| 2071 | +/* Annotation flags. Cannot overlap with DIFF flags */ | |
| 2072 | +#define ANN_FILE_VERS (((u64)0x40)<<32) /* Show file vers rather than commit vers */ | |
| 2073 | +#define ANN_FILE_ANCEST (((u64)0x80)<<32) /* Prefer check-ins in the ANCESTOR table */ | |
| 2073 | 2074 | |
| 2074 | 2075 | /* |
| 2075 | 2076 | ** Compute a complete annotation on a file. The file is identified |
| 2076 | 2077 | ** by its filename number (filename.fnid) and the baseline in which |
| 2077 | 2078 | ** it was checked in (mlink.mid). |
| @@ -2079,12 +2080,11 @@ | ||
| 2079 | 2080 | static void annotate_file( |
| 2080 | 2081 | Annotator *p, /* The annotator */ |
| 2081 | 2082 | int fnid, /* The name of the file to be annotated */ |
| 2082 | 2083 | int mid, /* Use the version of the file in this check-in */ |
| 2083 | 2084 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 2084 | - int annFlags, /* Flags to alter the annotation */ | |
| 2085 | - u64 diffFlags /* Flags to alter the whitespace handling */ | |
| 2085 | + u64 flags /* Flags to alter the annotation/whitespace handling */ | |
| 2086 | 2086 | ){ |
| 2087 | 2087 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2088 | 2088 | Blob step; /* Text of previous revision */ |
| 2089 | 2089 | int rid; /* Artifact ID of the file being annotated */ |
| 2090 | 2090 | Stmt q; /* Query returning all ancestor versions */ |
| @@ -2099,11 +2099,11 @@ | ||
| 2099 | 2099 | if( !content_get(rid, &toAnnotate) ){ |
| 2100 | 2100 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2101 | 2101 | } |
| 2102 | 2102 | if( iLimit<=0 ) iLimit = 1000000000; |
| 2103 | 2103 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2104 | - annotation_start(p, &toAnnotate, diffFlags); | |
| 2104 | + annotation_start(p, &toAnnotate, flags); | |
| 2105 | 2105 | db_begin_transaction(); |
| 2106 | 2106 | db_multi_exec( |
| 2107 | 2107 | "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);" |
| 2108 | 2108 | "DELETE FROM vseen;" |
| 2109 | 2109 | ); |
| @@ -2118,11 +2118,11 @@ | ||
| 2118 | 2118 | " FROM mlink, event" |
| 2119 | 2119 | " WHERE mlink.fid=:rid" |
| 2120 | 2120 | " AND event.objid=mlink.mid" |
| 2121 | 2121 | " AND mlink.pid NOT IN vseen" |
| 2122 | 2122 | " ORDER BY %s event.mtime", |
| 2123 | - (annFlags & ANN_FILE_ANCEST)!=0 ? | |
| 2123 | + (flags & ANN_FILE_ANCEST)!=0 ? | |
| 2124 | 2124 | "(mlink.mid IN (SELECT rid FROM ancestor)) DESC,":"" |
| 2125 | 2125 | ); |
| 2126 | 2126 | |
| 2127 | 2127 | db_bind_int(&q, ":rid", rid); |
| 2128 | 2128 | if( iLimit==0 ) iLimit = 1000000000; |
| @@ -2134,11 +2134,11 @@ | ||
| 2134 | 2134 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2135 | 2135 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2136 | 2136 | if( p->nVers ){ |
| 2137 | 2137 | content_get(rid, &step); |
| 2138 | 2138 | blob_to_utf8_no_bom(&step, 0); |
| 2139 | - annotation_step(p, &step, p->nVers-1, diffFlags); | |
| 2139 | + annotation_step(p, &step, p->nVers-1, flags); | |
| 2140 | 2140 | blob_reset(&step); |
| 2141 | 2141 | } |
| 2142 | 2142 | p->nVers++; |
| 2143 | 2143 | db_bind_int(&ins, ":rid", rid); |
| 2144 | 2144 | db_step(&ins); |
| @@ -2189,14 +2189,14 @@ | ||
| 2189 | 2189 | void annotation_page(void){ |
| 2190 | 2190 | int mid; |
| 2191 | 2191 | int fnid; |
| 2192 | 2192 | int i; |
| 2193 | 2193 | int iLimit; /* Depth limit */ |
| 2194 | - int annFlags = ANN_FILE_ANCEST; | |
| 2194 | + u64 flags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); | |
| 2195 | 2195 | int showLog = 0; /* True to display the log */ |
| 2196 | 2196 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2197 | - u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */ | |
| 2197 | + u64 diffFlags; /* diff flags for ignore whitespace */ | |
| 2198 | 2198 | const char *zFilename; /* Name of file to annotate */ |
| 2199 | 2199 | const char *zCI; /* The check-in containing zFilename */ |
| 2200 | 2200 | Annotator ann; |
| 2201 | 2201 | HQuery url; |
| 2202 | 2202 | struct AnnVers *p; |
| @@ -2211,20 +2211,20 @@ | ||
| 2211 | 2211 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2212 | 2212 | zFilename = P("filename"); |
| 2213 | 2213 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2214 | 2214 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 2215 | 2215 | iLimit = atoi(PD("limit","20")); |
| 2216 | - if( P("filevers") ) annFlags |= ANN_FILE_VERS; | |
| 2216 | + if( P("filevers") ) flags |= ANN_FILE_VERS; | |
| 2217 | 2217 | ignoreWs = P("w")!=0; |
| 2218 | - if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS; | |
| 2218 | + if( ignoreWs ) flags |= DIFF_IGNORE_ALLWS; | |
| 2219 | 2219 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 2220 | 2220 | fossil_redirect_home(); |
| 2221 | 2221 | } |
| 2222 | 2222 | |
| 2223 | 2223 | /* compute the annotation */ |
| 2224 | 2224 | compute_direct_ancestors(mid, 10000000); |
| 2225 | - annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); | |
| 2225 | + annotate_file(&ann, fnid, mid, iLimit, flags); | |
| 2226 | 2226 | zCI = ann.aVers[0].zMUuid; |
| 2227 | 2227 | |
| 2228 | 2228 | /* generate the web page */ |
| 2229 | 2229 | style_header("Annotation For %h", zFilename); |
| 2230 | 2230 | if( bBlame ){ |
| @@ -2386,22 +2386,25 @@ | ||
| 2386 | 2386 | Annotator ann; /* The annotation of the file */ |
| 2387 | 2387 | int i; /* Loop counter */ |
| 2388 | 2388 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2389 | 2389 | int iLimit; /* How far back in time to look */ |
| 2390 | 2390 | int showLog; /* True to show the log */ |
| 2391 | - u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */ | |
| 2391 | + u64 flags = 0; /* Flags to control annotation/whitespace handling */ | |
| 2392 | 2392 | int fileVers; /* Show file version instead of check-in versions */ |
| 2393 | - int annFlags = 0; /* Flags to control annotation properties */ | |
| 2394 | 2393 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 2395 | 2394 | |
| 2396 | 2395 | bBlame = g.argv[1][0]!='a'; |
| 2397 | 2396 | zLimit = find_option("limit","n",1); |
| 2398 | 2397 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2399 | 2398 | iLimit = atoi(zLimit); |
| 2400 | 2399 | showLog = find_option("log","l",0)!=0; |
| 2401 | - if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS; | |
| 2402 | - if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS; | |
| 2400 | + if( find_option("ignore-trailing-space","Z",0)!=0 ){ | |
| 2401 | + flags |= DIFF_IGNORE_EOLWS; | |
| 2402 | + } | |
| 2403 | + if( find_option("ignore-all-space","w",0)!=0 ){ | |
| 2404 | + flags |= DIFF_IGNORE_ALLWS; | |
| 2405 | + } | |
| 2403 | 2406 | fileVers = find_option("filevers",0,0)!=0; |
| 2404 | 2407 | db_must_be_within_tree(); |
| 2405 | 2408 | if( g.argc<3 ) { |
| 2406 | 2409 | usage("FILENAME"); |
| 2407 | 2410 | } |
| @@ -2426,12 +2429,12 @@ | ||
| 2426 | 2429 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2427 | 2430 | fid, fnid); |
| 2428 | 2431 | if( mid==0 ){ |
| 2429 | 2432 | fossil_fatal("unable to find manifest"); |
| 2430 | 2433 | } |
| 2431 | - annFlags |= ANN_FILE_ANCEST; | |
| 2432 | - annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); | |
| 2434 | + flags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); | |
| 2435 | + annotate_file(&ann, fnid, mid, iLimit, flags); | |
| 2433 | 2436 | if( showLog ){ |
| 2434 | 2437 | struct AnnVers *p; |
| 2435 | 2438 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2436 | 2439 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2437 | 2440 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2438 | 2441 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -28,12 +28,11 @@ | |
| 28 | ** Flag parameters to the text_diff() routine used to control the formatting |
| 29 | ** of the diff output. |
| 30 | */ |
| 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | #define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */ |
| 34 | #define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */ |
| 35 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 36 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 37 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 38 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 39 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -41,10 +40,11 @@ | |
| 41 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 42 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 43 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 44 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 45 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 46 | |
| 47 | /* |
| 48 | ** These error messages are shared in multiple locations. They are defined |
| 49 | ** here for consistency. |
| 50 | */ |
| @@ -168,16 +168,17 @@ | |
| 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | k = j; |
| 170 | s = 0; |
| 171 | extent = 0; /* number of spaces ignored from start/end */ |
| 172 | numws = 0; /* number of spaces ignored in between */ |
| 173 | if( diffFlags & DIFF_IGNORE_EOLWS ){ |
| 174 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} |
| 175 | }else if( diffFlags & DIFF_STRIP_EOLCR ){ |
| 176 | /* Don't do "extend++" here, because the CR needs to be stripped! */ |
| 177 | if( k>0 && z[k-1]=='\r' ){ k--; } |
| 178 | } |
| 179 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 180 | while( s<k && fossil_isspace(z[s]) ){s++; extent++;} |
| 181 | for(h=0, x=s; x<k; x++){ |
| 182 | if( fossil_isspace(z[x]) ){ |
| 183 | ++numws; |
| @@ -1786,11 +1787,11 @@ | |
| 1786 | if( diffFlags & DIFF_INVERT ){ |
| 1787 | Blob *pTemp = pA_Blob; |
| 1788 | pA_Blob = pB_Blob; |
| 1789 | pB_Blob = pTemp; |
| 1790 | } |
| 1791 | ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0; |
| 1792 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1793 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1794 | |
| 1795 | /* Prepare the input files */ |
| 1796 | memset(&c, 0, sizeof(c)); |
| @@ -1873,18 +1874,18 @@ | |
| 1873 | */ |
| 1874 | u64 diff_options(void){ |
| 1875 | u64 diffFlags = 0; |
| 1876 | const char *z; |
| 1877 | int f; |
| 1878 | if( find_option("strip-trailing-cr",0,0)!=0 ){ |
| 1879 | diffFlags = DIFF_STRIP_EOLCR; |
| 1880 | } |
| 1881 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1882 | diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */ |
| 1883 | } |
| 1884 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 1885 | diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 1886 | } |
| 1887 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1888 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1889 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1890 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| @@ -2065,13 +2066,13 @@ | |
| 2065 | /* Return no errors */ |
| 2066 | return 0; |
| 2067 | } |
| 2068 | |
| 2069 | |
| 2070 | /* Annotation flags */ |
| 2071 | #define ANN_FILE_VERS 0x01 /* Show file vers rather than commit vers */ |
| 2072 | #define ANN_FILE_ANCEST 0x02 /* Prefer check-ins in the ANCESTOR table */ |
| 2073 | |
| 2074 | /* |
| 2075 | ** Compute a complete annotation on a file. The file is identified |
| 2076 | ** by its filename number (filename.fnid) and the baseline in which |
| 2077 | ** it was checked in (mlink.mid). |
| @@ -2079,12 +2080,11 @@ | |
| 2079 | static void annotate_file( |
| 2080 | Annotator *p, /* The annotator */ |
| 2081 | int fnid, /* The name of the file to be annotated */ |
| 2082 | int mid, /* Use the version of the file in this check-in */ |
| 2083 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 2084 | int annFlags, /* Flags to alter the annotation */ |
| 2085 | u64 diffFlags /* Flags to alter the whitespace handling */ |
| 2086 | ){ |
| 2087 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2088 | Blob step; /* Text of previous revision */ |
| 2089 | int rid; /* Artifact ID of the file being annotated */ |
| 2090 | Stmt q; /* Query returning all ancestor versions */ |
| @@ -2099,11 +2099,11 @@ | |
| 2099 | if( !content_get(rid, &toAnnotate) ){ |
| 2100 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2101 | } |
| 2102 | if( iLimit<=0 ) iLimit = 1000000000; |
| 2103 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2104 | annotation_start(p, &toAnnotate, diffFlags); |
| 2105 | db_begin_transaction(); |
| 2106 | db_multi_exec( |
| 2107 | "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);" |
| 2108 | "DELETE FROM vseen;" |
| 2109 | ); |
| @@ -2118,11 +2118,11 @@ | |
| 2118 | " FROM mlink, event" |
| 2119 | " WHERE mlink.fid=:rid" |
| 2120 | " AND event.objid=mlink.mid" |
| 2121 | " AND mlink.pid NOT IN vseen" |
| 2122 | " ORDER BY %s event.mtime", |
| 2123 | (annFlags & ANN_FILE_ANCEST)!=0 ? |
| 2124 | "(mlink.mid IN (SELECT rid FROM ancestor)) DESC,":"" |
| 2125 | ); |
| 2126 | |
| 2127 | db_bind_int(&q, ":rid", rid); |
| 2128 | if( iLimit==0 ) iLimit = 1000000000; |
| @@ -2134,11 +2134,11 @@ | |
| 2134 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2135 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2136 | if( p->nVers ){ |
| 2137 | content_get(rid, &step); |
| 2138 | blob_to_utf8_no_bom(&step, 0); |
| 2139 | annotation_step(p, &step, p->nVers-1, diffFlags); |
| 2140 | blob_reset(&step); |
| 2141 | } |
| 2142 | p->nVers++; |
| 2143 | db_bind_int(&ins, ":rid", rid); |
| 2144 | db_step(&ins); |
| @@ -2189,14 +2189,14 @@ | |
| 2189 | void annotation_page(void){ |
| 2190 | int mid; |
| 2191 | int fnid; |
| 2192 | int i; |
| 2193 | int iLimit; /* Depth limit */ |
| 2194 | int annFlags = ANN_FILE_ANCEST; |
| 2195 | int showLog = 0; /* True to display the log */ |
| 2196 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2197 | u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */ |
| 2198 | const char *zFilename; /* Name of file to annotate */ |
| 2199 | const char *zCI; /* The check-in containing zFilename */ |
| 2200 | Annotator ann; |
| 2201 | HQuery url; |
| 2202 | struct AnnVers *p; |
| @@ -2211,20 +2211,20 @@ | |
| 2211 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2212 | zFilename = P("filename"); |
| 2213 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2214 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 2215 | iLimit = atoi(PD("limit","20")); |
| 2216 | if( P("filevers") ) annFlags |= ANN_FILE_VERS; |
| 2217 | ignoreWs = P("w")!=0; |
| 2218 | if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS; |
| 2219 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 2220 | fossil_redirect_home(); |
| 2221 | } |
| 2222 | |
| 2223 | /* compute the annotation */ |
| 2224 | compute_direct_ancestors(mid, 10000000); |
| 2225 | annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); |
| 2226 | zCI = ann.aVers[0].zMUuid; |
| 2227 | |
| 2228 | /* generate the web page */ |
| 2229 | style_header("Annotation For %h", zFilename); |
| 2230 | if( bBlame ){ |
| @@ -2386,22 +2386,25 @@ | |
| 2386 | Annotator ann; /* The annotation of the file */ |
| 2387 | int i; /* Loop counter */ |
| 2388 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2389 | int iLimit; /* How far back in time to look */ |
| 2390 | int showLog; /* True to show the log */ |
| 2391 | u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */ |
| 2392 | int fileVers; /* Show file version instead of check-in versions */ |
| 2393 | int annFlags = 0; /* Flags to control annotation properties */ |
| 2394 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 2395 | |
| 2396 | bBlame = g.argv[1][0]!='a'; |
| 2397 | zLimit = find_option("limit","n",1); |
| 2398 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2399 | iLimit = atoi(zLimit); |
| 2400 | showLog = find_option("log","l",0)!=0; |
| 2401 | if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS; |
| 2402 | if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS; |
| 2403 | fileVers = find_option("filevers",0,0)!=0; |
| 2404 | db_must_be_within_tree(); |
| 2405 | if( g.argc<3 ) { |
| 2406 | usage("FILENAME"); |
| 2407 | } |
| @@ -2426,12 +2429,12 @@ | |
| 2426 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2427 | fid, fnid); |
| 2428 | if( mid==0 ){ |
| 2429 | fossil_fatal("unable to find manifest"); |
| 2430 | } |
| 2431 | annFlags |= ANN_FILE_ANCEST; |
| 2432 | annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags); |
| 2433 | if( showLog ){ |
| 2434 | struct AnnVers *p; |
| 2435 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2436 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2437 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2438 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -28,12 +28,11 @@ | |
| 28 | ** Flag parameters to the text_diff() routine used to control the formatting |
| 29 | ** of the diff output. |
| 30 | */ |
| 31 | #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */ |
| 32 | #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */ |
| 33 | #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */ |
| 34 | #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */ |
| 35 | #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */ |
| 36 | #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */ |
| 37 | #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */ |
| 38 | #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */ |
| @@ -41,10 +40,11 @@ | |
| 40 | #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */ |
| 41 | #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */ |
| 42 | #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */ |
| 43 | #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */ |
| 44 | #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */ |
| 45 | #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */ |
| 46 | |
| 47 | /* |
| 48 | ** These error messages are shared in multiple locations. They are defined |
| 49 | ** here for consistency. |
| 50 | */ |
| @@ -168,16 +168,17 @@ | |
| 168 | for(j=0; z[j] && z[j]!='\n'; j++){} |
| 169 | k = j; |
| 170 | s = 0; |
| 171 | extent = 0; /* number of spaces ignored from start/end */ |
| 172 | numws = 0; /* number of spaces ignored in between */ |
| 173 | if( diffFlags & DIFF_STRIP_EOLCR ){ |
| 174 | /* Don't do "extend++" here, because the CR needs to be stripped! */ |
| 175 | if( k>0 && z[k-1]=='\r' ){ k--; } |
| 176 | } |
| 177 | if( diffFlags & DIFF_IGNORE_ALLWS ){ |
| 178 | while( k>0 && fossil_isspace(z[k-1]) ){ k--; extent++;} |
| 179 | } |
| 180 | if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){ |
| 181 | while( s<k && fossil_isspace(z[s]) ){s++; extent++;} |
| 182 | for(h=0, x=s; x<k; x++){ |
| 183 | if( fossil_isspace(z[x]) ){ |
| 184 | ++numws; |
| @@ -1786,11 +1787,11 @@ | |
| 1787 | if( diffFlags & DIFF_INVERT ){ |
| 1788 | Blob *pTemp = pA_Blob; |
| 1789 | pA_Blob = pB_Blob; |
| 1790 | pB_Blob = pTemp; |
| 1791 | } |
| 1792 | ignoreWs = (diffFlags & (DIFF_IGNORE_ALLWS|DIFF_STRIP_EOLCR))!=0; |
| 1793 | blob_to_utf8_no_bom(pA_Blob, 0); |
| 1794 | blob_to_utf8_no_bom(pB_Blob, 0); |
| 1795 | |
| 1796 | /* Prepare the input files */ |
| 1797 | memset(&c, 0, sizeof(c)); |
| @@ -1873,18 +1874,18 @@ | |
| 1874 | */ |
| 1875 | u64 diff_options(void){ |
| 1876 | u64 diffFlags = 0; |
| 1877 | const char *z; |
| 1878 | int f; |
| 1879 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 1880 | diffFlags = DIFF_IGNORE_EOLWS; |
| 1881 | } |
| 1882 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 1883 | diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */ |
| 1884 | } |
| 1885 | if( find_option("strip-trailing-cr",0,0)!=0 ){ |
| 1886 | diffFlags |= DIFF_STRIP_EOLCR; |
| 1887 | } |
| 1888 | if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE; |
| 1889 | if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE; |
| 1890 | if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){ |
| 1891 | if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK; |
| @@ -2065,13 +2066,13 @@ | |
| 2066 | /* Return no errors */ |
| 2067 | return 0; |
| 2068 | } |
| 2069 | |
| 2070 | |
| 2071 | /* Annotation flags. Cannot overlap with DIFF flags */ |
| 2072 | #define ANN_FILE_VERS (((u64)0x40)<<32) /* Show file vers rather than commit vers */ |
| 2073 | #define ANN_FILE_ANCEST (((u64)0x80)<<32) /* Prefer check-ins in the ANCESTOR table */ |
| 2074 | |
| 2075 | /* |
| 2076 | ** Compute a complete annotation on a file. The file is identified |
| 2077 | ** by its filename number (filename.fnid) and the baseline in which |
| 2078 | ** it was checked in (mlink.mid). |
| @@ -2079,12 +2080,11 @@ | |
| 2080 | static void annotate_file( |
| 2081 | Annotator *p, /* The annotator */ |
| 2082 | int fnid, /* The name of the file to be annotated */ |
| 2083 | int mid, /* Use the version of the file in this check-in */ |
| 2084 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 2085 | u64 flags /* Flags to alter the annotation/whitespace handling */ |
| 2086 | ){ |
| 2087 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 2088 | Blob step; /* Text of previous revision */ |
| 2089 | int rid; /* Artifact ID of the file being annotated */ |
| 2090 | Stmt q; /* Query returning all ancestor versions */ |
| @@ -2099,11 +2099,11 @@ | |
| 2099 | if( !content_get(rid, &toAnnotate) ){ |
| 2100 | fossil_fatal("unable to retrieve content of artifact #%d", rid); |
| 2101 | } |
| 2102 | if( iLimit<=0 ) iLimit = 1000000000; |
| 2103 | blob_to_utf8_no_bom(&toAnnotate, 0); |
| 2104 | annotation_start(p, &toAnnotate, flags); |
| 2105 | db_begin_transaction(); |
| 2106 | db_multi_exec( |
| 2107 | "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);" |
| 2108 | "DELETE FROM vseen;" |
| 2109 | ); |
| @@ -2118,11 +2118,11 @@ | |
| 2118 | " FROM mlink, event" |
| 2119 | " WHERE mlink.fid=:rid" |
| 2120 | " AND event.objid=mlink.mid" |
| 2121 | " AND mlink.pid NOT IN vseen" |
| 2122 | " ORDER BY %s event.mtime", |
| 2123 | (flags & ANN_FILE_ANCEST)!=0 ? |
| 2124 | "(mlink.mid IN (SELECT rid FROM ancestor)) DESC,":"" |
| 2125 | ); |
| 2126 | |
| 2127 | db_bind_int(&q, ":rid", rid); |
| 2128 | if( iLimit==0 ) iLimit = 1000000000; |
| @@ -2134,11 +2134,11 @@ | |
| 2134 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2135 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2136 | if( p->nVers ){ |
| 2137 | content_get(rid, &step); |
| 2138 | blob_to_utf8_no_bom(&step, 0); |
| 2139 | annotation_step(p, &step, p->nVers-1, flags); |
| 2140 | blob_reset(&step); |
| 2141 | } |
| 2142 | p->nVers++; |
| 2143 | db_bind_int(&ins, ":rid", rid); |
| 2144 | db_step(&ins); |
| @@ -2189,14 +2189,14 @@ | |
| 2189 | void annotation_page(void){ |
| 2190 | int mid; |
| 2191 | int fnid; |
| 2192 | int i; |
| 2193 | int iLimit; /* Depth limit */ |
| 2194 | u64 flags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2195 | int showLog = 0; /* True to display the log */ |
| 2196 | int ignoreWs = 0; /* Ignore whitespace */ |
| 2197 | u64 diffFlags; /* diff flags for ignore whitespace */ |
| 2198 | const char *zFilename; /* Name of file to annotate */ |
| 2199 | const char *zCI; /* The check-in containing zFilename */ |
| 2200 | Annotator ann; |
| 2201 | HQuery url; |
| 2202 | struct AnnVers *p; |
| @@ -2211,20 +2211,20 @@ | |
| 2211 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2212 | zFilename = P("filename"); |
| 2213 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2214 | if( mid==0 || fnid==0 ){ fossil_redirect_home(); } |
| 2215 | iLimit = atoi(PD("limit","20")); |
| 2216 | if( P("filevers") ) flags |= ANN_FILE_VERS; |
| 2217 | ignoreWs = P("w")!=0; |
| 2218 | if( ignoreWs ) flags |= DIFF_IGNORE_ALLWS; |
| 2219 | if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ |
| 2220 | fossil_redirect_home(); |
| 2221 | } |
| 2222 | |
| 2223 | /* compute the annotation */ |
| 2224 | compute_direct_ancestors(mid, 10000000); |
| 2225 | annotate_file(&ann, fnid, mid, iLimit, flags); |
| 2226 | zCI = ann.aVers[0].zMUuid; |
| 2227 | |
| 2228 | /* generate the web page */ |
| 2229 | style_header("Annotation For %h", zFilename); |
| 2230 | if( bBlame ){ |
| @@ -2386,22 +2386,25 @@ | |
| 2386 | Annotator ann; /* The annotation of the file */ |
| 2387 | int i; /* Loop counter */ |
| 2388 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2389 | int iLimit; /* How far back in time to look */ |
| 2390 | int showLog; /* True to show the log */ |
| 2391 | u64 flags = 0; /* Flags to control annotation/whitespace handling */ |
| 2392 | int fileVers; /* Show file version instead of check-in versions */ |
| 2393 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 2394 | |
| 2395 | bBlame = g.argv[1][0]!='a'; |
| 2396 | zLimit = find_option("limit","n",1); |
| 2397 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2398 | iLimit = atoi(zLimit); |
| 2399 | showLog = find_option("log","l",0)!=0; |
| 2400 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 2401 | flags |= DIFF_IGNORE_EOLWS; |
| 2402 | } |
| 2403 | if( find_option("ignore-all-space","w",0)!=0 ){ |
| 2404 | flags |= DIFF_IGNORE_ALLWS; |
| 2405 | } |
| 2406 | fileVers = find_option("filevers",0,0)!=0; |
| 2407 | db_must_be_within_tree(); |
| 2408 | if( g.argc<3 ) { |
| 2409 | usage("FILENAME"); |
| 2410 | } |
| @@ -2426,12 +2429,12 @@ | |
| 2429 | " ORDER BY ancestor.generation ASC LIMIT 1", |
| 2430 | fid, fnid); |
| 2431 | if( mid==0 ){ |
| 2432 | fossil_fatal("unable to find manifest"); |
| 2433 | } |
| 2434 | flags |= (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR); |
| 2435 | annotate_file(&ann, fnid, mid, iLimit, flags); |
| 2436 | if( showLog ){ |
| 2437 | struct AnnVers *p; |
| 2438 | for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){ |
| 2439 | fossil_print("version %3d: %s %.10s file %.10s\n", |
| 2440 | i+1, p->zDate, p->zMUuid, p->zFUuid); |
| 2441 |
+1
-1
| --- src/json_wiki.c | ||
| +++ src/json_wiki.c | ||
| @@ -542,11 +542,11 @@ | ||
| 542 | 542 | |
| 543 | 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | 544 | blob_zero(&w2); |
| 545 | 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | 546 | blob_zero(&d); |
| 547 | - diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE; | |
| 547 | + diffFlags = DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR | DIFF_INLINE; | |
| 548 | 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | 549 | blob_reset(&w1); |
| 550 | 550 | blob_reset(&w2); |
| 551 | 551 | |
| 552 | 552 | pay = cson_new_object(); |
| 553 | 553 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | |
| 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | blob_zero(&w2); |
| 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | blob_zero(&d); |
| 547 | diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE; |
| 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | blob_reset(&w1); |
| 550 | blob_reset(&w2); |
| 551 | |
| 552 | pay = cson_new_object(); |
| 553 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | |
| 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | blob_zero(&w2); |
| 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | blob_zero(&d); |
| 547 | diffFlags = DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR | DIFF_INLINE; |
| 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | blob_reset(&w1); |
| 550 | blob_reset(&w2); |
| 551 | |
| 552 | pay = cson_new_object(); |
| 553 |
+1
-1
| --- src/json_wiki.c | ||
| +++ src/json_wiki.c | ||
| @@ -542,11 +542,11 @@ | ||
| 542 | 542 | |
| 543 | 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | 544 | blob_zero(&w2); |
| 545 | 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | 546 | blob_zero(&d); |
| 547 | - diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE; | |
| 547 | + diffFlags = DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR | DIFF_INLINE; | |
| 548 | 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | 549 | blob_reset(&w1); |
| 550 | 550 | blob_reset(&w2); |
| 551 | 551 | |
| 552 | 552 | pay = cson_new_object(); |
| 553 | 553 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | |
| 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | blob_zero(&w2); |
| 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | blob_zero(&d); |
| 547 | diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE; |
| 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | blob_reset(&w1); |
| 550 | blob_reset(&w2); |
| 551 | |
| 552 | pay = cson_new_object(); |
| 553 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | |
| 543 | blob_init(&w1, pW1->zWiki, -1); |
| 544 | blob_zero(&w2); |
| 545 | blob_init(&w2, pW2->zWiki, -1); |
| 546 | blob_zero(&d); |
| 547 | diffFlags = DIFF_IGNORE_EOLWS | DIFF_STRIP_EOLCR | DIFF_INLINE; |
| 548 | text_diff(&w2, &w1, &d, 0, diffFlags); |
| 549 | blob_reset(&w1); |
| 550 | blob_reset(&w2); |
| 551 | |
| 552 | pay = cson_new_object(); |
| 553 |
| --- test/utf16be.txt | ||
| +++ test/utf16be.txt | ||
| --- test/utf16be.txt | |
| +++ test/utf16be.txt | |
| 0 |
| --- test/utf16be.txt | |
| +++ test/utf16be.txt | |
| 0 |
| --- test/utf16le.txt | ||
| +++ test/utf16le.txt | ||
| --- test/utf16le.txt | |
| +++ test/utf16le.txt | |
| 0 |
| --- test/utf16le.txt | |
| +++ test/utf16le.txt | |
| 0 |
+2
-2
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -1,10 +1,10 @@ | ||
| 1 | 1 | <title>Change Log</title> |
| 2 | 2 | |
| 3 | 3 | <h2>Changes For Version 1.29 (as yet unreleased)</h2> |
| 4 | - * Add the ability to display content and diffs for UTF16 text files | |
| 5 | - in the web interface. | |
| 4 | + * Add the ability to display content, diffs and annotations for UTF16 | |
| 5 | + text files in the web interface. | |
| 6 | 6 | * Add the "SaveAs..." button to the graphical diff display that results |
| 7 | 7 | from using the --tk option with the [/help/diff | fossil diff] command. |
| 8 | 8 | * Honor timezones in imports from git. |
| 9 | 9 | * The [/reports] page now requires Read ("o") permissions. The "byweek" |
| 10 | 10 | report now properly propagates the selected year through the event type |
| 11 | 11 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,10 +1,10 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2>Changes For Version 1.29 (as yet unreleased)</h2> |
| 4 | * Add the ability to display content and diffs for UTF16 text files |
| 5 | in the web interface. |
| 6 | * Add the "SaveAs..." button to the graphical diff display that results |
| 7 | from using the --tk option with the [/help/diff | fossil diff] command. |
| 8 | * Honor timezones in imports from git. |
| 9 | * The [/reports] page now requires Read ("o") permissions. The "byweek" |
| 10 | report now properly propagates the selected year through the event type |
| 11 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,10 +1,10 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2>Changes For Version 1.29 (as yet unreleased)</h2> |
| 4 | * Add the ability to display content, diffs and annotations for UTF16 |
| 5 | text files in the web interface. |
| 6 | * Add the "SaveAs..." button to the graphical diff display that results |
| 7 | from using the --tk option with the [/help/diff | fossil diff] command. |
| 8 | * Honor timezones in imports from git. |
| 9 | * The [/reports] page now requires Read ("o") permissions. The "byweek" |
| 10 | report now properly propagates the selected year through the event type |
| 11 |
+2
-2
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -1,10 +1,10 @@ | ||
| 1 | 1 | <title>Change Log</title> |
| 2 | 2 | |
| 3 | 3 | <h2>Changes For Version 1.29 (as yet unreleased)</h2> |
| 4 | - * Add the ability to display content and diffs for UTF16 text files | |
| 5 | - in the web interface. | |
| 4 | + * Add the ability to display content, diffs and annotations for UTF16 | |
| 5 | + text files in the web interface. | |
| 6 | 6 | * Add the "SaveAs..." button to the graphical diff display that results |
| 7 | 7 | from using the --tk option with the [/help/diff | fossil diff] command. |
| 8 | 8 | * Honor timezones in imports from git. |
| 9 | 9 | * The [/reports] page now requires Read ("o") permissions. The "byweek" |
| 10 | 10 | report now properly propagates the selected year through the event type |
| 11 | 11 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,10 +1,10 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2>Changes For Version 1.29 (as yet unreleased)</h2> |
| 4 | * Add the ability to display content and diffs for UTF16 text files |
| 5 | in the web interface. |
| 6 | * Add the "SaveAs..." button to the graphical diff display that results |
| 7 | from using the --tk option with the [/help/diff | fossil diff] command. |
| 8 | * Honor timezones in imports from git. |
| 9 | * The [/reports] page now requires Read ("o") permissions. The "byweek" |
| 10 | report now properly propagates the selected year through the event type |
| 11 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,10 +1,10 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2>Changes For Version 1.29 (as yet unreleased)</h2> |
| 4 | * Add the ability to display content, diffs and annotations for UTF16 |
| 5 | text files in the web interface. |
| 6 | * Add the "SaveAs..." button to the graphical diff display that results |
| 7 | from using the --tk option with the [/help/diff | fossil diff] command. |
| 8 | * Honor timezones in imports from git. |
| 9 | * The [/reports] page now requires Read ("o") permissions. The "byweek" |
| 10 | report now properly propagates the selected year through the event type |
| 11 |