Skip to content

Commit a1023a4

Browse files
authored
Merge pull request libgit2#4179 from libgit2/ethomson/expand_tilde
Introduce home directory expansion function for config files, attribute files
2 parents 9b1260d + e65b5e9 commit a1023a4

File tree

6 files changed

+52
-19
lines changed

6 files changed

+52
-19
lines changed

src/attrcache.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,16 @@ static int attr_cache__lookup_path(
290290
const char *cfgval = entry->value;
291291

292292
/* expand leading ~/ as needed */
293-
if (cfgval && cfgval[0] == '~' && cfgval[1] == '/' &&
294-
!git_sysdir_find_global_file(&buf, &cfgval[2]))
295-
*out = git_buf_detach(&buf);
296-
else if (cfgval)
293+
if (cfgval && cfgval[0] == '~' && cfgval[1] == '/') {
294+
if (! (error = git_sysdir_expand_global_file(&buf, &cfgval[2])))
295+
*out = git_buf_detach(&buf);
296+
} else if (cfgval) {
297297
*out = git__strdup(cfgval);
298+
}
298299
}
299-
else if (!git_sysdir_find_xdg_file(&buf, fallback))
300+
else if (!git_sysdir_find_xdg_file(&buf, fallback)) {
300301
*out = git_buf_detach(&buf);
302+
}
301303

302304
git_config_entry_free(entry);
303305
git_buf_free(&buf);

src/config.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,9 +1358,6 @@ int git_config_parse_int32(int32_t *out, const char *value)
13581358

13591359
int git_config_parse_path(git_buf *out, const char *value)
13601360
{
1361-
int error = 0;
1362-
const git_buf *home;
1363-
13641361
assert(out && value);
13651362

13661363
git_buf_sanitize(out);
@@ -1371,16 +1368,7 @@ int git_config_parse_path(git_buf *out, const char *value)
13711368
return -1;
13721369
}
13731370

1374-
if ((error = git_sysdir_get(&home, GIT_SYSDIR_GLOBAL)) < 0)
1375-
return error;
1376-
1377-
git_buf_sets(out, home->ptr);
1378-
git_buf_puts(out, value + 1);
1379-
1380-
if (git_buf_oom(out))
1381-
return -1;
1382-
1383-
return 0;
1371+
return git_sysdir_expand_global_file(out, value[1] ? &value[2] : NULL);
13841372
}
13851373

13861374
return git_buf_sets(out, value);

src/config_file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ static int included_path(git_buf *out, const char *dir, const char *path)
12561256
{
12571257
/* From the user's home */
12581258
if (path[0] == '~' && path[1] == '/')
1259-
return git_sysdir_find_global_file(out, &path[1]);
1259+
return git_sysdir_expand_global_file(out, &path[1]);
12601260

12611261
return git_path_join_unrooted(out, path, dir, NULL);
12621262
}

src/sysdir.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,14 @@ int git_sysdir_find_template_dir(git_buf *path)
275275
path, NULL, GIT_SYSDIR_TEMPLATE, "template");
276276
}
277277

278+
int git_sysdir_expand_global_file(git_buf *path, const char *filename)
279+
{
280+
int error;
281+
282+
if ((error = git_sysdir_find_global_file(path, NULL)) == 0) {
283+
if (filename)
284+
error = git_buf_joinpath(path, path->ptr, filename);
285+
}
286+
287+
return error;
288+
}

src/sysdir.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ extern int git_sysdir_find_programdata_file(git_buf *path, const char *filename)
5555
*/
5656
extern int git_sysdir_find_template_dir(git_buf *path);
5757

58+
/**
59+
* Expand the name of a "global" file (i.e. one in a user's home
60+
* directory). Unlike `find_global_file` (above), this makes no
61+
* attempt to check for the existence of the file, and is useful if
62+
* you want the full path regardless of existence.
63+
*
64+
* @param path buffer to write the full path into
65+
* @param filename name of file in the home directory
66+
* @return 0 on success or -1 on error
67+
*/
68+
extern int git_sysdir_expand_global_file(git_buf *path, const char *filename);
69+
5870
typedef enum {
5971
GIT_SYSDIR_SYSTEM = 0,
6072
GIT_SYSDIR_GLOBAL = 1,

tests/config/include.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@ void test_config_include__missing(void)
108108
git_config_free(cfg);
109109
}
110110

111+
void test_config_include__missing_homedir(void)
112+
{
113+
git_config *cfg;
114+
git_buf buf = GIT_BUF_INIT;
115+
116+
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, cl_fixture("config")));
117+
cl_git_mkfile("including", "[include]\npath = ~/.nonexistentfile\n[foo]\nbar = baz");
118+
119+
giterr_clear();
120+
cl_git_pass(git_config_open_ondisk(&cfg, "including"));
121+
cl_assert(giterr_last() == NULL);
122+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar"));
123+
cl_assert_equal_s("baz", git_buf_cstr(&buf));
124+
125+
git_buf_free(&buf);
126+
git_config_free(cfg);
127+
128+
cl_sandbox_set_search_path_defaults();
129+
}
130+
111131
#define replicate10(s) s s s s s s s s s s
112132
void test_config_include__depth2(void)
113133
{

0 commit comments

Comments
 (0)