read.c 16.5 KB
Newer Older
1
#include "clar_libgit2.h"
2 3
#include "buffer.h"
#include "path.h"
4

5 6 7 8 9 10 11
static git_buf buf = GIT_BUF_INIT;

void test_config_read__cleanup(void)
{
	git_buf_free(&buf);
}

12 13 14 15 16 17 18
void test_config_read__simple_read(void)
{
	git_config *cfg;
	int32_t i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config0")));

19
	cl_git_pass(git_config_get_int32(&i, cfg, "core.repositoryformatversion"));
20
	cl_assert(i == 0);
21
	cl_git_pass(git_config_get_bool(&i, cfg, "core.filemode"));
22
	cl_assert(i == 1);
23
	cl_git_pass(git_config_get_bool(&i, cfg, "core.bare"));
24
	cl_assert(i == 0);
25
	cl_git_pass(git_config_get_bool(&i, cfg, "core.logallrefupdates"));
26 27 28 29 30 31 32 33 34 35 36 37
	cl_assert(i == 1);

	git_config_free(cfg);
}

void test_config_read__case_sensitive(void)
{
	git_config *cfg;
	int i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config1")));

38 39 40 41 42 43
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.that.other"));
	cl_assert_equal_s("true", git_buf_cstr(&buf));
	git_buf_clear(&buf);

	cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.other"));
	cl_assert_equal_s("yes", git_buf_cstr(&buf));
44

45
	cl_git_pass(git_config_get_bool(&i, cfg, "this.that.other"));
46
	cl_assert(i == 1);
47
	cl_git_pass(git_config_get_bool(&i, cfg, "this.That.other"));
48 49 50
	cl_assert(i == 1);

	/* This one doesn't exist */
51
	cl_must_fail(git_config_get_bool(&i, cfg, "this.thaT.other"));
52 53 54 55 56 57 58 59 60 61 62 63 64 65

	git_config_free(cfg);
}

/*
 * If \ is the last non-space character on the line, we read the next
 * one, separating each line with SP.
 */
void test_config_read__multiline_value(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config2")));

66 67
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.and"));
	cl_assert_equal_s("one one one two two three three", git_buf_cstr(&buf));
68 69 70 71 72 73 74 75 76 77 78 79 80

	git_config_free(cfg);
}

/*
 * This kind of subsection declaration is case-insensitive
 */
void test_config_read__subsection_header(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config3")));

81 82
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "section.subsection.var"));
	cl_assert_equal_s("hello", git_buf_cstr(&buf));
83 84

	/* The subsection is transformed to lower-case */
85
	cl_must_fail(git_config_get_string_buf(&buf, cfg, "section.subSectIon.var"));
86 87 88 89 90 91 92 93 94 95 96

	git_config_free(cfg);
}

void test_config_read__lone_variable(void)
{
	git_config *cfg;
	int i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config4")));

97 98
	cl_git_fail(git_config_get_int32(&i, cfg, "some.section.variable"));

99 100 101
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variable"));
	cl_assert_equal_s("", git_buf_cstr(&buf));
	git_buf_clear(&buf);
102

103
	cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variable"));
104 105
	cl_assert(i == 1);

106 107
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variableeq"));
	cl_assert_equal_s("", git_buf_cstr(&buf));
108 109 110 111

	cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variableeq"));
	cl_assert(i == 0);

112 113 114 115 116 117 118 119 120 121
	git_config_free(cfg);
}

void test_config_read__number_suffixes(void)
{
	git_config *cfg;
	int64_t i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config5")));

122
	cl_git_pass(git_config_get_int64(&i, cfg, "number.simple"));
123 124
	cl_assert(i == 1);

125
	cl_git_pass(git_config_get_int64(&i, cfg, "number.k"));
126 127
	cl_assert(i == 1 * 1024);

128
	cl_git_pass(git_config_get_int64(&i, cfg, "number.kk"));
129 130
	cl_assert(i == 1 * 1024);

131
	cl_git_pass(git_config_get_int64(&i, cfg, "number.m"));
132 133
	cl_assert(i == 1 * 1024 * 1024);

134
	cl_git_pass(git_config_get_int64(&i, cfg, "number.mm"));
135 136
	cl_assert(i == 1 * 1024 * 1024);

137
	cl_git_pass(git_config_get_int64(&i, cfg, "number.g"));
138 139
	cl_assert(i == 1 * 1024 * 1024 * 1024);

140
	cl_git_pass(git_config_get_int64(&i, cfg, "number.gg"));
141 142 143 144 145 146 147 148 149 150 151 152
	cl_assert(i == 1 * 1024 * 1024 * 1024);

	git_config_free(cfg);
}

void test_config_read__blank_lines(void)
{
	git_config *cfg;
	int i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config6")));

153
	cl_git_pass(git_config_get_bool(&i, cfg, "valid.subsection.something"));
154 155
	cl_assert(i == 1);

156
	cl_git_pass(git_config_get_bool(&i, cfg, "something.else.something"));
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
	cl_assert(i == 0);

	git_config_free(cfg);
}

void test_config_read__invalid_ext_headers(void)
{
	git_config *cfg;
	cl_must_fail(git_config_open_ondisk(&cfg, cl_fixture("config/config7")));
}

void test_config_read__empty_files(void)
{
	git_config *cfg;
	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config8")));
	git_config_free(cfg);
}

175 176 177 178 179 180 181
void test_config_read__symbol_headers(void)
{
	git_config *cfg;
	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config20")));
	git_config_free(cfg);
}

182 183 184 185 186 187 188 189 190 191 192 193 194
void test_config_read__header_in_last_line(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config10")));
	git_config_free(cfg);
}

void test_config_read__prefixes(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
195 196 197
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.ab.url"));
	cl_assert_equal_s("http://example.com/git/ab", git_buf_cstr(&buf));
	git_buf_clear(&buf);
198

199 200
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.abba.url"));
	cl_assert_equal_s("http://example.com/git/abba", git_buf_cstr(&buf));
201 202 203 204

	git_config_free(cfg);
}

205 206 207 208 209
void test_config_read__escaping_quotes(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config13")));
210 211
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.editor"));
	cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", git_buf_cstr(&buf));
212 213 214 215

	git_config_free(cfg);
}

216 217
static int count_cfg_entries_and_compare_levels(
	const git_config_entry *entry, void *payload)
218 219
{
	int *count = payload;
220 221 222 223 224 225

	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);

226 227 228 229
	(*count)++;
	return 0;
}

230
static int cfg_callback_countdown(const git_config_entry *entry, void *payload)
231 232
{
	int *count = payload;
233
	GIT_UNUSED(entry);
234 235 236 237 238 239 240 241 242 243 244
	(*count)--;
	if (*count == 0)
		return -100;
	return 0;
}

void test_config_read__foreach(void)
{
	git_config *cfg;
	int count, ret;

245 246 247 248 249
	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));
250 251

	count = 0;
252 253
	cl_git_pass(git_config_foreach(cfg, count_cfg_entries_and_compare_levels, &count));
	cl_assert_equal_i(7, count);
254 255 256

	count = 3;
	cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count));
257
	cl_assert_equal_i(-100, ret);
258 259 260 261

	git_config_free(cfg);
}

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
void test_config_read__iterator(void)
{
	git_config *cfg;
	git_config_iterator *iter;
	git_config_entry *entry;
	int count, ret;

	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_iterator_new(&iter, cfg));

	while ((ret = git_config_next(&entry, iter)) == 0) {
		count++;
	}

282
	git_config_iterator_free(iter);
283 284 285 286 287 288 289 290 291 292
	cl_assert_equal_i(GIT_ITEROVER, ret);
	cl_assert_equal_i(7, count);

	count = 3;
	cl_git_pass(git_config_iterator_new(&iter, cfg));

	git_config_iterator_free(iter);
	git_config_free(cfg);
}

293 294 295 296 297 298 299 300
static int count_cfg_entries(const git_config_entry *entry, void *payload)
{
	int *count = payload;
	GIT_UNUSED(entry);
	(*count)++;
	return 0;
}

301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
void test_config_read__foreach_match(void)
{
	git_config *cfg;
	int count;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, "core.*", count_cfg_entries, &count));
	cl_assert_equal_i(3, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, "remote\\.ab.*", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*url$", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*dummy.*", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*nomatch.*", count_cfg_entries, &count));
	cl_assert_equal_i(0, count);

	git_config_free(cfg);
}

336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
static void check_glob_iter(git_config *cfg, const char *regexp, int expected)
{
	git_config_iterator *iter;
	git_config_entry *entry;
	int count, error;

	cl_git_pass(git_config_iterator_glob_new(&iter, cfg, regexp));

	count = 0;
	while ((error = git_config_next(&entry, iter)) == 0)
		count++;

	cl_assert_equal_i(GIT_ITEROVER, error);
	cl_assert_equal_i(expected, count);
	git_config_iterator_free(iter);
}

void test_config_read__iterator_glob(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));

	check_glob_iter(cfg, "core.*", 3);
	check_glob_iter(cfg, "remote\\.ab.*", 2);
	check_glob_iter(cfg, ".*url$", 2);
	check_glob_iter(cfg, ".*dummy.*", 2);
	check_glob_iter(cfg, ".*nomatch.*", 0);

	git_config_free(cfg);
}

368 369 370 371 372 373
void test_config_read__whitespace_not_required_around_assignment(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config14")));

374 375 376
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "a.b"));
	cl_assert_equal_s("c", git_buf_cstr(&buf));
	git_buf_clear(&buf);
377

378 379
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "d.e"));
	cl_assert_equal_s("f", git_buf_cstr(&buf));
380 381 382 383

	git_config_free(cfg);
}

384 385 386
void test_config_read__read_git_config_entry(void)
{
	git_config *cfg;
387
	git_config_entry *entry;
388

389 390 391 392
	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));

393
	cl_git_pass(git_config_get_entry(&entry, cfg, "core.dummy2"));
394 395 396 397
	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);

398
	git_config_entry_free(entry);
399 400 401 402 403 404 405 406 407 408 409
	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)
{
410
	git_config *cfg;
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
	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);
434 435

	git_config_free(cfg);
436
}
437

438 439 440 441 442 443 444 445 446 447 448 449 450
/*
 * 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)
{
451
	git_config *cfg;
452
	int32_t i;
453

454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
	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;

	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);
504 505
	cl_git_pass(git_config_get_string_buf(&buf, cfg_specific, "core.stringglobal"));
	cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf));
506 507

	git_config_free(cfg_specific);
508
	git_config_free(cfg);
509
}
510

511
static void clean_test_config(void *unused)
Vicent Marti committed
512 513
{
	GIT_UNUSED(unused);
514
	cl_fixture_cleanup("./testconfig");
Vicent Marti committed
515 516
}

517 518 519 520 521
void test_config_read__can_load_and_parse_an_empty_config_file(void)
{
	git_config *cfg;
	int i;

522 523 524
	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "");
	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
525 526 527 528
	cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither"));

	git_config_free(cfg);
}
529 530 531 532 533 534 535 536 537 538 539

void test_config_read__corrupt_header(void)
{
	git_config *cfg;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));

	git_config_free(cfg);
}
540

541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
void test_config_read__corrupt_header2(void)
{
	git_config *cfg;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n    lib = git2\n");
	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));

	git_config_free(cfg);
}

void test_config_read__corrupt_header3(void)
{
	git_config *cfg;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n    lib = git2\n");
	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));

	git_config_free(cfg);
}

563 564 565 566 567 568 569 570
void test_config_read__override_variable(void)
{
	git_config *cfg;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));

571 572
	cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var"));
	cl_assert_equal_s("two", git_buf_cstr(&buf));
573 574 575

	git_config_free(cfg);
}
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619

void test_config_read__path(void)
{
	git_config *cfg;
	git_buf path = GIT_BUF_INIT;
	git_buf old_path = GIT_BUF_INIT;
	git_buf home_path = GIT_BUF_INIT;
	git_buf expected_path = GIT_BUF_INIT;

	cl_git_pass(p_mkdir("fakehome", 0777));
	cl_git_pass(git_path_prettify(&home_path, "fakehome", NULL));
	cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &old_path));
	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, home_path.ptr));
	cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile");
	cl_git_pass(git_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL));

	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
	cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
	cl_assert_equal_s(expected_path.ptr, path.ptr);
	git_buf_free(&path);

	cl_git_mkfile("./testconfig", "[some]\n path = ~/");
	cl_git_pass(git_path_join_unrooted(&expected_path, "", home_path.ptr, NULL));

	cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
	cl_assert_equal_s(expected_path.ptr, path.ptr);
	git_buf_free(&path);

	cl_git_mkfile("./testconfig", "[some]\n path = ~");
	cl_git_pass(git_buf_sets(&expected_path, home_path.ptr));

	cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
	cl_assert_equal_s(expected_path.ptr, path.ptr);
	git_buf_free(&path);

	cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo");
	cl_git_fail(git_config_get_path(&path, cfg, "some.path"));

	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, old_path.ptr));
	git_buf_free(&old_path);
	git_buf_free(&home_path);
	git_buf_free(&expected_path);
	git_config_free(cfg);
}