Preserve indexed executable modes in WASI git
This commit is contained in:
@@ -238,6 +238,22 @@ pub fn status(repo: &gix::Repository) -> Result<Status> {
|
||||
.map_err(|e| error("status", e))?;
|
||||
for item in iter {
|
||||
let item = item.map_err(|e| error("status", e))?;
|
||||
#[cfg(target_os = "wasi")]
|
||||
if matches!(
|
||||
&item,
|
||||
Item::Modification {
|
||||
status: gix::status::plumbing::index_as_worktree::EntryStatus::Change(
|
||||
gix::status::plumbing::index_as_worktree::Change::Modification {
|
||||
executable_bit_changed: true,
|
||||
content_change: None,
|
||||
..
|
||||
}
|
||||
),
|
||||
..
|
||||
}
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
let path = item.rela_path().to_str_lossy().into_owned();
|
||||
let Some(summary) = item.summary() else {
|
||||
continue;
|
||||
@@ -332,7 +348,7 @@ fn worktree_file(
|
||||
} else {
|
||||
entry.mode
|
||||
};
|
||||
#[cfg(unix)]
|
||||
#[cfg(all(unix, not(target_os = "wasi")))]
|
||||
let mode = if mode != 0o120000 && caps.executable_bit {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
if meta.permissions().mode() & 0o111 != 0 {
|
||||
|
||||
@@ -229,7 +229,7 @@ fn work_entry(
|
||||
Mode::SYMLINK,
|
||||
)
|
||||
} else if m.is_file() {
|
||||
#[cfg(unix)]
|
||||
#[cfg(all(unix, not(target_os = "wasi")))]
|
||||
let mode = {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
if m.permissions().mode() & 0o111 != 0 {
|
||||
@@ -238,7 +238,7 @@ fn work_entry(
|
||||
Mode::FILE
|
||||
}
|
||||
};
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(any(not(unix), target_os = "wasi"))]
|
||||
let mode = if previous == Some(Mode::FILE_EXECUTABLE) {
|
||||
Mode::FILE_EXECUTABLE
|
||||
} else {
|
||||
|
||||
@@ -268,6 +268,24 @@ def main [component: path] {
|
||||
print $'($args | str join " "): (if $equal {"PASS documented usage"} else {"FAIL documented usage"}) wasi=($result.exit_code)'
|
||||
if not $equal { $failures += 1; print ($result | to json) }
|
||||
}
|
||||
# WASI checkout and staging retain an existing executable file's indexed mode.
|
||||
let executable = ($root | path join executable)
|
||||
mkdir $executable
|
||||
^git -C $executable init -q -b main
|
||||
"#!/bin/sh\necho executable\n" | save ($executable | path join run.sh)
|
||||
^chmod +x ($executable | path join run.sh)
|
||||
^git -C $executable add run.sh
|
||||
^git -C $executable commit --no-gpg-sign -q -m executable
|
||||
rm ($executable | path join run.sh)
|
||||
mut executable_ok = true
|
||||
for args in [[checkout -q HEAD -- run.sh] [status --short] [diff] [add run.sh] [diff --cached] [status --short]] {
|
||||
let result = (^wasmtime run -S http=y -S cli-exit-with-code=y --dir $'($executable)::/mode' $component -C /mode ...$args | complete)
|
||||
if $result.exit_code != 0 or $result.stdout != '' { $executable_ok = false; print ($result | to json) }
|
||||
}
|
||||
let indexed = (^git -C $executable ls-files --stage run.sh | complete)
|
||||
$executable_ok = ($executable_ok and $indexed.exit_code == 0 and ($indexed.stdout | str starts-with '100755 '))
|
||||
print $'executable checkout stays clean: (if $executable_ok {"PASS"} else {"FAIL"})'
|
||||
if not $executable_ok { $failures += 1 }
|
||||
# A merge tree that differs from both parents requires a combined diff.
|
||||
'combined resolution\n' | save --force ($root | path join native/repo/file.txt)
|
||||
let native = ($root | path join native/repo)
|
||||
|
||||
Reference in New Issue
Block a user