]> git.proxmox.com Git - libgit2.git/blob - tests/object/commit/commitstagedfile.c
f7ff05c01daa480fb02815ff389f2da80d2137a2
[libgit2.git] / tests / object / commit / commitstagedfile.c
1 #include "clar_libgit2.h"
2 #include "posix.h"
3
4 static git_repository *repo;
5
6 void test_object_commit_commitstagedfile__initialize(void)
7 {
8 cl_fixture("treebuilder");
9 cl_git_pass(git_repository_init(&repo, "treebuilder/", 0));
10 cl_assert(repo != NULL);
11 }
12
13 void test_object_commit_commitstagedfile__cleanup(void)
14 {
15 git_repository_free(repo);
16 repo = NULL;
17
18 cl_fixture_cleanup("treebuilder");
19 }
20
21 void test_object_commit_commitstagedfile__generate_predictable_object_ids(void)
22 {
23 git_index *index;
24 const git_index_entry *entry;
25 git_oid expected_blob_oid, tree_oid, expected_tree_oid, commit_oid, expected_commit_oid;
26 git_signature *signature;
27 git_tree *tree;
28 git_buf buffer;
29
30 /*
31 * The test below replicates the following git scenario
32 *
33 * $ echo "test" > test.txt
34 * $ git hash-object test.txt
35 * 9daeafb9864cf43055ae93beb0afd6c7d144bfa4
36 *
37 * $ git add .
38 * $ git commit -m "Initial commit"
39 *
40 * $ git log
41 * commit 1fe3126578fc4eca68c193e4a3a0a14a0704624d
42 * Author: nulltoken <emeric.fermas@gmail.com>
43 * Date: Wed Dec 14 08:29:03 2011 +0100
44 *
45 * Initial commit
46 *
47 * $ git show 1fe3 --format=raw
48 * commit 1fe3126578fc4eca68c193e4a3a0a14a0704624d
49 * tree 2b297e643c551e76cfa1f93810c50811382f9117
50 * author nulltoken <emeric.fermas@gmail.com> 1323847743 +0100
51 * committer nulltoken <emeric.fermas@gmail.com> 1323847743 +0100
52 *
53 * Initial commit
54 *
55 * diff --git a/test.txt b/test.txt
56 * new file mode 100644
57 * index 0000000..9daeafb
58 * --- /dev/null
59 * +++ b/test.txt
60 * @@ -0,0 +1 @@
61 * +test
62 *
63 * $ git ls-tree 2b297
64 * 100644 blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 test.txt
65 */
66
67 cl_git_pass(git_oid_fromstr(&expected_commit_oid, "1fe3126578fc4eca68c193e4a3a0a14a0704624d"));
68 cl_git_pass(git_oid_fromstr(&expected_tree_oid, "2b297e643c551e76cfa1f93810c50811382f9117"));
69 cl_git_pass(git_oid_fromstr(&expected_blob_oid, "9daeafb9864cf43055ae93beb0afd6c7d144bfa4"));
70
71 /*
72 * Add a new file to the index
73 */
74 cl_git_mkfile("treebuilder/test.txt", "test\n");
75 cl_git_pass(git_repository_index(&index, repo));
76 cl_git_pass(git_index_add_bypath(index, "test.txt"));
77
78 entry = git_index_get_byindex(index, 0);
79
80 cl_assert(git_oid_cmp(&expected_blob_oid, &entry->id) == 0);
81
82 /*
83 * Information about index entry should match test file
84 */
85 {
86 struct stat st;
87 cl_must_pass(p_lstat("treebuilder/test.txt", &st));
88 cl_assert(entry->file_size == st.st_size);
89 #ifndef _WIN32
90 /*
91 * Windows doesn't populate these fields, and the signage is
92 * wrong in the Windows version of the struct, so lets avoid
93 * the "comparing signed and unsigned" compilation warning in
94 * that case.
95 */
96 cl_assert(entry->uid == st.st_uid);
97 cl_assert(entry->gid == st.st_gid);
98 #endif
99 }
100
101 /*
102 * Build the tree from the index
103 */
104 cl_git_pass(git_index_write_tree(&tree_oid, index));
105
106 cl_assert(git_oid_cmp(&expected_tree_oid, &tree_oid) == 0);
107
108 /*
109 * Commit the staged file
110 */
111 cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60));
112 cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));
113
114 memset(&buffer, 0, sizeof(git_buf));
115 cl_git_pass(git_message_prettify(&buffer, "Initial commit", 0, '#'));
116
117 cl_git_pass(git_commit_create_v(
118 &commit_oid,
119 repo,
120 "HEAD",
121 signature,
122 signature,
123 NULL,
124 buffer.ptr,
125 tree,
126 0));
127
128 cl_assert(git_oid_cmp(&expected_commit_oid, &commit_oid) == 0);
129
130 git_buf_dispose(&buffer);
131 git_signature_free(signature);
132 git_tree_free(tree);
133 git_index_free(index);
134 }
135
136 static void assert_commit_tree_has_n_entries(git_commit *c, int count)
137 {
138 git_tree *tree;
139 cl_git_pass(git_commit_tree(&tree, c));
140 cl_assert_equal_i(count, git_tree_entrycount(tree));
141 git_tree_free(tree);
142 }
143
144 static void assert_commit_is_head_(git_commit *c, const char *file, const char *func, int line)
145 {
146 git_commit *head;
147 cl_git_pass(git_revparse_single((git_object **)&head, repo, "HEAD"));
148 clar__assert(git_oid_equal(git_commit_id(c), git_commit_id(head)), file, func, line, "Commit is not the HEAD", NULL, 1);
149 git_commit_free(head);
150 }
151 #define assert_commit_is_head(C) assert_commit_is_head_((C),__FILE__,__func__,__LINE__)
152
153 void test_object_commit_commitstagedfile__amend_commit(void)
154 {
155 git_index *index;
156 git_oid old_oid, new_oid, tree_oid;
157 git_commit *old_commit, *new_commit;
158 git_tree *tree;
159
160 /* make a commit */
161
162 cl_git_mkfile("treebuilder/myfile", "This is a file\n");
163 cl_git_pass(git_repository_index(&index, repo));
164 cl_git_pass(git_index_add_bypath(index, "myfile"));
165 cl_repo_commit_from_index(&old_oid, repo, NULL, 0, "first commit");
166
167 cl_git_pass(git_commit_lookup(&old_commit, repo, &old_oid));
168
169 cl_assert_equal_i(0, git_commit_parentcount(old_commit));
170 assert_commit_tree_has_n_entries(old_commit, 1);
171 assert_commit_is_head(old_commit);
172
173 /* let's amend the message of the HEAD commit */
174
175 cl_git_pass(git_commit_amend(
176 &new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", NULL));
177
178 /* fail because the commit isn't the tip of the branch anymore */
179 cl_git_fail(git_commit_amend(
180 &new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", NULL));
181
182 cl_git_pass(git_commit_lookup(&new_commit, repo, &new_oid));
183
184 cl_assert_equal_i(0, git_commit_parentcount(new_commit));
185 assert_commit_tree_has_n_entries(new_commit, 1);
186 assert_commit_is_head(new_commit);
187
188 git_commit_free(old_commit);
189
190 old_commit = new_commit;
191
192 /* let's amend the tree of that last commit */
193
194 cl_git_mkfile("treebuilder/anotherfile", "This is another file\n");
195 cl_git_pass(git_index_add_bypath(index, "anotherfile"));
196 cl_git_pass(git_index_write_tree(&tree_oid, index));
197 cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));
198 cl_assert_equal_i(2, git_tree_entrycount(tree));
199
200 /* fail to amend on a ref which does not exist */
201 cl_git_fail_with(GIT_ENOTFOUND, git_commit_amend(
202 &new_oid, old_commit, "refs/heads/nope", NULL, NULL, NULL, "Initial commit", tree));
203
204 cl_git_pass(git_commit_amend(
205 &new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", tree));
206 git_tree_free(tree);
207
208 cl_git_pass(git_commit_lookup(&new_commit, repo, &new_oid));
209
210 cl_assert_equal_i(0, git_commit_parentcount(new_commit));
211 assert_commit_tree_has_n_entries(new_commit, 2);
212 assert_commit_is_head(new_commit);
213
214 /* cleanup */
215
216 git_commit_free(old_commit);
217 git_commit_free(new_commit);
218 git_index_free(index);
219 }