From 7777777c2161395b7503810c4776a591688284bb Mon Sep 17 00:00:00 2001 From: HappyOnigiri <253838257+NodeMeld@users.noreply.github.com> Date: Sun, 17 May 2026 17:05:19 +0900 Subject: [PATCH 1/5] =?UTF-8?q?chore:=20Rust=20=E3=83=90=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=82=A2=E3=83=83=E3=83=97=E3=81=AB=E8=BF=BD?= =?UTF-8?q?=E5=BE=93=E3=81=97=20sha1=20crate=20=E3=81=B8=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rust-crypto 0.2 は新しい Rust ツールチェインでビルドできないため sha1 crate 0.10 へ移行。これに伴い Cargo.lock を最新フォーマット (v4) で再生成した。 seahorse は Cargo.toml では ^1.0.0 のまま、Cargo.lock で 1.0.0 に ピン留めする。1.1.2 で Flag::usage() が削除されており、^1.0.0 が 1.1.2 に解決されるとビルドできないため。 --- Cargo.lock | 294 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 146 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b0871d..11565bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,289 +1,285 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 4 + [[package]] name = "aho-corasick" -version = "0.7.8" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ - "memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] -name = "c2-chacha" -version = "0.2.3" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", ] [[package]] name = "cfg-if" -version = "0.1.10" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "commit_artist" version = "1.0.1" dependencies = [ - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "seahorse 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus", + "rand", + "regex", + "seahorse", + "sha1", ] [[package]] -name = "fuchsia-cprng" -version = "0.1.1" +name = "cpufeatures" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] [[package]] -name = "gcc" -version = "0.3.55" +name = "crypto-common" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] [[package]] -name = "getrandom" -version = "0.1.14" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "crypto-common", ] [[package]] -name = "hermit-abi" -version = "0.1.7" +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi", ] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "hermit-abi" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "libc" -version = "0.2.66" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "memchr" -version = "2.3.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "num_cpus" -version = "1.12.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", ] [[package]] name = "ppv-lite86" -version = "0.2.6" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] -name = "rand" -version = "0.3.23" +name = "proc-macro2" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-ident", ] [[package]] -name = "rand" -version = "0.4.6" +name = "quote" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", ] [[package]] name = "rand_chacha" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core", ] [[package]] -name = "rdrand" -version = "0.4.0" +name = "regex" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "redox_syscall" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "regex" -version = "1.3.4" +name = "regex-automata" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ - "aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.14" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] -name = "rust-crypto" -version = "0.2.36" +name = "seahorse" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48badc1e4709936b554463f45691c5c5d667c2203a6872aa4283bc14bed3e9c7" + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "cpufeatures", + "digest", ] [[package]] -name = "rustc-serialize" -version = "0.3.24" +name = "syn" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "seahorse" -version = "1.0.0" +name = "typenum" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] -name = "thread_local" -version = "1.0.1" +name = "unicode-ident" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] -name = "time" -version = "0.1.42" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] -name = "winapi" -version = "0.3.8" +name = "zerocopy" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zerocopy-derive", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "zerocopy-derive" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" -"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" -"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -"checksum hermit-abi 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c55f143919fbc0bc77e427fe2d74cf23786d7c1875666f2fde3ac3c659bb67" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53445de381a1f436797497c61d851644d0e8e88e6140f22872ad33a704933978" -"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" -"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" -"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" -"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum seahorse 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48badc1e4709936b554463f45691c5c5d667c2203a6872aa4283bc14bed3e9c7" -"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 4fbee24..53fdda9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ include = [ [features] [dependencies] -rust-crypto = "^0.2" +sha1 = "0.10" rand ="0.7.3" regex = "^1.3" num_cpus = "1.0" From 7777777e5838e089e1f55e36555f12d949aa358b Mon Sep 17 00:00:00 2001 From: HappyOnigiri <253838257+NodeMeld@users.noreply.github.com> Date: Sun, 17 May 2026 17:05:41 +0900 Subject: [PATCH 2/5] =?UTF-8?q?perf:=20--bench=20=E3=83=95=E3=83=A9?= =?UTF-8?q?=E3=82=B0=E8=BF=BD=E5=8A=A0=EF=BC=88=E3=83=99=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=B3=E8=A8=88=E6=B8=AC=E7=94=A8=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/git/commit_object.rs | 11 +++--- src/main.rs | 75 ++++++++++++++++++++++++++++++++-------- src/settings.rs | 36 +++++++++++++------ 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/src/git/commit_object.rs b/src/git/commit_object.rs index af53f03..88abaa5 100644 --- a/src/git/commit_object.rs +++ b/src/git/commit_object.rs @@ -1,6 +1,6 @@ use super::Gitter; -use crypto::{digest::Digest, sha1::Sha1}; use regex::Regex; +use sha1::{Digest, Sha1}; #[derive(Clone)] pub struct CommitObject { @@ -96,11 +96,10 @@ impl CommitObject { } /// Calculate commit hash - pub fn to_sha1(&self, hasher: &mut Sha1) -> String { - hasher.input_str(&format!("commit {}\0{}", self.bytes(), self)); - let r = hasher.result_str(); - hasher.reset(); - r + pub fn to_sha1(&self) -> String { + let mut hasher = Sha1::new(); + hasher.update(format!("commit {}\0{}", self.bytes(), self).as_bytes()); + format!("{:x}", hasher.finalize()) } } diff --git a/src/main.rs b/src/main.rs index e30cbd6..9fe137c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ mod settings; use crate::external_command as command; use crate::git::commit_object::CommitObject; use crate::settings::Settings; -use crypto::sha1::Sha1; use seahorse::{App, Context, Flag, FlagType}; use std::env; use std::sync::mpsc::channel; @@ -37,6 +36,15 @@ fn main() { .usage("[optional] --jobs 4") .alias("j"), ) + .flag( + Flag::new("force", FlagType::Bool) + .usage("[optional] --force / -f Skip unstaged changes check") + .alias("f"), + ) + .flag( + Flag::new("bench", FlagType::Bool) + .usage("[optional] --bench Measure single-threaded hash rate and exit"), + ) .action(art); app.run(args); @@ -51,7 +59,7 @@ fn art(c: &Context) { } if let Ok(pattern) = c.string_flag("pattern") { - settings.pattern(pattern); + settings.patterns(pattern); } if let Ok(block) = c.int_flag("block") { @@ -62,12 +70,15 @@ fn art(c: &Context) { settings.jobs(jobs as usize); } + let force = c.bool_flag("force"); + let bench_mode = c.bool_flag("bench"); + if command::check().is_err() { println!("git command not found"); return; } - if !command::check_unstaged() { + if !force && !bench_mode && !command::check_unstaged() { println!( "There are unstages changes. You should stash or discard them before running this." ); @@ -82,6 +93,12 @@ fn art(c: &Context) { let latest_cat_file: String = command::cat_file(&settings.path, &latest_commit_hash); let co = CommitObject::parse_cat_file(&latest_cat_file); + + if bench_mode { + bench_hash_rate(&co, settings.jobs); + return; + } + let new_committer_name = bruteforce(settings.clone(), &co, settings.jobs); command::filter_branch(&settings.path, &latest_commit_hash, &new_committer_name); let latest_commit_hash = command::latest_commit_hash(&settings.path); @@ -91,6 +108,42 @@ fn art(c: &Context) { ); } +/// Measure hash rate across `jobs` threads and report aggregate hashes/sec. +fn bench_hash_rate(commit_object: &CommitObject, jobs: usize) { + use std::time::{Duration, Instant}; + + let duration = Duration::from_secs(5); + let start = Instant::now(); // Instant は Copy なのでスレッドにそのまま渡せる + let (tx, rx) = channel::(); + + for i in 0..jobs { + let mut co = commit_object.clone(); + let tx = tx.clone(); + thread::spawn(move || { + co.committer.name.push_str(&i.to_string()); + co.committer.name = co.to_sha1(); + let mut hash = co.to_sha1(); + let mut count: u64 = 0; + while start.elapsed() < duration { + co.committer.name = hash.clone(); + hash = co.to_sha1(); + count += 1; + } + tx.send(count).unwrap(); + }); + } + drop(tx); + let total: u64 = rx.iter().sum(); + let elapsed = start.elapsed().as_secs_f64(); + println!( + "Benchmark ({} threads): {:.2}M hashes/sec ({} hashes in {:.1}s)", + jobs, + total as f64 / elapsed / 1_000_000.0, + total, + elapsed + ); +} + /// Spawn bruteforce thread and catch the result and check it and loop back unless there are no expected result. fn bruteforce(settings: Settings, commit_object: &CommitObject, job_count: usize) -> String { let mut found_hash: String = "".to_owned(); @@ -105,22 +158,14 @@ fn bruteforce(settings: Settings, commit_object: &CommitObject, job_count: usize let mut co = commit_object.clone(); thread::spawn(move || { - let mut hasher = Sha1::new(); - co.committer = { - let mut committer = co.committer; - committer - .name - .push_str(&(iteration_count * job_count + i).to_string()); - committer - }; - co.to_sha1(&mut hasher); - let mut commit_hash = co.to_sha1(&mut hasher); + co.committer.name.push_str(&(iteration_count * job_count + i).to_string()); + let mut commit_hash = co.to_sha1(); for _ in 0..1u64 << settings.block_size { co.committer.name = commit_hash.clone(); let pre = commit_hash.clone(); - commit_hash = co.to_sha1(&mut hasher); - if commit_hash.starts_with(&settings.pattern) { + commit_hash = co.to_sha1(); + if settings.patterns.iter().any(|p| commit_hash.starts_with(p.as_str())) { tx.send(Some(pre)).unwrap(); return; } diff --git a/src/settings.rs b/src/settings.rs index 822dee3..4d54452 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -5,7 +5,7 @@ use regex::Regex; #[derive(Clone)] pub struct Settings { pub path: String, - pub pattern: String, + pub patterns: Vec, pub block_size: usize, pub jobs: usize, } @@ -15,29 +15,43 @@ impl Settings { /// Construct. /// /// # Panics - /// pattern chars length should be 1..=40 + /// patterns is a comma-separated list of hex strings (each 1..=40 chars) /// jobs should be more than 0 /// block size should be less than 64. /// - pub fn new>(path: T, pattern: T, block_size: usize, jobs: usize) -> Self { - let pattern: String = pattern.into(); + pub fn new, Q: Into>(path: P, patterns: Q, block_size: usize, jobs: usize) -> Self { let regx = Regex::new(r"^[0-9a-f]{1,40}$").unwrap(); - assert!(regx.is_match(&pattern)); + let patterns: Vec = patterns + .into() + .split(',') + .map(|p| p.trim().to_owned()) + .collect(); + assert!(!patterns.is_empty()); + for p in &patterns { + assert!(regx.is_match(p)); + } assert!(jobs > 0); assert!(block_size < 64); Self { path: path.into(), - pattern, + patterns, block_size, jobs, } } - pub fn pattern>(&mut self, pattern: T) { - let pattern: String = pattern.into(); + pub fn patterns>(&mut self, patterns: T) { let regx = Regex::new(r"^[0-9a-f]{1,40}$").unwrap(); - assert!(regx.is_match(&pattern)); - self.pattern = pattern; + let parsed: Vec = patterns + .into() + .split(',') + .map(|p| p.trim().to_owned()) + .collect(); + assert!(!parsed.is_empty()); + for p in &parsed { + assert!(regx.is_match(p)); + } + self.patterns = parsed; } pub fn jobs(&mut self, jobs: usize) { @@ -55,7 +69,7 @@ impl Default for Settings { fn default() -> Self { let path: String = command::current_dir_path(); let num = num_cpus::get(); - Self::new(path, "0000000".to_owned(), 20, num - 1) + Self::new(path, "0000000", 20, num - 1) } } From 7777777b2c5c583eff3afd2bb03c977808b7be24 Mon Sep 17 00:00:00 2001 From: HappyOnigiri <253838257+NodeMeld@users.noreply.github.com> Date: Sun, 17 May 2026 14:33:13 +0900 Subject: [PATCH 3/5] =?UTF-8?q?perf:=20SHA1=20midstate=20=E3=81=AB?= =?UTF-8?q?=E3=82=88=E3=82=8B=E5=86=85=E5=81=B4=E3=83=AB=E3=83=BC=E3=83=97?= =?UTF-8?q?=E9=AB=98=E9=80=9F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit prefix("commit N\0...committer ")を一度だけフィードしたハッシャーを クローンして再利用することで、毎イテレーションのハッシュ計算を削減。 --- src/git/commit_object.rs | 35 +++++++++++++++++++++++++++++++++++ src/main.rs | 30 ++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/git/commit_object.rs b/src/git/commit_object.rs index 88abaa5..3654b0a 100644 --- a/src/git/commit_object.rs +++ b/src/git/commit_object.rs @@ -101,6 +101,41 @@ impl CommitObject { hasher.update(format!("commit {}\0{}", self.bytes(), self).as_bytes()); format!("{:x}", hasher.finalize()) } + + /// SHA1 midstate: committer name より前の固定部分を事前にフィードしたハッシャーを返す。 + /// committer.name が 40文字の時点で呼ぶこと(bytes() が安定するため)。 + pub fn prefix_hasher(&self) -> Sha1 { + let prefix = match &self.parent { + Some(parent) => format!( + "commit {}\0tree {}\nparent {}\nauthor {}\ncommitter ", + self.bytes(), + self.tree, + parent, + self.author + ), + None => format!( + "commit {}\0tree {}\nauthor {}\ncommitter ", + self.bytes(), + self.tree, + self.author + ), + }; + let mut hasher = Sha1::new(); + hasher.update(prefix.as_bytes()); + hasher + } + + /// committer name より後の固定部分(suffix)をバイト列で返す。 + pub fn suffix_bytes(&self) -> Vec { + format!( + " <{}@{}> {}\n\n{}", + self.committer.email_user, + self.committer.email_domain, + self.committer.time, + self.message + ) + .into_bytes() + } } // TODO: tests diff --git a/src/main.rs b/src/main.rs index 9fe137c..6b110ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use crate::external_command as command; use crate::git::commit_object::CommitObject; use crate::settings::Settings; use seahorse::{App, Context, Flag, FlagType}; +use sha1::Digest; use std::env; use std::sync::mpsc::channel; use std::thread; @@ -123,10 +124,15 @@ fn bench_hash_rate(commit_object: &CommitObject, jobs: usize) { co.committer.name.push_str(&i.to_string()); co.committer.name = co.to_sha1(); let mut hash = co.to_sha1(); + // midstate: prefix/suffix を一度だけ構築 + let prefix_hasher = co.prefix_hasher(); + let suffix = co.suffix_bytes(); let mut count: u64 = 0; while start.elapsed() < duration { - co.committer.name = hash.clone(); - hash = co.to_sha1(); + let mut h = prefix_hasher.clone(); + h.update(hash.as_bytes()); // 40 bytes (committer name) + h.update(&suffix); + hash = format!("{:x}", h.finalize()); count += 1; } tx.send(count).unwrap(); @@ -158,17 +164,25 @@ fn bruteforce(settings: Settings, commit_object: &CommitObject, job_count: usize let mut co = commit_object.clone(); thread::spawn(move || { + // シードで name を変えて各スレッドの探索空間を分散させる co.committer.name.push_str(&(iteration_count * job_count + i).to_string()); - let mut commit_hash = co.to_sha1(); + let mut commit_hash = co.to_sha1(); // 40文字ハッシュ + + // name が 40文字に確定したので midstate を構築(ループ外で1回のみ) + co.committer.name = commit_hash.clone(); + let prefix_hasher = co.prefix_hasher(); + let suffix = co.suffix_bytes(); for _ in 0..1u64 << settings.block_size { - co.committer.name = commit_hash.clone(); - let pre = commit_hash.clone(); - commit_hash = co.to_sha1(); - if settings.patterns.iter().any(|p| commit_hash.starts_with(p.as_str())) { - tx.send(Some(pre)).unwrap(); + let mut h = prefix_hasher.clone(); + h.update(commit_hash.as_bytes()); // 40 bytes (committer name) + h.update(&suffix); + let next_hash = format!("{:x}", h.finalize()); + if settings.patterns.iter().any(|p| next_hash.starts_with(p)) { + tx.send(Some(commit_hash)).unwrap(); return; } + commit_hash = next_hash; } tx.send(None).unwrap(); }); From 7777777536eaecf231f7cdd05c9aecdfc0c81352 Mon Sep 17 00:00:00 2001 From: HappyOnigiri <253838257+NodeMeld@users.noreply.github.com> Date: Sun, 17 May 2026 14:34:31 +0900 Subject: [PATCH 4/5] =?UTF-8?q?perf:=20AtomicBool=20=E3=81=A7=E4=BB=96?= =?UTF-8?q?=E3=82=B9=E3=83=AC=E3=83=83=E3=83=89=E3=81=B8=E3=81=AE=E6=97=A9?= =?UTF-8?q?=E6=9C=9F=E7=B5=82=E4=BA=86=E3=82=B7=E3=82=B0=E3=83=8A=E3=83=AB?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit マッチ発見時に found フラグを立て、同ブロックの他スレッドが 内側ループの先頭でチェックして即リターンするようにした。 --- src/main.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main.rs b/src/main.rs index 6b110ac..d1cdad9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,9 @@ use crate::settings::Settings; use seahorse::{App, Context, Flag, FlagType}; use sha1::Digest; use std::env; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::channel; +use std::sync::Arc; use std::thread; fn main() { @@ -158,9 +160,13 @@ fn bruteforce(settings: Settings, commit_object: &CommitObject, job_count: usize println!(); while found_hash.is_empty() { + // ブロック内の全スレッドで共有する「発見済み」フラグ + let found = Arc::new(AtomicBool::new(false)); + for i in 0..job_count { let settings: Settings = settings.clone(); let tx = tx.clone(); + let found = Arc::clone(&found); let mut co = commit_object.clone(); thread::spawn(move || { @@ -174,11 +180,17 @@ fn bruteforce(settings: Settings, commit_object: &CommitObject, job_count: usize let suffix = co.suffix_bytes(); for _ in 0..1u64 << settings.block_size { + // 他スレッドが発見済みなら即終了 + if found.load(Ordering::Relaxed) { + tx.send(None).unwrap(); + return; + } let mut h = prefix_hasher.clone(); h.update(commit_hash.as_bytes()); // 40 bytes (committer name) h.update(&suffix); let next_hash = format!("{:x}", h.finalize()); if settings.patterns.iter().any(|p| next_hash.starts_with(p)) { + found.store(true, Ordering::Relaxed); tx.send(Some(commit_hash)).unwrap(); return; } From 7777777bfe111ec6e4c5d41d3a4ce151fa94ff9e Mon Sep 17 00:00:00 2001 From: HappyOnigiri <253838257+NodeMeld@users.noreply.github.com> Date: Sun, 17 May 2026 14:45:27 +0900 Subject: [PATCH 5/5] =?UTF-8?q?perf:=20sha1=20crate=20=E3=81=AE=20asm=20?= =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=BC=E3=83=81=E3=83=A3=E3=83=BC=E3=81=A7?= =?UTF-8?q?=20ARM=20=E3=83=8F=E3=83=BC=E3=83=89=E3=82=A6=E3=82=A7=E3=82=A2?= =?UTF-8?q?=20SHA1=20=E3=82=92=E6=9C=89=E5=8A=B9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple M1 の ARMv8 Crypto Extensions を利用する。 --- Cargo.lock | 32 ++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 11565bd..9de4a50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "cc" +version = "1.2.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -66,6 +76,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "generic-array" version = "0.14.7" @@ -227,8 +243,24 @@ dependencies = [ "cfg-if", "cpufeatures", "digest", + "sha1-asm", ] +[[package]] +name = "sha1-asm" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "286acebaf8b67c1130aedffad26f594eff0c1292389158135327d2e23aed582b" +dependencies = [ + "cc", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "syn" version = "2.0.117" diff --git a/Cargo.toml b/Cargo.toml index 53fdda9..6116d1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ include = [ [features] [dependencies] -sha1 = "0.10" +sha1 = { version = "0.10", features = ["asm"] } rand ="0.7.3" regex = "^1.3" num_cpus = "1.0"