]>
git.proxmox.com Git - libgit2.git/blob - tests/refs/branches/create.c
1 #include "clar_libgit2.h"
5 static git_repository
*repo
;
6 static git_commit
*target
;
7 static git_reference
*branch
;
9 void test_refs_branches_create__initialize(void)
11 repo
= cl_git_sandbox_init("testrepo.git");
16 void test_refs_branches_create__cleanup(void)
18 git_reference_free(branch
);
21 git_commit_free(target
);
24 cl_git_sandbox_cleanup();
28 static void retrieve_target_from_oid(git_commit
**out
, git_repository
*repo
, const char *sha
)
32 cl_git_pass(git_revparse_single(&obj
, repo
, sha
));
33 cl_git_pass(git_commit_lookup(out
, repo
, git_object_id(obj
)));
37 static void retrieve_known_commit(git_commit
**commit
, git_repository
*repo
)
39 retrieve_target_from_oid(commit
, repo
, "e90810b8df3");
42 #define NEW_BRANCH_NAME "new-branch-on-the-block"
44 void test_refs_branches_create__can_create_a_local_branch(void)
46 retrieve_known_commit(&target
, repo
);
48 cl_git_pass(git_branch_create(&branch
, repo
, NEW_BRANCH_NAME
, target
, 0, NULL
));
49 cl_git_pass(git_oid_cmp(git_reference_target(branch
), git_commit_id(target
)));
52 void test_refs_branches_create__can_not_create_a_branch_if_its_name_collide_with_an_existing_one(void)
54 retrieve_known_commit(&target
, repo
);
56 cl_assert_equal_i(GIT_EEXISTS
, git_branch_create(&branch
, repo
, "br2", target
, 0, NULL
));
59 void test_refs_branches_create__can_force_create_over_an_existing_branch(void)
61 retrieve_known_commit(&target
, repo
);
63 cl_git_pass(git_branch_create(&branch
, repo
, "br2", target
, 1, NULL
));
64 cl_git_pass(git_oid_cmp(git_reference_target(branch
), git_commit_id(target
)));
65 cl_assert_equal_s("refs/heads/br2", git_reference_name(branch
));
68 void test_refs_branches_create__cannot_force_create_over_current_branch(void)
71 git_reference
*branch2
;
72 retrieve_known_commit(&target
, repo
);
74 cl_git_pass(git_branch_lookup(&branch2
, repo
, "master", GIT_BRANCH_LOCAL
));
75 cl_assert_equal_s("refs/heads/master", git_reference_name(branch2
));
76 cl_assert_equal_i(true, git_branch_is_head(branch2
));
77 oid
= git_reference_target(branch2
);
79 cl_git_fail_with(-1, git_branch_create(&branch
, repo
, "master", target
, 1, NULL
));
81 cl_git_pass(git_branch_lookup(&branch
, repo
, "master", GIT_BRANCH_LOCAL
));
82 cl_assert_equal_s("refs/heads/master", git_reference_name(branch
));
83 cl_git_pass(git_oid_cmp(git_reference_target(branch
), oid
));
84 git_reference_free(branch2
);
87 void test_refs_branches_create__creating_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
89 retrieve_known_commit(&target
, repo
);
91 cl_assert_equal_i(GIT_EINVALIDSPEC
,
92 git_branch_create(&branch
, repo
, "inv@{id", target
, 0, NULL
));
95 void test_refs_branches_create__creation_creates_new_reflog(void)
98 const git_reflog_entry
*entry
;
101 cl_git_pass(git_signature_now(&sig
, "me", "foo@example.com"));
103 retrieve_known_commit(&target
, repo
);
104 cl_git_pass(git_branch_create(&branch
, repo
, NEW_BRANCH_NAME
, target
, false, "create!"));
105 cl_git_pass(git_reflog_read(&log
, repo
, "refs/heads/" NEW_BRANCH_NAME
));
107 cl_assert_equal_i(1, git_reflog_entrycount(log
));
108 entry
= git_reflog_entry_byindex(log
, 0);
109 cl_assert_equal_s("create!", git_reflog_entry_message(entry
));
111 git_reflog_free(log
);
112 git_signature_free(sig
);
115 void test_refs_branches_create__default_reflog_message(void)
118 const git_reflog_entry
*entry
;
122 cl_git_pass(git_repository_config(&cfg
, repo
));
123 cl_git_pass(git_config_set_string(cfg
, "user.name", "Foo Bar"));
124 cl_git_pass(git_config_set_string(cfg
, "user.email", "foo@example.com"));
125 git_config_free(cfg
);
127 cl_git_pass(git_signature_default(&sig
, repo
));
129 retrieve_known_commit(&target
, repo
);
130 cl_git_pass(git_branch_create(&branch
, repo
, NEW_BRANCH_NAME
, target
, false, NULL
));
131 cl_git_pass(git_reflog_read(&log
, repo
, "refs/heads/" NEW_BRANCH_NAME
));
133 entry
= git_reflog_entry_byindex(log
, 0);
134 cl_assert_equal_s("Branch: created", git_reflog_entry_message(entry
));
135 cl_assert_equal_s(sig
->email
, git_reflog_entry_committer(entry
)->email
);
137 git_reflog_free(log
);
138 git_signature_free(sig
);
141 static void assert_branch_matches_name(
142 const char *expected
, const char *lookup_as
)
145 git_buf b
= GIT_BUF_INIT
;
147 cl_git_pass(git_branch_lookup(&ref
, repo
, lookup_as
, GIT_BRANCH_LOCAL
));
149 cl_git_pass(git_buf_sets(&b
, "refs/heads/"));
150 cl_git_pass(git_buf_puts(&b
, expected
));
151 cl_assert_equal_s(b
.ptr
, git_reference_name(ref
));
154 git_oid_cmp(git_reference_target(ref
), git_commit_id(target
)));
156 git_reference_free(ref
);
160 void test_refs_branches_create__can_create_branch_with_unicode(void)
162 const char *nfc
= "\xC3\x85\x73\x74\x72\xC3\xB6\x6D";
163 const char *nfd
= "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D";
164 const char *emoji
= "\xF0\x9F\x8D\xB7";
165 const char *names
[] = { nfc
, nfd
, emoji
};
166 const char *alt
[] = { nfd
, nfc
, NULL
};
167 const char *expected
[] = { nfc
, nfd
, emoji
};
169 bool fs_decompose_unicode
=
170 git_path_does_fs_decompose_unicode(git_repository_path(repo
));
172 retrieve_known_commit(&target
, repo
);
174 if (cl_repo_get_bool(repo
, "core.precomposeunicode"))
176 /* test decomp. because not all Mac filesystems decompose unicode */
177 else if (fs_decompose_unicode
)
180 for (i
= 0; i
< ARRAY_SIZE(names
); ++i
) {
182 cl_git_pass(git_branch_create(
183 &branch
, repo
, names
[i
], target
, 0, NULL
));
184 cl_git_pass(git_oid_cmp(
185 git_reference_target(branch
), git_commit_id(target
)));
187 cl_git_pass(git_branch_name(&name
, branch
));
188 cl_assert_equal_s(expected
[i
], name
);
189 assert_branch_matches_name(expected
[i
], names
[i
]);
190 if (fs_decompose_unicode
&& alt
[i
])
191 assert_branch_matches_name(expected
[i
], alt
[i
]);
193 cl_git_pass(git_branch_delete(branch
));
194 git_reference_free(branch
);
200 * Verify that we can create a branch with a name that matches the
201 * namespace of a previously delete branch.
203 * git branch level_one/level_two
204 * git branch -D level_one/level_two
205 * git branch level_one
207 * We expect the delete to have deleted the files:
208 * ".git/refs/heads/level_one/level_two"
209 * ".git/logs/refs/heads/level_one/level_two"
210 * It may or may not have deleted the (now empty)
211 * containing directories. To match git.git behavior,
212 * the second create needs to implicilty delete the
213 * directories and create the new files.
214 * "refs/heads/level_one"
215 * "logs/refs/heads/level_one"
217 * We should not fail to create the branch or its
218 * reflog because of an obsolete namespace container
221 void test_refs_branches_create__name_vs_namespace(void)
228 static const struct item item
[] = {
229 { "level_one/level_two", "level_one" },
230 { "a/b/c/d/e", "a/b/c/d" },
231 { "ss/tt/uu/vv/ww", "ss" },
232 /* And one test case that is deeper. */
233 { "xx1/xx2/xx3/xx4", "xx1/xx2/xx3/xx4/xx5/xx6" },
236 const struct item
*p
;
238 retrieve_known_commit(&target
, repo
);
240 for (p
=item
; p
->first
; p
++) {
241 cl_git_pass(git_branch_create(&branch
, repo
, p
->first
, target
, 0, NULL
));
242 cl_git_pass(git_oid_cmp(git_reference_target(branch
), git_commit_id(target
)));
243 cl_git_pass(git_branch_name(&name
, branch
));
244 cl_assert_equal_s(name
, p
->first
);
246 cl_git_pass(git_branch_delete(branch
));
247 git_reference_free(branch
);
250 cl_git_pass(git_branch_create(&branch
, repo
, p
->second
, target
, 0, NULL
));
251 git_reference_free(branch
);
257 * We still need to fail if part of the namespace is
260 void test_refs_branches_create__name_vs_namespace_fail(void)
265 const char *first_alternate
;
268 static const struct item item
[] = {
269 { "level_one/level_two", "level_one/alternate", "level_one" },
270 { "a/b/c/d/e", "a/b/c/d/alternate", "a/b/c/d" },
271 { "ss/tt/uu/vv/ww", "ss/alternate", "ss" },
272 { NULL
, NULL
, NULL
},
274 const struct item
*p
;
276 retrieve_known_commit(&target
, repo
);
278 for (p
=item
; p
->first
; p
++) {
279 cl_git_pass(git_branch_create(&branch
, repo
, p
->first
, target
, 0, NULL
));
280 cl_git_pass(git_oid_cmp(git_reference_target(branch
), git_commit_id(target
)));
281 cl_git_pass(git_branch_name(&name
, branch
));
282 cl_assert_equal_s(name
, p
->first
);
284 cl_git_pass(git_branch_delete(branch
));
285 git_reference_free(branch
);
288 cl_git_pass(git_branch_create(&branch
, repo
, p
->first_alternate
, target
, 0, NULL
));
289 cl_git_pass(git_oid_cmp(git_reference_target(branch
), git_commit_id(target
)));
290 cl_git_pass(git_branch_name(&name
, branch
));
291 cl_assert_equal_s(name
, p
->first_alternate
);
293 /* we do not delete the alternate. */
294 git_reference_free(branch
);
297 cl_git_fail(git_branch_create(&branch
, repo
, p
->second
, target
, 0, NULL
));
298 git_reference_free(branch
);