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 dad9cd7d51
  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
  ...
This commit is contained in:
Jiang Xin 2022-04-13 14:51:53 +08:00
commit 61de00a321
31 changed files with 332 additions and 49 deletions

View File

@ -390,7 +390,7 @@ gitman.texi: $(MAN_XML) cat-texi.perl texi.xsl
$(RM) $@+ $(RM) $@+
gitman.info: gitman.texi 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 $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml
$(QUIET_DB2TEXI)$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@ $(QUIET_DB2TEXI)$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -397,6 +397,8 @@ Fixes since v2.35
entry it moved. entry it moved.
(merge b7f9130a06 vd/mv-refresh-stat later to maint). (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. * Other code cleanup, docfix, build fix, etc.
(merge cfc5cf428b jc/find-header later to maint). (merge cfc5cf428b jc/find-header later to maint).
(merge 40e7cfdd46 jh/p4-fix-use-of-process-error-exception later to maint). (merge 40e7cfdd46 jh/p4-fix-use-of-process-error-exception later to maint).

View File

@ -495,6 +495,8 @@ include::config/repack.txt[]
include::config/rerere.txt[] include::config/rerere.txt[]
include::config/safe.txt[]
include::config/sendemail.txt[] include::config/sendemail.txt[]
include::config/sequencer.txt[] include::config/sequencer.txt[]

View File

@ -63,7 +63,7 @@ core.protectNTFS::
core.fsmonitor:: core.fsmonitor::
If set to true, enable the built-in file system monitor 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 Like hook-based file system monitors, the built-in file system monitor
can speed up Git commands that need to refresh the Git index can speed up Git commands that need to refresh the Git index

View File

@ -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.

View File

@ -12,7 +12,7 @@ SYNOPSIS
'git cat-file' <type> <object> 'git cat-file' <type> <object>
'git cat-file' (-e | -p) <object> 'git cat-file' (-e | -p) <object>
'git cat-file' (-t | -s) [--allow-unknown-type] <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] [--buffer] [--follow-symlinks] [--unordered]
[--textconv | --filters] [--textconv | --filters]
'git cat-file' (--textconv | --filters) 'git cat-file' (--textconv | --filters)

View File

@ -1,5 +1,5 @@
git-credential-cache--daemon(1) git-credential-cache{litdd}daemon(1)
=============================== ====================================
NAME NAME
---- ----
@ -8,7 +8,7 @@ git-credential-cache--daemon - Temporarily store user credentials in memory
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
git credential-cache--daemon [--debug] <socket> 'git credential-cache{litdd}daemon' [--debug] <socket>
DESCRIPTION DESCRIPTION
----------- -----------

View File

@ -1,5 +1,5 @@
git-fsmonitor--daemon(1) git-fsmonitor{litdd}daemon(1)
======================== =============================
NAME NAME
---- ----
@ -8,10 +8,10 @@ git-fsmonitor--daemon - A Built-in File System Monitor
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git fsmonitor--daemon' start 'git fsmonitor{litdd}daemon' start
'git fsmonitor--daemon' run 'git fsmonitor{litdd}daemon' run
'git fsmonitor--daemon' stop 'git fsmonitor{litdd}daemon' stop
'git fsmonitor--daemon' status 'git fsmonitor{litdd}daemon' status
DESCRIPTION DESCRIPTION
----------- -----------

View File

@ -151,12 +151,12 @@ names can be used:
objectmode:: objectmode::
The mode of the object. The mode of the object.
objecttype:: objecttype::
The type of the object (`blob` or `tree`). The type of the object (`commit`, `blob` or `tree`).
objectname:: objectname::
The name of the object. The name of the object.
objectsize[:padded]:: objectsize[:padded]::
The size of the object ("-" if it's a tree). The size of a `blob` object ("-" if it's a `commit` or `tree`).
It also supports a padded format of size with "%(size:padded)". It also supports a padded format of size with "%(objectsize:padded)".
path:: path::
The pathname of the object. The pathname of the object.

View File

@ -528,7 +528,7 @@ This feature is intended to speed up git operations for repos that have
large working directories. large working directories.
It enables git to work together with a file system monitor (see 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 and the
"fsmonitor-watchman" section of linkgit:githooks[5]) that can "fsmonitor-watchman" section of linkgit:githooks[5]) that can
inform it as to what files have been modified. This enables git to avoid inform it as to what files have been modified. This enables git to avoid

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
GVF=GIT-VERSION-FILE GVF=GIT-VERSION-FILE
DEF_VER=v2.36.0-rc0 DEF_VER=v2.36.0-rc2
LF=' LF='
' '

View File

@ -1972,6 +1972,7 @@ endif
ifneq ($(findstring openssl,$(CSPRNG_METHOD)),) ifneq ($(findstring openssl,$(CSPRNG_METHOD)),)
BASIC_CFLAGS += -DHAVE_OPENSSL_CSPRNG BASIC_CFLAGS += -DHAVE_OPENSSL_CSPRNG
EXTLIBS += -lcrypto -lssl
endif endif
ifneq ($(PROCFS_EXECUTABLE_PATH),) ifneq ($(PROCFS_EXECUTABLE_PATH),)

View File

@ -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), printf("%06o %s %s %7s\t", data.mode, type_name(data.type),
find_unique_abbrev(data.oid, abbrev), size_text); find_unique_abbrev(data.oid, abbrev), size_text);
show_tree_common_default_long(base, pathname, data.base->len); 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, static int show_tree_name_only(const struct object_id *oid, struct strbuf *base,

View File

@ -1902,7 +1902,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
const char *const git_submodule_helper_usage[] = { const char *const git_submodule_helper_usage[] = {
N_("git submodule--helper clone [--prefix=<path>] [--quiet] " N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
"[--reference <repository>] [--name <name>] [--depth <depth>] " "[--reference <repository>] [--name <name>] [--depth <depth>] "
"[--single-branch] [--filter <filter-spec>]" "[--single-branch] [--filter <filter-spec>] "
"--url <url> --path <path>"), "--url <url> --path <path>"),
NULL NULL
}; };
@ -3082,7 +3082,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)
OPT_END() OPT_END()
}; };
const char *const usage[] = { 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 NULL
}; };

View File

@ -1,5 +1,6 @@
#include "../git-compat-util.h" #include "../git-compat-util.h"
#include "win32.h" #include "win32.h"
#include <aclapi.h>
#include <conio.h> #include <conio.h>
#include <wchar.h> #include <wchar.h>
#include "../strbuf.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) int is_valid_win32_path(const char *path, int allow_literal_nul)
{ {
const char *p = path; const char *p = path;

View File

@ -456,6 +456,13 @@ char *mingw_query_user_email(void);
#include <inttypes.h> #include <inttypes.h>
#endif #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. * Verifies that the given path is a valid one on Windows.
* *

View File

@ -1087,7 +1087,7 @@ GIT_CONF_SUBST([HAVE_CLOCK_MONOTONIC])
# Define HAVE_SYNC_FILE_RANGE=YesPlease if sync_file_range is available. # Define HAVE_SYNC_FILE_RANGE=YesPlease if sync_file_range is available.
GIT_CHECK_FUNC(sync_file_range, GIT_CHECK_FUNC(sync_file_range,
[HAVE_SYNC_FILE_RANGE=YesPlease], [HAVE_SYNC_FILE_RANGE=YesPlease],
[HAVE_SYNC_FILE_RANGE]) [HAVE_SYNC_FILE_RANGE=])
GIT_CONF_SUBST([HAVE_SYNC_FILE_RANGE]) GIT_CONF_SUBST([HAVE_SYNC_FILE_RANGE])
# #

View File

@ -11,7 +11,7 @@ include ../../config.mak.uname
TARGETS = scalar$(X) scalar.o TARGETS = scalar$(X) scalar.o
GITLIBS = ../../common-main.o ../../libgit.a ../../xdiff/lib.a GITLIBS = ../../common-main.o ../../libgit.a ../../xdiff/lib.a
all: scalar$(X) ../../bin-wrappers/scalar all:: scalar$(X) ../../bin-wrappers/scalar
$(GITLIBS): $(GITLIBS):
$(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) $(subst ../../,,$@) $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) $(subst ../../,,$@)

View File

@ -436,6 +436,18 @@ static inline int git_offset_1st_component(const char *path)
#define is_valid_path(path) 1 #define is_valid_path(path) 1
#endif #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 #ifndef find_last_dir_sep
static inline char *git_find_last_dir_sep(const char *path) 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> #include <openssl/x509v3.h>
#endif /* NO_OPENSSL */ #endif /* NO_OPENSSL */
#ifdef HAVE_OPENSSL_CSPRNG
#include <openssl/rand.h>
#endif
/* /*
* Let callers be aware of the constant return value; this can help * Let callers be aware of the constant return value; this can help
* gcc with -Wuninitialized analysis. We restrict this trick to gcc, though, * gcc with -Wuninitialized analysis. We restrict this trick to gcc, though,

View File

@ -2096,10 +2096,9 @@ sub validate_patch {
chdir($cwd_save) or die("chdir: $!"); chdir($cwd_save) or die("chdir: $!");
} }
if ($hook_error) { if ($hook_error) {
$hook_error = sprintf(__("fatal: %s: rejected by %s hook\n" . $hook_error = sprintf(
$hook_error . "\n" . __("fatal: %s: rejected by %s hook\n%s\nwarning: no patches were sent\n"),
"warning: no patches were sent\n"), $fn, $hook_name, $hook_error);
$fn, $hook_name);
die $hook_error; die $hook_error;
} }
} }

View File

@ -27,7 +27,7 @@
#include "exec-cmd.h" #include "exec-cmd.h"
#include "run-command.h" #include "run-command.h"
#include "parse-options.h" #include "parse-options.h"
#ifdef NO_OPENSSL #if defined(NO_OPENSSL) && !defined(HAVE_OPENSSL_CSPRNG)
typedef void *SSL; typedef void *SSL;
#endif #endif
#ifdef USE_CURL_FOR_IMAP_SEND #ifdef USE_CURL_FOR_IMAP_SEND

14
path.c
View File

@ -1225,11 +1225,15 @@ int longest_ancestor_length(const char *path, struct string_list *prefixes)
const char *ceil = prefixes->items[i].string; const char *ceil = prefixes->items[i].string;
int len = strlen(ceil); int len = strlen(ceil);
if (len == 1 && ceil[0] == '/') /*
len = 0; /* root matches anything, with length 0 */ * For root directories (`/`, `C:/`, `//server/share/`)
else if (!strncmp(path, ceil, len) && path[len] == '/') * adjust the length to exclude the trailing slash.
; /* match of length len */ */
else if (len > 0 && ceil[len - 1] == '/')
len--;
if (strncmp(path, ceil, len) ||
path[len] != '/' || !path[len + 1])
continue; /* no match */ continue; /* no match */
if (len > max_len) if (len > max_len)

57
setup.c
View File

@ -5,6 +5,7 @@
#include "string-list.h" #include "string-list.h"
#include "chdir-notify.h" #include "chdir-notify.h"
#include "promisor-remote.h" #include "promisor-remote.h"
#include "quote.h"
static int inside_git_dir = -1; static int inside_git_dir = -1;
static int inside_work_tree = -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 { enum discovery_result {
GIT_DIR_NONE = 0, GIT_DIR_NONE = 0,
GIT_DIR_EXPLICIT, GIT_DIR_EXPLICIT,
@ -1098,7 +1135,8 @@ enum discovery_result {
/* these are errors */ /* these are errors */
GIT_DIR_HIT_CEILING = -1, GIT_DIR_HIT_CEILING = -1,
GIT_DIR_HIT_MOUNT_POINT = -2, 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); strbuf_setlen(dir, offset);
if (gitdirenv) { if (gitdirenv) {
if (!ensure_valid_ownership(dir->buf))
return GIT_DIR_INVALID_OWNERSHIP;
strbuf_addstr(gitdir, gitdirenv); strbuf_addstr(gitdir, gitdirenv);
return GIT_DIR_DISCOVERED; return GIT_DIR_DISCOVERED;
} }
if (is_git_directory(dir->buf)) { if (is_git_directory(dir->buf)) {
if (!ensure_valid_ownership(dir->buf))
return GIT_DIR_INVALID_OWNERSHIP;
strbuf_addstr(gitdir, "."); strbuf_addstr(gitdir, ".");
return GIT_DIR_BARE; return GIT_DIR_BARE;
} }
@ -1324,6 +1366,19 @@ const char *setup_git_directory_gently(int *nongit_ok)
dir.buf); dir.buf);
*nongit_ok = 1; *nongit_ok = 1;
break; break;
case GIT_DIR_INVALID_OWNERSHIP:
if (!nongit_ok) {
struct strbuf quoted = STRBUF_INIT;
sq_quote_buf_pretty(&quoted, 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: case GIT_DIR_NONE:
/* /*
* As a safeguard against setup_git_directory_gently_1 returning * As a safeguard against setup_git_directory_gently_1 returning

View File

@ -55,12 +55,15 @@ fi
ancestor() { ancestor() {
# We do some math with the expected ancestor length. # We do some math with the expected ancestor length.
expected=$3 expected=$3
if test -n "$rootoff" && test "x$expected" != x-1; then case "$rootoff,$expected,$2" in
expected=$(($expected-$rootslash)) *,*,//*) ;; # leave UNC paths alone
test $expected -lt 0 || [0-9]*,[0-9]*,/*)
expected=$(($expected+$rootoff)) # On Windows, expect MSYS2 pseudo root translation for
fi # Unix-style absolute paths
test_expect_success "longest ancestor: $1 $2 => $expected" \ expected=$(($expected-$rootslash+$rootoff))
;;
esac
test_expect_success $4 "longest ancestor: $1 $2 => $expected" \
"actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') && "actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
test \"\$actual\" = '$expected'" test \"\$actual\" = '$expected'"
} }
@ -156,6 +159,11 @@ ancestor /foo/bar /foo 4
ancestor /foo/bar /foo:/bar 4 ancestor /foo/bar /foo:/bar 4
ancestor /foo/bar /bar -1 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_expect_success 'strip_path_suffix' '
test c:/msysgit = $(test-tool path-utils strip_path_suffix \ test c:/msysgit = $(test-tool path-utils strip_path_suffix \
c:/msysgit/libexec//git-core libexec/git-core) c:/msysgit/libexec//git-core libexec/git-core)

View File

@ -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 # 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 backslashes and tabs' ' 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 "$(printf "directory\twith\ttabs")" &&
>"$(printf "directory\twith\ttabs")/randomfile" &&
git add . &&
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 tabs/
EOF
rm -rf "$(printf "directory\twith\ttabs")" &&
git add . &&
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 # reset sparse-checkout
git -C sparse-checkout sparse-checkout disable && git -C sparse-checkout sparse-checkout disable &&
( (
cd sparse-checkout && cd sparse-checkout &&
mkdir "directory\with\backslashes" && mkdir "directory\with\backslashes" &&
mkdir "$(printf "directory\twith\ttabs")" &&
>"directory\with\backslashes/randomfile" && >"directory\with\backslashes/randomfile" &&
>"$(printf "directory\twith\ttabs")/randomfile" &&
git add . && git add . &&
git commit -m "Add directory with backslashes and directory with tabs" && git commit -m "Add directory with backslashes" &&
git sparse-checkout set --cone "directory\with\backslashes" \ git sparse-checkout set --cone \
"$(printf "directory\twith\ttabs")" && "directory\with\backslashes" &&
test_completion "git sparse-checkout add dir" <<-\EOF && test_completion "git sparse-checkout add dir" <<-\EOF &&
directory\with\backslashes/ directory\with\backslashes/
directory with tabs/
EOF EOF
rm -rf "directory\with\backslashes" && rm -rf "directory\with\backslashes" &&
rm -rf "$(printf "directory\twith\ttabs")" &&
git add . && git add . &&
git commit -m "Remove directory with backslashes and directory with tabs" git commit -m "Remove directory with backslashes"
) )
' '