Fossil SCM
Add the "fossil blame" command that shows the username without a line number. The "fossil annotate" command continues to show the line number and omit the username.
Commit
6f686403d74889ae8f171c1a5a6032e2170991cd
Parent
27dc7a5671d44cc…
1 file changed
+27
-11
+27
-11
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -1939,10 +1939,11 @@ | ||
| 1939 | 1939 | struct AnnVers { |
| 1940 | 1940 | const char *zFUuid; /* File being analyzed */ |
| 1941 | 1941 | const char *zMUuid; /* Check-in containing the file */ |
| 1942 | 1942 | const char *zDate; /* Date of the check-in */ |
| 1943 | 1943 | const char *zBgColor; /* Suggested background color */ |
| 1944 | + const char *zUser; /* Name of user who did the check-in */ | |
| 1944 | 1945 | unsigned cnt; /* Number of lines contributed by this check-in */ |
| 1945 | 1946 | } *aVers; /* For each check-in analyzed */ |
| 1946 | 1947 | char **azVers; /* Names of versions analyzed */ |
| 1947 | 1948 | }; |
| 1948 | 1949 | |
| @@ -2061,10 +2062,11 @@ | ||
| 2061 | 2062 | db_prepare(&ins, "INSERT OR IGNORE INTO vseen(rid) VALUES(:rid)"); |
| 2062 | 2063 | db_prepare(&q, |
| 2063 | 2064 | "SELECT (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 2064 | 2065 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 2065 | 2066 | " date(event.mtime)," |
| 2067 | + " coalesce(event.euser,event.user)," | |
| 2066 | 2068 | " mlink.pid" |
| 2067 | 2069 | " FROM mlink, event" |
| 2068 | 2070 | " WHERE mlink.fid=:rid" |
| 2069 | 2071 | " AND event.objid=mlink.mid" |
| 2070 | 2072 | " AND mlink.pid NOT IN vseen" |
| @@ -2074,15 +2076,16 @@ | ||
| 2074 | 2076 | ); |
| 2075 | 2077 | |
| 2076 | 2078 | db_bind_int(&q, ":rid", rid); |
| 2077 | 2079 | if( iLimit==0 ) iLimit = 1000000000; |
| 2078 | 2080 | while( rid && iLimit>cnt && db_step(&q)==SQLITE_ROW ){ |
| 2079 | - int prevId = db_column_int(&q, 3); | |
| 2081 | + int prevId = db_column_int(&q, 4); | |
| 2080 | 2082 | p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); |
| 2081 | 2083 | p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); |
| 2082 | 2084 | p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); |
| 2083 | 2085 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2086 | + p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); | |
| 2084 | 2087 | if( p->nVers ){ |
| 2085 | 2088 | content_get(rid, &step); |
| 2086 | 2089 | annotation_step(p, &step, p->nVers-1); |
| 2087 | 2090 | blob_reset(&step); |
| 2088 | 2091 | } |
| @@ -2268,15 +2271,18 @@ | ||
| 2268 | 2271 | style_footer(); |
| 2269 | 2272 | } |
| 2270 | 2273 | |
| 2271 | 2274 | /* |
| 2272 | 2275 | ** COMMAND: annotate |
| 2276 | +** COMMAND: blame | |
| 2273 | 2277 | ** |
| 2274 | -** %fossil annotate ?OPTIONS? FILENAME | |
| 2278 | +** %fossil (annotate|blame) ?OPTIONS? FILENAME | |
| 2275 | 2279 | ** |
| 2276 | 2280 | ** Output the text of a file with markings to show when each line of |
| 2277 | -** the file was last modified. | |
| 2281 | +** the file was last modified. The "annotate" command shows line numbers | |
| 2282 | +** and omits the username. The "blame" command user the user who made each | |
| 2283 | +** checkin and omits the line number. | |
| 2278 | 2284 | ** |
| 2279 | 2285 | ** Options: |
| 2280 | 2286 | ** --filevers Show file version numbers rather than check-in versions |
| 2281 | 2287 | ** -l|--log List all versions analyzed |
| 2282 | 2288 | ** -n|--limit N Only look backwards in time by N versions |
| @@ -2295,11 +2301,13 @@ | ||
| 2295 | 2301 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2296 | 2302 | int iLimit; /* How far back in time to look */ |
| 2297 | 2303 | int showLog; /* True to show the log */ |
| 2298 | 2304 | int fileVers; /* Show file version instead of check-in versions */ |
| 2299 | 2305 | int annFlags = 0; /* Flags to control annotation properties */ |
| 2306 | + int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ | |
| 2300 | 2307 | |
| 2308 | + bBlame = g.argv[1][0]=='b'; | |
| 2301 | 2309 | zLimit = find_option("limit","n",1); |
| 2302 | 2310 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2303 | 2311 | iLimit = atoi(zLimit); |
| 2304 | 2312 | showLog = find_option("log","l",0)!=0; |
| 2305 | 2313 | fileVers = find_option("filevers",0,0)!=0; |
| @@ -2342,18 +2350,26 @@ | ||
| 2342 | 2350 | } |
| 2343 | 2351 | for(i=0; i<ann.nOrig; i++){ |
| 2344 | 2352 | int iVers = ann.aOrig[i].iVers; |
| 2345 | 2353 | char *z = (char*)ann.aOrig[i].z; |
| 2346 | 2354 | int n = ann.aOrig[i].n; |
| 2347 | - char zPrefix[200]; | |
| 2348 | - z[n] = 0; | |
| 2355 | + struct AnnVers *p; | |
| 2349 | 2356 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2350 | - if( iVers>=0 ){ | |
| 2351 | - struct AnnVers *p = ann.aVers+iVers; | |
| 2352 | - sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%.10s %s", | |
| 2353 | - fileVers ? p->zFUuid : p->zMUuid, p->zDate); | |
| 2357 | + p = ann.aVers + iVers; | |
| 2358 | + if( bBlame ){ | |
| 2359 | + if( iVers>=0 ){ | |
| 2360 | + fossil_print("%.10s %s %13.13s: %.*s\n", | |
| 2361 | + fileVers ? p->zFUuid : p->zMUuid, p->zDate, p->zUser, n, z); | |
| 2362 | + }else{ | |
| 2363 | + fossil_print("%35s %.*s\n", "", n, z); | |
| 2364 | + } | |
| 2354 | 2365 | }else{ |
| 2355 | - zPrefix[0] = 0; | |
| 2366 | + if( iVers>=0 ){ | |
| 2367 | + fossil_print("%.10s %s %5d: %.*s\n", | |
| 2368 | + fileVers ? p->zFUuid : p->zMUuid, p->zDate, i+1, n, z); | |
| 2369 | + }else{ | |
| 2370 | + fossil_print("%21s %5d: %.*s\n", | |
| 2371 | + "", i+1, n, z); | |
| 2372 | + } | |
| 2356 | 2373 | } |
| 2357 | - fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z); | |
| 2358 | 2374 | } |
| 2359 | 2375 | } |
| 2360 | 2376 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1939,10 +1939,11 @@ | |
| 1939 | struct AnnVers { |
| 1940 | const char *zFUuid; /* File being analyzed */ |
| 1941 | const char *zMUuid; /* Check-in containing the file */ |
| 1942 | const char *zDate; /* Date of the check-in */ |
| 1943 | const char *zBgColor; /* Suggested background color */ |
| 1944 | unsigned cnt; /* Number of lines contributed by this check-in */ |
| 1945 | } *aVers; /* For each check-in analyzed */ |
| 1946 | char **azVers; /* Names of versions analyzed */ |
| 1947 | }; |
| 1948 | |
| @@ -2061,10 +2062,11 @@ | |
| 2061 | db_prepare(&ins, "INSERT OR IGNORE INTO vseen(rid) VALUES(:rid)"); |
| 2062 | db_prepare(&q, |
| 2063 | "SELECT (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 2064 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 2065 | " date(event.mtime)," |
| 2066 | " mlink.pid" |
| 2067 | " FROM mlink, event" |
| 2068 | " WHERE mlink.fid=:rid" |
| 2069 | " AND event.objid=mlink.mid" |
| 2070 | " AND mlink.pid NOT IN vseen" |
| @@ -2074,15 +2076,16 @@ | |
| 2074 | ); |
| 2075 | |
| 2076 | db_bind_int(&q, ":rid", rid); |
| 2077 | if( iLimit==0 ) iLimit = 1000000000; |
| 2078 | while( rid && iLimit>cnt && db_step(&q)==SQLITE_ROW ){ |
| 2079 | int prevId = db_column_int(&q, 3); |
| 2080 | p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); |
| 2081 | p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); |
| 2082 | p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); |
| 2083 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2084 | if( p->nVers ){ |
| 2085 | content_get(rid, &step); |
| 2086 | annotation_step(p, &step, p->nVers-1); |
| 2087 | blob_reset(&step); |
| 2088 | } |
| @@ -2268,15 +2271,18 @@ | |
| 2268 | style_footer(); |
| 2269 | } |
| 2270 | |
| 2271 | /* |
| 2272 | ** COMMAND: annotate |
| 2273 | ** |
| 2274 | ** %fossil annotate ?OPTIONS? FILENAME |
| 2275 | ** |
| 2276 | ** Output the text of a file with markings to show when each line of |
| 2277 | ** the file was last modified. |
| 2278 | ** |
| 2279 | ** Options: |
| 2280 | ** --filevers Show file version numbers rather than check-in versions |
| 2281 | ** -l|--log List all versions analyzed |
| 2282 | ** -n|--limit N Only look backwards in time by N versions |
| @@ -2295,11 +2301,13 @@ | |
| 2295 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2296 | int iLimit; /* How far back in time to look */ |
| 2297 | int showLog; /* True to show the log */ |
| 2298 | int fileVers; /* Show file version instead of check-in versions */ |
| 2299 | int annFlags = 0; /* Flags to control annotation properties */ |
| 2300 | |
| 2301 | zLimit = find_option("limit","n",1); |
| 2302 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2303 | iLimit = atoi(zLimit); |
| 2304 | showLog = find_option("log","l",0)!=0; |
| 2305 | fileVers = find_option("filevers",0,0)!=0; |
| @@ -2342,18 +2350,26 @@ | |
| 2342 | } |
| 2343 | for(i=0; i<ann.nOrig; i++){ |
| 2344 | int iVers = ann.aOrig[i].iVers; |
| 2345 | char *z = (char*)ann.aOrig[i].z; |
| 2346 | int n = ann.aOrig[i].n; |
| 2347 | char zPrefix[200]; |
| 2348 | z[n] = 0; |
| 2349 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2350 | if( iVers>=0 ){ |
| 2351 | struct AnnVers *p = ann.aVers+iVers; |
| 2352 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%.10s %s", |
| 2353 | fileVers ? p->zFUuid : p->zMUuid, p->zDate); |
| 2354 | }else{ |
| 2355 | zPrefix[0] = 0; |
| 2356 | } |
| 2357 | fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z); |
| 2358 | } |
| 2359 | } |
| 2360 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -1939,10 +1939,11 @@ | |
| 1939 | struct AnnVers { |
| 1940 | const char *zFUuid; /* File being analyzed */ |
| 1941 | const char *zMUuid; /* Check-in containing the file */ |
| 1942 | const char *zDate; /* Date of the check-in */ |
| 1943 | const char *zBgColor; /* Suggested background color */ |
| 1944 | const char *zUser; /* Name of user who did the check-in */ |
| 1945 | unsigned cnt; /* Number of lines contributed by this check-in */ |
| 1946 | } *aVers; /* For each check-in analyzed */ |
| 1947 | char **azVers; /* Names of versions analyzed */ |
| 1948 | }; |
| 1949 | |
| @@ -2061,10 +2062,11 @@ | |
| 2062 | db_prepare(&ins, "INSERT OR IGNORE INTO vseen(rid) VALUES(:rid)"); |
| 2063 | db_prepare(&q, |
| 2064 | "SELECT (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 2065 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," |
| 2066 | " date(event.mtime)," |
| 2067 | " coalesce(event.euser,event.user)," |
| 2068 | " mlink.pid" |
| 2069 | " FROM mlink, event" |
| 2070 | " WHERE mlink.fid=:rid" |
| 2071 | " AND event.objid=mlink.mid" |
| 2072 | " AND mlink.pid NOT IN vseen" |
| @@ -2074,15 +2076,16 @@ | |
| 2076 | ); |
| 2077 | |
| 2078 | db_bind_int(&q, ":rid", rid); |
| 2079 | if( iLimit==0 ) iLimit = 1000000000; |
| 2080 | while( rid && iLimit>cnt && db_step(&q)==SQLITE_ROW ){ |
| 2081 | int prevId = db_column_int(&q, 4); |
| 2082 | p->aVers = fossil_realloc(p->aVers, (p->nVers+1)*sizeof(p->aVers[0])); |
| 2083 | p->aVers[p->nVers].zFUuid = fossil_strdup(db_column_text(&q, 0)); |
| 2084 | p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1)); |
| 2085 | p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2)); |
| 2086 | p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3)); |
| 2087 | if( p->nVers ){ |
| 2088 | content_get(rid, &step); |
| 2089 | annotation_step(p, &step, p->nVers-1); |
| 2090 | blob_reset(&step); |
| 2091 | } |
| @@ -2268,15 +2271,18 @@ | |
| 2271 | style_footer(); |
| 2272 | } |
| 2273 | |
| 2274 | /* |
| 2275 | ** COMMAND: annotate |
| 2276 | ** COMMAND: blame |
| 2277 | ** |
| 2278 | ** %fossil (annotate|blame) ?OPTIONS? FILENAME |
| 2279 | ** |
| 2280 | ** Output the text of a file with markings to show when each line of |
| 2281 | ** the file was last modified. The "annotate" command shows line numbers |
| 2282 | ** and omits the username. The "blame" command user the user who made each |
| 2283 | ** checkin and omits the line number. |
| 2284 | ** |
| 2285 | ** Options: |
| 2286 | ** --filevers Show file version numbers rather than check-in versions |
| 2287 | ** -l|--log List all versions analyzed |
| 2288 | ** -n|--limit N Only look backwards in time by N versions |
| @@ -2295,11 +2301,13 @@ | |
| 2301 | const char *zLimit; /* The value to the -n|--limit option */ |
| 2302 | int iLimit; /* How far back in time to look */ |
| 2303 | int showLog; /* True to show the log */ |
| 2304 | int fileVers; /* Show file version instead of check-in versions */ |
| 2305 | int annFlags = 0; /* Flags to control annotation properties */ |
| 2306 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 2307 | |
| 2308 | bBlame = g.argv[1][0]=='b'; |
| 2309 | zLimit = find_option("limit","n",1); |
| 2310 | if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1"; |
| 2311 | iLimit = atoi(zLimit); |
| 2312 | showLog = find_option("log","l",0)!=0; |
| 2313 | fileVers = find_option("filevers",0,0)!=0; |
| @@ -2342,18 +2350,26 @@ | |
| 2350 | } |
| 2351 | for(i=0; i<ann.nOrig; i++){ |
| 2352 | int iVers = ann.aOrig[i].iVers; |
| 2353 | char *z = (char*)ann.aOrig[i].z; |
| 2354 | int n = ann.aOrig[i].n; |
| 2355 | struct AnnVers *p; |
| 2356 | if( iLimit>ann.nVers && iVers<0 ) iVers = ann.nVers-1; |
| 2357 | p = ann.aVers + iVers; |
| 2358 | if( bBlame ){ |
| 2359 | if( iVers>=0 ){ |
| 2360 | fossil_print("%.10s %s %13.13s: %.*s\n", |
| 2361 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, p->zUser, n, z); |
| 2362 | }else{ |
| 2363 | fossil_print("%35s %.*s\n", "", n, z); |
| 2364 | } |
| 2365 | }else{ |
| 2366 | if( iVers>=0 ){ |
| 2367 | fossil_print("%.10s %s %5d: %.*s\n", |
| 2368 | fileVers ? p->zFUuid : p->zMUuid, p->zDate, i+1, n, z); |
| 2369 | }else{ |
| 2370 | fossil_print("%21s %5d: %.*s\n", |
| 2371 | "", i+1, n, z); |
| 2372 | } |
| 2373 | } |
| 2374 | } |
| 2375 | } |
| 2376 |