Conversation
Collaborator
|
An excellent and complete implementation! However, I prefer to only provide just one CheckBox - |
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
PR Description
Problem
Starting with Git 2.35.2, if the repository's top-level directory is owned by another user (the fix for CVE-2022-24765), Git will refuse to use the repository.
Repositories on network shares / UNC paths inevitably trigger this check, because the file owner SID of an SMB share cannot be resolved on the client:
Currently SourceGit treats such paths as "not a valid Git repository" (it pops up
Initialize Repository, or silently ignores them on drag and drop). This is misleading—the path is indeed a valid repository; Git is simply refusing to access it.Approach
Detect this specific error and let the user decide how to trust the repository; do not write anything before the user explicitly confirms:
-c safe.directory=<value>until the application exits. When the detected Git is older than 2.38 this option is disabled with an explanation, because those versions do not respect-c safe.directory(see Notes);git config --global --add safe.directory "<value>". The option text uses a warning color, and when selected, the exact command to be executed is displayed below it.The value to be allowed is taken directly from Git's own suggested value, so platform-specific forms are handled correctly, and Git's shell quoting is decoded back to the plain path (
'and!are escaped by Git). When Git does not provide a hint, it falls back to constructing the value from the path.Implementation
Models/SafeDirectories.cssafe.directoryvalue suggested by Git, maintains in-memory session trust and builds the-c safe.directory=...argumentsModels/GitVersions.csSAFE_DIRECTORY_COMMAND_LINE = 2.38.0(the first Git version that respects the command-line option)Commands/AddSafeDirectory.csgit config --global --add safe.directory ...Commands/Command.cs-c safe.directory=...to working directories trusted for the session (also used by the few commands that spawn Git directly:QueryFileContent,SaveRevisionFile,UpdateIndexInfo,SaveChangesAsPatch)ViewModels/TrustRepository.cs+Views/TrustRepository.axamlViewModels/Launcher.cs,ViewModels/OpenLocalRepository.cs,ViewModels/Welcome.cs,Views/Welcome.axaml.csViewModels/ScanRepositories.csApp.axaml.cs--history/--blameoutputs Git's real stderr instead of a generic messageResources/Themes.axamlColor.Warn/Brush.Warnfor the permanent trust optionResources/Locales/{en_US,zh_CN,zh_TW}.axamlScreenshots
Testing
dotnet build -c Debug: 0 warnings / 0 errors;dotnet format --verify-no-changes src/SourceGit.csproj: passes;\\service\share\...):git rev-parse --show-toplevelsucceeds;GIT_CONFIG_GLOBAL;'and!is parsed correctly: the dialog showssafe.directory "%(prefix)///.../service'test!ok"without any'\''/'\!'leftovers;Notes
-c safe.directory, which Git only respects since 2.38 (2.35.2 - 2.37.x intentionally ignored the command-line option). On older Git the session option is disabled in the dialog, so the user is never sent into a dead end; permanent trust works on every version;en_US,zh_CN, andzh_TW; other languages will be marked as missing inTRANSLATION.mdaccording to the existing process;