Fossil SCM
Add the "-f|--file" flag to the "whatis" command which consist to search for any other files in the repo with the exact same content as the given file.
Commit
a821cbf522bee8d267a21b0a354cb1ff89b0713864b8975e990f5de5520935d1
Parent
7de2410f742af79…
1 file changed
+65
-24
+65
-24
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -1015,10 +1015,47 @@ | ||
| 1015 | 1015 | " FROM description WHERE rid=%d", rid); |
| 1016 | 1016 | fossil_print("%s\n", zDesc); |
| 1017 | 1017 | fossil_free(zDesc); |
| 1018 | 1018 | } |
| 1019 | 1019 | } |
| 1020 | + | |
| 1021 | +/* | |
| 1022 | +** Generate a description of artifact from it symbolic name. | |
| 1023 | +*/ | |
| 1024 | +void whatis_artifact( | |
| 1025 | + const char *zName, /* Symbolic name or full hash */ | |
| 1026 | + const char *zFileName,/* Optional: original filename (in file mode) */ | |
| 1027 | + const char *zType, /* Artifact type filter */ | |
| 1028 | + int verboseFlag /* Verbosity flag */ | |
| 1029 | +){ | |
| 1030 | + const char* zNameTitle = "name:"; | |
| 1031 | + int rid = symbolic_name_to_rid(zName, zType); | |
| 1032 | + if( zFileName ){ | |
| 1033 | + fossil_print("%-12s%s\n", zNameTitle, zFileName); | |
| 1034 | + zNameTitle = "hash:"; | |
| 1035 | + } | |
| 1036 | + if( rid<0 ){ | |
| 1037 | + Stmt q; | |
| 1038 | + int cnt = 0; | |
| 1039 | + fossil_print("%-12s%s (ambiguous)\n", zNameTitle, zName); | |
| 1040 | + db_prepare(&q, | |
| 1041 | + "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", | |
| 1042 | + zName, zName | |
| 1043 | + ); | |
| 1044 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 1045 | + if( cnt++ ) fossil_print("%12s---- meaning #%d ----\n", " ", cnt); | |
| 1046 | + whatis_rid(db_column_int(&q, 0), verboseFlag); | |
| 1047 | + } | |
| 1048 | + db_finalize(&q); | |
| 1049 | + }else if( rid==0 ){ | |
| 1050 | + /* 0123456789 12 */ | |
| 1051 | + fossil_print("unknown: %s\n", zName); | |
| 1052 | + }else{ | |
| 1053 | + fossil_print("%-12s%s\n", zNameTitle, zName); | |
| 1054 | + whatis_rid(rid, verboseFlag); | |
| 1055 | + } | |
| 1056 | +} | |
| 1020 | 1057 | |
| 1021 | 1058 | /* |
| 1022 | 1059 | ** COMMAND: whatis* |
| 1023 | 1060 | ** |
| 1024 | 1061 | ** Usage: %fossil whatis NAME |
| @@ -1027,51 +1064,55 @@ | ||
| 1027 | 1064 | ** artifact name and provide a description of what role that artifact |
| 1028 | 1065 | ** plays. |
| 1029 | 1066 | ** |
| 1030 | 1067 | ** Options: |
| 1031 | 1068 | ** |
| 1069 | +** -f|--file Find artifacts with same hash as file NAME. | |
| 1070 | +** (if NAME is "-", read from standard input) | |
| 1032 | 1071 | ** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't', |
| 1033 | 1072 | ** 'w', 'g', or 'e') |
| 1034 | 1073 | ** -v|--verbose Provide extra information (such as the RID) |
| 1035 | 1074 | */ |
| 1036 | 1075 | void whatis_cmd(void){ |
| 1037 | - int rid; | |
| 1038 | - const char *zName; | |
| 1039 | 1076 | int verboseFlag; |
| 1077 | + int fileFlag; | |
| 1040 | 1078 | int i; |
| 1041 | 1079 | const char *zType = 0; |
| 1042 | 1080 | db_find_and_open_repository(0,0); |
| 1043 | 1081 | verboseFlag = find_option("verbose","v",0)!=0; |
| 1082 | + fileFlag = find_option("file","f",0)!=0; | |
| 1044 | 1083 | zType = find_option("type",0,1); |
| 1045 | 1084 | |
| 1046 | 1085 | /* We should be done with options.. */ |
| 1047 | 1086 | verify_all_options(); |
| 1048 | 1087 | |
| 1049 | 1088 | if( g.argc<3 ) usage("NAME ..."); |
| 1050 | 1089 | for(i=2; i<g.argc; i++){ |
| 1051 | - zName = g.argv[i]; | |
| 1052 | - if( i>2 ) fossil_print("%.79c\n",'-'); | |
| 1053 | - rid = symbolic_name_to_rid(zName, zType); | |
| 1054 | - if( rid<0 ){ | |
| 1055 | - Stmt q; | |
| 1056 | - int cnt = 0; | |
| 1057 | - fossil_print("name: %s (ambiguous)\n", zName); | |
| 1058 | - db_prepare(&q, | |
| 1059 | - "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", | |
| 1060 | - zName, zName | |
| 1061 | - ); | |
| 1062 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 1063 | - if( cnt++ ) fossil_print("%12s---- meaning #%d ----\n", " ", cnt); | |
| 1064 | - whatis_rid(db_column_int(&q, 0), verboseFlag); | |
| 1065 | - } | |
| 1066 | - db_finalize(&q); | |
| 1067 | - }else if( rid==0 ){ | |
| 1068 | - /* 0123456789 12 */ | |
| 1069 | - fossil_print("unknown: %s\n", zName); | |
| 1070 | - }else{ | |
| 1071 | - fossil_print("name: %s\n", zName); | |
| 1072 | - whatis_rid(rid, verboseFlag); | |
| 1090 | + const char *zName = g.argv[i]; | |
| 1091 | + if( i>2 ) fossil_print("%.79c\n",'-'); | |
| 1092 | + if( fileFlag ){ | |
| 1093 | + Blob in; | |
| 1094 | + Blob hash = empty_blob; | |
| 1095 | + const char *zHash; | |
| 1096 | + /* Always follow symlinks (when applicable) */ | |
| 1097 | + blob_read_from_file(&in, zName, ExtFILE); | |
| 1098 | + | |
| 1099 | + /* First check the auxiliary hash to see if there is already an artifact | |
| 1100 | + ** that uses the auxiliary hash name */ | |
| 1101 | + hname_hash(&in, 1, &hash); | |
| 1102 | + zHash = (const char*)blob_str(&hash); | |
| 1103 | + if( fast_uuid_to_rid(zHash)==0 ){ | |
| 1104 | + /* No existing artifact with the auxiliary hash name. Therefore, use | |
| 1105 | + ** the primary hash name. */ | |
| 1106 | + blob_reset(&hash); | |
| 1107 | + hname_hash(&in, 0, &hash); | |
| 1108 | + zHash = (const char*)blob_str(&hash); | |
| 1109 | + } | |
| 1110 | + whatis_artifact(zHash, zName, zType, verboseFlag); | |
| 1111 | + blob_reset(&hash); | |
| 1112 | + }else{ | |
| 1113 | + whatis_artifact(zName, 0, zType, verboseFlag); | |
| 1073 | 1114 | } |
| 1074 | 1115 | } |
| 1075 | 1116 | } |
| 1076 | 1117 | |
| 1077 | 1118 | /* |
| 1078 | 1119 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -1015,10 +1015,47 @@ | |
| 1015 | " FROM description WHERE rid=%d", rid); |
| 1016 | fossil_print("%s\n", zDesc); |
| 1017 | fossil_free(zDesc); |
| 1018 | } |
| 1019 | } |
| 1020 | |
| 1021 | /* |
| 1022 | ** COMMAND: whatis* |
| 1023 | ** |
| 1024 | ** Usage: %fossil whatis NAME |
| @@ -1027,51 +1064,55 @@ | |
| 1027 | ** artifact name and provide a description of what role that artifact |
| 1028 | ** plays. |
| 1029 | ** |
| 1030 | ** Options: |
| 1031 | ** |
| 1032 | ** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't', |
| 1033 | ** 'w', 'g', or 'e') |
| 1034 | ** -v|--verbose Provide extra information (such as the RID) |
| 1035 | */ |
| 1036 | void whatis_cmd(void){ |
| 1037 | int rid; |
| 1038 | const char *zName; |
| 1039 | int verboseFlag; |
| 1040 | int i; |
| 1041 | const char *zType = 0; |
| 1042 | db_find_and_open_repository(0,0); |
| 1043 | verboseFlag = find_option("verbose","v",0)!=0; |
| 1044 | zType = find_option("type",0,1); |
| 1045 | |
| 1046 | /* We should be done with options.. */ |
| 1047 | verify_all_options(); |
| 1048 | |
| 1049 | if( g.argc<3 ) usage("NAME ..."); |
| 1050 | for(i=2; i<g.argc; i++){ |
| 1051 | zName = g.argv[i]; |
| 1052 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 1053 | rid = symbolic_name_to_rid(zName, zType); |
| 1054 | if( rid<0 ){ |
| 1055 | Stmt q; |
| 1056 | int cnt = 0; |
| 1057 | fossil_print("name: %s (ambiguous)\n", zName); |
| 1058 | db_prepare(&q, |
| 1059 | "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", |
| 1060 | zName, zName |
| 1061 | ); |
| 1062 | while( db_step(&q)==SQLITE_ROW ){ |
| 1063 | if( cnt++ ) fossil_print("%12s---- meaning #%d ----\n", " ", cnt); |
| 1064 | whatis_rid(db_column_int(&q, 0), verboseFlag); |
| 1065 | } |
| 1066 | db_finalize(&q); |
| 1067 | }else if( rid==0 ){ |
| 1068 | /* 0123456789 12 */ |
| 1069 | fossil_print("unknown: %s\n", zName); |
| 1070 | }else{ |
| 1071 | fossil_print("name: %s\n", zName); |
| 1072 | whatis_rid(rid, verboseFlag); |
| 1073 | } |
| 1074 | } |
| 1075 | } |
| 1076 | |
| 1077 | /* |
| 1078 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -1015,10 +1015,47 @@ | |
| 1015 | " FROM description WHERE rid=%d", rid); |
| 1016 | fossil_print("%s\n", zDesc); |
| 1017 | fossil_free(zDesc); |
| 1018 | } |
| 1019 | } |
| 1020 | |
| 1021 | /* |
| 1022 | ** Generate a description of artifact from it symbolic name. |
| 1023 | */ |
| 1024 | void whatis_artifact( |
| 1025 | const char *zName, /* Symbolic name or full hash */ |
| 1026 | const char *zFileName,/* Optional: original filename (in file mode) */ |
| 1027 | const char *zType, /* Artifact type filter */ |
| 1028 | int verboseFlag /* Verbosity flag */ |
| 1029 | ){ |
| 1030 | const char* zNameTitle = "name:"; |
| 1031 | int rid = symbolic_name_to_rid(zName, zType); |
| 1032 | if( zFileName ){ |
| 1033 | fossil_print("%-12s%s\n", zNameTitle, zFileName); |
| 1034 | zNameTitle = "hash:"; |
| 1035 | } |
| 1036 | if( rid<0 ){ |
| 1037 | Stmt q; |
| 1038 | int cnt = 0; |
| 1039 | fossil_print("%-12s%s (ambiguous)\n", zNameTitle, zName); |
| 1040 | db_prepare(&q, |
| 1041 | "SELECT rid FROM blob WHERE uuid>=lower(%Q) AND uuid<(lower(%Q)||'z')", |
| 1042 | zName, zName |
| 1043 | ); |
| 1044 | while( db_step(&q)==SQLITE_ROW ){ |
| 1045 | if( cnt++ ) fossil_print("%12s---- meaning #%d ----\n", " ", cnt); |
| 1046 | whatis_rid(db_column_int(&q, 0), verboseFlag); |
| 1047 | } |
| 1048 | db_finalize(&q); |
| 1049 | }else if( rid==0 ){ |
| 1050 | /* 0123456789 12 */ |
| 1051 | fossil_print("unknown: %s\n", zName); |
| 1052 | }else{ |
| 1053 | fossil_print("%-12s%s\n", zNameTitle, zName); |
| 1054 | whatis_rid(rid, verboseFlag); |
| 1055 | } |
| 1056 | } |
| 1057 | |
| 1058 | /* |
| 1059 | ** COMMAND: whatis* |
| 1060 | ** |
| 1061 | ** Usage: %fossil whatis NAME |
| @@ -1027,51 +1064,55 @@ | |
| 1064 | ** artifact name and provide a description of what role that artifact |
| 1065 | ** plays. |
| 1066 | ** |
| 1067 | ** Options: |
| 1068 | ** |
| 1069 | ** -f|--file Find artifacts with same hash as file NAME. |
| 1070 | ** (if NAME is "-", read from standard input) |
| 1071 | ** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't', |
| 1072 | ** 'w', 'g', or 'e') |
| 1073 | ** -v|--verbose Provide extra information (such as the RID) |
| 1074 | */ |
| 1075 | void whatis_cmd(void){ |
| 1076 | int verboseFlag; |
| 1077 | int fileFlag; |
| 1078 | int i; |
| 1079 | const char *zType = 0; |
| 1080 | db_find_and_open_repository(0,0); |
| 1081 | verboseFlag = find_option("verbose","v",0)!=0; |
| 1082 | fileFlag = find_option("file","f",0)!=0; |
| 1083 | zType = find_option("type",0,1); |
| 1084 | |
| 1085 | /* We should be done with options.. */ |
| 1086 | verify_all_options(); |
| 1087 | |
| 1088 | if( g.argc<3 ) usage("NAME ..."); |
| 1089 | for(i=2; i<g.argc; i++){ |
| 1090 | const char *zName = g.argv[i]; |
| 1091 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 1092 | if( fileFlag ){ |
| 1093 | Blob in; |
| 1094 | Blob hash = empty_blob; |
| 1095 | const char *zHash; |
| 1096 | /* Always follow symlinks (when applicable) */ |
| 1097 | blob_read_from_file(&in, zName, ExtFILE); |
| 1098 | |
| 1099 | /* First check the auxiliary hash to see if there is already an artifact |
| 1100 | ** that uses the auxiliary hash name */ |
| 1101 | hname_hash(&in, 1, &hash); |
| 1102 | zHash = (const char*)blob_str(&hash); |
| 1103 | if( fast_uuid_to_rid(zHash)==0 ){ |
| 1104 | /* No existing artifact with the auxiliary hash name. Therefore, use |
| 1105 | ** the primary hash name. */ |
| 1106 | blob_reset(&hash); |
| 1107 | hname_hash(&in, 0, &hash); |
| 1108 | zHash = (const char*)blob_str(&hash); |
| 1109 | } |
| 1110 | whatis_artifact(zHash, zName, zType, verboseFlag); |
| 1111 | blob_reset(&hash); |
| 1112 | }else{ |
| 1113 | whatis_artifact(zName, 0, zType, verboseFlag); |
| 1114 | } |
| 1115 | } |
| 1116 | } |
| 1117 | |
| 1118 | /* |
| 1119 |