@@ -496,14 +496,47 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
496496{
497497 validate_ownership_data * data = payload ;
498498
499- if (strcmp (entry -> value , "" ) == 0 )
499+ if (strcmp (entry -> value , "" ) == 0 ) {
500500 * data -> is_safe = false;
501-
502- if (strcmp (entry -> value , "*" ) == 0 )
503- * data -> is_safe = true;
504- else if (git_fs_path_prettify_dir (& data -> tmp , entry -> value , NULL ) == 0 &&
505- strcmp (data -> tmp .ptr , data -> repo_path ) == 0 )
501+ } else if (strcmp (entry -> value , "*" ) == 0 ) {
506502 * data -> is_safe = true;
503+ } else {
504+ const char * test_path = entry -> value ;
505+
506+ #ifdef GIT_WIN32
507+ /*
508+ * Git for Windows does some truly bizarre things with
509+ * paths that start with a forward slash; and expects you
510+ * to escape that with `%(prefix)`. This syntax generally
511+ * means to add the prefix that Git was installed to -- eg
512+ * `/usr/local` -- unless it's an absolute path, in which
513+ * case the leading `%(prefix)/` is just removed. And Git
514+ * for Windows expects you to use this syntax for absolute
515+ * Unix-style paths (in "Git Bash" or Windows Subsystem for
516+ * Linux).
517+ *
518+ * Worse, the behavior used to be that a leading `/` was
519+ * not absolute. It would indicate that Git for Windows
520+ * should add the prefix. So `//` is required for absolute
521+ * Unix-style paths. Yes, this is truly horrifying.
522+ *
523+ * Emulate that behavior, I guess, but only for absolute
524+ * paths. We won't deal with the Git install prefix. Also,
525+ * give WSL users an escape hatch where they don't have to
526+ * think about this and can use the literal path that the
527+ * filesystem APIs provide (`//wsl.localhost/...`).
528+ */
529+ if (strncmp (test_path , "%(prefix)//" , strlen ("%(prefix)//" )) == 0 )
530+ test_path += strlen ("%(prefix)/" );
531+ else if (strncmp (test_path , "//" , 2 ) == 0 &&
532+ strncmp (test_path , "//wsl.localhost/" , strlen ("//wsl.localhost/" )) != 0 )
533+ test_path ++ ;
534+ #endif
535+
536+ if (git_fs_path_prettify_dir (& data -> tmp , test_path , NULL ) == 0 &&
537+ strcmp (data -> tmp .ptr , data -> repo_path ) == 0 )
538+ * data -> is_safe = true;
539+ }
507540
508541 return 0 ;
509542}
@@ -547,6 +580,9 @@ static int validate_ownership_path(bool *is_safe, const char *path)
547580 if (error == GIT_ENOTFOUND ) {
548581 * is_safe = true;
549582 error = 0 ;
583+ } else if (error == GIT_EINVALID ) {
584+ * is_safe = false;
585+ error = 0 ;
550586 }
551587
552588 return error ;
0 commit comments