cargo: git error `invalid data in index` with index.skipHash config
Problem
before 1.68, this worked:
# be in a git repository
$ git init .
# create a junk commit (required; any history)
$ touch x && git add x && git commit -m x
$ mkdir -p a/b && cd a/b
# grab a rust project, that does not have a git repository in it (github tag tarball, .crate, ...)
$ curl https://github.com/sharkdp/hyperfine/archive/refs/tags/v1.16.0.tar.gz | tar -xz --strip-components=1
# build the project somehow
$ cargo build
however, since 1.68, you now get:
>>> hyperfine: Unpacking /var/cache/distfiles/hyperfine-1.16.0.tar.gz...
error: failed to determine package fingerprint for build script for hyperfine v1.16.0 (/home/demon/src/aports/community/hyperfine/src/hyperfine-1.16.0)
Caused by:
failed to determine the most recently modified file in /home/demon/src/aports/community/hyperfine/src/hyperfine-1.16.0
Caused by:
failed to determine list of files in /home/demon/src/aports/community/hyperfine/src/hyperfine-1.16.0
Caused by:
failed to open git index at /home/demon/src/aports/.git/
Caused by:
invalid data in index - calculated checksum does not match expected; class=Index (10)
>>> ERROR: hyperfine: build failed
of course, there is a workaround:
git init .inside the source directory
however, i’m not sure if it’s necessarily “correct” to break here, or why that is the case.
Steps
# be in a git repository
$ git init .
# create a junk commit (required; any history)
$ touch x && git add x && git commit -m x
$ mkdir -p a/b && cd a/b
# grab a rust project, that does not have a git repository in it (github tag tarball, .crate, ...)
$ curl https://github.com/sharkdp/hyperfine/archive/refs/tags/v1.16.0.tar.gz | tar -xz --strip-components=1
# build the project somehow
$ cargo build
Possible Solution(s)
revert to old behaviour? i don’t know the semantics for why this is the case now.
Notes
for background, the reason why the build is in an arbitrary git repository is because it is ran inside a ports tree (alpine linux aports in this case), and that is inside git.
as an aside (does not impact the above), GIT_CEILING_DIRECTORIES is set to prevent actual access to the repository metadata (versioning), but it does not affect this issue (whether it is set or not).
my question is- is there a reason cargo now ‘requires’ git to be clean/new or not exist to succeed and fails inside an existing repository?
Version
$ cargo version --verbose
cargo 1.68.0
release: 1.68.0
host: x86_64-alpine-linux-musl
libgit2: 1.5.0 (sys:0.16.0 vendored)
libcurl: 7.88.1 (sys:0.4.59+curl-7.86.0 system ssl:OpenSSL/3.1.0)
os: Alpine Linux 3.18_alpha20230208 [64-bit]
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 7
- Comments: 15 (7 by maintainers)
Commits related to this issue
- Don't set git config `features.manyFiles` on post install This reverts #31408, as it also sets the git config value `index.skipHash` which breaks cargo at the moment: https://github.com/rust-lang/car... — committed to vercel/next.js by wbinnssmith a year ago
- Don't set git config `features.manyFiles` on post install (#47375) This reverts #31408, as it also sets the git config value `index.skipHash` which breaks cargo at the moment: https://github.com/ru... — committed to vercel/next.js by wbinnssmith a year ago
I had a repo I really didn’t want to clone fresh. Running
git reset --mixedafter disablingfeature.manyFilesfixed my repo. Hope it can fix yours to!ok, i figured it out. this seems to actually indeed be the gitconfig.
essentially, my gitconfig had
feature.manyFiles=true. this itself toggles some options.the specific option in this case that causes this failure is
index.skipHash=true. that sounds like it causes the exact error. from the manpage:note that my git version is 2.40.0, but i’m not sure if this is relevant when cargo utilises libgit(?).
an easy reproducer via dockerfile:
Thanks for investigating! I have filed the upstream issue at https://github.com/libgit2/libgit2/issues/6531
i think the ‘earlier than 2.40’ here implies they made a breaking change in 2.40. since cargo is using libgit, it has not prepared to handle the error yet, and fails with the above. makes sense for a start?
it’s to do with the current ‘state’. the moment you enable it, some hashes will be in that intentionally slightly broken state (because stuff gets regenerated)- you’d have to probably run some very specific commands to get it into a ‘pure’ state again that doesn’t fail. cloning just starts fresh anew. (in very wishy-washy non-technical terms)
if i change only to alpine:3.17 with git 2.38.4, the failure goes away. almost for sure git then…
I encountered the same issue for helix although I am not in a nested repository. I tested with the latest commit on helix https://github.com/helix-editor/helix/commit/583f6a1337590e0f55d7a3bbf8a79fa65202df65.
Maybe it’s a different issue?