forked from git/git
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[NEW FEATURE] make git-for-windows supports posix file mode bits in WSL's way #4438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
name: Windows Nano Server tests | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
env: | ||
DEVELOPER: 1 | ||
|
||
jobs: | ||
test-nano-server: | ||
runs-on: windows-2022 | ||
env: | ||
WINDBG_DIR: "C:/Program Files (x86)/Windows Kits/10/Debuggers/x64" | ||
IMAGE: mcr.microsoft.com/powershell:nanoserver-ltsc2022 | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: git-for-windows/setup-git-for-windows-sdk@v1 | ||
- name: build Git | ||
shell: bash | ||
run: make -j15 | ||
- name: pull nanoserver image | ||
shell: bash | ||
run: docker pull $IMAGE | ||
- name: run nano-server test | ||
shell: bash | ||
run: | | ||
docker run \ | ||
--user "ContainerAdministrator" \ | ||
-v "$WINDBG_DIR:C:/dbg" \ | ||
-v "$(cygpath -aw /mingw64/bin):C:/mingw64-bin" \ | ||
-v "$(cygpath -aw .):C:/test" \ | ||
$IMAGE pwsh.exe -Command ' | ||
# Extend the PATH to include the `.dll` files in /mingw64/bin/ | ||
$env:PATH += ";C:\mingw64-bin" | ||
|
||
# For each executable to test pick some no-operation set of | ||
# flags/subcommands or something that should quickly result in an | ||
# error with known exit code that is not a negative 32-bit | ||
# number, and set the expected return code appropriately. | ||
# | ||
# Only test executables that could be expected to run in a UI | ||
# less environment. | ||
# | ||
# ( Executable path, arguments, expected return code ) | ||
# also note space is required before close parenthesis (a | ||
# powershell quirk when defining nested arrays like this) | ||
|
||
$executables_to_test = @( | ||
("C:\test\git.exe", "", 1 ), | ||
("C:\test\scalar.exe", "version", 0 ) | ||
) | ||
|
||
foreach ($executable in $executables_to_test) | ||
{ | ||
Write-Output "Now testing $($executable[0])" | ||
&$executable[0] $executable[1] | ||
if ($LASTEXITCODE -ne $executable[2]) { | ||
# if we failed, run the debugger to find out what function | ||
# or DLL could not be found and then exit the script with | ||
# failure The missing DLL or EXE will be referenced near | ||
# the end of the output | ||
|
||
# Set a flag to have the debugger show loader stub | ||
# diagnostics. This requires running as administrator, | ||
# otherwise the flag will be ignored. | ||
C:\dbg\gflags -i $executable[0] +SLS | ||
|
||
C:\dbg\cdb.exe -c "g" -c "q" $executable[0] $executable[1] | ||
|
||
exit 1 | ||
} | ||
} | ||
|
||
exit 0 | ||
' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
#include "../../git-compat-util.h" | ||
#include "../win32.h" | ||
#include "../../repository.h" | ||
#include "config.h" | ||
#include "ntifs.h" | ||
#include "wsl.h" | ||
|
||
int are_wsl_compatible_mode_bits_enabled(void) | ||
{ | ||
/* default to `false` during initialization */ | ||
static const int fallback = 0; | ||
static int enabled = -1; | ||
|
||
if (enabled < 0) { | ||
/* avoid infinite recursion */ | ||
if (!the_repository) | ||
return fallback; | ||
|
||
if (the_repository->config && | ||
the_repository->config->hash_initialized && | ||
git_config_get_bool("core.wslcompat", &enabled) < 0) | ||
enabled = 0; | ||
} | ||
|
||
return enabled < 0 ? fallback : enabled; | ||
} | ||
|
||
int copy_wsl_mode_bits_from_disk(const wchar_t *wpath, ssize_t wpathlen, | ||
_mode_t *mode) | ||
{ | ||
int ret = -1; | ||
HANDLE h; | ||
if (wpathlen >= 0) { | ||
/* | ||
* It's caller's duty to make sure wpathlen is reasonable so | ||
* it does not overflow. | ||
*/ | ||
wchar_t *fn2 = (wchar_t*)alloca((wpathlen + 1) * sizeof(wchar_t)); | ||
memcpy(fn2, wpath, wpathlen * sizeof(wchar_t)); | ||
fn2[wpathlen] = 0; | ||
wpath = fn2; | ||
} | ||
h = CreateFileW(wpath, FILE_READ_EA | SYNCHRONIZE, | ||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||
NULL, OPEN_EXISTING, | ||
FILE_FLAG_BACKUP_SEMANTICS | | ||
FILE_FLAG_OPEN_REPARSE_POINT, | ||
NULL); | ||
if (h != INVALID_HANDLE_VALUE) { | ||
ret = get_wsl_mode_bits_by_handle(h, mode); | ||
CloseHandle(h); | ||
} | ||
return ret; | ||
} | ||
|
||
#define LX_FILE_METADATA_HAS_UID 0x1 | ||
#define LX_FILE_METADATA_HAS_GID 0x2 | ||
#define LX_FILE_METADATA_HAS_MODE 0x4 | ||
#define LX_FILE_METADATA_HAS_DEVICE_ID 0x8 | ||
#define LX_FILE_CASE_SENSITIVE_DIR 0x10 | ||
typedef struct _FILE_STAT_LX_INFORMATION { | ||
LARGE_INTEGER FileId; | ||
LARGE_INTEGER CreationTime; | ||
LARGE_INTEGER LastAccessTime; | ||
LARGE_INTEGER LastWriteTime; | ||
LARGE_INTEGER ChangeTime; | ||
LARGE_INTEGER AllocationSize; | ||
LARGE_INTEGER EndOfFile; | ||
uint32_t FileAttributes; | ||
uint32_t ReparseTag; | ||
uint32_t NumberOfLinks; | ||
ACCESS_MASK EffectiveAccess; | ||
uint32_t LxFlags; | ||
uint32_t LxUid; | ||
uint32_t LxGid; | ||
uint32_t LxMode; | ||
uint32_t LxDeviceIdMajor; | ||
uint32_t LxDeviceIdMinor; | ||
} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION; | ||
|
||
/* | ||
* This struct is extended from the original FILE_FULL_EA_INFORMATION of | ||
* Microsoft Windows. | ||
*/ | ||
struct wsl_full_ea_info_t { | ||
uint32_t NextEntryOffset; | ||
uint8_t Flags; | ||
uint8_t EaNameLength; | ||
uint16_t EaValueLength; | ||
char EaName[7]; | ||
char EaValue[4]; | ||
char Padding[1]; | ||
}; | ||
|
||
enum { | ||
FileStatLxInformation = 70, | ||
}; | ||
__declspec(dllimport) NTSTATUS WINAPI | ||
NtQueryInformationFile(HANDLE FileHandle, | ||
PIO_STATUS_BLOCK IoStatusBlock, | ||
PVOID FileInformation, ULONG Length, | ||
uint32_t FileInformationClass); | ||
__declspec(dllimport) NTSTATUS WINAPI | ||
NtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, | ||
PVOID FileInformation, ULONG Length, | ||
uint32_t FileInformationClass); | ||
__declspec(dllimport) NTSTATUS WINAPI | ||
NtSetEaFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, | ||
PVOID EaBuffer, ULONG EaBufferSize); | ||
|
||
int set_wsl_mode_bits_by_handle(HANDLE h, _mode_t mode) | ||
{ | ||
uint32_t value = mode; | ||
struct wsl_full_ea_info_t ea_info; | ||
IO_STATUS_BLOCK iob; | ||
/* mode should be valid to make WSL happy */ | ||
assert(S_ISREG(mode) || S_ISDIR(mode)); | ||
ea_info.NextEntryOffset = 0; | ||
ea_info.Flags = 0; | ||
ea_info.EaNameLength = 6; | ||
ea_info.EaValueLength = sizeof(value); /* 4 */ | ||
strlcpy(ea_info.EaName, "$LXMOD", sizeof(ea_info.EaName)); | ||
memcpy(ea_info.EaValue, &value, sizeof(value)); | ||
ea_info.Padding[0] = 0; | ||
return NtSetEaFile(h, &iob, &ea_info, sizeof(ea_info)); | ||
} | ||
|
||
int get_wsl_mode_bits_by_handle(HANDLE h, _mode_t *mode) | ||
{ | ||
FILE_STAT_LX_INFORMATION fxi; | ||
IO_STATUS_BLOCK iob; | ||
if (NtQueryInformationFile(h, &iob, &fxi, sizeof(fxi), | ||
FileStatLxInformation) == 0) { | ||
if (fxi.LxFlags & LX_FILE_METADATA_HAS_MODE) | ||
*mode = (_mode_t)fxi.LxMode; | ||
return 0; | ||
} | ||
return -1; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#ifndef COMPAT_WIN32_WSL_H | ||
#define COMPAT_WIN32_WSL_H | ||
|
||
int are_wsl_compatible_mode_bits_enabled(void); | ||
|
||
int copy_wsl_mode_bits_from_disk(const wchar_t *wpath, ssize_t wpathlen, | ||
_mode_t *mode); | ||
|
||
int get_wsl_mode_bits_by_handle(HANDLE h, _mode_t *mode); | ||
int set_wsl_mode_bits_by_handle(HANDLE h, _mode_t mode); | ||
|
||
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.