gitでタイプミスした時に出るアレ
かみまみた
% git statsu git: 'statsu' is not a git command. See 'git --help'. Did you mean this? status
これ。
この"Did you mean this?"ってのどうやって出してるのかなって思って、とりあえずgitのソースをgrepしてみたけど(ソースはFri Mar 23 14:50:23 2012 -0700のmaster)
% cd $GIT_SOURCE % grep -rn statsu *
なにもなし。
% grep -rn "Did you mean" * Makefile:2464: echo 2>&1 "Did you mean 'make test'?"; \ help.c:380: fprintf(stderr, "\nDid you mean %s?\n", sha1_name.c:924: "Did you mean '%s:%s' aka '%s:./%s'?", sha1_name.c:961: "Did you mean ':%d:%s'?", sha1_name.c:979: "Did you mean ':%d:%s' aka ':%d:./%s'?", t/t1506-rev-parse-diagnosis.sh:14: Did you mean '$1:$2$3'${2:+ aka $sq$1:./$3$sq}?
help.cっぽい。
この380行目はhelp_unknown_cmd()の最後あたりで、例のメッセージを出している関数のようです。
290 const char *help_unknown_cmd(const char *cmd) 291 { 292 int i, n, best_similarity = 0; 293 struct cmdnames main_cmds, other_cmds; (略) 340 qsort(main_cmds.names, main_cmds.cnt, 341 sizeof(*main_cmds.names), levenshtein_compare); 342 343 if (!main_cmds.cnt) 344 die ("Uh oh. Your system reports no Git commands at all."); 345 346 /* skip and count prefix matches */ 347 for (n = 0; n < main_cmds.cnt && !main_cmds.names[n]->len; n++) 348 ; /* still counting */ 349 350 if (main_cmds.cnt <= n) { 351 /* prefix matches with everything? that is too ambiguous */ 352 best_similarity = SIMILARITY_FLOOR + 1; 353 } else { 354 /* count all the most similar ones */ 355 for (best_similarity = main_cmds.names[n++]->len; 356 (n < main_cmds.cnt && 357 best_similarity == main_cmds.names[n]->len); 358 n++) 359 ; /* still counting */ 360 } (略) 377 fprintf(stderr, "git: '%s' is not a git command. See 'git --help'.\n", cmd); 378 379 if (SIMILAR_ENOUGH(best_similarity)) { 380 fprintf(stderr, "\nDid you mean %s?\n", 381 n < 2 ? "this": "one of these"); 382 383 for (i = 0; i < n; i++) 384 fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); 385 } 386 387 exit(1); 388 }
似てるコマンドを探して、メッセージを出力して終わり。
別に「よくある間違い文字列リスト」みたいなのを全部持っているわけじゃないみたい。そんな辞書あったら面白いかなぁと思ったんだけど。Levenshtein距離を測る関数とかあったから、まあそういうことなんでしょう。