WIP: List the most recent change to each top-level entry in a git tree

glc: list the latest change to each entry of the current git tree

Walks the commit history of a git repository, listing the most recent
commit to change each entry of the initial top-level tree.

Signed-off-by: tjh <x@tjh.dev>
Change-Id: I6a6a6964e3b37227790b42bac4610b3884a7cab5

tjh.dev bf8d29b5

+1
.gitignore
··· 1 + /target
+1715
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 4 4 + 5 + [[package]] 6 + name = "adler2" 7 + version = "2.0.0" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 10 + 11 + [[package]] 12 + name = "anstream" 13 + version = "0.6.19" 14 + source = "registry+https://github.com/rust-lang/crates.io-index" 15 + checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" 16 + dependencies = [ 17 + "anstyle", 18 + "anstyle-parse", 19 + "anstyle-query", 20 + "anstyle-wincon", 21 + "colorchoice", 22 + "is_terminal_polyfill", 23 + "utf8parse", 24 + ] 25 + 26 + [[package]] 27 + name = "anstyle" 28 + version = "1.0.11" 29 + source = "registry+https://github.com/rust-lang/crates.io-index" 30 + checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" 31 + 32 + [[package]] 33 + name = "anstyle-parse" 34 + version = "0.2.7" 35 + source = "registry+https://github.com/rust-lang/crates.io-index" 36 + checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 37 + dependencies = [ 38 + "utf8parse", 39 + ] 40 + 41 + [[package]] 42 + name = "anstyle-query" 43 + version = "1.1.3" 44 + source = "registry+https://github.com/rust-lang/crates.io-index" 45 + checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" 46 + dependencies = [ 47 + "windows-sys", 48 + ] 49 + 50 + [[package]] 51 + name = "anstyle-wincon" 52 + version = "3.0.9" 53 + source = "registry+https://github.com/rust-lang/crates.io-index" 54 + checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" 55 + dependencies = [ 56 + "anstyle", 57 + "once_cell_polyfill", 58 + "windows-sys", 59 + ] 60 + 61 + [[package]] 62 + name = "anyhow" 63 + version = "1.0.98" 64 + source = "registry+https://github.com/rust-lang/crates.io-index" 65 + checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 66 + 67 + [[package]] 68 + name = "arc-swap" 69 + version = "1.7.1" 70 + source = "registry+https://github.com/rust-lang/crates.io-index" 71 + checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" 72 + 73 + [[package]] 74 + name = "autocfg" 75 + version = "1.4.0" 76 + source = "registry+https://github.com/rust-lang/crates.io-index" 77 + checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 78 + 79 + [[package]] 80 + name = "bitflags" 81 + version = "2.9.1" 82 + source = "registry+https://github.com/rust-lang/crates.io-index" 83 + checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 84 + 85 + [[package]] 86 + name = "block-buffer" 87 + version = "0.10.4" 88 + source = "registry+https://github.com/rust-lang/crates.io-index" 89 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 90 + dependencies = [ 91 + "generic-array", 92 + ] 93 + 94 + [[package]] 95 + name = "bstr" 96 + version = "1.12.0" 97 + source = "registry+https://github.com/rust-lang/crates.io-index" 98 + checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" 99 + dependencies = [ 100 + "memchr", 101 + "regex-automata", 102 + "serde", 103 + ] 104 + 105 + [[package]] 106 + name = "byteorder" 107 + version = "1.5.0" 108 + source = "registry+https://github.com/rust-lang/crates.io-index" 109 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 110 + 111 + [[package]] 112 + name = "cfg-if" 113 + version = "1.0.0" 114 + source = "registry+https://github.com/rust-lang/crates.io-index" 115 + checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 116 + 117 + [[package]] 118 + name = "clap" 119 + version = "4.5.39" 120 + source = "registry+https://github.com/rust-lang/crates.io-index" 121 + checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f" 122 + dependencies = [ 123 + "clap_builder", 124 + "clap_derive", 125 + ] 126 + 127 + [[package]] 128 + name = "clap_builder" 129 + version = "4.5.39" 130 + source = "registry+https://github.com/rust-lang/crates.io-index" 131 + checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51" 132 + dependencies = [ 133 + "anstream", 134 + "anstyle", 135 + "clap_lex", 136 + "strsim", 137 + ] 138 + 139 + [[package]] 140 + name = "clap_derive" 141 + version = "4.5.32" 142 + source = "registry+https://github.com/rust-lang/crates.io-index" 143 + checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" 144 + dependencies = [ 145 + "heck", 146 + "proc-macro2", 147 + "quote", 148 + "syn", 149 + ] 150 + 151 + [[package]] 152 + name = "clap_lex" 153 + version = "0.7.4" 154 + source = "registry+https://github.com/rust-lang/crates.io-index" 155 + checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 156 + 157 + [[package]] 158 + name = "clru" 159 + version = "0.6.2" 160 + source = "registry+https://github.com/rust-lang/crates.io-index" 161 + checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" 162 + 163 + [[package]] 164 + name = "colorchoice" 165 + version = "1.0.4" 166 + source = "registry+https://github.com/rust-lang/crates.io-index" 167 + checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 168 + 169 + [[package]] 170 + name = "cpufeatures" 171 + version = "0.2.17" 172 + source = "registry+https://github.com/rust-lang/crates.io-index" 173 + checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 174 + dependencies = [ 175 + "libc", 176 + ] 177 + 178 + [[package]] 179 + name = "crc32fast" 180 + version = "1.4.2" 181 + source = "registry+https://github.com/rust-lang/crates.io-index" 182 + checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 183 + dependencies = [ 184 + "cfg-if", 185 + ] 186 + 187 + [[package]] 188 + name = "crypto-common" 189 + version = "0.1.6" 190 + source = "registry+https://github.com/rust-lang/crates.io-index" 191 + checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 192 + dependencies = [ 193 + "generic-array", 194 + "typenum", 195 + ] 196 + 197 + [[package]] 198 + name = "deranged" 199 + version = "0.4.0" 200 + source = "registry+https://github.com/rust-lang/crates.io-index" 201 + checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" 202 + dependencies = [ 203 + "powerfmt", 204 + ] 205 + 206 + [[package]] 207 + name = "digest" 208 + version = "0.10.7" 209 + source = "registry+https://github.com/rust-lang/crates.io-index" 210 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 211 + dependencies = [ 212 + "block-buffer", 213 + "crypto-common", 214 + ] 215 + 216 + [[package]] 217 + name = "displaydoc" 218 + version = "0.2.5" 219 + source = "registry+https://github.com/rust-lang/crates.io-index" 220 + checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 221 + dependencies = [ 222 + "proc-macro2", 223 + "quote", 224 + "syn", 225 + ] 226 + 227 + [[package]] 228 + name = "dunce" 229 + version = "1.0.5" 230 + source = "registry+https://github.com/rust-lang/crates.io-index" 231 + checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" 232 + 233 + [[package]] 234 + name = "errno" 235 + version = "0.3.12" 236 + source = "registry+https://github.com/rust-lang/crates.io-index" 237 + checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" 238 + dependencies = [ 239 + "libc", 240 + "windows-sys", 241 + ] 242 + 243 + [[package]] 244 + name = "faster-hex" 245 + version = "0.10.0" 246 + source = "registry+https://github.com/rust-lang/crates.io-index" 247 + checksum = "7223ae2d2f179b803433d9c830478527e92b8117eab39460edae7f1614d9fb73" 248 + dependencies = [ 249 + "heapless", 250 + "serde", 251 + ] 252 + 253 + [[package]] 254 + name = "fastrand" 255 + version = "2.3.0" 256 + source = "registry+https://github.com/rust-lang/crates.io-index" 257 + checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 258 + 259 + [[package]] 260 + name = "flate2" 261 + version = "1.1.2" 262 + source = "registry+https://github.com/rust-lang/crates.io-index" 263 + checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" 264 + dependencies = [ 265 + "crc32fast", 266 + "libz-rs-sys", 267 + "miniz_oxide", 268 + ] 269 + 270 + [[package]] 271 + name = "form_urlencoded" 272 + version = "1.2.1" 273 + source = "registry+https://github.com/rust-lang/crates.io-index" 274 + checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 275 + dependencies = [ 276 + "percent-encoding", 277 + ] 278 + 279 + [[package]] 280 + name = "generic-array" 281 + version = "0.14.7" 282 + source = "registry+https://github.com/rust-lang/crates.io-index" 283 + checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 284 + dependencies = [ 285 + "typenum", 286 + "version_check", 287 + ] 288 + 289 + [[package]] 290 + name = "getrandom" 291 + version = "0.3.3" 292 + source = "registry+https://github.com/rust-lang/crates.io-index" 293 + checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 294 + dependencies = [ 295 + "cfg-if", 296 + "libc", 297 + "r-efi", 298 + "wasi", 299 + ] 300 + 301 + [[package]] 302 + name = "gix" 303 + version = "0.72.1" 304 + source = "registry+https://github.com/rust-lang/crates.io-index" 305 + checksum = "01237e8d3d78581f71642be8b0c2ae8c0b2b5c251c9c5d9ebbea3c1ea280dce8" 306 + dependencies = [ 307 + "gix-actor", 308 + "gix-commitgraph", 309 + "gix-config", 310 + "gix-date", 311 + "gix-diff", 312 + "gix-discover", 313 + "gix-features", 314 + "gix-fs", 315 + "gix-glob", 316 + "gix-hash", 317 + "gix-hashtable", 318 + "gix-lock", 319 + "gix-object", 320 + "gix-odb", 321 + "gix-pack", 322 + "gix-path", 323 + "gix-protocol", 324 + "gix-ref", 325 + "gix-refspec", 326 + "gix-revision", 327 + "gix-revwalk", 328 + "gix-sec", 329 + "gix-shallow", 330 + "gix-tempfile", 331 + "gix-trace", 332 + "gix-traverse", 333 + "gix-url", 334 + "gix-utils", 335 + "gix-validate", 336 + "once_cell", 337 + "smallvec", 338 + "thiserror", 339 + ] 340 + 341 + [[package]] 342 + name = "gix-actor" 343 + version = "0.35.1" 344 + source = "registry+https://github.com/rust-lang/crates.io-index" 345 + checksum = "6b300e6e4f31f3f6bd2de5e2b0caab192ced00dc0fcd0f7cc56e28c575c8e1ff" 346 + dependencies = [ 347 + "bstr", 348 + "gix-date", 349 + "gix-utils", 350 + "itoa", 351 + "thiserror", 352 + "winnow", 353 + ] 354 + 355 + [[package]] 356 + name = "gix-chunk" 357 + version = "0.4.11" 358 + source = "registry+https://github.com/rust-lang/crates.io-index" 359 + checksum = "0b1f1d8764958699dc764e3f727cef280ff4d1bd92c107bbf8acd85b30c1bd6f" 360 + dependencies = [ 361 + "thiserror", 362 + ] 363 + 364 + [[package]] 365 + name = "gix-command" 366 + version = "0.6.1" 367 + source = "registry+https://github.com/rust-lang/crates.io-index" 368 + checksum = "d05dd813ef6bb798570308aa7f1245cefa350ec9f30dc53308335eb22b9d0f8b" 369 + dependencies = [ 370 + "bstr", 371 + "gix-path", 372 + "gix-quote", 373 + "gix-trace", 374 + "shell-words", 375 + ] 376 + 377 + [[package]] 378 + name = "gix-commitgraph" 379 + version = "0.28.0" 380 + source = "registry+https://github.com/rust-lang/crates.io-index" 381 + checksum = "e05050fd6caa6c731fe3bd7f9485b3b520be062d3d139cb2626e052d6c127951" 382 + dependencies = [ 383 + "bstr", 384 + "gix-chunk", 385 + "gix-hash", 386 + "memmap2", 387 + "thiserror", 388 + ] 389 + 390 + [[package]] 391 + name = "gix-config" 392 + version = "0.45.1" 393 + source = "registry+https://github.com/rust-lang/crates.io-index" 394 + checksum = "48f3c8f357ae049bfb77493c2ec9010f58cfc924ae485e1116c3718fc0f0d881" 395 + dependencies = [ 396 + "bstr", 397 + "gix-config-value", 398 + "gix-features", 399 + "gix-glob", 400 + "gix-path", 401 + "gix-ref", 402 + "gix-sec", 403 + "memchr", 404 + "once_cell", 405 + "smallvec", 406 + "thiserror", 407 + "unicode-bom", 408 + "winnow", 409 + ] 410 + 411 + [[package]] 412 + name = "gix-config-value" 413 + version = "0.15.0" 414 + source = "registry+https://github.com/rust-lang/crates.io-index" 415 + checksum = "439d62e241dae2dffd55bfeeabe551275cf9d9f084c5ebc6b48bad49d03285b7" 416 + dependencies = [ 417 + "bitflags", 418 + "bstr", 419 + "gix-path", 420 + "libc", 421 + "thiserror", 422 + ] 423 + 424 + [[package]] 425 + name = "gix-date" 426 + version = "0.10.2" 427 + source = "registry+https://github.com/rust-lang/crates.io-index" 428 + checksum = "139d1d52b21741e3f0c72b0fc65e1ff34d4eaceb100ef529d182725d2e09b8cb" 429 + dependencies = [ 430 + "bstr", 431 + "itoa", 432 + "jiff", 433 + "smallvec", 434 + "thiserror", 435 + ] 436 + 437 + [[package]] 438 + name = "gix-diff" 439 + version = "0.52.1" 440 + source = "registry+https://github.com/rust-lang/crates.io-index" 441 + checksum = "5e9b43e95fe352da82a969f0c84ff860c2de3e724d93f6681fedbcd6c917f252" 442 + dependencies = [ 443 + "bstr", 444 + "gix-hash", 445 + "gix-object", 446 + "thiserror", 447 + ] 448 + 449 + [[package]] 450 + name = "gix-discover" 451 + version = "0.40.1" 452 + source = "registry+https://github.com/rust-lang/crates.io-index" 453 + checksum = "dccfe3e25b4ea46083916c56db3ba9d1e6ef6dce54da485f0463f9fc0fe1837c" 454 + dependencies = [ 455 + "bstr", 456 + "dunce", 457 + "gix-fs", 458 + "gix-hash", 459 + "gix-path", 460 + "gix-ref", 461 + "gix-sec", 462 + "thiserror", 463 + ] 464 + 465 + [[package]] 466 + name = "gix-features" 467 + version = "0.42.1" 468 + source = "registry+https://github.com/rust-lang/crates.io-index" 469 + checksum = "56f4399af6ec4fd9db84dd4cf9656c5c785ab492ab40a7c27ea92b4241923fed" 470 + dependencies = [ 471 + "crc32fast", 472 + "flate2", 473 + "gix-path", 474 + "gix-trace", 475 + "gix-utils", 476 + "libc", 477 + "once_cell", 478 + "prodash", 479 + "thiserror", 480 + "walkdir", 481 + ] 482 + 483 + [[package]] 484 + name = "gix-fs" 485 + version = "0.15.0" 486 + source = "registry+https://github.com/rust-lang/crates.io-index" 487 + checksum = "67a0637149b4ef24d3ea55f81f77231401c8463fae6da27331c987957eb597c7" 488 + dependencies = [ 489 + "bstr", 490 + "fastrand", 491 + "gix-features", 492 + "gix-path", 493 + "gix-utils", 494 + "thiserror", 495 + ] 496 + 497 + [[package]] 498 + name = "gix-glob" 499 + version = "0.20.1" 500 + source = "registry+https://github.com/rust-lang/crates.io-index" 501 + checksum = "90181472925b587f6079698f79065ff64786e6d6c14089517a1972bca99fb6e9" 502 + dependencies = [ 503 + "bitflags", 504 + "bstr", 505 + "gix-features", 506 + "gix-path", 507 + ] 508 + 509 + [[package]] 510 + name = "gix-hash" 511 + version = "0.18.0" 512 + source = "registry+https://github.com/rust-lang/crates.io-index" 513 + checksum = "8d4900562c662852a6b42e2ef03442eccebf24f047d8eab4f23bc12ef0d785d8" 514 + dependencies = [ 515 + "faster-hex", 516 + "gix-features", 517 + "sha1-checked", 518 + "thiserror", 519 + ] 520 + 521 + [[package]] 522 + name = "gix-hashtable" 523 + version = "0.8.1" 524 + source = "registry+https://github.com/rust-lang/crates.io-index" 525 + checksum = "b5b5cb3c308b4144f2612ff64e32130e641279fcf1a84d8d40dad843b4f64904" 526 + dependencies = [ 527 + "gix-hash", 528 + "hashbrown", 529 + "parking_lot", 530 + ] 531 + 532 + [[package]] 533 + name = "gix-lock" 534 + version = "17.1.0" 535 + source = "registry+https://github.com/rust-lang/crates.io-index" 536 + checksum = "570f8b034659f256366dc90f1a24924902f20acccd6a15be96d44d1269e7a796" 537 + dependencies = [ 538 + "gix-tempfile", 539 + "gix-utils", 540 + "thiserror", 541 + ] 542 + 543 + [[package]] 544 + name = "gix-object" 545 + version = "0.49.1" 546 + source = "registry+https://github.com/rust-lang/crates.io-index" 547 + checksum = "d957ca3640c555d48bb27f8278c67169fa1380ed94f6452c5590742524c40fbb" 548 + dependencies = [ 549 + "bstr", 550 + "gix-actor", 551 + "gix-date", 552 + "gix-features", 553 + "gix-hash", 554 + "gix-hashtable", 555 + "gix-path", 556 + "gix-utils", 557 + "gix-validate", 558 + "itoa", 559 + "smallvec", 560 + "thiserror", 561 + "winnow", 562 + ] 563 + 564 + [[package]] 565 + name = "gix-odb" 566 + version = "0.69.1" 567 + source = "registry+https://github.com/rust-lang/crates.io-index" 568 + checksum = "868f703905fdbcfc1bd750942f82419903ecb7039f5288adb5206d6de405e0c9" 569 + dependencies = [ 570 + "arc-swap", 571 + "gix-date", 572 + "gix-features", 573 + "gix-fs", 574 + "gix-hash", 575 + "gix-hashtable", 576 + "gix-object", 577 + "gix-pack", 578 + "gix-path", 579 + "gix-quote", 580 + "parking_lot", 581 + "tempfile", 582 + "thiserror", 583 + ] 584 + 585 + [[package]] 586 + name = "gix-pack" 587 + version = "0.59.1" 588 + source = "registry+https://github.com/rust-lang/crates.io-index" 589 + checksum = "9d49c55d69c8449f2a0a5a77eb9cbacfebb6b0e2f1215f0fc23a4cb60528a450" 590 + dependencies = [ 591 + "clru", 592 + "gix-chunk", 593 + "gix-features", 594 + "gix-hash", 595 + "gix-hashtable", 596 + "gix-object", 597 + "gix-path", 598 + "memmap2", 599 + "smallvec", 600 + "thiserror", 601 + ] 602 + 603 + [[package]] 604 + name = "gix-packetline" 605 + version = "0.19.0" 606 + source = "registry+https://github.com/rust-lang/crates.io-index" 607 + checksum = "8ddc034bc67c848e4ef7596ab5528cd8fd439d310858dbe1ce8b324f25deb91c" 608 + dependencies = [ 609 + "bstr", 610 + "faster-hex", 611 + "gix-trace", 612 + "thiserror", 613 + ] 614 + 615 + [[package]] 616 + name = "gix-path" 617 + version = "0.10.18" 618 + source = "registry+https://github.com/rust-lang/crates.io-index" 619 + checksum = "567f65fec4ef10dfab97ae71f26a27fd4d7fe7b8e3f90c8a58551c41ff3fb65b" 620 + dependencies = [ 621 + "bstr", 622 + "gix-trace", 623 + "gix-validate", 624 + "home", 625 + "once_cell", 626 + "thiserror", 627 + ] 628 + 629 + [[package]] 630 + name = "gix-protocol" 631 + version = "0.50.1" 632 + source = "registry+https://github.com/rust-lang/crates.io-index" 633 + checksum = "f5c17d78bb0414f8d60b5f952196dc2e47ec320dca885de9128ecdb4a0e38401" 634 + dependencies = [ 635 + "bstr", 636 + "gix-date", 637 + "gix-features", 638 + "gix-hash", 639 + "gix-ref", 640 + "gix-shallow", 641 + "gix-transport", 642 + "gix-utils", 643 + "maybe-async", 644 + "thiserror", 645 + "winnow", 646 + ] 647 + 648 + [[package]] 649 + name = "gix-quote" 650 + version = "0.6.0" 651 + source = "registry+https://github.com/rust-lang/crates.io-index" 652 + checksum = "4a375a75b4d663e8bafe3bf4940a18a23755644c13582fa326e99f8f987d83fd" 653 + dependencies = [ 654 + "bstr", 655 + "gix-utils", 656 + "thiserror", 657 + ] 658 + 659 + [[package]] 660 + name = "gix-ref" 661 + version = "0.52.1" 662 + source = "registry+https://github.com/rust-lang/crates.io-index" 663 + checksum = "d1b7985657029684d759f656b09abc3e2c73085596d5cdb494428823970a7762" 664 + dependencies = [ 665 + "gix-actor", 666 + "gix-features", 667 + "gix-fs", 668 + "gix-hash", 669 + "gix-lock", 670 + "gix-object", 671 + "gix-path", 672 + "gix-tempfile", 673 + "gix-utils", 674 + "gix-validate", 675 + "memmap2", 676 + "thiserror", 677 + "winnow", 678 + ] 679 + 680 + [[package]] 681 + name = "gix-refspec" 682 + version = "0.30.1" 683 + source = "registry+https://github.com/rust-lang/crates.io-index" 684 + checksum = "445ed14e3db78e8e79980085e3723df94e1c8163b3ae5bc8ed6a8fe6cf983b42" 685 + dependencies = [ 686 + "bstr", 687 + "gix-hash", 688 + "gix-revision", 689 + "gix-validate", 690 + "smallvec", 691 + "thiserror", 692 + ] 693 + 694 + [[package]] 695 + name = "gix-revision" 696 + version = "0.34.1" 697 + source = "registry+https://github.com/rust-lang/crates.io-index" 698 + checksum = "78d0b8e5cbd1c329e25383e088cb8f17439414021a643b30afa5146b71e3c65d" 699 + dependencies = [ 700 + "bstr", 701 + "gix-commitgraph", 702 + "gix-date", 703 + "gix-hash", 704 + "gix-object", 705 + "gix-revwalk", 706 + "thiserror", 707 + ] 708 + 709 + [[package]] 710 + name = "gix-revwalk" 711 + version = "0.20.1" 712 + source = "registry+https://github.com/rust-lang/crates.io-index" 713 + checksum = "1bc756b73225bf005ddeb871d1ca7b3c33e2417d0d53e56effa5a36765b52b28" 714 + dependencies = [ 715 + "gix-commitgraph", 716 + "gix-date", 717 + "gix-hash", 718 + "gix-hashtable", 719 + "gix-object", 720 + "smallvec", 721 + "thiserror", 722 + ] 723 + 724 + [[package]] 725 + name = "gix-sec" 726 + version = "0.11.0" 727 + source = "registry+https://github.com/rust-lang/crates.io-index" 728 + checksum = "d0dabbc78c759ecc006b970339394951b2c8e1e38a37b072c105b80b84c308fd" 729 + dependencies = [ 730 + "bitflags", 731 + "gix-path", 732 + "libc", 733 + "windows-sys", 734 + ] 735 + 736 + [[package]] 737 + name = "gix-shallow" 738 + version = "0.4.0" 739 + source = "registry+https://github.com/rust-lang/crates.io-index" 740 + checksum = "6b9a6f6e34d6ede08f522d89e5c7990b4f60524b8ae6ebf8e850963828119ad4" 741 + dependencies = [ 742 + "bstr", 743 + "gix-hash", 744 + "gix-lock", 745 + "thiserror", 746 + ] 747 + 748 + [[package]] 749 + name = "gix-tempfile" 750 + version = "17.1.0" 751 + source = "registry+https://github.com/rust-lang/crates.io-index" 752 + checksum = "c750e8c008453a2dba67a2b0d928b7716e05da31173a3f5e351d5457ad4470aa" 753 + dependencies = [ 754 + "gix-fs", 755 + "libc", 756 + "once_cell", 757 + "parking_lot", 758 + "tempfile", 759 + ] 760 + 761 + [[package]] 762 + name = "gix-trace" 763 + version = "0.1.12" 764 + source = "registry+https://github.com/rust-lang/crates.io-index" 765 + checksum = "7c396a2036920c69695f760a65e7f2677267ccf483f25046977d87e4cb2665f7" 766 + 767 + [[package]] 768 + name = "gix-transport" 769 + version = "0.47.0" 770 + source = "registry+https://github.com/rust-lang/crates.io-index" 771 + checksum = "edfe22ba26d4b65c17879f12b9882eafe65d3c8611c933b272fce2c10f546f59" 772 + dependencies = [ 773 + "bstr", 774 + "gix-command", 775 + "gix-features", 776 + "gix-packetline", 777 + "gix-quote", 778 + "gix-sec", 779 + "gix-url", 780 + "thiserror", 781 + ] 782 + 783 + [[package]] 784 + name = "gix-traverse" 785 + version = "0.46.2" 786 + source = "registry+https://github.com/rust-lang/crates.io-index" 787 + checksum = "b8648172f85aca3d6e919c06504b7ac26baef54e04c55eb0100fa588c102cc33" 788 + dependencies = [ 789 + "bitflags", 790 + "gix-commitgraph", 791 + "gix-date", 792 + "gix-hash", 793 + "gix-hashtable", 794 + "gix-object", 795 + "gix-revwalk", 796 + "smallvec", 797 + "thiserror", 798 + ] 799 + 800 + [[package]] 801 + name = "gix-url" 802 + version = "0.31.0" 803 + source = "registry+https://github.com/rust-lang/crates.io-index" 804 + checksum = "42a1ad0b04a5718b5cb233e6888e52a9b627846296161d81dcc5eb9203ec84b8" 805 + dependencies = [ 806 + "bstr", 807 + "gix-features", 808 + "gix-path", 809 + "percent-encoding", 810 + "thiserror", 811 + "url", 812 + ] 813 + 814 + [[package]] 815 + name = "gix-utils" 816 + version = "0.3.0" 817 + source = "registry+https://github.com/rust-lang/crates.io-index" 818 + checksum = "5351af2b172caf41a3728eb4455326d84e0d70fe26fc4de74ab0bd37df4191c5" 819 + dependencies = [ 820 + "fastrand", 821 + "unicode-normalization", 822 + ] 823 + 824 + [[package]] 825 + name = "gix-validate" 826 + version = "0.10.0" 827 + source = "registry+https://github.com/rust-lang/crates.io-index" 828 + checksum = "77b9e00cacde5b51388d28ed746c493b18a6add1f19b5e01d686b3b9ece66d4d" 829 + dependencies = [ 830 + "bstr", 831 + "thiserror", 832 + ] 833 + 834 + [[package]] 835 + name = "glc" 836 + version = "0.1.0" 837 + dependencies = [ 838 + "anyhow", 839 + "clap", 840 + "gix", 841 + "time", 842 + ] 843 + 844 + [[package]] 845 + name = "hash32" 846 + version = "0.3.1" 847 + source = "registry+https://github.com/rust-lang/crates.io-index" 848 + checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" 849 + dependencies = [ 850 + "byteorder", 851 + ] 852 + 853 + [[package]] 854 + name = "hashbrown" 855 + version = "0.14.5" 856 + source = "registry+https://github.com/rust-lang/crates.io-index" 857 + checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 858 + 859 + [[package]] 860 + name = "heapless" 861 + version = "0.8.0" 862 + source = "registry+https://github.com/rust-lang/crates.io-index" 863 + checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" 864 + dependencies = [ 865 + "hash32", 866 + "stable_deref_trait", 867 + ] 868 + 869 + [[package]] 870 + name = "heck" 871 + version = "0.5.0" 872 + source = "registry+https://github.com/rust-lang/crates.io-index" 873 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 874 + 875 + [[package]] 876 + name = "home" 877 + version = "0.5.11" 878 + source = "registry+https://github.com/rust-lang/crates.io-index" 879 + checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 880 + dependencies = [ 881 + "windows-sys", 882 + ] 883 + 884 + [[package]] 885 + name = "icu_collections" 886 + version = "2.0.0" 887 + source = "registry+https://github.com/rust-lang/crates.io-index" 888 + checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" 889 + dependencies = [ 890 + "displaydoc", 891 + "potential_utf", 892 + "yoke", 893 + "zerofrom", 894 + "zerovec", 895 + ] 896 + 897 + [[package]] 898 + name = "icu_locale_core" 899 + version = "2.0.0" 900 + source = "registry+https://github.com/rust-lang/crates.io-index" 901 + checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" 902 + dependencies = [ 903 + "displaydoc", 904 + "litemap", 905 + "tinystr", 906 + "writeable", 907 + "zerovec", 908 + ] 909 + 910 + [[package]] 911 + name = "icu_normalizer" 912 + version = "2.0.0" 913 + source = "registry+https://github.com/rust-lang/crates.io-index" 914 + checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" 915 + dependencies = [ 916 + "displaydoc", 917 + "icu_collections", 918 + "icu_normalizer_data", 919 + "icu_properties", 920 + "icu_provider", 921 + "smallvec", 922 + "zerovec", 923 + ] 924 + 925 + [[package]] 926 + name = "icu_normalizer_data" 927 + version = "2.0.0" 928 + source = "registry+https://github.com/rust-lang/crates.io-index" 929 + checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" 930 + 931 + [[package]] 932 + name = "icu_properties" 933 + version = "2.0.1" 934 + source = "registry+https://github.com/rust-lang/crates.io-index" 935 + checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" 936 + dependencies = [ 937 + "displaydoc", 938 + "icu_collections", 939 + "icu_locale_core", 940 + "icu_properties_data", 941 + "icu_provider", 942 + "potential_utf", 943 + "zerotrie", 944 + "zerovec", 945 + ] 946 + 947 + [[package]] 948 + name = "icu_properties_data" 949 + version = "2.0.1" 950 + source = "registry+https://github.com/rust-lang/crates.io-index" 951 + checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" 952 + 953 + [[package]] 954 + name = "icu_provider" 955 + version = "2.0.0" 956 + source = "registry+https://github.com/rust-lang/crates.io-index" 957 + checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" 958 + dependencies = [ 959 + "displaydoc", 960 + "icu_locale_core", 961 + "stable_deref_trait", 962 + "tinystr", 963 + "writeable", 964 + "yoke", 965 + "zerofrom", 966 + "zerotrie", 967 + "zerovec", 968 + ] 969 + 970 + [[package]] 971 + name = "idna" 972 + version = "1.0.3" 973 + source = "registry+https://github.com/rust-lang/crates.io-index" 974 + checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 975 + dependencies = [ 976 + "idna_adapter", 977 + "smallvec", 978 + "utf8_iter", 979 + ] 980 + 981 + [[package]] 982 + name = "idna_adapter" 983 + version = "1.2.1" 984 + source = "registry+https://github.com/rust-lang/crates.io-index" 985 + checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" 986 + dependencies = [ 987 + "icu_normalizer", 988 + "icu_properties", 989 + ] 990 + 991 + [[package]] 992 + name = "is_terminal_polyfill" 993 + version = "1.70.1" 994 + source = "registry+https://github.com/rust-lang/crates.io-index" 995 + checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 996 + 997 + [[package]] 998 + name = "itoa" 999 + version = "1.0.15" 1000 + source = "registry+https://github.com/rust-lang/crates.io-index" 1001 + checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 1002 + 1003 + [[package]] 1004 + name = "jiff" 1005 + version = "0.2.14" 1006 + source = "registry+https://github.com/rust-lang/crates.io-index" 1007 + checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93" 1008 + dependencies = [ 1009 + "jiff-static", 1010 + "jiff-tzdb-platform", 1011 + "log", 1012 + "portable-atomic", 1013 + "portable-atomic-util", 1014 + "serde", 1015 + "windows-sys", 1016 + ] 1017 + 1018 + [[package]] 1019 + name = "jiff-static" 1020 + version = "0.2.14" 1021 + source = "registry+https://github.com/rust-lang/crates.io-index" 1022 + checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442" 1023 + dependencies = [ 1024 + "proc-macro2", 1025 + "quote", 1026 + "syn", 1027 + ] 1028 + 1029 + [[package]] 1030 + name = "jiff-tzdb" 1031 + version = "0.1.4" 1032 + source = "registry+https://github.com/rust-lang/crates.io-index" 1033 + checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" 1034 + 1035 + [[package]] 1036 + name = "jiff-tzdb-platform" 1037 + version = "0.1.3" 1038 + source = "registry+https://github.com/rust-lang/crates.io-index" 1039 + checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" 1040 + dependencies = [ 1041 + "jiff-tzdb", 1042 + ] 1043 + 1044 + [[package]] 1045 + name = "libc" 1046 + version = "0.2.172" 1047 + source = "registry+https://github.com/rust-lang/crates.io-index" 1048 + checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 1049 + 1050 + [[package]] 1051 + name = "libz-rs-sys" 1052 + version = "0.5.1" 1053 + source = "registry+https://github.com/rust-lang/crates.io-index" 1054 + checksum = "172a788537a2221661b480fee8dc5f96c580eb34fa88764d3205dc356c7e4221" 1055 + dependencies = [ 1056 + "zlib-rs", 1057 + ] 1058 + 1059 + [[package]] 1060 + name = "linux-raw-sys" 1061 + version = "0.9.4" 1062 + source = "registry+https://github.com/rust-lang/crates.io-index" 1063 + checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" 1064 + 1065 + [[package]] 1066 + name = "litemap" 1067 + version = "0.8.0" 1068 + source = "registry+https://github.com/rust-lang/crates.io-index" 1069 + checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" 1070 + 1071 + [[package]] 1072 + name = "lock_api" 1073 + version = "0.4.13" 1074 + source = "registry+https://github.com/rust-lang/crates.io-index" 1075 + checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" 1076 + dependencies = [ 1077 + "autocfg", 1078 + "scopeguard", 1079 + ] 1080 + 1081 + [[package]] 1082 + name = "log" 1083 + version = "0.4.27" 1084 + source = "registry+https://github.com/rust-lang/crates.io-index" 1085 + checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 1086 + 1087 + [[package]] 1088 + name = "maybe-async" 1089 + version = "0.2.10" 1090 + source = "registry+https://github.com/rust-lang/crates.io-index" 1091 + checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" 1092 + dependencies = [ 1093 + "proc-macro2", 1094 + "quote", 1095 + "syn", 1096 + ] 1097 + 1098 + [[package]] 1099 + name = "memchr" 1100 + version = "2.7.4" 1101 + source = "registry+https://github.com/rust-lang/crates.io-index" 1102 + checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1103 + 1104 + [[package]] 1105 + name = "memmap2" 1106 + version = "0.9.5" 1107 + source = "registry+https://github.com/rust-lang/crates.io-index" 1108 + checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" 1109 + dependencies = [ 1110 + "libc", 1111 + ] 1112 + 1113 + [[package]] 1114 + name = "miniz_oxide" 1115 + version = "0.8.8" 1116 + source = "registry+https://github.com/rust-lang/crates.io-index" 1117 + checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 1118 + dependencies = [ 1119 + "adler2", 1120 + ] 1121 + 1122 + [[package]] 1123 + name = "num-conv" 1124 + version = "0.1.0" 1125 + source = "registry+https://github.com/rust-lang/crates.io-index" 1126 + checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 1127 + 1128 + [[package]] 1129 + name = "once_cell" 1130 + version = "1.21.3" 1131 + source = "registry+https://github.com/rust-lang/crates.io-index" 1132 + checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 1133 + 1134 + [[package]] 1135 + name = "once_cell_polyfill" 1136 + version = "1.70.1" 1137 + source = "registry+https://github.com/rust-lang/crates.io-index" 1138 + checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" 1139 + 1140 + [[package]] 1141 + name = "parking_lot" 1142 + version = "0.12.4" 1143 + source = "registry+https://github.com/rust-lang/crates.io-index" 1144 + checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" 1145 + dependencies = [ 1146 + "lock_api", 1147 + "parking_lot_core", 1148 + ] 1149 + 1150 + [[package]] 1151 + name = "parking_lot_core" 1152 + version = "0.9.11" 1153 + source = "registry+https://github.com/rust-lang/crates.io-index" 1154 + checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" 1155 + dependencies = [ 1156 + "cfg-if", 1157 + "libc", 1158 + "redox_syscall", 1159 + "smallvec", 1160 + "windows-targets", 1161 + ] 1162 + 1163 + [[package]] 1164 + name = "percent-encoding" 1165 + version = "2.3.1" 1166 + source = "registry+https://github.com/rust-lang/crates.io-index" 1167 + checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1168 + 1169 + [[package]] 1170 + name = "portable-atomic" 1171 + version = "1.11.1" 1172 + source = "registry+https://github.com/rust-lang/crates.io-index" 1173 + checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" 1174 + 1175 + [[package]] 1176 + name = "portable-atomic-util" 1177 + version = "0.2.4" 1178 + source = "registry+https://github.com/rust-lang/crates.io-index" 1179 + checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" 1180 + dependencies = [ 1181 + "portable-atomic", 1182 + ] 1183 + 1184 + [[package]] 1185 + name = "potential_utf" 1186 + version = "0.1.2" 1187 + source = "registry+https://github.com/rust-lang/crates.io-index" 1188 + checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" 1189 + dependencies = [ 1190 + "zerovec", 1191 + ] 1192 + 1193 + [[package]] 1194 + name = "powerfmt" 1195 + version = "0.2.0" 1196 + source = "registry+https://github.com/rust-lang/crates.io-index" 1197 + checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1198 + 1199 + [[package]] 1200 + name = "proc-macro2" 1201 + version = "1.0.95" 1202 + source = "registry+https://github.com/rust-lang/crates.io-index" 1203 + checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 1204 + dependencies = [ 1205 + "unicode-ident", 1206 + ] 1207 + 1208 + [[package]] 1209 + name = "prodash" 1210 + version = "29.0.2" 1211 + source = "registry+https://github.com/rust-lang/crates.io-index" 1212 + checksum = "f04bb108f648884c23b98a0e940ebc2c93c0c3b89f04dbaf7eb8256ce617d1bc" 1213 + dependencies = [ 1214 + "log", 1215 + "parking_lot", 1216 + ] 1217 + 1218 + [[package]] 1219 + name = "quote" 1220 + version = "1.0.40" 1221 + source = "registry+https://github.com/rust-lang/crates.io-index" 1222 + checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 1223 + dependencies = [ 1224 + "proc-macro2", 1225 + ] 1226 + 1227 + [[package]] 1228 + name = "r-efi" 1229 + version = "5.2.0" 1230 + source = "registry+https://github.com/rust-lang/crates.io-index" 1231 + checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" 1232 + 1233 + [[package]] 1234 + name = "redox_syscall" 1235 + version = "0.5.12" 1236 + source = "registry+https://github.com/rust-lang/crates.io-index" 1237 + checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" 1238 + dependencies = [ 1239 + "bitflags", 1240 + ] 1241 + 1242 + [[package]] 1243 + name = "regex-automata" 1244 + version = "0.4.9" 1245 + source = "registry+https://github.com/rust-lang/crates.io-index" 1246 + checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1247 + 1248 + [[package]] 1249 + name = "rustix" 1250 + version = "1.0.7" 1251 + source = "registry+https://github.com/rust-lang/crates.io-index" 1252 + checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" 1253 + dependencies = [ 1254 + "bitflags", 1255 + "errno", 1256 + "libc", 1257 + "linux-raw-sys", 1258 + "windows-sys", 1259 + ] 1260 + 1261 + [[package]] 1262 + name = "same-file" 1263 + version = "1.0.6" 1264 + source = "registry+https://github.com/rust-lang/crates.io-index" 1265 + checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1266 + dependencies = [ 1267 + "winapi-util", 1268 + ] 1269 + 1270 + [[package]] 1271 + name = "scopeguard" 1272 + version = "1.2.0" 1273 + source = "registry+https://github.com/rust-lang/crates.io-index" 1274 + checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1275 + 1276 + [[package]] 1277 + name = "serde" 1278 + version = "1.0.219" 1279 + source = "registry+https://github.com/rust-lang/crates.io-index" 1280 + checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1281 + dependencies = [ 1282 + "serde_derive", 1283 + ] 1284 + 1285 + [[package]] 1286 + name = "serde_derive" 1287 + version = "1.0.219" 1288 + source = "registry+https://github.com/rust-lang/crates.io-index" 1289 + checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1290 + dependencies = [ 1291 + "proc-macro2", 1292 + "quote", 1293 + "syn", 1294 + ] 1295 + 1296 + [[package]] 1297 + name = "sha1" 1298 + version = "0.10.6" 1299 + source = "registry+https://github.com/rust-lang/crates.io-index" 1300 + checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1301 + dependencies = [ 1302 + "cfg-if", 1303 + "cpufeatures", 1304 + "digest", 1305 + ] 1306 + 1307 + [[package]] 1308 + name = "sha1-checked" 1309 + version = "0.10.0" 1310 + source = "registry+https://github.com/rust-lang/crates.io-index" 1311 + checksum = "89f599ac0c323ebb1c6082821a54962b839832b03984598375bff3975b804423" 1312 + dependencies = [ 1313 + "digest", 1314 + "sha1", 1315 + ] 1316 + 1317 + [[package]] 1318 + name = "shell-words" 1319 + version = "1.1.0" 1320 + source = "registry+https://github.com/rust-lang/crates.io-index" 1321 + checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" 1322 + 1323 + [[package]] 1324 + name = "smallvec" 1325 + version = "1.15.1" 1326 + source = "registry+https://github.com/rust-lang/crates.io-index" 1327 + checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 1328 + 1329 + [[package]] 1330 + name = "stable_deref_trait" 1331 + version = "1.2.0" 1332 + source = "registry+https://github.com/rust-lang/crates.io-index" 1333 + checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1334 + 1335 + [[package]] 1336 + name = "strsim" 1337 + version = "0.11.1" 1338 + source = "registry+https://github.com/rust-lang/crates.io-index" 1339 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1340 + 1341 + [[package]] 1342 + name = "syn" 1343 + version = "2.0.101" 1344 + source = "registry+https://github.com/rust-lang/crates.io-index" 1345 + checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 1346 + dependencies = [ 1347 + "proc-macro2", 1348 + "quote", 1349 + "unicode-ident", 1350 + ] 1351 + 1352 + [[package]] 1353 + name = "synstructure" 1354 + version = "0.13.2" 1355 + source = "registry+https://github.com/rust-lang/crates.io-index" 1356 + checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" 1357 + dependencies = [ 1358 + "proc-macro2", 1359 + "quote", 1360 + "syn", 1361 + ] 1362 + 1363 + [[package]] 1364 + name = "tempfile" 1365 + version = "3.20.0" 1366 + source = "registry+https://github.com/rust-lang/crates.io-index" 1367 + checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" 1368 + dependencies = [ 1369 + "fastrand", 1370 + "getrandom", 1371 + "once_cell", 1372 + "rustix", 1373 + "windows-sys", 1374 + ] 1375 + 1376 + [[package]] 1377 + name = "thiserror" 1378 + version = "2.0.12" 1379 + source = "registry+https://github.com/rust-lang/crates.io-index" 1380 + checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 1381 + dependencies = [ 1382 + "thiserror-impl", 1383 + ] 1384 + 1385 + [[package]] 1386 + name = "thiserror-impl" 1387 + version = "2.0.12" 1388 + source = "registry+https://github.com/rust-lang/crates.io-index" 1389 + checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 1390 + dependencies = [ 1391 + "proc-macro2", 1392 + "quote", 1393 + "syn", 1394 + ] 1395 + 1396 + [[package]] 1397 + name = "time" 1398 + version = "0.3.41" 1399 + source = "registry+https://github.com/rust-lang/crates.io-index" 1400 + checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" 1401 + dependencies = [ 1402 + "deranged", 1403 + "itoa", 1404 + "num-conv", 1405 + "powerfmt", 1406 + "serde", 1407 + "time-core", 1408 + "time-macros", 1409 + ] 1410 + 1411 + [[package]] 1412 + name = "time-core" 1413 + version = "0.1.4" 1414 + source = "registry+https://github.com/rust-lang/crates.io-index" 1415 + checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" 1416 + 1417 + [[package]] 1418 + name = "time-macros" 1419 + version = "0.2.22" 1420 + source = "registry+https://github.com/rust-lang/crates.io-index" 1421 + checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" 1422 + dependencies = [ 1423 + "num-conv", 1424 + "time-core", 1425 + ] 1426 + 1427 + [[package]] 1428 + name = "tinystr" 1429 + version = "0.8.1" 1430 + source = "registry+https://github.com/rust-lang/crates.io-index" 1431 + checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" 1432 + dependencies = [ 1433 + "displaydoc", 1434 + "zerovec", 1435 + ] 1436 + 1437 + [[package]] 1438 + name = "tinyvec" 1439 + version = "1.9.0" 1440 + source = "registry+https://github.com/rust-lang/crates.io-index" 1441 + checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" 1442 + dependencies = [ 1443 + "tinyvec_macros", 1444 + ] 1445 + 1446 + [[package]] 1447 + name = "tinyvec_macros" 1448 + version = "0.1.1" 1449 + source = "registry+https://github.com/rust-lang/crates.io-index" 1450 + checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1451 + 1452 + [[package]] 1453 + name = "typenum" 1454 + version = "1.18.0" 1455 + source = "registry+https://github.com/rust-lang/crates.io-index" 1456 + checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 1457 + 1458 + [[package]] 1459 + name = "unicode-bom" 1460 + version = "2.0.3" 1461 + source = "registry+https://github.com/rust-lang/crates.io-index" 1462 + checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" 1463 + 1464 + [[package]] 1465 + name = "unicode-ident" 1466 + version = "1.0.18" 1467 + source = "registry+https://github.com/rust-lang/crates.io-index" 1468 + checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1469 + 1470 + [[package]] 1471 + name = "unicode-normalization" 1472 + version = "0.1.24" 1473 + source = "registry+https://github.com/rust-lang/crates.io-index" 1474 + checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" 1475 + dependencies = [ 1476 + "tinyvec", 1477 + ] 1478 + 1479 + [[package]] 1480 + name = "url" 1481 + version = "2.5.4" 1482 + source = "registry+https://github.com/rust-lang/crates.io-index" 1483 + checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1484 + dependencies = [ 1485 + "form_urlencoded", 1486 + "idna", 1487 + "percent-encoding", 1488 + ] 1489 + 1490 + [[package]] 1491 + name = "utf8_iter" 1492 + version = "1.0.4" 1493 + source = "registry+https://github.com/rust-lang/crates.io-index" 1494 + checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1495 + 1496 + [[package]] 1497 + name = "utf8parse" 1498 + version = "0.2.2" 1499 + source = "registry+https://github.com/rust-lang/crates.io-index" 1500 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1501 + 1502 + [[package]] 1503 + name = "version_check" 1504 + version = "0.9.5" 1505 + source = "registry+https://github.com/rust-lang/crates.io-index" 1506 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1507 + 1508 + [[package]] 1509 + name = "walkdir" 1510 + version = "2.5.0" 1511 + source = "registry+https://github.com/rust-lang/crates.io-index" 1512 + checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 1513 + dependencies = [ 1514 + "same-file", 1515 + "winapi-util", 1516 + ] 1517 + 1518 + [[package]] 1519 + name = "wasi" 1520 + version = "0.14.2+wasi-0.2.4" 1521 + source = "registry+https://github.com/rust-lang/crates.io-index" 1522 + checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 1523 + dependencies = [ 1524 + "wit-bindgen-rt", 1525 + ] 1526 + 1527 + [[package]] 1528 + name = "winapi-util" 1529 + version = "0.1.9" 1530 + source = "registry+https://github.com/rust-lang/crates.io-index" 1531 + checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 1532 + dependencies = [ 1533 + "windows-sys", 1534 + ] 1535 + 1536 + [[package]] 1537 + name = "windows-sys" 1538 + version = "0.59.0" 1539 + source = "registry+https://github.com/rust-lang/crates.io-index" 1540 + checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1541 + dependencies = [ 1542 + "windows-targets", 1543 + ] 1544 + 1545 + [[package]] 1546 + name = "windows-targets" 1547 + version = "0.52.6" 1548 + source = "registry+https://github.com/rust-lang/crates.io-index" 1549 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1550 + dependencies = [ 1551 + "windows_aarch64_gnullvm", 1552 + "windows_aarch64_msvc", 1553 + "windows_i686_gnu", 1554 + "windows_i686_gnullvm", 1555 + "windows_i686_msvc", 1556 + "windows_x86_64_gnu", 1557 + "windows_x86_64_gnullvm", 1558 + "windows_x86_64_msvc", 1559 + ] 1560 + 1561 + [[package]] 1562 + name = "windows_aarch64_gnullvm" 1563 + version = "0.52.6" 1564 + source = "registry+https://github.com/rust-lang/crates.io-index" 1565 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1566 + 1567 + [[package]] 1568 + name = "windows_aarch64_msvc" 1569 + version = "0.52.6" 1570 + source = "registry+https://github.com/rust-lang/crates.io-index" 1571 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1572 + 1573 + [[package]] 1574 + name = "windows_i686_gnu" 1575 + version = "0.52.6" 1576 + source = "registry+https://github.com/rust-lang/crates.io-index" 1577 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1578 + 1579 + [[package]] 1580 + name = "windows_i686_gnullvm" 1581 + version = "0.52.6" 1582 + source = "registry+https://github.com/rust-lang/crates.io-index" 1583 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1584 + 1585 + [[package]] 1586 + name = "windows_i686_msvc" 1587 + version = "0.52.6" 1588 + source = "registry+https://github.com/rust-lang/crates.io-index" 1589 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1590 + 1591 + [[package]] 1592 + name = "windows_x86_64_gnu" 1593 + version = "0.52.6" 1594 + source = "registry+https://github.com/rust-lang/crates.io-index" 1595 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1596 + 1597 + [[package]] 1598 + name = "windows_x86_64_gnullvm" 1599 + version = "0.52.6" 1600 + source = "registry+https://github.com/rust-lang/crates.io-index" 1601 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1602 + 1603 + [[package]] 1604 + name = "windows_x86_64_msvc" 1605 + version = "0.52.6" 1606 + source = "registry+https://github.com/rust-lang/crates.io-index" 1607 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1608 + 1609 + [[package]] 1610 + name = "winnow" 1611 + version = "0.7.10" 1612 + source = "registry+https://github.com/rust-lang/crates.io-index" 1613 + checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" 1614 + dependencies = [ 1615 + "memchr", 1616 + ] 1617 + 1618 + [[package]] 1619 + name = "wit-bindgen-rt" 1620 + version = "0.39.0" 1621 + source = "registry+https://github.com/rust-lang/crates.io-index" 1622 + checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 1623 + dependencies = [ 1624 + "bitflags", 1625 + ] 1626 + 1627 + [[package]] 1628 + name = "writeable" 1629 + version = "0.6.1" 1630 + source = "registry+https://github.com/rust-lang/crates.io-index" 1631 + checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" 1632 + 1633 + [[package]] 1634 + name = "yoke" 1635 + version = "0.8.0" 1636 + source = "registry+https://github.com/rust-lang/crates.io-index" 1637 + checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" 1638 + dependencies = [ 1639 + "serde", 1640 + "stable_deref_trait", 1641 + "yoke-derive", 1642 + "zerofrom", 1643 + ] 1644 + 1645 + [[package]] 1646 + name = "yoke-derive" 1647 + version = "0.8.0" 1648 + source = "registry+https://github.com/rust-lang/crates.io-index" 1649 + checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" 1650 + dependencies = [ 1651 + "proc-macro2", 1652 + "quote", 1653 + "syn", 1654 + "synstructure", 1655 + ] 1656 + 1657 + [[package]] 1658 + name = "zerofrom" 1659 + version = "0.1.6" 1660 + source = "registry+https://github.com/rust-lang/crates.io-index" 1661 + checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 1662 + dependencies = [ 1663 + "zerofrom-derive", 1664 + ] 1665 + 1666 + [[package]] 1667 + name = "zerofrom-derive" 1668 + version = "0.1.6" 1669 + source = "registry+https://github.com/rust-lang/crates.io-index" 1670 + checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 1671 + dependencies = [ 1672 + "proc-macro2", 1673 + "quote", 1674 + "syn", 1675 + "synstructure", 1676 + ] 1677 + 1678 + [[package]] 1679 + name = "zerotrie" 1680 + version = "0.2.2" 1681 + source = "registry+https://github.com/rust-lang/crates.io-index" 1682 + checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" 1683 + dependencies = [ 1684 + "displaydoc", 1685 + "yoke", 1686 + "zerofrom", 1687 + ] 1688 + 1689 + [[package]] 1690 + name = "zerovec" 1691 + version = "0.11.2" 1692 + source = "registry+https://github.com/rust-lang/crates.io-index" 1693 + checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" 1694 + dependencies = [ 1695 + "yoke", 1696 + "zerofrom", 1697 + "zerovec-derive", 1698 + ] 1699 + 1700 + [[package]] 1701 + name = "zerovec-derive" 1702 + version = "0.11.1" 1703 + source = "registry+https://github.com/rust-lang/crates.io-index" 1704 + checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" 1705 + dependencies = [ 1706 + "proc-macro2", 1707 + "quote", 1708 + "syn", 1709 + ] 1710 + 1711 + [[package]] 1712 + name = "zlib-rs" 1713 + version = "0.5.1" 1714 + source = "registry+https://github.com/rust-lang/crates.io-index" 1715 + checksum = "626bd9fa9734751fc50d6060752170984d7053f5a39061f524cda68023d4db8a"
+18
Cargo.toml
··· 1 + [package] 2 + name = "glc" 3 + version = "0.1.0" 4 + authors = ["tjh <x@tjh.dev>"] 5 + license = "MIT" 6 + edition = "2024" 7 + rust-version = "1.85" 8 + publish = false 9 + 10 + [dependencies] 11 + anyhow = "1.0.98" 12 + clap = { version = "4.5.39", features = ["derive"] } 13 + gix = { version = "0.72.1", default-features = false } 14 + time = { version = "0.3.41", features = ["formatting"] } 15 + 16 + [profile.release] 17 + strip = true 18 + lto = "fat"
+3
README.md
··· 1 + # git-latest-change 2 + 3 + Prints the most recent change to each top-level entry in a git repository.
+48
deny.toml
··· 1 + [graph] 2 + targets = [ 3 + "x86_64-unknown-linux-gnu" 4 + ] 5 + all-features = false 6 + no-default-features = false 7 + 8 + [output] 9 + feature-depth = 1 10 + 11 + [advisories] 12 + ignore = [] 13 + 14 + [licenses] 15 + confidence-threshold = 0.9 16 + allow = [ 17 + "Apache-2.0", 18 + "MIT", 19 + "Unicode-3.0", 20 + "Zlib" 21 + ] 22 + 23 + [licenses.private] 24 + ignore = true 25 + registries = [] 26 + 27 + [bans] 28 + multiple-versions = "warn" 29 + wildcards = "allow" 30 + highlight = "all" 31 + workspace-default-features = "allow" 32 + external-default-features = "allow" 33 + allow = [] 34 + deny = [] 35 + 36 + skip = [] 37 + skip-tree = [] 38 + 39 + [sources] 40 + unknown-registry = "warn" 41 + unknown-git = "warn" 42 + allow-registry = ["https://github.com/rust-lang/crates.io-index"] 43 + allow-git = [] 44 + 45 + [sources.allow-org] 46 + github = [] 47 + gitlab = [] 48 + bitbucket = []
+25
src/cli.rs
··· 1 + use clap::{Parser, ValueHint}; 2 + use std::path::PathBuf; 3 + 4 + pub fn parse() -> Arguments { 5 + Arguments::parse() 6 + } 7 + 8 + #[derive(Parser)] 9 + pub struct Arguments { 10 + /// Commit, tag, or branch to start scanning from. 11 + #[arg(long, value_name = "from-revspec", default_value = "HEAD")] 12 + pub from: String, 13 + 14 + /// Optional commit, tag, or branch to stop scanning. 15 + #[arg(long, value_name = "to-revspec")] 16 + pub to: Option<String>, 17 + 18 + /// Convert timestamps to UTC. 19 + #[arg{long}] 20 + pub utc: bool, 21 + 22 + /// Path to the git repository. 23 + #[arg(value_hint = ValueHint::DirPath, default_value = ".")] 24 + pub repository_path: PathBuf, 25 + }
+235
src/main.rs
··· 1 + use anyhow::Context as _; 2 + use gix::Commit; 3 + use gix::ObjectId; 4 + use gix::Repository; 5 + use gix::bstr::BStr; 6 + use gix::date::Time; 7 + use gix::object::tree::EntryRef; 8 + use gix::objs::decode::Error as DecodeError; 9 + use gix::revision::walk::Sorting; 10 + use gix::traverse::commit::simple::CommitTimeOrder; 11 + use std::collections::HashSet; 12 + 13 + mod cli; 14 + 15 + fn main() -> anyhow::Result<()> { 16 + let arguments = cli::parse(); 17 + let repository = gix::open(arguments.repository_path)?; 18 + 19 + let mut current_commit = repository.resolve_revspec(&arguments.from)?; 20 + let current_tree = current_commit 21 + .tree() 22 + .context("Failed to get tree for initial commit")?; 23 + 24 + // Build a set of the entry file names we are interested in. 25 + let mut interested: HashSet<_> = Default::default(); 26 + for entry in current_tree.iter() { 27 + interested.insert(entry?.filename().to_owned()); 28 + } 29 + 30 + let name_pad = interested 31 + .iter() 32 + .fold(0, |len, filename| std::cmp::max(len, filename.len())); 33 + 34 + let mut rev_walk = repository 35 + .rev_walk([current_commit.id]) 36 + .use_commit_graph(true) 37 + .first_parent_only() 38 + .sorting(Sorting::ByCommitTime(CommitTimeOrder::NewestFirst)); 39 + 40 + if let Some(boundary) = arguments.to { 41 + let stop_commit = repository.resolve_revspec(&boundary)?; 42 + rev_walk = rev_walk.with_boundary([stop_commit.id]); 43 + } 44 + 45 + for revision in rev_walk.all()? { 46 + if interested.is_empty() { 47 + break; 48 + } 49 + 50 + let revision = revision?; 51 + let Some(&parent_id) = revision.parent_ids.first() else { 52 + break; 53 + }; 54 + 55 + let parent_commit = repository 56 + .find_commit(parent_id) 57 + .context("Failed to find parent commit")?; 58 + let parent_tree = parent_commit 59 + .tree() 60 + .context("Failed to retrieve parent tree")?; 61 + 62 + let mut scanner = EntryScanner::new(current_tree.iter(), parent_tree.iter())?; 63 + while let Some(change) = scanner.next_change()? { 64 + if interested.remove(change.filename()) { 65 + let id = revision.id; 66 + println!( 67 + "{:<name_pad$}\t{id}\t{}\t{}", 68 + change.filename().to_string(), 69 + format_ts(&current_commit.time()?, arguments.utc)?, 70 + current_commit.message()?.summary(), 71 + ); 72 + } 73 + } 74 + 75 + current_commit = parent_commit; 76 + } 77 + 78 + Ok(()) 79 + } 80 + 81 + struct EntryScanner<'repo, 'a, C, P> { 82 + current_tree: C, 83 + parent_tree: P, 84 + current_entry: Option<EntryRef<'repo, 'a>>, 85 + parent_entry: Option<EntryRef<'repo, 'a>>, 86 + } 87 + 88 + impl<'repo, 'a, C, P> EntryScanner<'repo, 'a, C, P> 89 + where 90 + C: Iterator<Item = Result<EntryRef<'repo, 'a>, DecodeError>>, 91 + P: Iterator<Item = Result<EntryRef<'repo, 'a>, DecodeError>>, 92 + { 93 + pub fn new(current_tree: C, parent_tree: P) -> Result<Self, DecodeError> { 94 + let mut this = Self { 95 + current_tree, 96 + parent_tree, 97 + current_entry: None, 98 + parent_entry: None, 99 + }; 100 + 101 + this.advance_both()?; 102 + Ok(this) 103 + } 104 + 105 + fn advance_current(&mut self) -> Result<Option<EntryRef<'repo, 'a>>, DecodeError> { 106 + let old = self.current_entry.take(); 107 + self.current_entry = self.current_tree.next().transpose()?; 108 + Ok(old) 109 + } 110 + 111 + fn advance_parent(&mut self) -> Result<Option<EntryRef<'repo, 'a>>, DecodeError> { 112 + let old = self.parent_entry.take(); 113 + self.parent_entry = self.parent_tree.next().transpose()?; 114 + Ok(old) 115 + } 116 + 117 + fn advance_both( 118 + &mut self, 119 + ) -> Result<(Option<EntryRef<'repo, 'a>>, Option<EntryRef<'repo, 'a>>), DecodeError> { 120 + Ok((self.advance_current()?, self.advance_parent()?)) 121 + } 122 + 123 + pub fn is_complete(&self) -> bool { 124 + self.current_entry.is_none() && self.parent_entry.is_none() 125 + } 126 + 127 + /// Get the next change between the two trees. 128 + pub fn next_change(&mut self) -> Result<Option<Change<'a>>, DecodeError> { 129 + while !self.is_complete() { 130 + match (&self.current_entry, &self.parent_entry) { 131 + (None, None) => break, 132 + (Some(head_entry), Some(parent_entry)) 133 + if head_entry.filename() == parent_entry.filename() => 134 + { 135 + if head_entry.id() != parent_entry.id() { 136 + return Ok(self 137 + .advance_both()? 138 + .0 139 + .map(|entry| Change::Modify(entry.detach()))); 140 + } 141 + self.advance_both()?; 142 + continue; 143 + } 144 + (Some(head_entry), Some(parent_entry)) => { 145 + if head_entry.filename() < parent_entry.filename() { 146 + return Ok(self 147 + .advance_current()? 148 + .map(|entry| Change::Create(entry.detach()))); 149 + } else { 150 + return Ok(self 151 + .advance_parent()? 152 + .map(|entry| Change::Delete(entry.detach()))); 153 + } 154 + } 155 + (Some(_), None) => { 156 + // Entry was created by the current commit. 157 + return Ok(self 158 + .advance_current()? 159 + .map(|entry| Change::Create(entry.detach()))); 160 + } 161 + (None, Some(_)) => { 162 + // Entry was deleted by the current commit. 163 + return Ok(self 164 + .advance_parent()? 165 + .map(|entry| Change::Delete(entry.detach()))); 166 + } 167 + } 168 + } 169 + 170 + Ok(None) 171 + } 172 + } 173 + 174 + #[derive(Debug)] 175 + pub enum Change<'a> { 176 + Create(gix::objs::tree::EntryRef<'a>), 177 + Modify(gix::objs::tree::EntryRef<'a>), 178 + Delete(gix::objs::tree::EntryRef<'a>), 179 + } 180 + 181 + impl<'a> Change<'a> { 182 + pub fn filename(&self) -> &BStr { 183 + match self { 184 + Self::Create(entry) => entry.filename, 185 + Self::Modify(entry) => entry.filename, 186 + Self::Delete(entry) => entry.filename, 187 + } 188 + } 189 + } 190 + 191 + fn format_ts(time: &Time, utc: bool) -> anyhow::Result<String> { 192 + use time::OffsetDateTime; 193 + use time::UtcOffset; 194 + use time::format_description::well_known::Rfc3339; 195 + 196 + let odt = OffsetDateTime::from_unix_timestamp(time.seconds)? 197 + .to_offset(UtcOffset::from_whole_seconds(time.offset)?); 198 + 199 + let formatted = match utc { 200 + true => odt.to_utc().format(&Rfc3339)?, 201 + false => odt.format(&Rfc3339)?, 202 + }; 203 + 204 + Ok(formatted) 205 + } 206 + 207 + trait ResolveRevSpec { 208 + type Error; 209 + /// Resolve a commit ID, reference, or symbolic reference to a [`Commit`]. 210 + fn resolve_revspec<'repo>(&'repo self, spec: &str) -> Result<Commit<'repo>, Self::Error>; 211 + } 212 + 213 + impl ResolveRevSpec for Repository { 214 + type Error = anyhow::Error; 215 + fn resolve_revspec<'repo>(&'repo self, spec: &str) -> Result<Commit<'repo>, Self::Error> { 216 + use std::str::FromStr; 217 + 218 + let resolved = match ObjectId::from_str(spec) { 219 + Ok(id) => self 220 + .find_commit(id) 221 + .context("Failed to find commit in repository")?, 222 + Err(_) => { 223 + let id = self 224 + .find_reference(spec) 225 + .context("Failed to resolve reference in repository {}")? 226 + .into_fully_peeled_id()?; 227 + 228 + self.find_commit(id) 229 + .context("Failed to find commit in repository")? 230 + } 231 + }; 232 + 233 + Ok(resolved) 234 + } 235 + }