summaryrefslogtreecommitdiff
path: root/tests/libgit2/repo/reservedname.c
blob: 245d8625ac74430de118ca0813f5af758a4bc32a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "clar_libgit2.h"
#include "../submodule/submodule_helpers.h"
#include "repository.h"

void test_repo_reservedname__cleanup(void)
{
	cl_git_sandbox_cleanup();
}

void test_repo_reservedname__includes_shortname_on_win32(void)
{
	git_repository *repo;
	git_str *reserved;
	size_t reserved_len;

	repo = cl_git_sandbox_init("nasty");
	cl_assert(git_repository__reserved_names(&reserved, &reserved_len, repo, false));

#ifdef GIT_WIN32
	cl_assert_equal_i(2, reserved_len);
	cl_assert_equal_s(".git", reserved[0].ptr);
	cl_assert_equal_s("GIT~1", reserved[1].ptr);
#else
	cl_assert_equal_i(1, reserved_len);
	cl_assert_equal_s(".git", reserved[0].ptr);
#endif
}

void test_repo_reservedname__includes_shortname_when_requested(void)
{
	git_repository *repo;
	git_str *reserved;
	size_t reserved_len;

	repo = cl_git_sandbox_init("nasty");
	cl_assert(git_repository__reserved_names(&reserved, &reserved_len, repo, true));

	cl_assert_equal_i(2, reserved_len);
	cl_assert_equal_s(".git", reserved[0].ptr);
	cl_assert_equal_s("GIT~1", reserved[1].ptr);
}

/* Ensures that custom shortnames are included: creates a GIT~1 so that the
 * .git folder itself will have to be named GIT~2
 */
void test_repo_reservedname__custom_shortname_recognized(void)
{
#ifdef GIT_WIN32
	git_repository *repo;
	git_str *reserved;
	size_t reserved_len;

	if (!cl_sandbox_supports_8dot3())
		clar__skip();

	repo = cl_git_sandbox_init("nasty");

	cl_must_pass(p_rename("nasty/.git", "nasty/_temp"));
	cl_git_write2file("nasty/git~1", "", 0, O_RDWR|O_CREAT, 0666);
	cl_must_pass(p_rename("nasty/_temp", "nasty/.git"));

	cl_assert(git_repository__reserved_names(&reserved, &reserved_len, repo, true));

	cl_assert_equal_i(3, reserved_len);
	cl_assert_equal_s(".git", reserved[0].ptr);
	cl_assert_equal_s("GIT~1", reserved[1].ptr);
	cl_assert_equal_s("GIT~2", reserved[2].ptr);
#endif
}

/* When looking at the short name for a submodule, we need to prevent
 * people from overwriting the `.git` file in the submodule working
 * directory itself.  We don't want to look at the actual repository
 * path, since it will be in the super's repository above us, and
 * typically named with the name of our subrepository.  Consequently,
 * preventing access to the short name of the actual repository path
 * would prevent us from creating files with the same name as the
 * subrepo.  (Eg, a submodule named "libgit2" could not contain a file
 * named "libgit2", which would be unfortunate.)
 */
void test_repo_reservedname__submodule_pointer(void)
{
#ifdef GIT_WIN32
	git_repository *super_repo, *sub_repo;
	git_submodule *sub;
	git_str *sub_reserved;
	size_t sub_reserved_len;

	if (!cl_sandbox_supports_8dot3())
		clar__skip();

	super_repo = setup_fixture_submod2();

	assert_submodule_exists(super_repo, "sm_unchanged");

	cl_git_pass(git_submodule_lookup(&sub, super_repo, "sm_unchanged"));
	cl_git_pass(git_submodule_open(&sub_repo, sub));

	cl_assert(git_repository__reserved_names(&sub_reserved, &sub_reserved_len, sub_repo, true));

	cl_assert_equal_i(2, sub_reserved_len);
	cl_assert_equal_s(".git", sub_reserved[0].ptr);
	cl_assert_equal_s("GIT~1", sub_reserved[1].ptr);

	git_submodule_free(sub);
	git_repository_free(sub_repo);
#endif
}

/* Like the `submodule_pointer` test (above), this ensures that we do not
 * follow the gitlink to the submodule's repository location and treat that
 * as a reserved name.  This tests at an initial submodule update, where the
 * submodule repo is being created.
 */
void test_repo_reservedname__submodule_pointer_during_create(void)
{
	git_repository *repo;
	git_submodule *sm;
	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
	git_str url = GIT_STR_INIT;

	repo = setup_fixture_super();

	cl_git_pass(git_str_joinpath(&url, clar_sandbox_path(), "sub.git"));
	cl_repo_set_string(repo, "submodule.sub.url", url.ptr);

	cl_git_pass(git_submodule_lookup(&sm, repo, "sub"));
	cl_git_pass(git_submodule_update(sm, 1, &update_options));

	git_submodule_free(sm);
	git_str_dispose(&url);
}