aboutsummaryrefslogtreecommitdiffstats
path: root/compat/win32/path-utils.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2024-07-13 21:08:20 +0000
committerJunio C Hamano <gitster@pobox.com>2024-07-13 16:23:36 -0700
commit193eda7507d0ccb2fe6fd42b403c56ecc205e546 (patch)
tree78c49fc2f26f9fe7f04bf84222c0aa36b3d60af6 /compat/win32/path-utils.c
parentstrvec: declare the `strvec_push_nodup()` function globally (diff)
downloadgit-193eda7507d0ccb2fe6fd42b403c56ecc205e546.tar.gz
git-193eda7507d0ccb2fe6fd42b403c56ecc205e546.zip
win32: override `fspathcmp()` with a directory separator-aware version
On Windows, the backslash is the directory separator, even if the forward slash can be used, too, at least since Windows NT. This means that the paths `a/b` and `a\b` are equivalent, and `fspathcmp()` needs to be made aware of that fact. Note that we have to override both `fspathcmp()` and `fspathncmp()`, and the former cannot be a mere pre-processor constant that transforms calls to `fspathcmp(a, b)` into `fspathncmp(a, b, (size_t)-1)` because the function `report_collided_checkout()` in `unpack-trees.c` wants to assign `list.cmp = fspathcmp`. Also note that `fspatheq()` does _not_ need to be overridden because it calls `fspathcmp()` internally. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat/win32/path-utils.c')
-rw-r--r--compat/win32/path-utils.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/compat/win32/path-utils.c b/compat/win32/path-utils.c
index ebf2f12eb6..b658ca3f81 100644
--- a/compat/win32/path-utils.c
+++ b/compat/win32/path-utils.c
@@ -1,4 +1,5 @@
#include "../../git-compat-util.h"
+#include "../../environment.h"
int win32_has_dos_drive_prefix(const char *path)
{
@@ -50,3 +51,39 @@ int win32_offset_1st_component(const char *path)
return pos + is_dir_sep(*pos) - path;
}
+
+int win32_fspathncmp(const char *a, const char *b, size_t count)
+{
+ int diff;
+
+ for (;;) {
+ if (!count--)
+ return 0;
+ if (!*a)
+ return *b ? -1 : 0;
+ if (!*b)
+ return +1;
+
+ if (is_dir_sep(*a)) {
+ if (!is_dir_sep(*b))
+ return -1;
+ a++;
+ b++;
+ continue;
+ } else if (is_dir_sep(*b))
+ return +1;
+
+ diff = ignore_case ?
+ (unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
+ (unsigned char)*a - (int)(unsigned char)*b;
+ if (diff)
+ return diff;
+ a++;
+ b++;
+ }
+}
+
+int win32_fspathcmp(const char *a, const char *b)
+{
+ return win32_fspathncmp(a, b, (size_t)-1);
+}