Commit 7a5ee3dc by Russell Belfer

Add ~ expansion to global attributes and excludes

This adds ~/ prefix expansion for the value of core.attributesfile
and core.excludesfile, plus it fixes the fact that the attributes
cache was holding on to the string data from the config for a long
time (instead of making its own strdup) which could have caused a
problem if the config was refreshed.  Adds a test for the new
expansion capability.
parent d20b0449
......@@ -596,26 +596,33 @@ static int collect_attr_files(
}
static int attr_cache__lookup_path(
const char **out, git_config *cfg, const char *key, const char *fallback)
char **out, git_config *cfg, const char *key, const char *fallback)
{
git_buf buf = GIT_BUF_INIT;
int error;
const char *cfgval = NULL;
if (!(error = git_config_get_string(out, cfg, key)))
return 0;
*out = NULL;
if (!(error = git_config_get_string(&cfgval, cfg, key))) {
/* expand leading ~/ as needed */
if (cfgval && cfgval[0] == '~' && cfgval[1] == '/' &&
!git_futils_find_global_file(&buf, &cfgval[2]))
*out = git_buf_detach(&buf);
else if (cfgval)
*out = git__strdup(cfgval);
if (error == GIT_ENOTFOUND) {
} else if (error == GIT_ENOTFOUND) {
giterr_clear();
error = 0;
if (!git_futils_find_xdg_file(&buf, fallback))
*out = git_buf_detach(&buf);
else
*out = NULL;
git_buf_free(&buf);
}
git_buf_free(&buf);
return error;
}
......@@ -696,6 +703,12 @@ void git_attr_cache_flush(
git_pool_clear(&cache->pool);
git__free(cache->cfg_attr_file);
cache->cfg_attr_file = NULL;
git__free(cache->cfg_excl_file);
cache->cfg_excl_file = NULL;
cache->initialized = 0;
}
......
......@@ -13,10 +13,10 @@
typedef struct {
int initialized;
git_pool pool;
git_strmap *files; /* hash path to git_attr_file of rules */
git_strmap *macros; /* hash name to vector<git_attr_assignment> */
const char *cfg_attr_file; /* cached value of core.attributesfile */
const char *cfg_excl_file; /* cached value of core.excludesfile */
git_strmap *files; /* hash path to git_attr_file of rules */
git_strmap *macros; /* hash name to vector<git_attr_assignment> */
char *cfg_attr_file; /* cached value of core.attributesfile */
char *cfg_excl_file; /* cached value of core.excludesfile */
} git_attr_cache;
extern int git_attr_cache__init(git_repository *repo);
......
#include "clar_libgit2.h"
#include "posix.h"
#include "path.h"
#include "fileops.h"
static git_repository *g_repo = NULL;
......@@ -20,7 +21,7 @@ void assert_is_ignored(bool expected, const char *filepath)
int is_ignored;
cl_git_pass(git_ignore_path_is_ignored(&is_ignored, g_repo, filepath));
cl_assert_equal_i(expected, is_ignored == 1);
cl_assert_equal_b(expected, is_ignored);
}
void test_attr_ignore__honor_temporary_rules(void)
......@@ -46,3 +47,35 @@ void test_attr_ignore__skip_gitignore_directory(void)
assert_is_ignored(true, "NewFolder/NewFolder");
assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
}
void test_attr_ignore__expand_tilde_to_homedir(void)
{
git_buf path = GIT_BUF_INIT;
git_config *cfg;
assert_is_ignored(false, "example.global_with_tilde");
/* construct fake home with fake global excludes */
cl_must_pass(p_mkdir("home", 0777));
cl_git_pass(git_path_prettify(&path, "home", NULL));
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
cl_git_mkfile("home/globalexcludes", "# found me\n*.global_with_tilde\n");
cl_git_pass(git_repository_config(&cfg, g_repo));
cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexcludes"));
git_config_free(cfg);
git_attr_cache_flush(g_repo); /* must reset to pick up change */
assert_is_ignored(true, "example.global_with_tilde");
cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES));
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
git_buf_free(&path);
}
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