Skip to content

Commit e9a379c

Browse files
j6tgitster
authored andcommitted
real_path: canonicalize directory separators in root parts
When an absolute path is resolved, resolution begins at the first path component after the root part. The root part is just copied verbatim, because it must not be inspected for symbolic links. For POSIX paths, this is just the initial slash, but on Windows, the root part has the forms c:\ or \\server\share. We do want to canonicalize the back-slashes in the root part because these parts are compared to the result of getcwd(), which does return a fully canonicalized path. Factor out a helper that splits off the root part, and have it canonicalize the copied part. This change was prompted because t1504-ceiling-dirs.sh caught a breakage in GIT_CEILING_DIRECTORIES handling on Windows. Signed-off-by: Johannes Sixt <[email protected]> Acked-by: Brandon Williams <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4ac9006 commit e9a379c

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

abspath.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,19 @@ static void get_next_component(struct strbuf *next, struct strbuf *remaining)
4848
strbuf_remove(remaining, 0, end - remaining->buf);
4949
}
5050

51+
/* copies root part from remaining to resolved, canonicalizing it on the way */
52+
static void get_root_part(struct strbuf *resolved, struct strbuf *remaining)
53+
{
54+
int offset = offset_1st_component(remaining->buf);
55+
56+
strbuf_reset(resolved);
57+
strbuf_add(resolved, remaining->buf, offset);
58+
#ifdef GIT_WINDOWS_NATIVE
59+
convert_slashes(resolved->buf);
60+
#endif
61+
strbuf_remove(remaining, 0, offset);
62+
}
63+
5164
/* We allow "recursive" symbolic links. Only within reason, though. */
5265
#define MAXSYMLINKS 5
5366

@@ -80,22 +93,17 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
8093
goto error_out;
8194
}
8295

83-
strbuf_reset(resolved);
96+
strbuf_addstr(&remaining, path);
97+
get_root_part(resolved, &remaining);
8498

85-
if (is_absolute_path(path)) {
86-
/* absolute path; start with only root as being resolved */
87-
int offset = offset_1st_component(path);
88-
strbuf_add(resolved, path, offset);
89-
strbuf_addstr(&remaining, path + offset);
90-
} else {
99+
if (!resolved->len) {
91100
/* relative path; can use CWD as the initial resolved path */
92101
if (strbuf_getcwd(resolved)) {
93102
if (die_on_error)
94103
die_errno("unable to get current working directory");
95104
else
96105
goto error_out;
97106
}
98-
strbuf_addstr(&remaining, path);
99107
}
100108

101109
/* Iterate over the remaining path components */
@@ -150,10 +158,7 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
150158

151159
if (is_absolute_path(symlink.buf)) {
152160
/* absolute symlink; set resolved to root */
153-
int offset = offset_1st_component(symlink.buf);
154-
strbuf_reset(resolved);
155-
strbuf_add(resolved, symlink.buf, offset);
156-
strbuf_remove(&symlink, 0, offset);
161+
get_root_part(resolved, &symlink);
157162
} else {
158163
/*
159164
* relative symlink

0 commit comments

Comments
 (0)