Fossil SCM
Enhancements to the "fossil finfo -i" command such that it only shows the first check-in for the file (unless -v is also used) and so that it shows the modification time as a separate line for easy parsing by scripts.
Commit
ac6edb35dff3cc1546f7896b75a253a2b813176a91beb1984ca520b13d0be470
Parent
c0162a4f09bc705…
2 files changed
+14
-7
+17
-5
+14
-7
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -31,12 +31,15 @@ | ||
| 31 | 31 | ** For the -l|--log mode: If "-b|--brief" is specified one line per revision |
| 32 | 32 | ** is printed, otherwise the full comment is printed. The "-n|--limit N" |
| 33 | 33 | ** and "--offset P" options limits the output to the first N changes |
| 34 | 34 | ** after skipping P changes. |
| 35 | 35 | ** |
| 36 | -** The -i mode will print the artifact ID of FILENAME given the REVISION | |
| 37 | -** provided by the -r flag (which is required). | |
| 36 | +** The -i mode will print various facts about FILENAME, including its | |
| 37 | +** hash and the check-in and time when the current version of the file | |
| 38 | +** was created. Use -v for additional information. Add the -r VERSION | |
| 39 | +** option to see similar information about the same file for the check-in | |
| 40 | +** specified by VERSION. | |
| 38 | 41 | ** |
| 39 | 42 | ** In the -s mode prints the status as <status> <revision>. This is |
| 40 | 43 | ** a quick status and does not check for up-to-date-ness of the file. |
| 41 | 44 | ** |
| 42 | 45 | ** In the -p mode, there's an optional flag "-r|--revision REVISION". |
| @@ -44,22 +47,24 @@ | ||
| 44 | 47 | ** to stdout. The -p mode is another form of the "cat" command. |
| 45 | 48 | ** |
| 46 | 49 | ** Options: |
| 47 | 50 | ** -b|--brief Display a brief (one line / revision) summary |
| 48 | 51 | ** --case-sensitive B Enable or disable case-sensitive filenames. B is a |
| 49 | -** boolean: "yes", "no", "true", "false", etc. | |
| 52 | +** boolean: "yes", "no", "true", "false", etc. | |
| 50 | 53 | ** -i|--id Print the artifact ID |
| 51 | 54 | ** -l|--log Select log mode (the default) |
| 52 | 55 | ** -n|--limit N Display the first N changes (default unlimited). |
| 53 | -** N less than 0 means no limit. | |
| 56 | +** N less than 0 means no limit. | |
| 54 | 57 | ** --offset P Skip P changes |
| 55 | 58 | ** -p|--print Select print mode |
| 56 | 59 | ** -r|--revision R Print the given revision (or ckout, if none is given) |
| 57 | -** to stdout (only in print mode) | |
| 60 | +** to stdout (only in print mode) | |
| 58 | 61 | ** -s|--status Select status mode (print a status indicator for FILE) |
| 62 | +** -v|--verbose On the -i option, show all check-ins that use the | |
| 63 | +** file, not just the earliest check-in | |
| 59 | 64 | ** -W|--width N Width of lines (default is to auto-detect). Must be |
| 60 | -** more than 22 or else 0 to indicate no limit. | |
| 65 | +** more than 22 or else 0 to indicate no limit. | |
| 61 | 66 | ** |
| 62 | 67 | ** See also: [[artifact]], [[cat]], [[descendants]], [[info]], [[leaves]] |
| 63 | 68 | */ |
| 64 | 69 | void finfo_cmd(void){ |
| 65 | 70 | db_must_be_within_tree(); |
| @@ -142,11 +147,13 @@ | ||
| 142 | 147 | blob_reset(&record); |
| 143 | 148 | blob_reset(&fname); |
| 144 | 149 | }else if( find_option("id","i",0) ){ |
| 145 | 150 | Blob fname; |
| 146 | 151 | int rid; |
| 152 | + int whatisFlags = WHATIS_BRIEF; | |
| 147 | 153 | const char *zRevision = find_option("revision", "r", 1); |
| 154 | + if( find_option("verbose","v",0)!=0 ) whatisFlags = 0; | |
| 148 | 155 | |
| 149 | 156 | verify_all_options(); |
| 150 | 157 | |
| 151 | 158 | if( zRevision==0 ) zRevision = "current"; |
| 152 | 159 | if( g.argc!=3 ) usage("FILENAME"); |
| @@ -157,11 +164,11 @@ | ||
| 157 | 164 | zRevision, &fname, filename_collation()); |
| 158 | 165 | if( rid==0 ) { |
| 159 | 166 | fossil_fatal("file not found for revision %s: %s", |
| 160 | 167 | zRevision, blob_str(&fname)); |
| 161 | 168 | } |
| 162 | - whatis_rid(rid,0); | |
| 169 | + whatis_rid(rid,whatisFlags); | |
| 163 | 170 | blob_reset(&fname); |
| 164 | 171 | }else{ |
| 165 | 172 | Blob line; |
| 166 | 173 | Stmt q; |
| 167 | 174 | Blob fname; |
| 168 | 175 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -31,12 +31,15 @@ | |
| 31 | ** For the -l|--log mode: If "-b|--brief" is specified one line per revision |
| 32 | ** is printed, otherwise the full comment is printed. The "-n|--limit N" |
| 33 | ** and "--offset P" options limits the output to the first N changes |
| 34 | ** after skipping P changes. |
| 35 | ** |
| 36 | ** The -i mode will print the artifact ID of FILENAME given the REVISION |
| 37 | ** provided by the -r flag (which is required). |
| 38 | ** |
| 39 | ** In the -s mode prints the status as <status> <revision>. This is |
| 40 | ** a quick status and does not check for up-to-date-ness of the file. |
| 41 | ** |
| 42 | ** In the -p mode, there's an optional flag "-r|--revision REVISION". |
| @@ -44,22 +47,24 @@ | |
| 44 | ** to stdout. The -p mode is another form of the "cat" command. |
| 45 | ** |
| 46 | ** Options: |
| 47 | ** -b|--brief Display a brief (one line / revision) summary |
| 48 | ** --case-sensitive B Enable or disable case-sensitive filenames. B is a |
| 49 | ** boolean: "yes", "no", "true", "false", etc. |
| 50 | ** -i|--id Print the artifact ID |
| 51 | ** -l|--log Select log mode (the default) |
| 52 | ** -n|--limit N Display the first N changes (default unlimited). |
| 53 | ** N less than 0 means no limit. |
| 54 | ** --offset P Skip P changes |
| 55 | ** -p|--print Select print mode |
| 56 | ** -r|--revision R Print the given revision (or ckout, if none is given) |
| 57 | ** to stdout (only in print mode) |
| 58 | ** -s|--status Select status mode (print a status indicator for FILE) |
| 59 | ** -W|--width N Width of lines (default is to auto-detect). Must be |
| 60 | ** more than 22 or else 0 to indicate no limit. |
| 61 | ** |
| 62 | ** See also: [[artifact]], [[cat]], [[descendants]], [[info]], [[leaves]] |
| 63 | */ |
| 64 | void finfo_cmd(void){ |
| 65 | db_must_be_within_tree(); |
| @@ -142,11 +147,13 @@ | |
| 142 | blob_reset(&record); |
| 143 | blob_reset(&fname); |
| 144 | }else if( find_option("id","i",0) ){ |
| 145 | Blob fname; |
| 146 | int rid; |
| 147 | const char *zRevision = find_option("revision", "r", 1); |
| 148 | |
| 149 | verify_all_options(); |
| 150 | |
| 151 | if( zRevision==0 ) zRevision = "current"; |
| 152 | if( g.argc!=3 ) usage("FILENAME"); |
| @@ -157,11 +164,11 @@ | |
| 157 | zRevision, &fname, filename_collation()); |
| 158 | if( rid==0 ) { |
| 159 | fossil_fatal("file not found for revision %s: %s", |
| 160 | zRevision, blob_str(&fname)); |
| 161 | } |
| 162 | whatis_rid(rid,0); |
| 163 | blob_reset(&fname); |
| 164 | }else{ |
| 165 | Blob line; |
| 166 | Stmt q; |
| 167 | Blob fname; |
| 168 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -31,12 +31,15 @@ | |
| 31 | ** For the -l|--log mode: If "-b|--brief" is specified one line per revision |
| 32 | ** is printed, otherwise the full comment is printed. The "-n|--limit N" |
| 33 | ** and "--offset P" options limits the output to the first N changes |
| 34 | ** after skipping P changes. |
| 35 | ** |
| 36 | ** The -i mode will print various facts about FILENAME, including its |
| 37 | ** hash and the check-in and time when the current version of the file |
| 38 | ** was created. Use -v for additional information. Add the -r VERSION |
| 39 | ** option to see similar information about the same file for the check-in |
| 40 | ** specified by VERSION. |
| 41 | ** |
| 42 | ** In the -s mode prints the status as <status> <revision>. This is |
| 43 | ** a quick status and does not check for up-to-date-ness of the file. |
| 44 | ** |
| 45 | ** In the -p mode, there's an optional flag "-r|--revision REVISION". |
| @@ -44,22 +47,24 @@ | |
| 47 | ** to stdout. The -p mode is another form of the "cat" command. |
| 48 | ** |
| 49 | ** Options: |
| 50 | ** -b|--brief Display a brief (one line / revision) summary |
| 51 | ** --case-sensitive B Enable or disable case-sensitive filenames. B is a |
| 52 | ** boolean: "yes", "no", "true", "false", etc. |
| 53 | ** -i|--id Print the artifact ID |
| 54 | ** -l|--log Select log mode (the default) |
| 55 | ** -n|--limit N Display the first N changes (default unlimited). |
| 56 | ** N less than 0 means no limit. |
| 57 | ** --offset P Skip P changes |
| 58 | ** -p|--print Select print mode |
| 59 | ** -r|--revision R Print the given revision (or ckout, if none is given) |
| 60 | ** to stdout (only in print mode) |
| 61 | ** -s|--status Select status mode (print a status indicator for FILE) |
| 62 | ** -v|--verbose On the -i option, show all check-ins that use the |
| 63 | ** file, not just the earliest check-in |
| 64 | ** -W|--width N Width of lines (default is to auto-detect). Must be |
| 65 | ** more than 22 or else 0 to indicate no limit. |
| 66 | ** |
| 67 | ** See also: [[artifact]], [[cat]], [[descendants]], [[info]], [[leaves]] |
| 68 | */ |
| 69 | void finfo_cmd(void){ |
| 70 | db_must_be_within_tree(); |
| @@ -142,11 +147,13 @@ | |
| 147 | blob_reset(&record); |
| 148 | blob_reset(&fname); |
| 149 | }else if( find_option("id","i",0) ){ |
| 150 | Blob fname; |
| 151 | int rid; |
| 152 | int whatisFlags = WHATIS_BRIEF; |
| 153 | const char *zRevision = find_option("revision", "r", 1); |
| 154 | if( find_option("verbose","v",0)!=0 ) whatisFlags = 0; |
| 155 | |
| 156 | verify_all_options(); |
| 157 | |
| 158 | if( zRevision==0 ) zRevision = "current"; |
| 159 | if( g.argc!=3 ) usage("FILENAME"); |
| @@ -157,11 +164,11 @@ | |
| 164 | zRevision, &fname, filename_collation()); |
| 165 | if( rid==0 ) { |
| 166 | fossil_fatal("file not found for revision %s: %s", |
| 167 | zRevision, blob_str(&fname)); |
| 168 | } |
| 169 | whatis_rid(rid,whatisFlags); |
| 170 | blob_reset(&fname); |
| 171 | }else{ |
| 172 | Blob line; |
| 173 | Stmt q; |
| 174 | Blob fname; |
| 175 |
+17
-5
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -844,14 +844,22 @@ | ||
| 844 | 844 | default: break; |
| 845 | 845 | } |
| 846 | 846 | return zType; |
| 847 | 847 | } |
| 848 | 848 | |
| 849 | +/* | |
| 850 | +** Flag values for whatis_rid(). | |
| 851 | +*/ | |
| 852 | +#if INTERFACE | |
| 853 | +#define WHATIS_VERBOSE 0x01 /* Extra output */ | |
| 854 | +#define WHATIS_BRIEF 0x02 /* Omit unnecessary output */ | |
| 855 | +#endif | |
| 856 | + | |
| 849 | 857 | /* |
| 850 | 858 | ** Generate a description of artifact "rid" |
| 851 | 859 | */ |
| 852 | -void whatis_rid(int rid, int verboseFlag){ | |
| 860 | +void whatis_rid(int rid, int flags){ | |
| 853 | 861 | Stmt q; |
| 854 | 862 | int cnt; |
| 855 | 863 | |
| 856 | 864 | /* Basic information about the object. */ |
| 857 | 865 | db_prepare(&q, |
| @@ -859,11 +867,11 @@ | ||
| 859 | 867 | " FROM blob, rcvfrom" |
| 860 | 868 | " WHERE rid=%d" |
| 861 | 869 | " AND rcvfrom.rcvid=blob.rcvid", |
| 862 | 870 | rid); |
| 863 | 871 | if( db_step(&q)==SQLITE_ROW ){ |
| 864 | - if( verboseFlag ){ | |
| 872 | + if( flags & WHATIS_VERBOSE ){ | |
| 865 | 873 | fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); |
| 866 | 874 | fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 867 | 875 | fossil_print("received: %s from %s\n", |
| 868 | 876 | db_column_text(&q, 2), |
| 869 | 877 | db_column_text(&q, 3)); |
| @@ -940,13 +948,17 @@ | ||
| 940 | 948 | " FROM mlink, filename, blob, event" |
| 941 | 949 | " WHERE mlink.fid=%d" |
| 942 | 950 | " AND filename.fnid=mlink.fnid" |
| 943 | 951 | " AND event.objid=mlink.mid" |
| 944 | 952 | " AND blob.rid=mlink.mid" |
| 945 | - " ORDER BY event.mtime DESC /*sort*/", | |
| 946 | - rid); | |
| 953 | + " ORDER BY event.mtime %s /*sort*/", | |
| 954 | + rid, | |
| 955 | + (flags & WHATIS_BRIEF) ? "LIMIT 1" : "DESC"); | |
| 947 | 956 | while( db_step(&q)==SQLITE_ROW ){ |
| 957 | + if( flags & WHATIS_BRIEF ){ | |
| 958 | + fossil_print("mtime: %s\n", db_column_text(&q,2)); | |
| 959 | + } | |
| 948 | 960 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 949 | 961 | fossil_print(" part of [%S] by %s on %s\n", |
| 950 | 962 | db_column_text(&q, 1), |
| 951 | 963 | db_column_text(&q, 3), |
| 952 | 964 | db_column_text(&q, 2)); |
| @@ -975,11 +987,11 @@ | ||
| 975 | 987 | ); |
| 976 | 988 | while( db_step(&q)==SQLITE_ROW ){ |
| 977 | 989 | fossil_print("attachment: %s\n", db_column_text(&q,0)); |
| 978 | 990 | fossil_print(" attached to %s %s\n", |
| 979 | 991 | db_column_text(&q,5), db_column_text(&q,4)); |
| 980 | - if( verboseFlag ){ | |
| 992 | + if( flags & WHATIS_VERBOSE ){ | |
| 981 | 993 | fossil_print(" via %s (%d)\n", |
| 982 | 994 | db_column_text(&q,7), db_column_int(&q,6)); |
| 983 | 995 | }else{ |
| 984 | 996 | fossil_print(" via %s\n", |
| 985 | 997 | db_column_text(&q,7)); |
| 986 | 998 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -844,14 +844,22 @@ | |
| 844 | default: break; |
| 845 | } |
| 846 | return zType; |
| 847 | } |
| 848 | |
| 849 | /* |
| 850 | ** Generate a description of artifact "rid" |
| 851 | */ |
| 852 | void whatis_rid(int rid, int verboseFlag){ |
| 853 | Stmt q; |
| 854 | int cnt; |
| 855 | |
| 856 | /* Basic information about the object. */ |
| 857 | db_prepare(&q, |
| @@ -859,11 +867,11 @@ | |
| 859 | " FROM blob, rcvfrom" |
| 860 | " WHERE rid=%d" |
| 861 | " AND rcvfrom.rcvid=blob.rcvid", |
| 862 | rid); |
| 863 | if( db_step(&q)==SQLITE_ROW ){ |
| 864 | if( verboseFlag ){ |
| 865 | fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); |
| 866 | fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 867 | fossil_print("received: %s from %s\n", |
| 868 | db_column_text(&q, 2), |
| 869 | db_column_text(&q, 3)); |
| @@ -940,13 +948,17 @@ | |
| 940 | " FROM mlink, filename, blob, event" |
| 941 | " WHERE mlink.fid=%d" |
| 942 | " AND filename.fnid=mlink.fnid" |
| 943 | " AND event.objid=mlink.mid" |
| 944 | " AND blob.rid=mlink.mid" |
| 945 | " ORDER BY event.mtime DESC /*sort*/", |
| 946 | rid); |
| 947 | while( db_step(&q)==SQLITE_ROW ){ |
| 948 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 949 | fossil_print(" part of [%S] by %s on %s\n", |
| 950 | db_column_text(&q, 1), |
| 951 | db_column_text(&q, 3), |
| 952 | db_column_text(&q, 2)); |
| @@ -975,11 +987,11 @@ | |
| 975 | ); |
| 976 | while( db_step(&q)==SQLITE_ROW ){ |
| 977 | fossil_print("attachment: %s\n", db_column_text(&q,0)); |
| 978 | fossil_print(" attached to %s %s\n", |
| 979 | db_column_text(&q,5), db_column_text(&q,4)); |
| 980 | if( verboseFlag ){ |
| 981 | fossil_print(" via %s (%d)\n", |
| 982 | db_column_text(&q,7), db_column_int(&q,6)); |
| 983 | }else{ |
| 984 | fossil_print(" via %s\n", |
| 985 | db_column_text(&q,7)); |
| 986 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -844,14 +844,22 @@ | |
| 844 | default: break; |
| 845 | } |
| 846 | return zType; |
| 847 | } |
| 848 | |
| 849 | /* |
| 850 | ** Flag values for whatis_rid(). |
| 851 | */ |
| 852 | #if INTERFACE |
| 853 | #define WHATIS_VERBOSE 0x01 /* Extra output */ |
| 854 | #define WHATIS_BRIEF 0x02 /* Omit unnecessary output */ |
| 855 | #endif |
| 856 | |
| 857 | /* |
| 858 | ** Generate a description of artifact "rid" |
| 859 | */ |
| 860 | void whatis_rid(int rid, int flags){ |
| 861 | Stmt q; |
| 862 | int cnt; |
| 863 | |
| 864 | /* Basic information about the object. */ |
| 865 | db_prepare(&q, |
| @@ -859,11 +867,11 @@ | |
| 867 | " FROM blob, rcvfrom" |
| 868 | " WHERE rid=%d" |
| 869 | " AND rcvfrom.rcvid=blob.rcvid", |
| 870 | rid); |
| 871 | if( db_step(&q)==SQLITE_ROW ){ |
| 872 | if( flags & WHATIS_VERBOSE ){ |
| 873 | fossil_print("artifact: %s (%d)\n", db_column_text(&q,0), rid); |
| 874 | fossil_print("size: %d bytes\n", db_column_int(&q,1)); |
| 875 | fossil_print("received: %s from %s\n", |
| 876 | db_column_text(&q, 2), |
| 877 | db_column_text(&q, 3)); |
| @@ -940,13 +948,17 @@ | |
| 948 | " FROM mlink, filename, blob, event" |
| 949 | " WHERE mlink.fid=%d" |
| 950 | " AND filename.fnid=mlink.fnid" |
| 951 | " AND event.objid=mlink.mid" |
| 952 | " AND blob.rid=mlink.mid" |
| 953 | " ORDER BY event.mtime %s /*sort*/", |
| 954 | rid, |
| 955 | (flags & WHATIS_BRIEF) ? "LIMIT 1" : "DESC"); |
| 956 | while( db_step(&q)==SQLITE_ROW ){ |
| 957 | if( flags & WHATIS_BRIEF ){ |
| 958 | fossil_print("mtime: %s\n", db_column_text(&q,2)); |
| 959 | } |
| 960 | fossil_print("file: %s\n", db_column_text(&q,0)); |
| 961 | fossil_print(" part of [%S] by %s on %s\n", |
| 962 | db_column_text(&q, 1), |
| 963 | db_column_text(&q, 3), |
| 964 | db_column_text(&q, 2)); |
| @@ -975,11 +987,11 @@ | |
| 987 | ); |
| 988 | while( db_step(&q)==SQLITE_ROW ){ |
| 989 | fossil_print("attachment: %s\n", db_column_text(&q,0)); |
| 990 | fossil_print(" attached to %s %s\n", |
| 991 | db_column_text(&q,5), db_column_text(&q,4)); |
| 992 | if( flags & WHATIS_VERBOSE ){ |
| 993 | fossil_print(" via %s (%d)\n", |
| 994 | db_column_text(&q,7), db_column_int(&q,6)); |
| 995 | }else{ |
| 996 | fossil_print(" via %s\n", |
| 997 | db_column_text(&q,7)); |
| 998 |