fix(file): handle GNU sparse files and tar crate extraction issues#6380
fix(file): handle GNU sparse files and tar crate extraction issues#6380
Conversation
There was a problem hiding this comment.
Pull Request Overview
Fixes extraction issues with GNU sparse files by implementing a fallback mechanism to system tar when the tar crate fails to handle sparse file formats properly.
- Adds detection for
GNUSparseFile.0directory after tar crate extraction - Implements fallback to system tar command when GNU sparse files are detected
- Maintains existing functionality for regular tar archives while fixing sparse file support
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
src/file.rs
Outdated
| let tar_cmd = if cfg!(target_os = "macos") || cfg!(target_os = "freebsd") { | ||
| "tar" // BSD tar handles sparse files better | ||
| } else { | ||
| "tar" // GNU tar | ||
| }; |
There was a problem hiding this comment.
The conditional logic assigns the same value 'tar' for both branches, making the condition redundant. Either remove the condition or implement platform-specific logic if different tar commands are needed.
| let tar_cmd = if cfg!(target_os = "macos") || cfg!(target_os = "freebsd") { | |
| "tar" // BSD tar handles sparse files better | |
| } else { | |
| "tar" // GNU tar | |
| }; | |
| let tar_cmd = "tar"; |
| } | ||
| // if let Some(pr) = &opts.pr { | ||
| // pr.set_position(total); | ||
| // } | ||
|
|
||
| strip_archive_path_components(dest, opts.strip_components).wrap_err_with(err)?; |
There was a problem hiding this comment.
The strip_archive_path_components function is called after both fallback and regular extraction, but it should only be called for regular extraction since the system tar command already handles --strip-components.
| } | |
| // if let Some(pr) = &opts.pr { | |
| // pr.set_position(total); | |
| // } | |
| strip_archive_path_components(dest, opts.strip_components).wrap_err_with(err)?; | |
| strip_archive_path_components(dest, opts.strip_components).wrap_err_with(err)?; | |
| } |
e46054a to
f7e76ac
Compare
The tar crate doesn't properly handle GNU sparse files, which can result in: 1. Files being extracted to GNUSparseFile.0 directory 2. Corrupted files with sparse metadata prepended This fix: - Checks for GNU sparse files using is_gnu_sparse() during extraction - Falls back to system tar when sparse files are detected - Also checks for GNUSparseFile.0 directory as a secondary detection (needed because some archives don't have the sparse entry type set but still cause the tar crate to extract incorrectly) - Cleans up any partial/corrupted extractions before retrying Fixes extraction issues with tools like tokei that use problematic tar archives. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
f7e76ac to
66cbf56
Compare
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.9.15 x -- echo |
19.8 ± 0.5 | 19.2 | 23.3 | 1.00 |
mise x -- echo |
20.2 ± 0.5 | 19.4 | 24.0 | 1.02 ± 0.03 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.9.15 env |
19.3 ± 0.5 | 18.7 | 24.4 | 1.00 |
mise env |
19.3 ± 0.3 | 18.7 | 20.8 | 1.00 ± 0.03 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.9.15 hook-env |
18.9 ± 0.3 | 18.3 | 20.4 | 1.00 |
mise hook-env |
19.1 ± 0.7 | 18.3 | 28.2 | 1.01 ± 0.04 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.9.15 ls |
16.9 ± 0.4 | 16.2 | 19.3 | 1.00 |
mise ls |
17.0 ± 0.4 | 16.4 | 18.8 | 1.01 ± 0.04 |
xtasks/test/perf
| Command | mise-2025.9.15 | mise | Variance |
|---|---|---|---|
| install (cached) | 170ms | ✅ 105ms | +61% |
| ls (cached) | 65ms | 65ms | +0% |
| bin-paths (cached) | 72ms | 70ms | +2% |
| task-ls (cached) | 496ms | 472ms | +5% |
✅ Performance improvement: install cached is 61%
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
…ponents to system tar
40fb335 to
61970e6
Compare
Summary
GNUSparseFile.0directoriesProblem
The rust tar crate has issues extracting certain tar archives:
GNUSparseFile.0directory instead of the intended locationThis was causing
cargo run test-tool tokeito fail because the tokei binary was being incorrectly extracted.Solution
is_gnu_sparse()GNUSparseFile.0directory (catches cases where sparse type isn't set but tar crate still mishandles the archive)Testing
✅ Verified with
cargo run test-tool tokei- now passes successfully✅ Tested clean installation after
mise uninstall --all tokei✅ Confirmed both detection methods are necessary (some archives need the
GNUSparseFile.0fallback)🤖 Generated with Claude Code