Commit 6a67a812 by Russell Belfer

Allow ignores (and attribs) for nonexistent files

This fixes issue 532 that attributes (and gitignores) could not
be checked for files that don't exist.  It should be possible to
query such things regardless of the existence of the file.
parent fdaa9240
......@@ -536,13 +536,25 @@ int git_futils_find_system_file(git_buf *path, const char *filename)
int git_futils_dir_for_path(git_buf *dir, const char *path, const char *base)
{
if (git_path_prettify(dir, path, base) == GIT_SUCCESS) {
/* call dirname if this is not a directory */
if (git_futils_isdir(dir->ptr) != GIT_SUCCESS)
git_path_dirname_r(dir, dir->ptr);
int error = GIT_SUCCESS;
if (base != NULL && git_path_root(path) < 0)
error = git_buf_joinpath(dir, base, path);
else
error = git_buf_sets(dir, path);
git_path_to_dir(dir);
if (error == GIT_SUCCESS) {
char buf[GIT_PATH_MAX];
if (p_realpath(dir->ptr, buf) != NULL)
error = git_buf_sets(dir, buf);
}
return git_buf_lasterror(dir);
/* call dirname if this is not a directory */
if (error == GIT_SUCCESS && git_futils_isdir(dir->ptr) != GIT_SUCCESS)
error = git_path_dirname_r(dir, dir->ptr);
if (error == GIT_SUCCESS)
error = git_path_to_dir(dir);
return error;
}
......@@ -104,8 +104,10 @@ extern int git_futils_rmdir_r(const char *path, int force);
/**
* Get the directory for a path.
*
* If the path is a directory, this does nothing (save append a '/' as needed).
* If path is a normal file, this gets the directory containing it.
* If the path is a directory, this does nothing (save append a '/' as
* needed). If path is a normal file, this gets the directory containing
* it. If the path does not exist, then this treats it a filename and
* returns the dirname of it.
*/
extern int git_futils_dir_for_path(git_buf *dir, const char *path, const char *base);
......
......@@ -146,3 +146,17 @@ found:
return error;
}
int git_ignore_is_ignored(git_repository *repo, const char *path, int *ignored)
{
int error;
git_vector ignores = GIT_VECTOR_INIT;
if ((error = git_ignore__for_path(repo, path, &ignores)) == GIT_SUCCESS)
error = git_ignore__lookup(&ignores, path, ignored);
git_ignore__free(&ignores);
return error;
}
......@@ -14,4 +14,6 @@ extern int git_ignore__for_path(git_repository *repo, const char *path, git_vect
extern void git_ignore__free(git_vector *stack);
extern int git_ignore__lookup(git_vector *stack, const char *path, int *ignored);
extern int git_ignore_is_ignored(git_repository *repo, const char *path, int *ignored);
#endif
......@@ -57,6 +57,7 @@ void test_attr_repo__get_one(void)
{ "subdir/subdir_test2.txt", "subattr", "yes" },
{ "subdir/subdir_test2.txt", "negattr", GIT_ATTR_FALSE },
{ "subdir/subdir_test2.txt", "another", "one" },
{ "does-not-exist", "foo", "yes" },
{ NULL, NULL, NULL }
}, *scan;
......
#include "clay_libgit2.h"
#include "fileops.h"
#include "ignore.h"
#include "status_data.h"
......@@ -135,3 +136,19 @@ void test_status_worktree__single_file(void)
cl_assert(entry_statuses0[i] == status_flags);
}
}
void test_status_worktree__ignores(void)
{
int i, ignored;
for (i = 0; i < (int)entry_count0; i++) {
cl_git_pass(git_ignore_is_ignored(_repository, entry_paths0[i], &ignored));
cl_assert(ignored == (entry_statuses0[i] == GIT_STATUS_IGNORED));
}
cl_git_pass(git_ignore_is_ignored(_repository, "nonexistent_file", &ignored));
cl_assert(!ignored);
cl_git_pass(git_ignore_is_ignored(_repository, "ignored_nonexistent_file", &ignored));
cl_assert(ignored);
}
......@@ -3,6 +3,7 @@ root_test2 -rootattr
root_test3 !rootattr
binfile binary
abc foo bar baz
does-not-exist foo=yes
root_test2 multiattr
root_test3 multi2=foo
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment