mirror of
https://git.proxmox.com/git/libgit2
synced 2025-10-14 16:48:01 +00:00
git_path_join_unrooted: return base len
The documentation for `git_path_join_unrooted` states that the base length will be returned, so that consumers like checkout know where to start creating directories instead of always creating directories at the directory root.
This commit is contained in:
parent
1d50b3649d
commit
1fbfcdfcd0
@ -1102,7 +1102,7 @@ static int checkout_conflicts_mark_directoryfile(
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixed = git_path_equal_or_prefixed(path, entry->path);
|
prefixed = git_path_equal_or_prefixed(path, entry->path, NULL);
|
||||||
|
|
||||||
if (prefixed == GIT_PATH_EQUAL)
|
if (prefixed == GIT_PATH_EQUAL)
|
||||||
continue;
|
continue;
|
||||||
|
27
src/path.c
27
src/path.c
@ -263,26 +263,31 @@ int git_path_root(const char *path)
|
|||||||
int git_path_join_unrooted(
|
int git_path_join_unrooted(
|
||||||
git_buf *path_out, const char *path, const char *base, ssize_t *root_at)
|
git_buf *path_out, const char *path, const char *base, ssize_t *root_at)
|
||||||
{
|
{
|
||||||
int error, root;
|
ssize_t root;
|
||||||
|
|
||||||
assert(path && path_out);
|
assert(path && path_out);
|
||||||
|
|
||||||
root = git_path_root(path);
|
root = (ssize_t)git_path_root(path);
|
||||||
|
|
||||||
if (base != NULL && root < 0) {
|
if (base != NULL && root < 0) {
|
||||||
error = git_buf_joinpath(path_out, base, path);
|
if (git_buf_joinpath(path_out, base, path) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (root_at)
|
root = (ssize_t)strlen(base);
|
||||||
*root_at = (ssize_t)strlen(base);
|
} else {
|
||||||
}
|
if (git_buf_sets(path_out, path) < 0)
|
||||||
else {
|
return -1;
|
||||||
error = git_buf_sets(path_out, path);
|
|
||||||
|
|
||||||
if (root_at)
|
if (root < 0)
|
||||||
*root_at = (root < 0) ? 0 : (ssize_t)root;
|
root = 0;
|
||||||
|
else if (base)
|
||||||
|
git_path_equal_or_prefixed(base, path, &root);
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
if (root_at)
|
||||||
|
*root_at = root;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_path_prettify(git_buf *path_out, const char *path, const char *base)
|
int git_path_prettify(git_buf *path_out, const char *path, const char *base)
|
||||||
|
20
src/path.h
20
src/path.h
@ -396,21 +396,35 @@ enum { GIT_PATH_NOTEQUAL = 0, GIT_PATH_EQUAL = 1, GIT_PATH_PREFIX = 2 };
|
|||||||
*/
|
*/
|
||||||
GIT_INLINE(int) git_path_equal_or_prefixed(
|
GIT_INLINE(int) git_path_equal_or_prefixed(
|
||||||
const char *parent,
|
const char *parent,
|
||||||
const char *child)
|
const char *child,
|
||||||
|
ssize_t *prefixlen)
|
||||||
{
|
{
|
||||||
const char *p = parent, *c = child;
|
const char *p = parent, *c = child;
|
||||||
|
int lastslash = 0;
|
||||||
|
|
||||||
while (*p && *c) {
|
while (*p && *c) {
|
||||||
|
lastslash = (*p == '/');
|
||||||
|
|
||||||
if (*p++ != *c++)
|
if (*p++ != *c++)
|
||||||
return GIT_PATH_NOTEQUAL;
|
return GIT_PATH_NOTEQUAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*p != '\0')
|
if (*p != '\0')
|
||||||
return GIT_PATH_NOTEQUAL;
|
return GIT_PATH_NOTEQUAL;
|
||||||
if (*c == '\0')
|
|
||||||
|
if (*c == '\0') {
|
||||||
|
if (prefixlen)
|
||||||
|
*prefixlen = p - parent;
|
||||||
|
|
||||||
return GIT_PATH_EQUAL;
|
return GIT_PATH_EQUAL;
|
||||||
if (*c == '/')
|
}
|
||||||
|
|
||||||
|
if (*c == '/' || lastslash) {
|
||||||
|
if (prefixlen)
|
||||||
|
*prefixlen = (p - parent) - lastslash;
|
||||||
|
|
||||||
return GIT_PATH_PREFIX;
|
return GIT_PATH_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
return GIT_PATH_NOTEQUAL;
|
return GIT_PATH_NOTEQUAL;
|
||||||
}
|
}
|
||||||
|
@ -305,3 +305,50 @@ void test_path_core__isvalid_dotgit_with_hfs_ignorables(void)
|
|||||||
cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", GIT_PATH_REJECT_DOT_GIT_HFS));
|
cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", GIT_PATH_REJECT_DOT_GIT_HFS));
|
||||||
cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", GIT_PATH_REJECT_DOT_GIT_HFS));
|
cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", GIT_PATH_REJECT_DOT_GIT_HFS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_join_unrooted(
|
||||||
|
const char *expected_result,
|
||||||
|
ssize_t expected_rootlen,
|
||||||
|
const char *path,
|
||||||
|
const char *base)
|
||||||
|
{
|
||||||
|
git_buf result = GIT_BUF_INIT;
|
||||||
|
ssize_t root_at;
|
||||||
|
|
||||||
|
cl_git_pass(git_path_join_unrooted(&result, path, base, &root_at));
|
||||||
|
cl_assert_equal_s(expected_result, result.ptr);
|
||||||
|
cl_assert_equal_i(expected_rootlen, root_at);
|
||||||
|
|
||||||
|
git_buf_free(&result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_path_core__join_unrooted(void)
|
||||||
|
{
|
||||||
|
git_buf out = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
test_join_unrooted("foo", 0, "foo", NULL);
|
||||||
|
test_join_unrooted("foo/bar", 0, "foo/bar", NULL);
|
||||||
|
|
||||||
|
/* Relative paths have base prepended */
|
||||||
|
test_join_unrooted("/foo/bar", 4, "bar", "/foo");
|
||||||
|
test_join_unrooted("/foo/bar/foobar", 4, "bar/foobar", "/foo");
|
||||||
|
test_join_unrooted("c:/foo/bar/foobar", 6, "bar/foobar", "c:/foo");
|
||||||
|
test_join_unrooted("c:/foo/bar/foobar", 10, "foobar", "c:/foo/bar");
|
||||||
|
|
||||||
|
/* Absolute paths are not prepended with base */
|
||||||
|
test_join_unrooted("/foo", 0, "/foo", "/asdf");
|
||||||
|
test_join_unrooted("/foo/bar", 0, "/foo/bar", "/asdf");
|
||||||
|
|
||||||
|
/* Drive letter is given as root length on Windows */
|
||||||
|
test_join_unrooted("c:/foo", 2, "c:/foo", "c:/asdf");
|
||||||
|
test_join_unrooted("c:/foo/bar", 2, "c:/foo/bar", "c:/asdf");
|
||||||
|
|
||||||
|
/* Base is returned when it's provided and is the prefix */
|
||||||
|
test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo");
|
||||||
|
test_join_unrooted("c:/foo/bar/foobar", 10, "c:/foo/bar/foobar", "c:/foo/bar");
|
||||||
|
|
||||||
|
/* Trailing slash in the base is ignored */
|
||||||
|
test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo/");
|
||||||
|
|
||||||
|
git_buf_free(&out);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user