summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2012-11-17 13:39:24 -0800
committernulltoken <emeric.fermas@gmail.com>2012-11-17 18:30:34 -0800
commit270160b91a0e55486f2cb6a6238c39fcd1271809 (patch)
tree9ba94cc336c12c29955324b1d3572869154aab94
parentd36451c9d4ba071de07106371553bf93f2717fc4 (diff)
downloadlibgit2-270160b91a0e55486f2cb6a6238c39fcd1271809.tar.gz
config: Opening a nonexistent file returns ENOTFOUND
-rw-r--r--include/git2/config.h11
-rw-r--r--src/config.c26
-rw-r--r--src/repository.c23
-rw-r--r--tests-clar/config/new.c1
-rw-r--r--tests-clar/config/read.c20
5 files changed, 69 insertions, 12 deletions
diff --git a/include/git2/config.h b/include/git2/config.h
index 8270aefa4..8ec78e35c 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -189,7 +189,8 @@ GIT_EXTERN(int) git_config_add_file(
* @param force if a config file already exists for the given
* priority level, replace it
* @return 0 on success, GIT_EEXISTS when adding more than one file
- * for a given priority level (and force_replace set to 0), or error code
+ * for a given priority level (and force_replace set to 0),
+ * GIT_ENOTFOUND when the file doesn't exist or error code
*/
GIT_EXTERN(int) git_config_add_file_ondisk(
git_config *cfg,
@@ -197,7 +198,6 @@ GIT_EXTERN(int) git_config_add_file_ondisk(
unsigned int level,
int force);
-
/**
* Create a new config instance containing a single on-disk file
*
@@ -206,11 +206,12 @@ GIT_EXTERN(int) git_config_add_file_ondisk(
* - git_config_new
* - git_config_add_file_ondisk
*
- * @param cfg The configuration instance to create
+ * @param out The configuration instance to create
* @param path Path to the on-disk file to open
- * @return 0 or an error code
+ * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist
+ * or an error code
*/
-GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path);
+GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path);
/**
* Build a single-level focused config object from a multi-level one.
diff --git a/src/config.c b/src/config.c
index 01a54ecf2..412965b73 100644
--- a/src/config.c
+++ b/src/config.c
@@ -90,6 +90,13 @@ int git_config_add_file_ondisk(
git_config_file *file = NULL;
int res;
+ assert(cfg && path);
+
+ if (!git_path_isfile(path)) {
+ giterr_set(GITERR_CONFIG, "File '%s' doesn't exists.", path);
+ return GIT_ENOTFOUND;
+ }
+
if (git_config_file__ondisk(&file, path) < 0)
return -1;
@@ -105,17 +112,22 @@ int git_config_add_file_ondisk(
return 0;
}
-int git_config_open_ondisk(git_config **cfg, const char *path)
+int git_config_open_ondisk(git_config **out, const char *path)
{
- if (git_config_new(cfg) < 0)
- return -1;
+ int error;
+ git_config *config;
- if (git_config_add_file_ondisk(*cfg, path, GIT_CONFIG_LEVEL_LOCAL, 0) < 0) {
- git_config_free(*cfg);
+ *out = NULL;
+
+ if (git_config_new(&config) < 0)
return -1;
- }
- return 0;
+ if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0)
+ git_config_free(config);
+ else
+ *out = config;
+
+ return error;
}
static int find_internal_file_by_level(
diff --git a/src/repository.c b/src/repository.c
index 2d6ce4dbb..c1756b1bc 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -750,6 +750,23 @@ static bool are_symlinks_supported(const char *wd_path)
return _symlinks_supported;
}
+static int create_empty_file(const char *path, mode_t mode)
+{
+ int fd;
+
+ if ((fd = p_creat(path, mode)) < 0) {
+ giterr_set(GITERR_OS, "Error while creating '%s'", path);
+ return -1;
+ }
+
+ if (p_close(fd) < 0) {
+ giterr_set(GITERR_OS, "Error while closing '%s'", path);
+ return -1;
+ }
+
+ return 0;
+}
+
static int repo_init_config(
const char *repo_dir,
const char *work_dir,
@@ -766,6 +783,12 @@ static int repo_init_config(
if (git_buf_joinpath(&cfg_path, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
return -1;
+ if (!git_path_isfile(git_buf_cstr(&cfg_path)) &&
+ create_empty_file(git_buf_cstr(&cfg_path), GIT_CONFIG_FILE_MODE) < 0) {
+ git_buf_free(&cfg_path);
+ return -1;
+ }
+
if (git_config_open_ondisk(&config, git_buf_cstr(&cfg_path)) < 0) {
git_buf_free(&cfg_path);
return -1;
diff --git a/tests-clar/config/new.c b/tests-clar/config/new.c
index 6bd719fba..dd6dbca9e 100644
--- a/tests-clar/config/new.c
+++ b/tests-clar/config/new.c
@@ -11,6 +11,7 @@ void test_config_new__write_new_config(void)
const char *out;
git_config *config;
+ cl_git_mkfile(TEST_CONFIG, "");
cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
cl_git_pass(git_config_set_string(config, "color.ui", "auto"));
diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c
index 7b30b6e12..d63ef4c91 100644
--- a/tests-clar/config/read.c
+++ b/tests-clar/config/read.c
@@ -430,3 +430,23 @@ void test_config_read__simple_read_from_specific_level(void)
git_config_free(cfg_specific);
git_config_free(cfg);
}
+
+void test_config_read__can_load_and_parse_an_empty_config_file(void)
+{
+ git_config *cfg;
+ int i;
+
+ cl_git_mkfile("./empty", "");
+ cl_git_pass(git_config_open_ondisk(&cfg, "./empty"));
+ cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither"));
+
+ git_config_free(cfg);
+}
+
+void test_config_read__cannot_load_a_non_existing_config_file(void)
+{
+ git_config *cfg;
+ int i;
+
+ cl_assert_equal_i(GIT_ENOTFOUND, git_config_open_ondisk(&cfg, "./no.config"));
+}