Fossil SCM
Enhance the /vdiff page to understand the nc (no-color) query parameter and to do a better job of preserving query parameter choices when clicking on other display options.
Commit
2e51bb9b03d6be85db8a49c2e8baf2ace436ba79c40d6b8fe2a2290c0ebb167d
Parent
8a231a7990198d2…
2 files changed
+1
-1
+48
-31
+1
-1
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -901,11 +901,11 @@ | ||
| 901 | 901 | /* 7 */ " isaux" |
| 902 | 902 | " FROM mlink WHERE mid=%d ORDER BY 1", |
| 903 | 903 | mid |
| 904 | 904 | ); |
| 905 | 905 | @ <h1>MLINK table for check-in %h(zCI)</h1> |
| 906 | - render_checkin_context(mid, 0, 1); | |
| 906 | + render_checkin_context(mid, 0, 1, 0); | |
| 907 | 907 | style_table_sorter(); |
| 908 | 908 | @ <hr /> |
| 909 | 909 | @ <div class='brlist'> |
| 910 | 910 | @ <table class='sortable' data-column-types='ttxtttt' data-init-sort='1'> |
| 911 | 911 | @ <thead><tr> |
| 912 | 912 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -901,11 +901,11 @@ | |
| 901 | /* 7 */ " isaux" |
| 902 | " FROM mlink WHERE mid=%d ORDER BY 1", |
| 903 | mid |
| 904 | ); |
| 905 | @ <h1>MLINK table for check-in %h(zCI)</h1> |
| 906 | render_checkin_context(mid, 0, 1); |
| 907 | style_table_sorter(); |
| 908 | @ <hr /> |
| 909 | @ <div class='brlist'> |
| 910 | @ <table class='sortable' data-column-types='ttxtttt' data-init-sort='1'> |
| 911 | @ <thead><tr> |
| 912 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -901,11 +901,11 @@ | |
| 901 | /* 7 */ " isaux" |
| 902 | " FROM mlink WHERE mid=%d ORDER BY 1", |
| 903 | mid |
| 904 | ); |
| 905 | @ <h1>MLINK table for check-in %h(zCI)</h1> |
| 906 | render_checkin_context(mid, 0, 1, 0); |
| 907 | style_table_sorter(); |
| 908 | @ <hr /> |
| 909 | @ <div class='brlist'> |
| 910 | @ <table class='sortable' data-column-types='ttxtttt' data-init-sort='1'> |
| 911 | @ <thead><tr> |
| 912 |
+48
-31
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -270,13 +270,13 @@ | ||
| 270 | 270 | } |
| 271 | 271 | } |
| 272 | 272 | |
| 273 | 273 | /* |
| 274 | 274 | ** Show the context graph (immediate parents and children) for |
| 275 | -** check-in rid. | |
| 275 | +** check-in rid and rid2 | |
| 276 | 276 | */ |
| 277 | -void render_checkin_context(int rid, int rid2, int parentsOnly){ | |
| 277 | +void render_checkin_context(int rid, int rid2, int parentsOnly, int mFlags){ | |
| 278 | 278 | Blob sql; |
| 279 | 279 | Stmt q; |
| 280 | 280 | int rx[2]; |
| 281 | 281 | int i, n; |
| 282 | 282 | rx[0] = rid; |
| @@ -313,11 +313,12 @@ | ||
| 313 | 313 | } |
| 314 | 314 | } |
| 315 | 315 | blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC"); |
| 316 | 316 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 317 | 317 | www_print_timeline(&q, |
| 318 | - TIMELINE_GRAPH | |
| 318 | + mFlags | |
| 319 | + |TIMELINE_GRAPH | |
| 319 | 320 | |TIMELINE_FILLGAPS |
| 320 | 321 | |TIMELINE_NOSCROLL |
| 321 | 322 | |TIMELINE_XMERGE |
| 322 | 323 | |TIMELINE_CHPICK, |
| 323 | 324 | 0, 0, 0, rid, rid2, 0); |
| @@ -880,11 +881,11 @@ | ||
| 880 | 881 | if( !PB("nowiki") ){ |
| 881 | 882 | wiki_render_associated("checkin", zUuid, 0); |
| 882 | 883 | } |
| 883 | 884 | render_backlink_graph(zUuid, "<div class=\"section\">References</div>\n"); |
| 884 | 885 | @ <div class="section">Context</div> |
| 885 | - render_checkin_context(rid, 0, 0); | |
| 886 | + render_checkin_context(rid, 0, 0, 0); | |
| 886 | 887 | @ <div class="section">Changes</div> |
| 887 | 888 | @ <div class="sectionmenu"> |
| 888 | 889 | diffFlags = construct_diff_flags(diffType); |
| 889 | 890 | zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 890 | 891 | if( diffType!=0 ){ |
| @@ -1164,11 +1165,12 @@ | ||
| 1164 | 1165 | ** diff=INTEGER 0: none, 1: unified, 2: side-by-side |
| 1165 | 1166 | ** glob=STRING only diff files matching this glob |
| 1166 | 1167 | ** dc=N show N lines of context around each diff |
| 1167 | 1168 | ** w=BOOLEAN ignore whitespace when computing diffs |
| 1168 | 1169 | ** nohdr omit the description at the top of the page |
| 1169 | -** | |
| 1170 | +** nc omit branch coloration from the header graph | |
| 1171 | +** inv "Invert". Exchange the roles of from= and to= | |
| 1170 | 1172 | ** |
| 1171 | 1173 | ** Show all differences between two check-ins. |
| 1172 | 1174 | */ |
| 1173 | 1175 | void vdiff_page(void){ |
| 1174 | 1176 | int ridFrom, ridTo; |
| @@ -1178,75 +1180,90 @@ | ||
| 1178 | 1180 | ManifestFile *pFileFrom, *pFileTo; |
| 1179 | 1181 | const char *zBranch; |
| 1180 | 1182 | const char *zFrom; |
| 1181 | 1183 | const char *zTo; |
| 1182 | 1184 | const char *zRe; |
| 1183 | - const char *zW; | |
| 1184 | 1185 | const char *zGlob; |
| 1185 | - char *zQuery; | |
| 1186 | 1186 | char *zMergeOrigin = 0; |
| 1187 | 1187 | ReCompiled *pRe = 0; |
| 1188 | + int graphFlags = 0; | |
| 1189 | + Blob qp; | |
| 1190 | + int bInvert = PB("inv"); | |
| 1191 | + | |
| 1188 | 1192 | login_check_credentials(); |
| 1189 | 1193 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1190 | 1194 | login_anonymous_available(); |
| 1191 | 1195 | load_control(); |
| 1196 | + blob_init(&qp, 0, 0); | |
| 1192 | 1197 | diffType = preferred_diff_type(); |
| 1193 | 1198 | zRe = P("regex"); |
| 1194 | 1199 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1195 | 1200 | zBranch = P("branch"); |
| 1196 | 1201 | if( zBranch && zBranch[0]==0 ) zBranch = 0; |
| 1197 | 1202 | if( zBranch ){ |
| 1198 | - zQuery = mprintf("branch=%T", zBranch); | |
| 1203 | + blob_appendf(&qp, "branch=%T", zBranch); | |
| 1199 | 1204 | zMergeOrigin = mprintf("merge-in:%s", zBranch); |
| 1200 | 1205 | cgi_replace_parameter("from", zMergeOrigin); |
| 1201 | 1206 | cgi_replace_parameter("to", zBranch); |
| 1202 | 1207 | }else{ |
| 1203 | - zQuery = mprintf("from=%T&to=%T",PD("from",""),PD("to","")); | |
| 1208 | + if( bInvert ){ | |
| 1209 | + blob_appendf(&qp, "to=%T&from=%T",PD("from",""),PD("to","")); | |
| 1210 | + }else{ | |
| 1211 | + blob_appendf(&qp, "from=%T&to=%T",PD("from",""),PD("to","")); | |
| 1212 | + } | |
| 1204 | 1213 | } |
| 1205 | 1214 | pTo = vdiff_parse_manifest("to", &ridTo); |
| 1206 | 1215 | if( pTo==0 ) return; |
| 1207 | 1216 | pFrom = vdiff_parse_manifest("from", &ridFrom); |
| 1208 | 1217 | if( pFrom==0 ) return; |
| 1209 | 1218 | zGlob = P("glob"); |
| 1210 | 1219 | zFrom = P("from"); |
| 1211 | 1220 | zTo = P("to"); |
| 1212 | - if(zGlob && !*zGlob){ | |
| 1213 | - zGlob = NULL; | |
| 1221 | + if( bInvert ){ | |
| 1222 | + Manifest *pTemp = pTo; | |
| 1223 | + const char *zTemp = zTo; | |
| 1224 | + pTo = pFrom; | |
| 1225 | + pFrom = pTemp; | |
| 1226 | + zTo = zFrom; | |
| 1227 | + zFrom = zTemp; | |
| 1228 | + } | |
| 1229 | + if( zGlob ){ | |
| 1230 | + if( !*zGlob ){ | |
| 1231 | + zGlob = NULL; | |
| 1232 | + }else{ | |
| 1233 | + blob_appendf(&qp, "&glob=%T", zGlob); | |
| 1234 | + } | |
| 1235 | + } | |
| 1236 | + if( PB("nc") ){ | |
| 1237 | + graphFlags |= TIMELINE_NOCOLOR; | |
| 1238 | + blob_appendf(&qp, "&nc"); | |
| 1214 | 1239 | } |
| 1215 | 1240 | diffFlags = construct_diff_flags(diffType); |
| 1216 | - zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; | |
| 1241 | + if( diffFlags & DIFF_IGNORE_ALLWS ){ | |
| 1242 | + blob_appendf(&qp, "&w"); | |
| 1243 | + } | |
| 1217 | 1244 | style_set_current_feature("vdiff"); |
| 1218 | 1245 | if( zBranch==0 ){ |
| 1219 | 1246 | style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo); |
| 1220 | 1247 | } |
| 1221 | 1248 | if( diffType!=0 ){ |
| 1222 | - style_submenu_element("Hide Diff", "%R/vdiff?%s&diff=0%s%T%s", | |
| 1223 | - zQuery, | |
| 1224 | - zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); | |
| 1249 | + style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b", &qp); | |
| 1225 | 1250 | } |
| 1226 | 1251 | if( diffType!=2 ){ |
| 1227 | - style_submenu_element("Side-by-Side Diff", | |
| 1228 | - "%R/vdiff?%s&diff=2%s%T%s", | |
| 1229 | - zQuery, | |
| 1230 | - zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); | |
| 1252 | + style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b", &qp); | |
| 1231 | 1253 | } |
| 1232 | 1254 | if( diffType!=1 ) { |
| 1233 | - style_submenu_element("Unified Diff", | |
| 1234 | - "%R/vdiff?%s&diff=1%s%T%s", | |
| 1235 | - zQuery, | |
| 1236 | - zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); | |
| 1255 | + style_submenu_element("Unified Diff", "%R/vdiff?diff=1&%b", &qp); | |
| 1237 | 1256 | } |
| 1238 | 1257 | if( zBranch==0 ){ |
| 1239 | - style_submenu_element("Invert", | |
| 1240 | - "%R/vdiff?from=%T&to=%T&%s%T%s", zTo, zFrom, | |
| 1241 | - zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); | |
| 1258 | + style_submenu_element("Invert","%R/vdiff?diff=%d&inv&%b", diffType, &qp); | |
| 1242 | 1259 | } |
| 1243 | 1260 | if( zGlob ){ |
| 1244 | - style_submenu_element("Clear glob", | |
| 1245 | - "%R/vdiff?%s&%s", zQuery, zW); | |
| 1261 | + style_submenu_element("Clear glob", "%R/vdiff?diff=%d&%b", diffType, &qp); | |
| 1246 | 1262 | }else{ |
| 1247 | - style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo, zW); | |
| 1263 | + style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo, | |
| 1264 | + (diffFlags & DIFF_IGNORE_ALLWS)?"&w":""); | |
| 1248 | 1265 | } |
| 1249 | 1266 | if( diffType!=0 ){ |
| 1250 | 1267 | style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); |
| 1251 | 1268 | } |
| 1252 | 1269 | if( zBranch ){ |
| @@ -1274,21 +1291,21 @@ | ||
| 1274 | 1291 | @ <h2>Difference From <span class='timelineSelected'>\ |
| 1275 | 1292 | @ %z(href("%R/info/%h",zFrom))%h(zFrom)</a></span> |
| 1276 | 1293 | @ To <span class='timelineSelected timelineSecondary'>\ |
| 1277 | 1294 | @ %z(href("%R/info/%h",zTo))%h(zTo)</a></span></h2> |
| 1278 | 1295 | } |
| 1279 | - render_checkin_context(ridFrom, ridTo, 0); | |
| 1296 | + render_checkin_context(ridFrom, ridTo, 0, graphFlags); | |
| 1280 | 1297 | if( pRe ){ |
| 1281 | 1298 | @ <p><b>Only differences that match regular expression "%h(zRe)" |
| 1282 | 1299 | @ are shown.</b></p> |
| 1283 | 1300 | } |
| 1284 | 1301 | if( zGlob ){ |
| 1285 | 1302 | @ <p><b>Only files matching the glob "%h(zGlob)" are shown.</b></p> |
| 1286 | 1303 | } |
| 1287 | 1304 | @<hr /><p> |
| 1288 | 1305 | } |
| 1289 | - fossil_free(zQuery); | |
| 1306 | + blob_reset(&qp); | |
| 1290 | 1307 | |
| 1291 | 1308 | manifest_file_rewind(pFrom); |
| 1292 | 1309 | pFileFrom = manifest_file_next(pFrom, 0); |
| 1293 | 1310 | manifest_file_rewind(pTo); |
| 1294 | 1311 | pFileTo = manifest_file_next(pTo, 0); |
| 1295 | 1312 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -270,13 +270,13 @@ | |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | /* |
| 274 | ** Show the context graph (immediate parents and children) for |
| 275 | ** check-in rid. |
| 276 | */ |
| 277 | void render_checkin_context(int rid, int rid2, int parentsOnly){ |
| 278 | Blob sql; |
| 279 | Stmt q; |
| 280 | int rx[2]; |
| 281 | int i, n; |
| 282 | rx[0] = rid; |
| @@ -313,11 +313,12 @@ | |
| 313 | } |
| 314 | } |
| 315 | blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC"); |
| 316 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 317 | www_print_timeline(&q, |
| 318 | TIMELINE_GRAPH |
| 319 | |TIMELINE_FILLGAPS |
| 320 | |TIMELINE_NOSCROLL |
| 321 | |TIMELINE_XMERGE |
| 322 | |TIMELINE_CHPICK, |
| 323 | 0, 0, 0, rid, rid2, 0); |
| @@ -880,11 +881,11 @@ | |
| 880 | if( !PB("nowiki") ){ |
| 881 | wiki_render_associated("checkin", zUuid, 0); |
| 882 | } |
| 883 | render_backlink_graph(zUuid, "<div class=\"section\">References</div>\n"); |
| 884 | @ <div class="section">Context</div> |
| 885 | render_checkin_context(rid, 0, 0); |
| 886 | @ <div class="section">Changes</div> |
| 887 | @ <div class="sectionmenu"> |
| 888 | diffFlags = construct_diff_flags(diffType); |
| 889 | zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 890 | if( diffType!=0 ){ |
| @@ -1164,11 +1165,12 @@ | |
| 1164 | ** diff=INTEGER 0: none, 1: unified, 2: side-by-side |
| 1165 | ** glob=STRING only diff files matching this glob |
| 1166 | ** dc=N show N lines of context around each diff |
| 1167 | ** w=BOOLEAN ignore whitespace when computing diffs |
| 1168 | ** nohdr omit the description at the top of the page |
| 1169 | ** |
| 1170 | ** |
| 1171 | ** Show all differences between two check-ins. |
| 1172 | */ |
| 1173 | void vdiff_page(void){ |
| 1174 | int ridFrom, ridTo; |
| @@ -1178,75 +1180,90 @@ | |
| 1178 | ManifestFile *pFileFrom, *pFileTo; |
| 1179 | const char *zBranch; |
| 1180 | const char *zFrom; |
| 1181 | const char *zTo; |
| 1182 | const char *zRe; |
| 1183 | const char *zW; |
| 1184 | const char *zGlob; |
| 1185 | char *zQuery; |
| 1186 | char *zMergeOrigin = 0; |
| 1187 | ReCompiled *pRe = 0; |
| 1188 | login_check_credentials(); |
| 1189 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1190 | login_anonymous_available(); |
| 1191 | load_control(); |
| 1192 | diffType = preferred_diff_type(); |
| 1193 | zRe = P("regex"); |
| 1194 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1195 | zBranch = P("branch"); |
| 1196 | if( zBranch && zBranch[0]==0 ) zBranch = 0; |
| 1197 | if( zBranch ){ |
| 1198 | zQuery = mprintf("branch=%T", zBranch); |
| 1199 | zMergeOrigin = mprintf("merge-in:%s", zBranch); |
| 1200 | cgi_replace_parameter("from", zMergeOrigin); |
| 1201 | cgi_replace_parameter("to", zBranch); |
| 1202 | }else{ |
| 1203 | zQuery = mprintf("from=%T&to=%T",PD("from",""),PD("to","")); |
| 1204 | } |
| 1205 | pTo = vdiff_parse_manifest("to", &ridTo); |
| 1206 | if( pTo==0 ) return; |
| 1207 | pFrom = vdiff_parse_manifest("from", &ridFrom); |
| 1208 | if( pFrom==0 ) return; |
| 1209 | zGlob = P("glob"); |
| 1210 | zFrom = P("from"); |
| 1211 | zTo = P("to"); |
| 1212 | if(zGlob && !*zGlob){ |
| 1213 | zGlob = NULL; |
| 1214 | } |
| 1215 | diffFlags = construct_diff_flags(diffType); |
| 1216 | zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 1217 | style_set_current_feature("vdiff"); |
| 1218 | if( zBranch==0 ){ |
| 1219 | style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo); |
| 1220 | } |
| 1221 | if( diffType!=0 ){ |
| 1222 | style_submenu_element("Hide Diff", "%R/vdiff?%s&diff=0%s%T%s", |
| 1223 | zQuery, |
| 1224 | zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); |
| 1225 | } |
| 1226 | if( diffType!=2 ){ |
| 1227 | style_submenu_element("Side-by-Side Diff", |
| 1228 | "%R/vdiff?%s&diff=2%s%T%s", |
| 1229 | zQuery, |
| 1230 | zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); |
| 1231 | } |
| 1232 | if( diffType!=1 ) { |
| 1233 | style_submenu_element("Unified Diff", |
| 1234 | "%R/vdiff?%s&diff=1%s%T%s", |
| 1235 | zQuery, |
| 1236 | zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); |
| 1237 | } |
| 1238 | if( zBranch==0 ){ |
| 1239 | style_submenu_element("Invert", |
| 1240 | "%R/vdiff?from=%T&to=%T&%s%T%s", zTo, zFrom, |
| 1241 | zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW); |
| 1242 | } |
| 1243 | if( zGlob ){ |
| 1244 | style_submenu_element("Clear glob", |
| 1245 | "%R/vdiff?%s&%s", zQuery, zW); |
| 1246 | }else{ |
| 1247 | style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo, zW); |
| 1248 | } |
| 1249 | if( diffType!=0 ){ |
| 1250 | style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); |
| 1251 | } |
| 1252 | if( zBranch ){ |
| @@ -1274,21 +1291,21 @@ | |
| 1274 | @ <h2>Difference From <span class='timelineSelected'>\ |
| 1275 | @ %z(href("%R/info/%h",zFrom))%h(zFrom)</a></span> |
| 1276 | @ To <span class='timelineSelected timelineSecondary'>\ |
| 1277 | @ %z(href("%R/info/%h",zTo))%h(zTo)</a></span></h2> |
| 1278 | } |
| 1279 | render_checkin_context(ridFrom, ridTo, 0); |
| 1280 | if( pRe ){ |
| 1281 | @ <p><b>Only differences that match regular expression "%h(zRe)" |
| 1282 | @ are shown.</b></p> |
| 1283 | } |
| 1284 | if( zGlob ){ |
| 1285 | @ <p><b>Only files matching the glob "%h(zGlob)" are shown.</b></p> |
| 1286 | } |
| 1287 | @<hr /><p> |
| 1288 | } |
| 1289 | fossil_free(zQuery); |
| 1290 | |
| 1291 | manifest_file_rewind(pFrom); |
| 1292 | pFileFrom = manifest_file_next(pFrom, 0); |
| 1293 | manifest_file_rewind(pTo); |
| 1294 | pFileTo = manifest_file_next(pTo, 0); |
| 1295 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -270,13 +270,13 @@ | |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | /* |
| 274 | ** Show the context graph (immediate parents and children) for |
| 275 | ** check-in rid and rid2 |
| 276 | */ |
| 277 | void render_checkin_context(int rid, int rid2, int parentsOnly, int mFlags){ |
| 278 | Blob sql; |
| 279 | Stmt q; |
| 280 | int rx[2]; |
| 281 | int i, n; |
| 282 | rx[0] = rid; |
| @@ -313,11 +313,12 @@ | |
| 313 | } |
| 314 | } |
| 315 | blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC"); |
| 316 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 317 | www_print_timeline(&q, |
| 318 | mFlags |
| 319 | |TIMELINE_GRAPH |
| 320 | |TIMELINE_FILLGAPS |
| 321 | |TIMELINE_NOSCROLL |
| 322 | |TIMELINE_XMERGE |
| 323 | |TIMELINE_CHPICK, |
| 324 | 0, 0, 0, rid, rid2, 0); |
| @@ -880,11 +881,11 @@ | |
| 881 | if( !PB("nowiki") ){ |
| 882 | wiki_render_associated("checkin", zUuid, 0); |
| 883 | } |
| 884 | render_backlink_graph(zUuid, "<div class=\"section\">References</div>\n"); |
| 885 | @ <div class="section">Context</div> |
| 886 | render_checkin_context(rid, 0, 0, 0); |
| 887 | @ <div class="section">Changes</div> |
| 888 | @ <div class="sectionmenu"> |
| 889 | diffFlags = construct_diff_flags(diffType); |
| 890 | zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; |
| 891 | if( diffType!=0 ){ |
| @@ -1164,11 +1165,12 @@ | |
| 1165 | ** diff=INTEGER 0: none, 1: unified, 2: side-by-side |
| 1166 | ** glob=STRING only diff files matching this glob |
| 1167 | ** dc=N show N lines of context around each diff |
| 1168 | ** w=BOOLEAN ignore whitespace when computing diffs |
| 1169 | ** nohdr omit the description at the top of the page |
| 1170 | ** nc omit branch coloration from the header graph |
| 1171 | ** inv "Invert". Exchange the roles of from= and to= |
| 1172 | ** |
| 1173 | ** Show all differences between two check-ins. |
| 1174 | */ |
| 1175 | void vdiff_page(void){ |
| 1176 | int ridFrom, ridTo; |
| @@ -1178,75 +1180,90 @@ | |
| 1180 | ManifestFile *pFileFrom, *pFileTo; |
| 1181 | const char *zBranch; |
| 1182 | const char *zFrom; |
| 1183 | const char *zTo; |
| 1184 | const char *zRe; |
| 1185 | const char *zGlob; |
| 1186 | char *zMergeOrigin = 0; |
| 1187 | ReCompiled *pRe = 0; |
| 1188 | int graphFlags = 0; |
| 1189 | Blob qp; |
| 1190 | int bInvert = PB("inv"); |
| 1191 | |
| 1192 | login_check_credentials(); |
| 1193 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1194 | login_anonymous_available(); |
| 1195 | load_control(); |
| 1196 | blob_init(&qp, 0, 0); |
| 1197 | diffType = preferred_diff_type(); |
| 1198 | zRe = P("regex"); |
| 1199 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1200 | zBranch = P("branch"); |
| 1201 | if( zBranch && zBranch[0]==0 ) zBranch = 0; |
| 1202 | if( zBranch ){ |
| 1203 | blob_appendf(&qp, "branch=%T", zBranch); |
| 1204 | zMergeOrigin = mprintf("merge-in:%s", zBranch); |
| 1205 | cgi_replace_parameter("from", zMergeOrigin); |
| 1206 | cgi_replace_parameter("to", zBranch); |
| 1207 | }else{ |
| 1208 | if( bInvert ){ |
| 1209 | blob_appendf(&qp, "to=%T&from=%T",PD("from",""),PD("to","")); |
| 1210 | }else{ |
| 1211 | blob_appendf(&qp, "from=%T&to=%T",PD("from",""),PD("to","")); |
| 1212 | } |
| 1213 | } |
| 1214 | pTo = vdiff_parse_manifest("to", &ridTo); |
| 1215 | if( pTo==0 ) return; |
| 1216 | pFrom = vdiff_parse_manifest("from", &ridFrom); |
| 1217 | if( pFrom==0 ) return; |
| 1218 | zGlob = P("glob"); |
| 1219 | zFrom = P("from"); |
| 1220 | zTo = P("to"); |
| 1221 | if( bInvert ){ |
| 1222 | Manifest *pTemp = pTo; |
| 1223 | const char *zTemp = zTo; |
| 1224 | pTo = pFrom; |
| 1225 | pFrom = pTemp; |
| 1226 | zTo = zFrom; |
| 1227 | zFrom = zTemp; |
| 1228 | } |
| 1229 | if( zGlob ){ |
| 1230 | if( !*zGlob ){ |
| 1231 | zGlob = NULL; |
| 1232 | }else{ |
| 1233 | blob_appendf(&qp, "&glob=%T", zGlob); |
| 1234 | } |
| 1235 | } |
| 1236 | if( PB("nc") ){ |
| 1237 | graphFlags |= TIMELINE_NOCOLOR; |
| 1238 | blob_appendf(&qp, "&nc"); |
| 1239 | } |
| 1240 | diffFlags = construct_diff_flags(diffType); |
| 1241 | if( diffFlags & DIFF_IGNORE_ALLWS ){ |
| 1242 | blob_appendf(&qp, "&w"); |
| 1243 | } |
| 1244 | style_set_current_feature("vdiff"); |
| 1245 | if( zBranch==0 ){ |
| 1246 | style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo); |
| 1247 | } |
| 1248 | if( diffType!=0 ){ |
| 1249 | style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b", &qp); |
| 1250 | } |
| 1251 | if( diffType!=2 ){ |
| 1252 | style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b", &qp); |
| 1253 | } |
| 1254 | if( diffType!=1 ) { |
| 1255 | style_submenu_element("Unified Diff", "%R/vdiff?diff=1&%b", &qp); |
| 1256 | } |
| 1257 | if( zBranch==0 ){ |
| 1258 | style_submenu_element("Invert","%R/vdiff?diff=%d&inv&%b", diffType, &qp); |
| 1259 | } |
| 1260 | if( zGlob ){ |
| 1261 | style_submenu_element("Clear glob", "%R/vdiff?diff=%d&%b", diffType, &qp); |
| 1262 | }else{ |
| 1263 | style_submenu_element("Patch", "%R/vpatch?from=%T&to=%T%s", zFrom, zTo, |
| 1264 | (diffFlags & DIFF_IGNORE_ALLWS)?"&w":""); |
| 1265 | } |
| 1266 | if( diffType!=0 ){ |
| 1267 | style_submenu_checkbox("w", "Ignore Whitespace", 0, 0); |
| 1268 | } |
| 1269 | if( zBranch ){ |
| @@ -1274,21 +1291,21 @@ | |
| 1291 | @ <h2>Difference From <span class='timelineSelected'>\ |
| 1292 | @ %z(href("%R/info/%h",zFrom))%h(zFrom)</a></span> |
| 1293 | @ To <span class='timelineSelected timelineSecondary'>\ |
| 1294 | @ %z(href("%R/info/%h",zTo))%h(zTo)</a></span></h2> |
| 1295 | } |
| 1296 | render_checkin_context(ridFrom, ridTo, 0, graphFlags); |
| 1297 | if( pRe ){ |
| 1298 | @ <p><b>Only differences that match regular expression "%h(zRe)" |
| 1299 | @ are shown.</b></p> |
| 1300 | } |
| 1301 | if( zGlob ){ |
| 1302 | @ <p><b>Only files matching the glob "%h(zGlob)" are shown.</b></p> |
| 1303 | } |
| 1304 | @<hr /><p> |
| 1305 | } |
| 1306 | blob_reset(&qp); |
| 1307 | |
| 1308 | manifest_file_rewind(pFrom); |
| 1309 | pFileFrom = manifest_file_next(pFrom, 0); |
| 1310 | manifest_file_rewind(pTo); |
| 1311 | pFileTo = manifest_file_next(pTo, 0); |
| 1312 |