summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe rugged tests are fragile <tanoku@gmail.com>2014-09-17 14:52:31 +0200
committerThe rugged tests are fragile <tanoku@gmail.com>2014-09-17 15:00:12 +0200
commitbbb988a5190be2a8763c60cb37c52466a39f6441 (patch)
tree691ad5fcfc3097bf2d593d280fa64f808b27dbf5
parent1312f87b6838649cca525935656c84c7bd07a9a1 (diff)
downloadlibgit2-bbb988a5190be2a8763c60cb37c52466a39f6441.tar.gz
path: Fix `git_path_walk_up` to work with non-rooted paths
-rw-r--r--src/attr.c4
-rw-r--r--src/fileops.c8
-rw-r--r--src/ignore.c4
-rw-r--r--src/path.c19
-rw-r--r--src/path.h2
-rw-r--r--tests/core/path.c53
-rw-r--r--tests/path/core.c2
7 files changed, 64 insertions, 28 deletions
diff --git a/src/attr.c b/src/attr.c
index dee84b0ab..fd0ab9274 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -377,7 +377,7 @@ static int push_attr_file(
return error;
}
-static int push_one_attr(void *ref, git_buf *path)
+static int push_one_attr(void *ref, const char *path)
{
int error = 0, n_src, i;
attr_walk_up_info *info = (attr_walk_up_info *)ref;
@@ -388,7 +388,7 @@ static int push_one_attr(void *ref, git_buf *path)
for (i = 0; !error && i < n_src; ++i)
error = push_attr_file(
- info->repo, info->files, src[i], path->ptr, GIT_ATTR_FILE);
+ info->repo, info->files, src[i], path, GIT_ATTR_FILE);
return error;
}
diff --git a/src/fileops.c b/src/fileops.c
index 34659ad3b..bd9d27c7a 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -505,15 +505,15 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
return error;
}
-static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
+static int futils__rmdir_empty_parent(void *opaque, const char *path)
{
futils__rmdir_data *data = opaque;
int error = 0;
- if (git_buf_len(path) <= data->baselen)
+ if (strlen(path) <= data->baselen)
error = GIT_ITEROVER;
- else if (p_rmdir(git_buf_cstr(path)) < 0) {
+ else if (p_rmdir(path) < 0) {
int en = errno;
if (en == ENOENT || en == ENOTDIR) {
@@ -521,7 +521,7 @@ static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
} else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) {
error = GIT_ITEROVER;
} else {
- error = git_path_set_error(errno, git_buf_cstr(path), "rmdir");
+ error = git_path_set_error(errno, path, "rmdir");
}
}
diff --git a/src/ignore.c b/src/ignore.c
index 78f01ac44..520bcfe41 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -91,11 +91,11 @@ static int push_ignore_file(
return error;
}
-static int push_one_ignore(void *payload, git_buf *path)
+static int push_one_ignore(void *payload, const char *path)
{
git_ignores *ign = payload;
ign->depth++;
- return push_ignore_file(ign, &ign->ign_path, path->ptr, GIT_IGNORE_FILE);
+ return push_ignore_file(ign, &ign->ign_path, path, GIT_IGNORE_FILE);
}
static int get_internal_ignores(git_attr_file **out, git_repository *repo)
diff --git a/src/path.c b/src/path.c
index 760efec12..599e92295 100644
--- a/src/path.c
+++ b/src/path.c
@@ -417,7 +417,7 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url)
int git_path_walk_up(
git_buf *path,
const char *ceiling,
- int (*cb)(void *data, git_buf *),
+ int (*cb)(void *data, const char *),
void *data)
{
int error = 0;
@@ -435,12 +435,20 @@ int git_path_walk_up(
}
scan = git_buf_len(path);
+ /* empty path: yield only once */
+ if (!scan) {
+ error = cb(data, "");
+ if (error)
+ giterr_set_after_callback(error);
+ return error;
+ }
+
iter.ptr = path->ptr;
iter.size = git_buf_len(path);
iter.asize = path->asize;
while (scan >= stop) {
- error = cb(data, &iter);
+ error = cb(data, iter.ptr);
iter.ptr[scan] = oldc;
if (error) {
@@ -460,6 +468,13 @@ int git_path_walk_up(
if (scan >= 0)
iter.ptr[scan] = oldc;
+ /* relative path: yield for the last component */
+ if (!error && stop == 0 && iter.ptr[0] != '/') {
+ error = cb(data, "");
+ if (error)
+ giterr_set_after_callback(error);
+ }
+
return error;
}
diff --git a/src/path.h b/src/path.h
index d0a9de707..11bb6d173 100644
--- a/src/path.h
+++ b/src/path.h
@@ -323,7 +323,7 @@ extern int git_path_cmp(
extern int git_path_walk_up(
git_buf *pathbuf,
const char *ceiling,
- int (*callback)(void *payload, git_buf *path),
+ int (*callback)(void *payload, const char *path),
void *payload);
/**
diff --git a/tests/core/path.c b/tests/core/path.c
index 471491b87..7d3e4938f 100644
--- a/tests/core/path.c
+++ b/tests/core/path.c
@@ -356,7 +356,7 @@ typedef struct {
#define CANCEL_VALUE 1234
-static int check_one_walkup_step(void *ref, git_buf *path)
+static int check_one_walkup_step(void *ref, const char *path)
{
check_walkup_info *info = (check_walkup_info *)ref;
@@ -367,7 +367,7 @@ static int check_one_walkup_step(void *ref, git_buf *path)
info->cancel_after--;
cl_assert(info->expect[info->expect_idx] != NULL);
- cl_assert_equal_s(info->expect[info->expect_idx], path->ptr);
+ cl_assert_equal_s(info->expect[info->expect_idx], path);
info->expect_idx++;
return 0;
@@ -376,18 +376,42 @@ static int check_one_walkup_step(void *ref, git_buf *path)
void test_core_path__11_walkup(void)
{
git_buf p = GIT_BUF_INIT;
+
char *expect[] = {
- "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
- "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
- "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
- "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
- "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
- "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
- "this is a path", NULL,
- "///a///b///c///d///e///", "///a///b///c///d///", "///a///b///c///", "///a///b///", "///a///", "///", NULL,
- NULL
+ /* 1 */ "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+ /* 2 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+ /* 3 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+ /* 4 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+ /* 5 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
+ /* 6 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
+ /* 7 */ "this_is_a_path", "", NULL,
+ /* 8 */ "this_is_a_path/", "", NULL,
+ /* 9 */ "///a///b///c///d///e///", "///a///b///c///d///", "///a///b///c///", "///a///b///", "///a///", "///", NULL,
+ /* 10 */ "a/b/c/", "a/b/", "a/", "", NULL,
+ /* 11 */ "a/b/c", "a/b/", "a/", "", NULL,
+ /* 12 */ "a/b/c/", "a/b/", "a/", NULL,
+ /* 13 */ "", NULL,
+ /* 14 */ "/", NULL,
+ /* 15 */ NULL
+ };
+
+ char *root[] = {
+ /* 1 */ NULL,
+ /* 2 */ NULL,
+ /* 3 */ "/",
+ /* 4 */ "",
+ /* 5 */ "/a/b",
+ /* 6 */ "/a/b/",
+ /* 7 */ NULL,
+ /* 8 */ NULL,
+ /* 9 */ NULL,
+ /* 10 */ NULL,
+ /* 11 */ NULL,
+ /* 12 */ "a/",
+ /* 13 */ NULL,
+ /* 14 */ NULL,
};
- char *root[] = { NULL, NULL, "/", "", "/a/b", "/a/b/", NULL, NULL, NULL };
+
int i, j;
check_walkup_info info;
@@ -404,9 +428,8 @@ void test_core_path__11_walkup(void)
);
cl_assert_equal_s(p.ptr, expect[i]);
-
- /* skip to next run of expectations */
- while (expect[i] != NULL) i++;
+ cl_assert(expect[info.expect_idx] == NULL);
+ i = info.expect_idx;
}
git_buf_free(&p);
diff --git a/tests/path/core.c b/tests/path/core.c
index be63e309b..45f54df29 100644
--- a/tests/path/core.c
+++ b/tests/path/core.c
@@ -16,8 +16,6 @@ static void test_make_relative(
void test_path_core__make_relative(void)
{
- git_buf buf = GIT_BUF_INIT;
-
test_make_relative("foo.c", "/path/to/foo.c", "/path/to", 0);
test_make_relative("bar/foo.c", "/path/to/bar/foo.c", "/path/to", 0);
test_make_relative("foo.c", "/path/to/foo.c", "/path/to/", 0);