diff options
author | Jiang Xin <worldhello.net@gmail.com> | 2022-04-13 14:51:53 +0800 |
---|---|---|
committer | Jiang Xin <worldhello.net@gmail.com> | 2022-04-13 14:51:53 +0800 |
commit | 61de00a32115b6090891f20797fdfd1501709ab9 (patch) | |
tree | e6a0290cef9e52589a8b78e55dbae3daf559e202 | |
parent | Merge branch 'fr_2.36_rnd1' of github.com:jnavila/git (diff) | |
parent | Git 2.36-rc2 (diff) | |
download | tgif-61de00a32115b6090891f20797fdfd1501709ab9.tar.xz |
Merge branch 'master' of github.com:git/git
* 'master' of github.com:git/git: (25 commits)
Git 2.36-rc2
i18n: fix some badly formatted i18n strings
Git 2.36-rc1
t9902: split test to run on appropriate systems
ls-tree doc: document interaction with submodules
Documentation: add --batch-command to cat-file synopsis
git-ls-tree.txt: fix the name of "%(objectsize:padded)"
submodule-helper: fix usage string
doc: replace "--" with {litdd} in credential-cache/fsmonitor
contrib/scalar: fix 'all' target in Makefile
Documentation/Makefile: fix "make info" regression in dad9cd7d518
configure.ac: fix HAVE_SYNC_FILE_RANGE definition
git-compat-util: really support openssl as a source of entropy
ls-tree: `-l` should not imply recursive listing
Git 2.35.2
Git 2.34.2
Git 2.33.2
Git 2.32.1
Git 2.31.2
Git 2.30.3
...
31 files changed, 331 insertions, 48 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile index 1eb9192dae..44c080e3e5 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -390,7 +390,7 @@ gitman.texi: $(MAN_XML) cat-texi.perl texi.xsl $(RM) $@+ gitman.info: gitman.texi - $(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $*.texi + $(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $< $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml $(QUIET_DB2TEXI)$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@ diff --git a/Documentation/RelNotes/2.30.3.txt b/Documentation/RelNotes/2.30.3.txt new file mode 100644 index 0000000000..31b2a4daa6 --- /dev/null +++ b/Documentation/RelNotes/2.30.3.txt @@ -0,0 +1,24 @@ +Git v2.30.2 Release Notes +========================= + +This release addresses the security issue CVE-2022-24765. + +Fixes since v2.30.2 +------------------- + + * Build fix on Windows. + + * Fix `GIT_CEILING_DIRECTORIES` with Windows-style root directories. + + * CVE-2022-24765: + On multi-user machines, Git users might find themselves + unexpectedly in a Git worktree, e.g. when another user created a + repository in `C:\.git`, in a mounted network drive or in a + scratch space. Merely having a Git-aware prompt that runs `git + status` (or `git diff`) and navigating to a directory which is + supposedly not a Git worktree, or opening such a directory in an + editor or IDE such as VS Code or Atom, will potentially run + commands defined by that other user. + +Credit for finding this vulnerability goes to 俞晨东; The fix was +authored by Johannes Schindelin. diff --git a/Documentation/RelNotes/2.31.2.txt b/Documentation/RelNotes/2.31.2.txt new file mode 100644 index 0000000000..aa13a5b022 --- /dev/null +++ b/Documentation/RelNotes/2.31.2.txt @@ -0,0 +1,6 @@ +Git v2.31.2 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.3 to address +the security issue CVE-2022-24765; see the release notes for that +version for details. diff --git a/Documentation/RelNotes/2.32.1.txt b/Documentation/RelNotes/2.32.1.txt new file mode 100644 index 0000000000..7dcca13b92 --- /dev/null +++ b/Documentation/RelNotes/2.32.1.txt @@ -0,0 +1,6 @@ +Git v2.32.1 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.3 and +v2.31.2 to address the security issue CVE-2022-24765; see the +release notes for these versions for details. diff --git a/Documentation/RelNotes/2.33.2.txt b/Documentation/RelNotes/2.33.2.txt new file mode 100644 index 0000000000..e504489d61 --- /dev/null +++ b/Documentation/RelNotes/2.33.2.txt @@ -0,0 +1,15 @@ +Git v2.33.2 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.3, v2.31.2 +and v2.32.1 to address the security issue CVE-2022-24765; see +the release notes for these versions for details. + +In addition, it contains the following fixes: + + * Squelch over-eager warning message added during this cycle. + + * A bug in "git rebase -r" has been fixed. + + * One CI task based on Fedora image noticed a not-quite-kosher + construct recently, which has been corrected. diff --git a/Documentation/RelNotes/2.34.2.txt b/Documentation/RelNotes/2.34.2.txt new file mode 100644 index 0000000000..0c32cd844b --- /dev/null +++ b/Documentation/RelNotes/2.34.2.txt @@ -0,0 +1,6 @@ +Git v2.34.2 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.3, v2.31.2, +v2.32.1 and v2.33.2 to address the security issue CVE-2022-24765; +see the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.35.2.txt b/Documentation/RelNotes/2.35.2.txt new file mode 100644 index 0000000000..290bfa9ea4 --- /dev/null +++ b/Documentation/RelNotes/2.35.2.txt @@ -0,0 +1,7 @@ +Git v2.35.2 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.3, +v2.31.2, v2.32.1, v2.33.2 and v2.34.2 to address the security +issue CVE-2022-24765; see the release notes for these versions +for details. diff --git a/Documentation/RelNotes/2.36.0.txt b/Documentation/RelNotes/2.36.0.txt index 8da5b2e1e7..d61ade21e2 100644 --- a/Documentation/RelNotes/2.36.0.txt +++ b/Documentation/RelNotes/2.36.0.txt @@ -397,6 +397,8 @@ Fixes since v2.35 entry it moved. (merge b7f9130a06 vd/mv-refresh-stat later to maint). + * Fix for CVE-2022-24765 has been merged up from 2.35.2 and others. + * Other code cleanup, docfix, build fix, etc. (merge cfc5cf428b jc/find-header later to maint). (merge 40e7cfdd46 jh/p4-fix-use-of-process-error-exception later to maint). diff --git a/Documentation/config.txt b/Documentation/config.txt index 43f5e6fd6d..e284b042f2 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -495,6 +495,8 @@ include::config/repack.txt[] include::config/rerere.txt[] +include::config/safe.txt[] + include::config/sendemail.txt[] include::config/sequencer.txt[] diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt index 889522956e..e67392cc83 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -63,7 +63,7 @@ core.protectNTFS:: core.fsmonitor:: If set to true, enable the built-in file system monitor - daemon for this working directory (linkgit:git-fsmonitor--daemon[1]). + daemon for this working directory (linkgit:git-fsmonitor{litdd}daemon[1]). + Like hook-based file system monitors, the built-in file system monitor can speed up Git commands that need to refresh the Git index diff --git a/Documentation/config/safe.txt b/Documentation/config/safe.txt new file mode 100644 index 0000000000..63597b2df8 --- /dev/null +++ b/Documentation/config/safe.txt @@ -0,0 +1,21 @@ +safe.directory:: + These config entries specify Git-tracked directories that are + considered safe even if they are owned by someone other than the + current user. By default, Git will refuse to even parse a Git + config of a repository owned by someone else, let alone run its + hooks, and this config setting allows users to specify exceptions, + e.g. for intentionally shared repositories (see the `--shared` + option in linkgit:git-init[1]). ++ +This is a multi-valued setting, i.e. you can add more than one directory +via `git config --add`. To reset the list of safe directories (e.g. to +override any such directories specified in the system config), add a +`safe.directory` entry with an empty value. ++ +This config setting is only respected when specified in a system or global +config, not when it is specified in a repository config or via the command +line option `-c safe.directory=<path>`. ++ +The value of this setting is interpolated, i.e. `~/<path>` expands to a +path relative to the home directory and `%(prefix)/<path>` expands to a +path relative to Git's (runtime) prefix. diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt index 70c5b4f12d..24a811f0ef 100644 --- a/Documentation/git-cat-file.txt +++ b/Documentation/git-cat-file.txt @@ -12,7 +12,7 @@ SYNOPSIS 'git cat-file' <type> <object> 'git cat-file' (-e | -p) <object> 'git cat-file' (-t | -s) [--allow-unknown-type] <object> -'git cat-file' (--batch | --batch-check) [--batch-all-objects] +'git cat-file' (--batch | --batch-check | --batch-command) [--batch-all-objects] [--buffer] [--follow-symlinks] [--unordered] [--textconv | --filters] 'git cat-file' (--textconv | --filters) diff --git a/Documentation/git-credential-cache--daemon.txt b/Documentation/git-credential-cache--daemon.txt index 7051c6bdf8..01e1c214dd 100644 --- a/Documentation/git-credential-cache--daemon.txt +++ b/Documentation/git-credential-cache--daemon.txt @@ -1,5 +1,5 @@ -git-credential-cache--daemon(1) -=============================== +git-credential-cache{litdd}daemon(1) +==================================== NAME ---- @@ -8,7 +8,7 @@ git-credential-cache--daemon - Temporarily store user credentials in memory SYNOPSIS -------- [verse] -git credential-cache--daemon [--debug] <socket> +'git credential-cache{litdd}daemon' [--debug] <socket> DESCRIPTION ----------- diff --git a/Documentation/git-fsmonitor--daemon.txt b/Documentation/git-fsmonitor--daemon.txt index 0fedf5a456..cc142fb861 100644 --- a/Documentation/git-fsmonitor--daemon.txt +++ b/Documentation/git-fsmonitor--daemon.txt @@ -1,5 +1,5 @@ -git-fsmonitor--daemon(1) -======================== +git-fsmonitor{litdd}daemon(1) +============================= NAME ---- @@ -8,10 +8,10 @@ git-fsmonitor--daemon - A Built-in File System Monitor SYNOPSIS -------- [verse] -'git fsmonitor--daemon' start -'git fsmonitor--daemon' run -'git fsmonitor--daemon' stop -'git fsmonitor--daemon' status +'git fsmonitor{litdd}daemon' start +'git fsmonitor{litdd}daemon' run +'git fsmonitor{litdd}daemon' stop +'git fsmonitor{litdd}daemon' status DESCRIPTION ----------- diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt index 43aebb9938..0240adb8ee 100644 --- a/Documentation/git-ls-tree.txt +++ b/Documentation/git-ls-tree.txt @@ -151,12 +151,12 @@ names can be used: objectmode:: The mode of the object. objecttype:: - The type of the object (`blob` or `tree`). + The type of the object (`commit`, `blob` or `tree`). objectname:: The name of the object. objectsize[:padded]:: - The size of the object ("-" if it's a tree). - It also supports a padded format of size with "%(size:padded)". + The size of a `blob` object ("-" if it's a `commit` or `tree`). + It also supports a padded format of size with "%(objectsize:padded)". path:: The pathname of the object. diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index 64315e2e8c..5ea2f2c60e 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -528,7 +528,7 @@ This feature is intended to speed up git operations for repos that have large working directories. It enables git to work together with a file system monitor (see -linkgit:git-fsmonitor--daemon[1] +linkgit:git-fsmonitor{litdd}daemon[1] and the "fsmonitor-watchman" section of linkgit:githooks[5]) that can inform it as to what files have been modified. This enables git to avoid diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index d92e7d4398..9252e0430d 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.36.0-rc0 +DEF_VER=v2.36.0-rc2 LF=' ' @@ -1972,6 +1972,7 @@ endif ifneq ($(findstring openssl,$(CSPRNG_METHOD)),) BASIC_CFLAGS += -DHAVE_OPENSSL_CSPRNG + EXTLIBS += -lcrypto -lssl endif ifneq ($(PROCFS_EXECUTABLE_PATH),) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 5dac9ee5b9..e279be8bb6 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -255,7 +255,7 @@ static int show_tree_long(const struct object_id *oid, struct strbuf *base, printf("%06o %s %s %7s\t", data.mode, type_name(data.type), find_unique_abbrev(data.oid, abbrev), size_text); show_tree_common_default_long(base, pathname, data.base->len); - return 1; + return recurse; } static int show_tree_name_only(const struct object_id *oid, struct strbuf *base, diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c3e0d4570f..2c87ef9364 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1902,7 +1902,7 @@ static int module_clone(int argc, const char **argv, const char *prefix) const char *const git_submodule_helper_usage[] = { N_("git submodule--helper clone [--prefix=<path>] [--quiet] " "[--reference <repository>] [--name <name>] [--depth <depth>] " - "[--single-branch] [--filter <filter-spec>]" + "[--single-branch] [--filter <filter-spec>] " "--url <url> --path <path>"), NULL }; @@ -3082,7 +3082,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix) OPT_END() }; const char *const usage[] = { - N_("git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--quiet] [-t|--track] [-n|--dry-run] <name> <start_oid> <start_name>"), + N_("git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>"), NULL }; diff --git a/compat/mingw.c b/compat/mingw.c index 58f347d6ae..6fe80fdf01 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1,5 +1,6 @@ #include "../git-compat-util.h" #include "win32.h" +#include <aclapi.h> #include <conio.h> #include <wchar.h> #include "../strbuf.h" @@ -2645,6 +2646,92 @@ static void setup_windows_environment(void) } } +static PSID get_current_user_sid(void) +{ + HANDLE token; + DWORD len = 0; + PSID result = NULL; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) + return NULL; + + if (!GetTokenInformation(token, TokenUser, NULL, 0, &len)) { + TOKEN_USER *info = xmalloc((size_t)len); + if (GetTokenInformation(token, TokenUser, info, len, &len)) { + len = GetLengthSid(info->User.Sid); + result = xmalloc(len); + if (!CopySid(len, result, info->User.Sid)) { + error(_("failed to copy SID (%ld)"), + GetLastError()); + FREE_AND_NULL(result); + } + } + FREE_AND_NULL(info); + } + CloseHandle(token); + + return result; +} + +int is_path_owned_by_current_sid(const char *path) +{ + WCHAR wpath[MAX_PATH]; + PSID sid = NULL; + PSECURITY_DESCRIPTOR descriptor = NULL; + DWORD err; + + static wchar_t home[MAX_PATH]; + + int result = 0; + + if (xutftowcs_path(wpath, path) < 0) + return 0; + + /* + * On Windows, the home directory is owned by the administrator, but for + * all practical purposes, it belongs to the user. Do pretend that it is + * owned by the user. + */ + if (!*home) { + DWORD size = ARRAY_SIZE(home); + DWORD len = GetEnvironmentVariableW(L"HOME", home, size); + if (!len || len > size) + wcscpy(home, L"::N/A::"); + } + if (!wcsicmp(wpath, home)) + return 1; + + /* Get the owner SID */ + err = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION, + &sid, NULL, NULL, NULL, &descriptor); + + if (err != ERROR_SUCCESS) + error(_("failed to get owner for '%s' (%ld)"), path, err); + else if (sid && IsValidSid(sid)) { + /* Now, verify that the SID matches the current user's */ + static PSID current_user_sid; + + if (!current_user_sid) + current_user_sid = get_current_user_sid(); + + if (current_user_sid && + IsValidSid(current_user_sid) && + EqualSid(sid, current_user_sid)) + result = 1; + } + + /* + * We can release the security descriptor struct only now because `sid` + * actually points into this struct. + */ + if (descriptor) + LocalFree(descriptor); + + return result; +} + int is_valid_win32_path(const char *path, int allow_literal_nul) { const char *p = path; diff --git a/compat/mingw.h b/compat/mingw.h index 6074a3d3ce..494cc8de92 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -457,6 +457,13 @@ char *mingw_query_user_email(void); #endif /** + * Verifies that the specified path is owned by the user running the + * current process. + */ +int is_path_owned_by_current_sid(const char *path); +#define is_path_owned_by_current_user is_path_owned_by_current_sid + +/** * Verifies that the given path is a valid one on Windows. * * In particular, path segments are disallowed which diff --git a/configure.ac b/configure.ac index 6bd6bef1c4..316a31d231 100644 --- a/configure.ac +++ b/configure.ac @@ -1087,7 +1087,7 @@ GIT_CONF_SUBST([HAVE_CLOCK_MONOTONIC]) # Define HAVE_SYNC_FILE_RANGE=YesPlease if sync_file_range is available. GIT_CHECK_FUNC(sync_file_range, [HAVE_SYNC_FILE_RANGE=YesPlease], - [HAVE_SYNC_FILE_RANGE]) + [HAVE_SYNC_FILE_RANGE=]) GIT_CONF_SUBST([HAVE_SYNC_FILE_RANGE]) # diff --git a/contrib/scalar/Makefile b/contrib/scalar/Makefile index 5e86d78e19..37f283f35d 100644 --- a/contrib/scalar/Makefile +++ b/contrib/scalar/Makefile @@ -11,7 +11,7 @@ include ../../config.mak.uname TARGETS = scalar$(X) scalar.o GITLIBS = ../../common-main.o ../../libgit.a ../../xdiff/lib.a -all: scalar$(X) ../../bin-wrappers/scalar +all:: scalar$(X) ../../bin-wrappers/scalar $(GITLIBS): $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) $(subst ../../,,$@) diff --git a/git-compat-util.h b/git-compat-util.h index 4d444dca27..58fd813bd0 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -436,6 +436,18 @@ static inline int git_offset_1st_component(const char *path) #define is_valid_path(path) 1 #endif +#ifndef is_path_owned_by_current_user +static inline int is_path_owned_by_current_uid(const char *path) +{ + struct stat st; + if (lstat(path, &st)) + return 0; + return st.st_uid == geteuid(); +} + +#define is_path_owned_by_current_user is_path_owned_by_current_uid +#endif + #ifndef find_last_dir_sep static inline char *git_find_last_dir_sep(const char *path) { @@ -525,6 +537,10 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); #include <openssl/x509v3.h> #endif /* NO_OPENSSL */ +#ifdef HAVE_OPENSSL_CSPRNG +#include <openssl/rand.h> +#endif + /* * Let callers be aware of the constant return value; this can help * gcc with -Wuninitialized analysis. We restrict this trick to gcc, though, diff --git a/git-send-email.perl b/git-send-email.perl index a98460bdb9..5861e99a6e 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -2096,10 +2096,9 @@ sub validate_patch { chdir($cwd_save) or die("chdir: $!"); } if ($hook_error) { - $hook_error = sprintf(__("fatal: %s: rejected by %s hook\n" . - $hook_error . "\n" . - "warning: no patches were sent\n"), - $fn, $hook_name); + $hook_error = sprintf( + __("fatal: %s: rejected by %s hook\n%s\nwarning: no patches were sent\n"), + $fn, $hook_name, $hook_error); die $hook_error; } } diff --git a/imap-send.c b/imap-send.c index 5ac6fa9c66..a50af56b82 100644 --- a/imap-send.c +++ b/imap-send.c @@ -27,7 +27,7 @@ #include "exec-cmd.h" #include "run-command.h" #include "parse-options.h" -#ifdef NO_OPENSSL +#if defined(NO_OPENSSL) && !defined(HAVE_OPENSSL_CSPRNG) typedef void *SSL; #endif #ifdef USE_CURL_FOR_IMAP_SEND @@ -1225,11 +1225,15 @@ int longest_ancestor_length(const char *path, struct string_list *prefixes) const char *ceil = prefixes->items[i].string; int len = strlen(ceil); - if (len == 1 && ceil[0] == '/') - len = 0; /* root matches anything, with length 0 */ - else if (!strncmp(path, ceil, len) && path[len] == '/') - ; /* match of length len */ - else + /* + * For root directories (`/`, `C:/`, `//server/share/`) + * adjust the length to exclude the trailing slash. + */ + if (len > 0 && ceil[len - 1] == '/') + len--; + + if (strncmp(path, ceil, len) || + path[len] != '/' || !path[len + 1]) continue; /* no match */ if (len > max_len) @@ -5,6 +5,7 @@ #include "string-list.h" #include "chdir-notify.h" #include "promisor-remote.h" +#include "quote.h" static int inside_git_dir = -1; static int inside_work_tree = -1; @@ -1090,6 +1091,42 @@ static int canonicalize_ceiling_entry(struct string_list_item *item, } } +struct safe_directory_data { + const char *path; + int is_safe; +}; + +static int safe_directory_cb(const char *key, const char *value, void *d) +{ + struct safe_directory_data *data = d; + + if (!value || !*value) + data->is_safe = 0; + else { + const char *interpolated = NULL; + + if (!git_config_pathname(&interpolated, key, value) && + !fspathcmp(data->path, interpolated ? interpolated : value)) + data->is_safe = 1; + + free((char *)interpolated); + } + + return 0; +} + +static int ensure_valid_ownership(const char *path) +{ + struct safe_directory_data data = { .path = path }; + + if (is_path_owned_by_current_user(path)) + return 1; + + read_very_early_config(safe_directory_cb, &data); + + return data.is_safe; +} + enum discovery_result { GIT_DIR_NONE = 0, GIT_DIR_EXPLICIT, @@ -1098,7 +1135,8 @@ enum discovery_result { /* these are errors */ GIT_DIR_HIT_CEILING = -1, GIT_DIR_HIT_MOUNT_POINT = -2, - GIT_DIR_INVALID_GITFILE = -3 + GIT_DIR_INVALID_GITFILE = -3, + GIT_DIR_INVALID_OWNERSHIP = -4 }; /* @@ -1188,11 +1226,15 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, } strbuf_setlen(dir, offset); if (gitdirenv) { + if (!ensure_valid_ownership(dir->buf)) + return GIT_DIR_INVALID_OWNERSHIP; strbuf_addstr(gitdir, gitdirenv); return GIT_DIR_DISCOVERED; } if (is_git_directory(dir->buf)) { + if (!ensure_valid_ownership(dir->buf)) + return GIT_DIR_INVALID_OWNERSHIP; strbuf_addstr(gitdir, "."); return GIT_DIR_BARE; } @@ -1324,6 +1366,19 @@ const char *setup_git_directory_gently(int *nongit_ok) dir.buf); *nongit_ok = 1; break; + case GIT_DIR_INVALID_OWNERSHIP: + if (!nongit_ok) { + struct strbuf quoted = STRBUF_INIT; + + sq_quote_buf_pretty("ed, dir.buf); + die(_("unsafe repository ('%s' is owned by someone else)\n" + "To add an exception for this directory, call:\n" + "\n" + "\tgit config --global --add safe.directory %s"), + dir.buf, quoted.buf); + } + *nongit_ok = 1; + break; case GIT_DIR_NONE: /* * As a safeguard against setup_git_directory_gently_1 returning diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 71a5d370cc..2fe6ae6a4e 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -55,12 +55,15 @@ fi ancestor() { # We do some math with the expected ancestor length. expected=$3 - if test -n "$rootoff" && test "x$expected" != x-1; then - expected=$(($expected-$rootslash)) - test $expected -lt 0 || - expected=$(($expected+$rootoff)) - fi - test_expect_success "longest ancestor: $1 $2 => $expected" \ + case "$rootoff,$expected,$2" in + *,*,//*) ;; # leave UNC paths alone + [0-9]*,[0-9]*,/*) + # On Windows, expect MSYS2 pseudo root translation for + # Unix-style absolute paths + expected=$(($expected-$rootslash+$rootoff)) + ;; + esac + test_expect_success $4 "longest ancestor: $1 $2 => $expected" \ "actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') && test \"\$actual\" = '$expected'" } @@ -156,6 +159,11 @@ ancestor /foo/bar /foo 4 ancestor /foo/bar /foo:/bar 4 ancestor /foo/bar /bar -1 +# Windows-specific: DOS drives, network shares +ancestor C:/Users/me C:/ 2 MINGW +ancestor D:/Users/me C:/ -1 MINGW +ancestor //server/share/my-directory //server/share/ 14 MINGW + test_expect_success 'strip_path_suffix' ' test c:/msysgit = $(test-tool path-utils strip_path_suffix \ c:/msysgit/libexec//git-core libexec/git-core) diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 24117cb901..31526e6b64 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1529,28 +1529,45 @@ test_expect_success 'cone mode sparse-checkout completes directory names with sp ) ' -# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes or tabs in paths -test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with backslashes and tabs' ' +# use FUNNYNAMES to avoid running on Windows, which doesn't permit tabs in paths +test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with tabs' ' # reset sparse-checkout git -C sparse-checkout sparse-checkout disable && ( cd sparse-checkout && - mkdir "directory\with\backslashes" && mkdir "$(printf "directory\twith\ttabs")" && - >"directory\with\backslashes/randomfile" && >"$(printf "directory\twith\ttabs")/randomfile" && git add . && - git commit -m "Add directory with backslashes and directory with tabs" && - git sparse-checkout set --cone "directory\with\backslashes" \ + git commit -m "Add directory with tabs" && + git sparse-checkout set --cone \ "$(printf "directory\twith\ttabs")" && test_completion "git sparse-checkout add dir" <<-\EOF && - directory\with\backslashes/ directory with tabs/ EOF - rm -rf "directory\with\backslashes" && rm -rf "$(printf "directory\twith\ttabs")" && git add . && - git commit -m "Remove directory with backslashes and directory with tabs" + git commit -m "Remove directory with tabs" + ) +' + +# use FUNNYNAMES to avoid running on Windows, and !CYGWIN for Cygwin, as neither permit backslashes in paths +test_expect_success FUNNYNAMES,!CYGWIN 'cone mode sparse-checkout completes directory names with backslashes' ' + # reset sparse-checkout + git -C sparse-checkout sparse-checkout disable && + ( + cd sparse-checkout && + mkdir "directory\with\backslashes" && + >"directory\with\backslashes/randomfile" && + git add . && + git commit -m "Add directory with backslashes" && + git sparse-checkout set --cone \ + "directory\with\backslashes" && + test_completion "git sparse-checkout add dir" <<-\EOF && + directory\with\backslashes/ + EOF + rm -rf "directory\with\backslashes" && + git add . && + git commit -m "Remove directory with backslashes" ) ' |