diff options
Diffstat (limited to 'tests-clar')
29 files changed, 670 insertions, 150 deletions
diff --git a/tests-clar/README.md b/tests-clar/README.md index 03a4d54d3..3aeaaf464 100644 --- a/tests-clar/README.md +++ b/tests-clar/README.md @@ -4,7 +4,7 @@ Writing Clar tests for libgit2 For information on the Clar testing framework and a detailed introduction please visit: -https://github.com/tanoku/clar +https://github.com/vmg/clar * Write your modules and tests. Use good, meaningful names. diff --git a/tests-clar/checkout/head.c b/tests-clar/checkout/head.c new file mode 100644 index 000000000..d36034c52 --- /dev/null +++ b/tests-clar/checkout/head.c @@ -0,0 +1,22 @@ +#include "clar_libgit2.h" +#include "refs.h" +#include "repo/repo_helpers.h" + +static git_repository *g_repo; + +void test_checkout_head__initialize(void) +{ + g_repo = cl_git_sandbox_init("testrepo"); +} + +void test_checkout_head__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_checkout_head__checking_out_an_orphaned_head_returns_GIT_EORPHANEDHEAD(void) +{ + make_head_orphaned(g_repo, NON_EXISTING_HEAD); + + cl_assert_equal_i(GIT_EORPHANEDHEAD, git_checkout_head(g_repo, NULL, NULL)); +} diff --git a/tests-clar/clar b/tests-clar/clar index 4d10d857e..7634b2c76 100755 --- a/tests-clar/clar +++ b/tests-clar/clar @@ -338,7 +338,7 @@ CLAR_FILES = { "clar_print_tap.c" : r"""eJyNVE1vnDAQPcOvmGWFBAiQot6yaqr2HFU9tLdKyAGzscLayDbbVlX+e8cDJPbuJtsTzPObmTcfdmwss6KFoxIdtAPTzaiFtI2Qwmb4A5Yb27RqkrYEZ5tJWL4CrZLGQvvINBTzgWQHbvL4bxxlLmT+6r5bIY94gq08ktBnyffP3+DItRFKws2HnzLJd/FzHL8h2TxOtlO/5HXZDuBaKz0D/yM3xDznXRxHoodsEwSMXmrYwsiM4R2wYYC0I2GZybGY0hOJhUV8MDxw7JkY0BGd2EHJ/am3l7BEvyiMtoa5qeu0O8/2dhspLPVQTod1xMbqqbUzjQhQ0MdrHbJdL9a8AFVVzSPzMJy5YXsOt5Ca1yKqu7mWg9mHdMNx/ML+uaVenEWj0QCcRSM8pLri4QLV4SGzx6ZfYjo8ZA5CrszOZzq8wXY8cJ2v67Ecddy0WozWbfTmI3z9cX/vLwuARzgV4B3lYafrur52OZSk1fEvLO2Du4bzhZhNUj0D8/rRhNdUqXFLWC3CUPiyop8gkcqCekqwGQl+3Jkf8MXEdHFE8kmc5qPSy86Z7EoFNNbs8pvj33IhO/470L2FoihQNWTbtMudQY313X3X92WwB5QcyMC9Ld0QKOeRNYPAI6b3445MjIQOzi5hWfF+UWbwxZrwRUq+YCMBfzdAO348JVAKFyKfY3LZZYv5HP8D5Mbj9w==""", "clar_sandbox.c" : r"""eJydVWtP4kAU/dz+iism0gpKfWQ3G9YPm+gasioEMJgomdR2KhPplMwM7KLxv++dTqEP0DVrTKjcO+eec+6cKpWvWADBxBdAgqkvyMxXk/tT79uXcdu2pSkzrmwmycKfspCoeJY2OUHCpTJH9/UXrv1qW4PhjyEZglR42mIROBrC0eUm7Enlws4ZeK5tWYKqueDgrfp2BqQzOO/08cChVCROQupW+7Jnxw8CKmWGOiLdXy6cadi2/VbiHDFe5JsyfZxHERVNkOyFEgVTyp8M9V0W8ZBGQEadm5Nj28pwjMqse4EGBcmcKziD03alx+BTvkCjhLwfYw8aYtWG1z3UVWuCfko/Lszn7eCi3+t3f3auLmo2WG8oEaxsEtN6o0SAwxDHawOD7/n4NjQazE3hK7Ox+YkqfHDWRNgYjbGMyfilNlWfUozPqZ6SVjbXq1vNCJQpeDBbOivvsNRcOaehC0uyrDcbf22rtQ+dCNSE6m4mEh5TtC1MqOR19NNfgs+XasL4UxOUWIJKYC4ptHA+7Lfsd0jVdL2W8arSMsUSswIxJLVLp5Ia6EuqhjSe9TSocz7q9s9dc6wJBq5y+XYpD1lkdA0nTIJcSkXjtaApe6YooKRFiw/mQqTCmaCBSrD4gbjDd5UdfiRr9efBUTEAi4SFkEZ6zqXPw8fkj6O/S2OqCRTy7o11gOoPXj1XjVcDI1FMRDBBFcgSaRYMiSQRcQGsmkL0k01DklEwStc8CrdXF4jy2TRNTi3F09bcpT81nbZ1ZFcvjXLAcw4m3klUpOVigIpvHu2WbSEYTkO/8aEsoqr+FXD1PBExLu2FpnT1onvdQecOMKm/fRGCnPpyQmW65EKUrY0oaxF5iKv7YNk+HtJ9WFalBPVWfR219SIqGFrZARyN9RsX+82gcr3RyMH0PVpdu7wLGpppM1/ONmdxDDZllgF6xjgNHUKuOzeXo5NjQtyMXPyMkZmVjqLMm9urq4296P74Wd+34la9r5638S9EH8BkF0enKytPJfKf92ML7v8QWb1i8NQn5a5XmOe6HKEU4fMhhr29banbngCNYpJdJLrVixK9v7GvgW8=""", "clar_fixtures.c" : r"""eJyFUV1LwzAUfW5+xZU9rLUVJ4ggZQ9DFAUfZEwQSglZmrBAl5Qkk6n43236tWbKfMvNOfecc+81llhBgSppLNAN0XCOuNjbnWa4InYTjpE1MSzxuD1Vki2L0BcKTKfn0EYgu57d3uRpjYhPhi1opSwumUwRCvo3zMFYXT9C5xA5stWSVh9hI5FAa+wUFG//osgJCA5tmQ1SF3CVw9kcppfTCAWBj8ZxDg3UN4/zZ7MaHBrHSBw7vpcJ4mGS5Ijtai9qnannNqk1q7myXU+KvhGaCF4wDnfPiyV+eHpbvS7v8cti9YjGq6Yl7lzCkxfo1L0j/lJOwOtrUrwrUcDBBRsii7Xan3bjBlNVL2WUzuMkgGlJdLuIP21oyYjcVf/a6G3ozXTQPRqmsZkwWQiOfgAVGffP""", -"clar_fs.c" : r"""eJylVdtu20YQfSa/YkAD8TKWY8dJX6L0wXDEVqgsBhINN7UFhiGX1qIkl9hd+dLG/57ZCynJUWEkfZE0s7NnZufMGe2xsqAlpJfj6ZsT399DgzUUojhKo8npb3Mg+ud8PBlNE/hq/NP4LJ5G49n5aTKOp71zNJvFs4vx06DzPz6MZ6HvS5UplkO+zAS89EtWUd7KtM3UkuS8kcqdGE/o/+t71tYm/ArTi8lk6HuS/UNTBRVtbtRyAGzo+x4rgaQ2zMaFvucJqlaicdd8z15AHKkE/rbxIQI6+DqrKp4TF3YAJ2GH/AxwTeu8fTBRA0jtl0Xp0K+sucAsx9suzPPauX2v5AIIMxYweO9AhnBwwELAbvTFXLGFrmf/aF+X4/Uu2L++3scEjwjmitRnQ/+x7/0tZ0XXecIaBTUv6AC22i/5SuRPnQWVynAy/z3CSYg/zpPZxVkCJQLp4m2YvYqVbJHrEHU7bJgG+y7IZNBQf1HBz2nNxQN5oeEHoDnnJdlOHYa2aa18dRetmlxziI8ZOl8bCV5ruk3u3ptw9OlUnaeMquxGorOfd/OcKs2kpEKlBFuMibHUuKUCm8gbW1aoOTge4HFwyZqC30l4EgdlhmYR+J4tVVBK1q0wpnv0U4JkKmqygxTDQEdfFKcfRpNRMsKx6zgzM7oLL+c4oz9A80aSs/jjp40U6bpmA46t0vgVzZpVS7TLApg3lOwe55A6ivMqE04hwcsgtCB7tJK0KxdH0pdLWlUpXylii3IVZuLm9mphsPXg6gsrqeXECtwH+Kl7jF96sLj4m6z1i773cGw1VLYCb5dEqoIKodnzgvmDVLQGtLl4B5/t7c+Q40ZwFL66bgLNmUfvmSKHr0Onsg5eT4LFp/c0vyWm1uPFwBTdBd9lTGGwvjCAF7b+Ad4b9mq9HP05TubJaXIxJ/b8f3DZU2lNU9Ivi+G2VNcL1dopLh3dt17IuC0LpHVDwuvA9TLtT21LrHm1EXlo9ly/s/4rwC5C1z00g6MvrDnK22DovCYoOJz1jpPFpsaN6412udkJndTNwdtF/zdiFF6vpMJxlNKIfD12hjQj7MiwD4qD7jkovbfcSEvtlVlTfOH3uxX+rKg3NL3B0dvFrh6I+rselNtN6F68oxk/+2araVBLuv3SZ6RvZL5q3BVi9r52bTgeUfZNwUr/G9kaoSs=""", +"clar_fs.c" : r"""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""", "clar_categorize.c" : r"""eJydVV1v0zAUfU5+xV3RKudj0/ZcOqkqAyGVIU3bA9omy01dsJQlJXYRY+K/c32ddE6WtMBLGzv365x77s2blVyrQsJ8Mbvm89nN5YfP11/4u8v3s9vFDYzwrdjmZhSG5mkj8QTaVNvMwHMYZGWhDWTfRAVxXIhHqSdhoAq8KreFqZ9FnpfZJPwNWS4qngkjv5bVE8+VRotQG2FU1vMOuH+nfkkuC7HM5erFiTK1HFVBvqwnXGx/U/BLRoMofHZVKqx2XVbAFEzhbAIK3oL1OLlwWCBJVBQGgVoDQwIyoWX2uGEYIq3tCP+deohgihGsbVBJs60KOMfY9eMZErGr/0epVh0AYrXipvwvEFhYPxm1D9rZolwhSCJ5eBDhYlojoY5FtsGBdwHJFM6x/uaS8CJZrKWCqJJkzSx+RgjjyHNI/RwQg8bOlutWjCjCJMiSn+fOKzRJHjAt4jnApdML65BF74ixYebHQ9ojGl2Ev0rOESazELkBvVVGckLQdLCeJPKk1xDTn6b6aj+rzBbFhLxbfg22d4gja94Vt1cOXiSJ1QbZYEi0cnWgnE8bFnC4LXoYj4lHOji3/lJImT5Ldsz4p9nHKz6fd9iiUSKMTjGiYcgdl8RHPUIn4M2fSJeHOrGpMHHTwJYaNhVuvp/+CgiD77qsDGuEO6SDU6dlxD5o4RqNFn0KT1/j723S/ui7pUQQ12x0rI/1fTFKwSFLh/13y6rboM4K0U6XHfqGdOvGyteqzsRu1xztR2OB/KOmKSplxtWwk+nLlhv4OljJ7hnxAzNkITUD4qedAKGFoylc3S4WE7AnNyDDu3lPGRQt6nxH2h+SPx6FmFM=""", "clar.h" : r"""eJy9VV1vmzAUfS6/wg17gAi1TR+7tlIUJWukqJvaVNueLGNMsQaG2mbNNO2/7xpICF/Juoe+JOZe33uOOecam4ciYCHCeLaaPuD1/HGN7zC2bAhywTpxy+aCxnnA0LXSQcz9s+jWsn6mPEA0JhJjohST2rFOuNCIpiLgmqfCs05grSASEYnGIY+ZV26JAaWVZVKmshULmKKSZ1UvU6iiNI8DTPxUavdjDwfMXnISY+Xs9/GGH6BpJwCNh/pyxxT0FfV12bbBimlMY0ZEnjlFzBlXj275PHY9VC7SjLzkrKaAQ9UoNW1tHhr5CpEWy2/rp4c5/jJd31n7HEwp3+hcMqepQhHDgiQNlCqsiAj8dPOWki27AyU2A0uE1s5gsxVe3uPZdD3/9PnhuwML17LOx2MLjdG0eN8gOUoIlalCr1xHiG2ymFOuUeETlDClyDOD/ee7pkApyZXGGSiGHSiQHjIOcpsmLTIuur1BFx44fbFczTE2q9XyvliNFrmgBQFK4hiFBHwbXKERsuueHpq4HWCz8zjw9SDufJMxqlmAwgYBnRYcjjCobHoU/nT43IAv4b0aYK6QSDXSMmd9uFutZhGjP/5DJ2rq3kmoC7eL/M5K9VF4B6Eujg2VSP9xnCpKfRN2/7Ra9Y9Cq2j/nXeKqqPvKppuLrcPm+7YOWq71QhdC3ZI1V5plx08S7GlXdF7kkUqqTERdIPL8vyVSMHFc5t9QaDHJ0PuWDO4hsthOBv1XxYV0lu6fi1LUJBL86cNCNswmhtXXY16PLf+lcHhSMt57dO1Pttq4qnLJqVdDpKu50Da2zHcERw96oJXwlVCNI2KYVAT+IU5MsvLgQtz912feLwfmDuQBGDeC2zzGoQfBvEdf+L5QyCnp5B2PfPXD+TXQP5hoMzJJl52uTdJDkRcdHODHAjvSWRUTJiO0gD0M7SIkaoU6cNvttFMCryf+WNtP+Z/AaQwXp0=""" } diff --git a/tests-clar/clar_helpers.c b/tests-clar/clar_helpers.c index f0ce37c28..647ea5201 100644 --- a/tests-clar/clar_helpers.c +++ b/tests-clar/clar_helpers.c @@ -92,6 +92,37 @@ int cl_setenv(const char *name, const char *value) cl_assert(SetEnvironmentVariableW(name_utf16, value ? value_utf16 : NULL)); return 0; } + +/* This function performs retries on calls to MoveFile in order + * to provide enhanced reliability in the face of antivirus + * agents that may be scanning the source (or in the case that + * the source is a directory, a child of the source). */ +int cl_rename(const char *source, const char *dest) +{ + wchar_t source_utf16[GIT_WIN_PATH]; + wchar_t dest_utf16[GIT_WIN_PATH]; + unsigned retries = 1; + + git__utf8_to_16(source_utf16, GIT_WIN_PATH, source); + git__utf8_to_16(dest_utf16, GIT_WIN_PATH, dest); + + while (!MoveFileW(source_utf16, dest_utf16)) { + /* Only retry if the error is ERROR_ACCESS_DENIED; + * this may indicate that an antivirus agent is + * preventing the rename from source to target */ + if (retries > 5 || + ERROR_ACCESS_DENIED != GetLastError()) + return -1; + + /* With 5 retries and a coefficient of 10ms, the maximum + * delay here is 550 ms */ + Sleep(10 * retries * retries); + retries++; + } + + return 0; +} + #else #include <stdlib.h> @@ -104,6 +135,12 @@ int cl_setenv(const char *name, const char *value) { return (value == NULL) ? unsetenv(name) : setenv(name, value, 1); } + +int cl_rename(const char *source, const char *dest) +{ + return p_rename(source, dest); +} + #endif static const char *_cl_sandbox = NULL; @@ -124,18 +161,18 @@ git_repository *cl_git_sandbox_init(const char *sandbox) * named `.git` inside the fixtures folder of our libgit2 repo. */ if (p_access(".gitted", F_OK) == 0) - cl_git_pass(p_rename(".gitted", ".git")); + cl_git_pass(cl_rename(".gitted", ".git")); /* If we have `gitattributes`, rename to `.gitattributes`. This may * be necessary if we don't want the attributes to be applied in the * libgit2 repo, but just during testing. */ if (p_access("gitattributes", F_OK) == 0) - cl_git_pass(p_rename("gitattributes", ".gitattributes")); + cl_git_pass(cl_rename("gitattributes", ".gitattributes")); /* As with `gitattributes`, we may need `gitignore` just for testing. */ if (p_access("gitignore", F_OK) == 0) - cl_git_pass(p_rename("gitignore", ".gitignore")); + cl_git_pass(cl_rename("gitignore", ".gitignore")); cl_git_pass(p_chdir("..")); diff --git a/tests-clar/clar_libgit2.h b/tests-clar/clar_libgit2.h index b4ee74cdb..ce3688ec4 100644 --- a/tests-clar/clar_libgit2.h +++ b/tests-clar/clar_libgit2.h @@ -49,6 +49,9 @@ bool cl_is_chmod_supported(void); char *cl_getenv(const char *name); int cl_setenv(const char *name, const char *value); +/* Reliable rename */ +int cl_rename(const char *source, const char *dest); + /* Git sandbox setup helpers */ git_repository *cl_git_sandbox_init(const char *sandbox); diff --git a/tests-clar/config/configlevel.c b/tests-clar/config/configlevel.c new file mode 100644 index 000000000..d947856fa --- /dev/null +++ b/tests-clar/config/configlevel.c @@ -0,0 +1,59 @@ +#include "clar_libgit2.h" + +void test_config_configlevel__adding_the_same_level_twice_returns_EEXISTS(void) +{ + int error; + git_config *cfg; + + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"), + GIT_CONFIG_LEVEL_LOCAL, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"), + GIT_CONFIG_LEVEL_GLOBAL, 0)); + error = git_config_add_file_ondisk(cfg, cl_fixture("config/config16"), + GIT_CONFIG_LEVEL_GLOBAL, 0); + + cl_git_fail(error); + cl_assert_equal_i(GIT_EEXISTS, error); + + git_config_free(cfg); +} + +void test_config_configlevel__can_replace_a_config_file_at_an_existing_level(void) +{ + git_config *cfg; + const char *s; + + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"), + GIT_CONFIG_LEVEL_LOCAL, 1)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"), + GIT_CONFIG_LEVEL_LOCAL, 1)); + + cl_git_pass(git_config_get_string(&s, cfg, "core.stringglobal")); + cl_assert_equal_s("don't find me!", s); + + git_config_free(cfg); +} + +void test_config_configlevel__can_read_from_a_single_level_focused_file_after_parent_config_has_been_freed(void) +{ + git_config *cfg; + git_config *single_level_cfg; + const char *s; + + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"), + GIT_CONFIG_LEVEL_GLOBAL, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"), + GIT_CONFIG_LEVEL_LOCAL, 0)); + + cl_git_pass(git_config_open_level(&single_level_cfg, cfg, GIT_CONFIG_LEVEL_LOCAL)); + + git_config_free(cfg); + + cl_git_pass(git_config_get_string(&s, single_level_cfg, "core.stringglobal")); + cl_assert_equal_s("don't find me!", s); + + git_config_free(single_level_cfg); +} diff --git a/tests-clar/config/multivar.c b/tests-clar/config/multivar.c index 3b40cd09a..26537e20a 100644 --- a/tests-clar/config/multivar.c +++ b/tests-clar/config/multivar.c @@ -12,13 +12,11 @@ void test_config_multivar__cleanup(void) cl_fixture_cleanup("config"); } -static int mv_read_cb(const char *name, const char *value, void *data) +static int mv_read_cb(const git_config_entry *entry, void *data) { int *n = (int *) data; - GIT_UNUSED(value); - - if (!strcmp(name, _name)) + if (!strcmp(entry->name, _name)) (*n)++; return 0; @@ -37,11 +35,11 @@ void test_config_multivar__foreach(void) git_config_free(cfg); } -static int cb(const char *val, void *data) +static int cb(const git_config_entry *entry, void *data) { int *n = (int *) data; - GIT_UNUSED(val); + GIT_UNUSED(entry); (*n)++; diff --git a/tests-clar/config/new.c b/tests-clar/config/new.c index fae3ce941..6bd719fba 100644 --- a/tests-clar/config/new.c +++ b/tests-clar/config/new.c @@ -9,21 +9,16 @@ void test_config_new__write_new_config(void) { const char *out; - struct git_config_file *file; git_config *config; - cl_git_pass(git_config_file__ondisk(&file, TEST_CONFIG)); - cl_git_pass(git_config_new(&config)); - cl_git_pass(git_config_add_file(config, file, 0)); + cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_set_string(config, "color.ui", "auto")); cl_git_pass(git_config_set_string(config, "core.editor", "ed")); git_config_free(config); - cl_git_pass(git_config_file__ondisk(&file, TEST_CONFIG)); - cl_git_pass(git_config_new(&config)); - cl_git_pass(git_config_add_file(config, file, 0)); + cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_get_string(&out, config, "color.ui")); cl_assert_equal_s(out, "auto"); diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c index fcd22463d..cf781e6bf 100644 --- a/tests-clar/config/read.c +++ b/tests-clar/config/read.c @@ -191,22 +191,24 @@ void test_config_read__escaping_quotes(void) git_config_free(cfg); } -static int count_cfg_entries( - const char *var_name, const char *value, void *payload) +static int count_cfg_entries_and_compare_levels( + const git_config_entry *entry, void *payload) { int *count = payload; - GIT_UNUSED(var_name); - GIT_UNUSED(value); + + if (!strcmp(entry->value, "7") || !strcmp(entry->value, "17")) + cl_assert(entry->level == GIT_CONFIG_LEVEL_GLOBAL); + else + cl_assert(entry->level == GIT_CONFIG_LEVEL_SYSTEM); + (*count)++; return 0; } -static int cfg_callback_countdown( - const char *var_name, const char *value, void *payload) +static int cfg_callback_countdown(const git_config_entry *entry, void *payload) { int *count = payload; - GIT_UNUSED(var_name); - GIT_UNUSED(value); + GIT_UNUSED(entry); (*count)--; if (*count == 0) return -100; @@ -218,11 +220,15 @@ void test_config_read__foreach(void) git_config *cfg; int count, ret; - cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9"))); + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"), + GIT_CONFIG_LEVEL_SYSTEM, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"), + GIT_CONFIG_LEVEL_GLOBAL, 0)); count = 0; - cl_git_pass(git_config_foreach(cfg, count_cfg_entries, &count)); - cl_assert_equal_i(5, count); + cl_git_pass(git_config_foreach(cfg, count_cfg_entries_and_compare_levels, &count)); + cl_assert_equal_i(7, count); count = 3; cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count)); @@ -231,6 +237,14 @@ void test_config_read__foreach(void) git_config_free(cfg); } +static int count_cfg_entries(const git_config_entry *entry, void *payload) +{ + int *count = payload; + GIT_UNUSED(entry); + (*count)++; + return 0; +} + void test_config_read__foreach_match(void) { git_config *cfg; @@ -282,31 +296,129 @@ void test_config_read__whitespace_not_required_around_assignment(void) git_config_free(cfg); } -#if 0 +void test_config_read__read_git_config_entry(void) +{ + git_config *cfg; + const git_config_entry *entry; -BEGIN_TEST(config10, "a repo's config overrides the global config") - git_repository *repo; + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"), + GIT_CONFIG_LEVEL_SYSTEM, 0)); + + cl_git_pass(git_config_get_config_entry(&entry, cfg, "core.dummy2")); + cl_assert_equal_s("core.dummy2", entry->name); + cl_assert_equal_s("42", entry->value); + cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM, entry->level); + + git_config_free(cfg); +} + +/* + * At the beginning of the test: + * - config9 has: core.dummy2=42 + * - config15 has: core.dummy2=7 + * - config16 has: core.dummy2=28 + */ +void test_config_read__local_config_overrides_global_config_overrides_system_config(void) +{ git_config *cfg; - int32_t version; + int32_t i; + + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"), + GIT_CONFIG_LEVEL_SYSTEM, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"), + GIT_CONFIG_LEVEL_GLOBAL, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"), + GIT_CONFIG_LEVEL_LOCAL, 0)); + + cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2")); + cl_assert_equal_i(28, i); + + git_config_free(cfg); + + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"), + GIT_CONFIG_LEVEL_SYSTEM, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"), + GIT_CONFIG_LEVEL_GLOBAL, 0)); + + cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2")); + cl_assert_equal_i(7, i); - cl_git_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); - cl_git_pass(git_repository_config(&cfg, repo, GLOBAL_CONFIG, NULL)); - cl_git_pass(git_config_get_int32(cfg, "core.repositoryformatversion", &version)); - cl_assert(version == 0); git_config_free(cfg); - git_repository_free(repo); -END_TEST +} -BEGIN_TEST(config11, "fall back to the global config") - git_repository *repo; +/* + * At the beginning of the test: + * - config9 has: core.global does not exist + * - config15 has: core.global=17 + * - config16 has: core.global=29 + * + * And also: + * - config9 has: core.system does not exist + * - config15 has: core.system does not exist + * - config16 has: core.system=11 + */ +void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void) +{ git_config *cfg; - int32_t num; + int32_t i; - cl_git_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); - cl_git_pass(git_repository_config(&cfg, repo, GLOBAL_CONFIG, NULL)); - cl_git_pass(git_config_get_int32(cfg, "core.something", &num)); - cl_assert(num == 2); + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"), + GIT_CONFIG_LEVEL_SYSTEM, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"), + GIT_CONFIG_LEVEL_GLOBAL, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"), + GIT_CONFIG_LEVEL_LOCAL, 0)); + + cl_git_pass(git_config_get_int32(&i, cfg, "core.global")); + cl_assert_equal_i(17, i); + cl_git_pass(git_config_get_int32(&i, cfg, "core.system")); + cl_assert_equal_i(11, i); + + git_config_free(cfg); +} + +/* + * At the beginning of the test, config18 has: + * int32global = 28 + * int64global = 9223372036854775803 + * boolglobal = true + * stringglobal = I'm a global config value! + * + * And config19 has: + * int32global = -1 + * int64global = -2 + * boolglobal = false + * stringglobal = don't find me! + * + */ +void test_config_read__simple_read_from_specific_level(void) +{ + git_config *cfg, *cfg_specific; + int i; + int64_t l, expected = +9223372036854775803; + const char *s; + + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"), + GIT_CONFIG_LEVEL_GLOBAL, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"), + GIT_CONFIG_LEVEL_SYSTEM, 0)); + + cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL)); + + cl_git_pass(git_config_get_int32(&i, cfg_specific, "core.int32global")); + cl_assert_equal_i(28, i); + cl_git_pass(git_config_get_int64(&l, cfg_specific, "core.int64global")); + cl_assert(l == expected); + cl_git_pass(git_config_get_bool(&i, cfg_specific, "core.boolglobal")); + cl_assert_equal_b(true, i); + cl_git_pass(git_config_get_string(&s, cfg_specific, "core.stringglobal")); + cl_assert_equal_s("I'm a global config value!", s); + + git_config_free(cfg_specific); git_config_free(cfg); - git_repository_free(repo); -END_TEST -#endif +} diff --git a/tests-clar/config/stress.c b/tests-clar/config/stress.c index 6e7db6e8f..317e877f7 100644 --- a/tests-clar/config/stress.c +++ b/tests-clar/config/stress.c @@ -4,11 +4,13 @@ #include "fileops.h" #include "posix.h" +#define TEST_CONFIG "git-test-config" + void test_config_stress__initialize(void) { git_filebuf file = GIT_FILEBUF_INIT; - cl_git_pass(git_filebuf_open(&file, "git-test-config", 0)); + cl_git_pass(git_filebuf_open(&file, TEST_CONFIG, 0)); git_filebuf_printf(&file, "[color]\n\tui = auto\n"); git_filebuf_printf(&file, "[core]\n\teditor = \n"); @@ -18,19 +20,16 @@ void test_config_stress__initialize(void) void test_config_stress__cleanup(void) { - p_unlink("git-test-config"); + p_unlink(TEST_CONFIG); } void test_config_stress__dont_break_on_invalid_input(void) { const char *editor, *color; - struct git_config_file *file; git_config *config; - cl_assert(git_path_exists("git-test-config")); - cl_git_pass(git_config_file__ondisk(&file, "git-test-config")); - cl_git_pass(git_config_new(&config)); - cl_git_pass(git_config_add_file(config, file, 0)); + cl_assert(git_path_exists(TEST_CONFIG)); + cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_get_string(&color, config, "color.ui")); cl_git_pass(git_config_get_string(&editor, config, "core.editor")); @@ -40,13 +39,10 @@ void test_config_stress__dont_break_on_invalid_input(void) void test_config_stress__comments(void) { - struct git_config_file *file; git_config *config; const char *str; - cl_git_pass(git_config_file__ondisk(&file, cl_fixture("config/config12"))); - cl_git_pass(git_config_new(&config)); - cl_git_pass(git_config_add_file(config, file, 0)); + cl_git_pass(git_config_open_ondisk(&config, cl_fixture("config/config12"))); cl_git_pass(git_config_get_string(&str, config, "some.section.other")); cl_assert(!strcmp(str, "hello! \" ; ; ; ")); @@ -62,21 +58,16 @@ void test_config_stress__comments(void) void test_config_stress__escape_subsection_names(void) { - struct git_config_file *file; git_config *config; const char *str; cl_assert(git_path_exists("git-test-config")); - cl_git_pass(git_config_file__ondisk(&file, "git-test-config")); - cl_git_pass(git_config_new(&config)); - cl_git_pass(git_config_add_file(config, file, 0)); + cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_set_string(config, "some.sec\\tion.other", "foo")); git_config_free(config); - cl_git_pass(git_config_file__ondisk(&file, "git-test-config")); - cl_git_pass(git_config_new(&config)); - cl_git_pass(git_config_add_file(config, file, 0)); + cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_get_string(&str, config, "some.sec\\tion.other")); cl_assert(!strcmp("foo", str)); diff --git a/tests-clar/config/write.c b/tests-clar/config/write.c index 13b669cb2..d98d1dd53 100644 --- a/tests-clar/config/write.c +++ b/tests-clar/config/write.c @@ -3,11 +3,15 @@ void test_config_write__initialize(void) { cl_fixture_sandbox("config/config9"); + cl_fixture_sandbox("config/config15"); + cl_fixture_sandbox("config/config17"); } void test_config_write__cleanup(void) { cl_fixture_cleanup("config9"); + cl_fixture_cleanup("config15"); + cl_fixture_cleanup("config17"); } void test_config_write__replace_value(void) @@ -67,6 +71,40 @@ void test_config_write__delete_value(void) git_config_free(cfg); } +/* + * At the beginning of the test: + * - config9 has: core.dummy2=42 + * - config15 has: core.dummy2=7 + */ +void test_config_write__delete_value_at_specific_level(void) +{ + git_config *cfg, *cfg_specific; + int32_t i; + + cl_git_pass(git_config_open_ondisk(&cfg, "config15")); + cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2")); + cl_assert(i == 7); + git_config_free(cfg); + + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, "config9", + GIT_CONFIG_LEVEL_LOCAL, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, "config15", + GIT_CONFIG_LEVEL_GLOBAL, 0)); + + cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL)); + + cl_git_pass(git_config_delete(cfg_specific, "core.dummy2")); + git_config_free(cfg); + + cl_git_pass(git_config_open_ondisk(&cfg, "config15")); + cl_assert(git_config_get_int32(&i, cfg, "core.dummy2") == GIT_ENOTFOUND); + cl_git_pass(git_config_set_int32(cfg, "core.dummy2", 7)); + + git_config_free(cfg_specific); + git_config_free(cfg); +} + void test_config_write__write_subsection(void) { git_config *cfg; @@ -136,3 +174,57 @@ void test_config_write__escape_value(void) cl_assert_equal_s(str, "this \"has\" quotes and \t"); git_config_free(cfg); } + +void test_config_write__add_value_at_specific_level(void) +{ + git_config *cfg, *cfg_specific; + int i; + int64_t l, expected = +9223372036854775803; + const char *s; + + // open config15 as global level config file + cl_git_pass(git_config_new(&cfg)); + cl_git_pass(git_config_add_file_ondisk(cfg, "config9", + GIT_CONFIG_LEVEL_LOCAL, 0)); + cl_git_pass(git_config_add_file_ondisk(cfg, "config15", + GIT_CONFIG_LEVEL_GLOBAL, 0)); + + cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL)); + + cl_git_pass(git_config_set_int32(cfg_specific, "core.int32global", 28)); + cl_git_pass(git_config_set_int64(cfg_specific, "core.int64global", expected)); + cl_git_pass(git_config_set_bool(cfg_specific, "core.boolglobal", true)); + cl_git_pass(git_config_set_string(cfg_specific, "core.stringglobal", "I'm a global config value!")); + git_config_free(cfg_specific); + git_config_free(cfg); + + // open config15 as local level config file + cl_git_pass(git_config_open_ondisk(&cfg, "config15")); + + cl_git_pass(git_config_get_int32(&i, cfg, "core.int32global")); + cl_assert_equal_i(28, i); + cl_git_pass(git_config_get_int64(&l, cfg, "core.int64global")); + cl_assert(l == expected); + cl_git_pass(git_config_get_bool(&i, cfg, "core.boolglobal")); + cl_assert_equal_b(true, i); + cl_git_pass(git_config_get_string(&s, cfg, "core.stringglobal")); + cl_assert_equal_s("I'm a global config value!", s); + + git_config_free(cfg); +} + +void test_config_write__add_value_at_file_with_no_clrf_at_the_end(void) +{ + git_config *cfg; + int i; + + cl_git_pass(git_config_open_ondisk(&cfg, "config17")); + cl_git_pass(git_config_set_int32(cfg, "core.newline", 7)); + git_config_free(cfg); + + cl_git_pass(git_config_open_ondisk(&cfg, "config17")); + cl_git_pass(git_config_get_int32(&i, cfg, "core.newline")); + cl_assert_equal_i(7, i); + + git_config_free(cfg); +} diff --git a/tests-clar/core/env.c b/tests-clar/core/env.c index 0e0ddf3b6..288222d29 100644 --- a/tests-clar/core/env.c +++ b/tests-clar/core/env.c @@ -3,31 +3,43 @@ #include "path.h" #ifdef GIT_WIN32 -static char *env_userprofile = NULL; -static char *env_programfiles = NULL; +#define NUM_VARS 5 +static const char *env_vars[NUM_VARS] = { + "HOME", "HOMEDRIVE", "HOMEPATH", "USERPROFILE", "PROGRAMFILES" +}; #else -static char *env_home = NULL; +#define NUM_VARS 1 +static const char *env_vars[NUM_VARS] = { "HOME" }; #endif +static char *env_save[NUM_VARS]; + void test_core_env__initialize(void) { + int i; + for (i = 0; i < NUM_VARS; ++i) + env_save[i] = cl_getenv(env_vars[i]); +} + +void test_core_env__cleanup(void) +{ + int i; + for (i = 0; i < NUM_VARS; ++i) { + cl_setenv(env_vars[i], env_save[i]); #ifdef GIT_WIN32 - env_userprofile = cl_getenv("USERPROFILE"); - env_programfiles = cl_getenv("PROGRAMFILES"); -#else - env_home = cl_getenv("HOME"); + git__free(env_save[i]); #endif + } } -void test_core_env__cleanup(void) +static void setenv_and_check(const char *name, const char *value) { + char *check; + cl_git_pass(cl_setenv(name, value)); + check = cl_getenv(name); + cl_assert_equal_s(value, check); #ifdef GIT_WIN32 - cl_setenv("USERPROFILE", env_userprofile); - git__free(env_userprofile); - cl_setenv("PROGRAMFILES", env_programfiles); - git__free(env_programfiles); -#else - cl_setenv("HOME", env_home); + git__free(check); #endif } @@ -45,38 +57,67 @@ void test_core_env__0(void) NULL }; git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT; + char testfile[16], tidx = '0'; char **val; - char *check; + + memset(testfile, 0, sizeof(testfile)); + memcpy(testfile, "testfile", 8); + cl_assert_equal_s("testfile", testfile); for (val = home_values; *val != NULL; val++) { - if (p_mkdir(*val, 0777) == 0) { - /* if we can't make the directory, let's just assume - * we are on a filesystem that doesn't support the - * characters in question and skip this test... - */ - cl_git_pass(git_path_prettify(&path, *val, NULL)); + /* if we can't make the directory, let's just assume + * we are on a filesystem that doesn't support the + * characters in question and skip this test... + */ + if (p_mkdir(*val, 0777) != 0) + continue; + + cl_git_pass(git_path_prettify(&path, *val, NULL)); + + /* vary testfile name in each directory so accidentally leaving + * an environment variable set from a previous iteration won't + * accidentally make this test pass... + */ + testfile[8] = tidx++; + cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile)); + cl_git_mkfile(path.ptr, "find me"); + git_buf_rtruncate_at_char(&path, '/'); + + cl_git_fail(git_futils_find_global_file(&found, testfile)); + + setenv_and_check("HOME", path.ptr); + cl_git_pass(git_futils_find_global_file(&found, testfile)); + + cl_setenv("HOME", env_save[0]); + cl_git_fail(git_futils_find_global_file(&found, testfile)); #ifdef GIT_WIN32 - cl_git_pass(cl_setenv("USERPROFILE", path.ptr)); + setenv_and_check("HOMEDRIVE", NULL); + setenv_and_check("HOMEPATH", NULL); + setenv_and_check("USERPROFILE", path.ptr); - /* do a quick check that it was set correctly */ - check = cl_getenv("USERPROFILE"); - cl_assert_equal_s(path.ptr, check); - git__free(check); -#else - cl_git_pass(cl_setenv("HOME", path.ptr)); + cl_git_pass(git_futils_find_global_file(&found, testfile)); - /* do a quick check that it was set correctly */ - check = cl_getenv("HOME"); - cl_assert_equal_s(path.ptr, check); -#endif + { + int root = git_path_root(path.ptr); + char old; - cl_git_pass(git_buf_puts(&path, "/testfile")); - cl_git_mkfile(path.ptr, "find me"); + if (root >= 0) { + setenv_and_check("USERPROFILE", NULL); - cl_git_pass(git_futils_find_global_file(&found, "testfile")); + cl_git_fail(git_futils_find_global_file(&found, testfile)); + + old = path.ptr[root]; + path.ptr[root] = '\0'; + setenv_and_check("HOMEDRIVE", path.ptr); + path.ptr[root] = old; + setenv_and_check("HOMEPATH", &path.ptr[root]); + + cl_git_pass(git_futils_find_global_file(&found, testfile)); + } } +#endif } git_buf_free(&path); @@ -89,21 +130,22 @@ void test_core_env__1(void) cl_must_fail(git_futils_find_global_file(&path, "nonexistentfile")); + cl_git_pass(cl_setenv("HOME", "doesnotexist")); #ifdef GIT_WIN32 + cl_git_pass(cl_setenv("HOMEPATH", "doesnotexist")); cl_git_pass(cl_setenv("USERPROFILE", "doesnotexist")); -#else - cl_git_pass(cl_setenv("HOME", "doesnotexist")); #endif cl_must_fail(git_futils_find_global_file(&path, "nonexistentfile")); + cl_git_pass(cl_setenv("HOME", NULL)); #ifdef GIT_WIN32 + cl_git_pass(cl_setenv("HOMEPATH", NULL)); cl_git_pass(cl_setenv("USERPROFILE", NULL)); -#else - cl_git_pass(cl_setenv("HOME", NULL)); #endif cl_must_fail(git_futils_find_global_file(&path, "nonexistentfile")); + cl_must_fail(git_futils_find_system_file(&path, "nonexistentfile")); #ifdef GIT_WIN32 diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c index e184c28b4..3e388ea70 100644 --- a/tests-clar/diff/workdir.c +++ b/tests-clar/diff/workdir.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "diff_helpers.h" +#include "repository.h" static git_repository *g_repo = NULL; @@ -818,3 +819,19 @@ void test_diff_workdir__submodules(void) git_diff_list_free(diff); git_tree_free(a); } + +void test_diff_workdir__cannot_diff_against_a_bare_repository(void) +{ + git_diff_options opts = {0}; + git_diff_list *diff = NULL; + git_tree *tree; + + g_repo = cl_git_sandbox_init("testrepo.git"); + + cl_assert_equal_i(GIT_EBAREREPO, git_diff_workdir_to_index(g_repo, &opts, &diff)); + + cl_git_pass(git_repository_head_tree(&tree, g_repo)); + cl_assert_equal_i(GIT_EBAREREPO, git_diff_workdir_to_tree(g_repo, &opts, tree, &diff)); + + git_tree_free(tree); +} diff --git a/tests-clar/network/remotes.c b/tests-clar/network/remotes.c index c7ee863e7..91c3e879d 100644 --- a/tests-clar/network/remotes.c +++ b/tests-clar/network/remotes.c @@ -225,3 +225,27 @@ void test_network_remotes__add(void) cl_assert(!strcmp(git_refspec_dst(_refspec), "refs/remotes/addtest/*")); cl_assert_equal_s(git_remote_url(_remote), "http://github.com/libgit2/libgit2"); } + +void test_network_remotes__tagopt(void) +{ + const char *opt; + git_config *cfg; + + cl_git_pass(git_repository_config(&cfg, _repo)); + + git_remote_set_autotag(_remote, GIT_REMOTE_DOWNLOAD_TAGS_ALL); + cl_git_pass(git_remote_save(_remote)); + cl_git_pass(git_config_get_string(&opt, cfg, "remote.test.tagopt")); + cl_assert(!strcmp(opt, "--tags")); + + git_remote_set_autotag(_remote, GIT_REMOTE_DOWNLOAD_TAGS_NONE); + cl_git_pass(git_remote_save(_remote)); + cl_git_pass(git_config_get_string(&opt, cfg, "remote.test.tagopt")); + cl_assert(!strcmp(opt, "--no-tags")); + + git_remote_set_autotag(_remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO); + cl_git_pass(git_remote_save(_remote)); + cl_assert(git_config_get_string(&opt, cfg, "remote.test.tagopt") == GIT_ENOTFOUND); + + git_config_free(cfg); +} diff --git a/tests-clar/refs/branches/delete.c b/tests-clar/refs/branches/delete.c index b261240cd..4e9c70904 100644 --- a/tests-clar/refs/branches/delete.c +++ b/tests-clar/refs/branches/delete.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "refs.h" +#include "repo/repo_helpers.h" static git_repository *repo; static git_reference *fake_remote; @@ -38,28 +39,39 @@ void test_refs_branches_delete__can_not_delete_a_branch_pointed_at_by_HEAD(void) git_reference_free(branch); } -void test_refs_branches_delete__can_not_delete_a_branch_if_HEAD_is_missing(void) +void test_refs_branches_delete__can_delete_a_branch_even_if_HEAD_is_missing(void) { git_reference *head; - git_reference *branch = NULL; + git_reference *branch; cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE)); git_reference_delete(head); cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL)); - cl_git_fail(git_branch_delete(branch)); - git_reference_free(branch); + cl_git_pass(git_branch_delete(branch)); +} + +void test_refs_branches_delete__can_delete_a_branch_when_HEAD_is_orphaned(void) +{ + git_reference *branch; + + make_head_orphaned(repo, NON_EXISTING_HEAD); + + cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL)); + cl_git_pass(git_branch_delete(branch)); } void test_refs_branches_delete__can_delete_a_branch_pointed_at_by_detached_HEAD(void) { - git_reference *master, *head, *branch; + git_reference *head, *branch; - /* Detach HEAD and make it target the commit that "master" points to */ - cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master")); - cl_git_pass(git_reference_create_oid(&head, repo, "HEAD", git_reference_oid(master), 1)); + cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE)); + cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); + cl_assert_equal_s("refs/heads/master", git_reference_target(head)); git_reference_free(head); - git_reference_free(master); + + /* Detach HEAD and make it target the commit that "master" points to */ + git_repository_detach_head(repo); cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL)); cl_git_pass(git_branch_delete(branch)); @@ -78,4 +90,3 @@ void test_refs_branches_delete__can_delete_a_remote_branch(void) cl_git_pass(git_branch_lookup(&branch, repo, "nulltoken/master", GIT_BRANCH_REMOTE)); cl_git_pass(git_branch_delete(branch)); } - diff --git a/tests-clar/refs/branches/ishead.c b/tests-clar/refs/branches/ishead.c index c40a43189..ab17482b8 100644 --- a/tests-clar/refs/branches/ishead.c +++ b/tests-clar/refs/branches/ishead.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "refs.h" +#include "repo/repo_helpers.h" static git_repository *repo; static git_reference *branch; @@ -22,6 +23,22 @@ void test_refs_branches_ishead__can_tell_if_a_branch_is_pointed_at_by_HEAD(void) cl_assert_equal_i(true, git_branch_is_head(branch)); } +void test_refs_branches_ishead__can_properly_handle_orphaned_HEAD(void) +{ + git_repository_free(repo); + + repo = cl_git_sandbox_init("testrepo.git"); + + make_head_orphaned(repo, NON_EXISTING_HEAD); + + cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master")); + + cl_assert_equal_i(false, git_branch_is_head(branch)); + + cl_git_sandbox_cleanup(); + repo = NULL; +} + void test_refs_branches_ishead__can_tell_if_a_branch_is_not_pointed_at_by_HEAD(void) { cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/br2")); diff --git a/tests-clar/refs/isvalidname.c b/tests-clar/refs/isvalidname.c index 99761de32..3cc838d34 100644 --- a/tests-clar/refs/isvalidname.c +++ b/tests-clar/refs/isvalidname.c @@ -20,4 +20,8 @@ void test_refs_isvalidname__wont_hopefully_choke_on_valid_formats(void) cl_assert_equal_i(true, git_reference_is_valid_name("HEAD")); cl_assert_equal_i(true, git_reference_is_valid_name("ONE_LEVEL")); cl_assert_equal_i(true, git_reference_is_valid_name("refs/stash")); + cl_assert_equal_i(true, git_reference_is_valid_name("refs/remotes/origin/bim_with_3d@11296")); + cl_assert_equal_i(true, git_reference_is_valid_name("refs/master{yesterday")); + cl_assert_equal_i(true, git_reference_is_valid_name("refs/master}yesterday")); + cl_assert_equal_i(true, git_reference_is_valid_name("refs/master{yesterday}")); } diff --git a/tests-clar/refs/revparse.c b/tests-clar/refs/revparse.c index 14bd9fb84..a1f0dbf2b 100644 --- a/tests-clar/refs/revparse.c +++ b/tests-clar/refs/revparse.c @@ -451,3 +451,37 @@ void test_refs_revparse__a_too_short_objectid_returns_EAMBIGUOUS(void) cl_assert_equal_i(GIT_EAMBIGUOUS, result); } + +void test_refs_revparse__issue_994(void) +{ + git_repository *repo; + git_reference *head, *with_at; + git_object *target; + + repo = cl_git_sandbox_init("testrepo.git"); + + cl_assert_equal_i(GIT_ENOTFOUND, + git_revparse_single(&target, repo, "origin/bim_with_3d@11296")); + + cl_assert_equal_i(GIT_ENOTFOUND, + git_revparse_single(&target, repo, "refs/remotes/origin/bim_with_3d@11296")); + + + cl_git_pass(git_repository_head(&head, repo)); + cl_git_pass(git_reference_create_oid( + &with_at, + repo, + "refs/remotes/origin/bim_with_3d@11296", + git_reference_oid(head), + 0)); + + cl_git_pass(git_revparse_single(&target, repo, "origin/bim_with_3d@11296")); + git_object_free(target); + + cl_git_pass(git_revparse_single(&target, repo, "refs/remotes/origin/bim_with_3d@11296")); + git_object_free(target); + + git_reference_free(with_at); + git_reference_free(head); + cl_git_sandbox_cleanup(); +} diff --git a/tests-clar/repo/head.c b/tests-clar/repo/head.c index 64dec69dd..22947168e 100644 --- a/tests-clar/repo/head.c +++ b/tests-clar/repo/head.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "refs.h" +#include "repo_helpers.h" git_repository *repo; @@ -16,21 +17,18 @@ void test_repo_head__cleanup(void) void test_repo_head__head_detached(void) { git_reference *ref; - git_oid oid; cl_assert(git_repository_head_detached(repo) == 0); - /* detach the HEAD */ - git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd"); - cl_git_pass(git_reference_create_oid(&ref, repo, "HEAD", &oid, 1)); - cl_assert(git_repository_head_detached(repo) == 1); - git_reference_free(ref); + git_repository_detach_head(repo); + + cl_assert_equal_i(true, git_repository_head_detached(repo)); /* take the reop back to it's original state */ cl_git_pass(git_reference_create_symbolic(&ref, repo, "HEAD", "refs/heads/master", 1)); - cl_assert(git_repository_head_detached(repo) == 0); - git_reference_free(ref); + + cl_assert_equal_i(false, git_repository_head_detached(repo)); } void test_repo_head__head_orphan(void) @@ -39,12 +37,12 @@ void test_repo_head__head_orphan(void) cl_assert(git_repository_head_orphan(repo) == 0); - /* orphan HEAD */ - cl_git_pass(git_reference_create_symbolic(&ref, repo, "HEAD", "refs/heads/orphan", 1)); + make_head_orphaned(repo, NON_EXISTING_HEAD); + cl_assert(git_repository_head_orphan(repo) == 1); - git_reference_free(ref); - /* take the reop back to it's original state */ + + /* take the repo back to it's original state */ cl_git_pass(git_reference_create_symbolic(&ref, repo, "HEAD", "refs/heads/master", 1)); cl_assert(git_repository_head_orphan(repo) == 0); @@ -59,7 +57,7 @@ void test_repo_head__set_head_Attaches_HEAD_to_un_unborn_branch_when_the_branch_ cl_assert_equal_i(false, git_repository_head_detached(repo)); - cl_assert_equal_i(GIT_ENOTFOUND, git_repository_head(&head, repo)); + cl_assert_equal_i(GIT_EORPHANEDHEAD, git_repository_head(&head, repo)); } void test_repo_head__set_head_Returns_ENOTFOUND_when_the_reference_doesnt_exist(void) @@ -163,3 +161,28 @@ void test_repo_head__detach_head_Fails_if_HEAD_and_point_to_a_non_commitish(void git_reference_free(head); } + +void test_repo_head__detaching_an_orphaned_head_returns_GIT_EORPHANEDHEAD(void) +{ + make_head_orphaned(repo, NON_EXISTING_HEAD); + + cl_assert_equal_i(GIT_EORPHANEDHEAD, git_repository_detach_head(repo)); +} + +void test_repo_head__retrieving_an_orphaned_head_returns_GIT_EORPHANEDHEAD(void) +{ + git_reference *head; + + make_head_orphaned(repo, NON_EXISTING_HEAD); + + cl_assert_equal_i(GIT_EORPHANEDHEAD, git_repository_head(&head, repo)); +} + +void test_repo_head__can_tell_if_an_orphaned_head_is_detached(void) +{ + git_reference *head; + + make_head_orphaned(repo, NON_EXISTING_HEAD); + + cl_assert_equal_i(false, git_repository_head_detached(repo)); +} diff --git a/tests-clar/repo/repo_helpers.c b/tests-clar/repo/repo_helpers.c new file mode 100644 index 000000000..35271feaa --- /dev/null +++ b/tests-clar/repo/repo_helpers.c @@ -0,0 +1,11 @@ +#include "clar_libgit2.h" +#include "refs.h" +#include "repo_helpers.h" + +void make_head_orphaned(git_repository* repo, const char *target) +{ + git_reference *head; + + cl_git_pass(git_reference_create_symbolic(&head, repo, GIT_HEAD_FILE, target, 1)); + git_reference_free(head); +} diff --git a/tests-clar/repo/repo_helpers.h b/tests-clar/repo/repo_helpers.h new file mode 100644 index 000000000..e6aeb4873 --- /dev/null +++ b/tests-clar/repo/repo_helpers.h @@ -0,0 +1,5 @@ +#include "common.h" + +#define NON_EXISTING_HEAD "refs/heads/hide/and/seek" + +extern void make_head_orphaned(git_repository* repo, const char *target); diff --git a/tests-clar/reset/soft.c b/tests-clar/reset/soft.c index 3200c1591..1872baf3b 100644 --- a/tests-clar/reset/soft.c +++ b/tests-clar/reset/soft.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "reset_helpers.h" +#include "repo/repo_helpers.h" static git_repository *repo; static git_object *target; @@ -39,20 +40,9 @@ void test_reset_soft__can_reset_the_non_detached_Head_to_the_specified_commit(vo assert_reset_soft(false); } -static void detach_head(void) -{ - git_reference *head; - git_oid oid; - - cl_git_pass(git_reference_name_to_oid(&oid, repo, "HEAD")); - - cl_git_pass(git_reference_create_oid(&head, repo, "HEAD", &oid, true)); - git_reference_free(head); -} - void test_reset_soft__can_reset_the_detached_Head_to_the_specified_commit(void) { - detach_head(); + git_repository_detach_head(repo); assert_reset_soft(true); } @@ -100,3 +90,23 @@ void test_reset_soft__cannot_reset_to_a_tag_not_pointing_at_a_commit(void) retrieve_target_from_oid(&target, repo, "521d87c1ec3aef9824daf6d96cc0ae3710766d91"); cl_git_fail(git_reset(repo, target, GIT_RESET_SOFT)); } + +void test_reset_soft__resetting_against_an_orphaned_head_repo_makes_the_head_no_longer_orphaned(void) +{ + git_reference *head; + + retrieve_target_from_oid(&target, repo, KNOWN_COMMIT_IN_BARE_REPO); + + make_head_orphaned(repo, NON_EXISTING_HEAD); + + cl_assert_equal_i(true, git_repository_head_orphan(repo)); + + cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT)); + + cl_assert_equal_i(false, git_repository_head_orphan(repo)); + + cl_git_pass(git_reference_lookup(&head, repo, NON_EXISTING_HEAD)); + cl_assert_equal_i(0, git_oid_streq(git_reference_oid(head), KNOWN_COMMIT_IN_BARE_REPO)); + + git_reference_free(head); +} diff --git a/tests-clar/resources/config/config15 b/tests-clar/resources/config/config15 new file mode 100644 index 000000000..6d34f817b --- /dev/null +++ b/tests-clar/resources/config/config15 @@ -0,0 +1,3 @@ +[core] + dummy2 = 7 + global = 17 diff --git a/tests-clar/resources/config/config16 b/tests-clar/resources/config/config16 new file mode 100644 index 000000000..f25cdb728 --- /dev/null +++ b/tests-clar/resources/config/config16 @@ -0,0 +1,3 @@ +[core] + dummy2 = 28 + system = 11 diff --git a/tests-clar/resources/config/config17 b/tests-clar/resources/config/config17 new file mode 100644 index 000000000..ca25a86af --- /dev/null +++ b/tests-clar/resources/config/config17 @@ -0,0 +1,3 @@ +[core] + dummy2 = 7 + global = 17
\ No newline at end of file diff --git a/tests-clar/resources/config/config18 b/tests-clar/resources/config/config18 new file mode 100644 index 000000000..cb6fd5ebc --- /dev/null +++ b/tests-clar/resources/config/config18 @@ -0,0 +1,5 @@ +[core] + int32global = 28 + int64global = 9223372036854775803 + boolglobal = true + stringglobal = I'm a global config value!
\ No newline at end of file diff --git a/tests-clar/resources/config/config19 b/tests-clar/resources/config/config19 new file mode 100644 index 000000000..f3ae5a640 --- /dev/null +++ b/tests-clar/resources/config/config19 @@ -0,0 +1,5 @@ +[core] + int32global = -1 + int64global = -2 + boolglobal = false + stringglobal = don't find me!
\ No newline at end of file diff --git a/tests-clar/status/worktree.c b/tests-clar/status/worktree.c index 4f03643c0..908d34510 100644 --- a/tests-clar/status/worktree.c +++ b/tests-clar/status/worktree.c @@ -414,15 +414,11 @@ void test_status_worktree__issue_592_ignored_dirs_with_tracked_content(void) void test_status_worktree__cannot_retrieve_the_status_of_a_bare_repository(void) { git_repository *repo; - int error; unsigned int status = 0; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - error = git_status_file(&status, repo, "dummy"); - - cl_git_fail(error); - cl_assert(error != GIT_ENOTFOUND); + cl_assert_equal_i(GIT_EBAREREPO, git_status_file(&status, repo, "dummy")); git_repository_free(repo); } diff --git a/tests-clar/submodule/modify.c b/tests-clar/submodule/modify.c index 0fd732cc3..bfb8c8aaf 100644 --- a/tests-clar/submodule/modify.c +++ b/tests-clar/submodule/modify.c @@ -73,12 +73,10 @@ void test_submodule_modify__add(void) git_config_free(cfg); } -static int delete_one_config( - const char *var_name, const char *value, void *payload) +static int delete_one_config(const git_config_entry *entry, void *payload) { git_config *cfg = payload; - GIT_UNUSED(value); - return git_config_delete(cfg, var_name); + return git_config_delete(cfg, entry->name); } static int init_one_submodule( |
