10000 hooks: commit-related wrappers · libgit2/libgit2@4563cf8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4563cf8

Browse files
committed
hooks: commit-related wrappers
1 parent d5f8fef commit 4563cf8

File tree

3 files changed

+225
-0
lines changed

3 files changed

+225
-0
lines changed

include/git2/hook.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ GIT_EXTERN(int) git_hook_register_callback(
105105
git_hook_destructor_cb destructor,
106106
void *payload);
107107

108+
GIT_EXTERN(int) git_hook_call_pre_commit(git_repository *repo);
109+
110+
GIT_EXTERN(int) git_hook_call_prepare_commit_message(git_repository *repo, const char *message);
111+
GIT_EXTERN(int) git_hook_call_prepare_commit_template(git_repository *repo, const char *template_file);
112+
113+
GIT_EXTERN(int) git_hook_call_commit_msg(git_repository *repo, const char *message);
114+
115+
GIT_EXTERN(int) git_hook_call_post_commit(git_repository *repo);
116+
108117
GIT_EXTERN(int) git_hook_call_pre_rebase(
109118
git_repository *repo,
110119
const git_annotated_commit *upstream,

src/hook.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,113 @@ int git_hook_execute_io(git_buf *io, git_repository *repo, const char *hook_name
244244

245245
/** High-level hook calls */
246246

247+
int git_hook_call_pre_commit(git_repository *repo)
248+
{
249+
assert(repo);
250+
251+
return git_hook_execute(repo, "pre-commit", NULL);
252+
}
253+
254+
static int commit_message_file(git_buf *msg_path, git_repository *repo, const char *message, const char *file)
255+
{
256+
int err = 0;
257+
git_buf msg_buf = GIT_BUF_INIT;
258+
259+
assert(msg_path && repo && message && file);
260+
261+
git_buf_attach_notowned(&msg_buf, message, strlen(message));
262+
263+
if ((err = git_repository_item_path(msg_path, repo, GIT_REPOSITORY_ITEM_GITDIR)) != 0)
264+
goto cleanup;
265+
266+
if ((err = git_buf_joinpath(msg_path, git_buf_cstr(msg_path), file)) != 0)
267+
goto cleanup;
268+
269+
if ((err = git_futils_writebuffer(&msg_buf, git_buf_cstr(msg_path), O_CREAT|O_WRONLY, 0766)) != 0)
270+
goto cleanup;
271+
272+
cleanup:
273+
git_buf_dispose(&msg_buf);
274+
if (err != 0) {
275+
git_buf_dispose(msg_path);
276+
}
277+
278+
return err;
279+
}
280+
281+
int git_hook_call_prepare_commit_message(git_repository *repo, const char *message)
282+
{
283+
int err = 0;
284+
git_buf msg_path = GIT_BUF_INIT;
285+
286+
assert(repo && message);
287+
288+
if ((err = commit_message_file(&msg_path, repo, message, "COMMIT_MSG")) != 0)
289+
goto cleanup;
290+
291+
err = git_hook_execute(repo, "prepare-commit-msg", git_buf_cstr(&msg_path), "message", NULL);
292+
293+
p_unlink(git_buf_cstr(&msg_path));
294+
295+
cleanup:
296+
git_buf_dispose(&msg_path);
297+
return err;
298+
}
299+
300+
int git_hook_call_prepare_commit_template(git_repository *repo, const char *template_file)
301+
{
302+
int err = 0;
303+
git_buf msg_path = GIT_BUF_INIT;
304+
git_buf tpl_path = GIT_BUF_INIT;
305+
git_buf tpl_msg = GIT_BUF_INIT;
306+
git_config *conf;
307+
308+
assert(repo);
309+
310+
if (template_file == NULL) {
311+
git_repository_config__weakptr(&conf, repo);
312+
git_config_get_path(&tpl_path, conf, "commit.template");
313+
} else {
314+
git_buf_puts(&tpl_path, template_file);
315+
}
316+
317+
git_futils_readbuffer(&tpl_msg, git_buf_cstr(&tpl_path));
318+
git_buf_dispose(&tpl_path);
319+
320+
commit_message_file(&msg_path, repo, git_buf_cstr(&tpl_msg), "COMMIT_MSG");
321+
322+
err = git_hook_execute(repo, "prepare-commit-msg", git_buf_cstr(&msg_path), "template", NULL);
323+
324+
p_unlink(git_buf_cstr(&msg_path));
325+
326+
return err;
327+
}
328+
329+
int git_hook_call_commit_msg(git_repository *repo, const char *message)
330+
{
331+
int err = 0;
332+
git_buf msg_path = GIT_BUF_INIT;
333+
334+
assert(repo && message);
335+
336+
if ((err = commit_message_file(&msg_path, repo, message, "COMMIT_MSG")) != 0)
337+
goto cleanup;
338+
339+
err = git_hook_execute(repo, "commit-msg", git_buf_cstr(&msg_path), NULL);
340+
341+
p_unlink(git_buf_cstr(&msg_path));
342+
343+
cleanup:
344+
return err;
345+
}
346+
347+
int git_hook_call_post_commit(git_repository *repo)
348+
{
349+
assert(repo);
350+
351+
return git_hook_execute(repo, "post-commit", NULL);
352+
}
353+
247354
int git_hook_call_pre_rebase(git_repository *repo, const git_annotated_commit *upstream, const git_annotated_commit *rebased)
248355
{
249356
int err = 0;

tests/hook/call.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,112 @@ void test_hook_call__pre_rebase_hook(void)
6969
git_reference_free(upstream_ref);
7070
git_rebase_free(rebase);
7171
}
72+
73+
struct hook_data {
74+
int calls;
75+
git_strarray args;
76+
};
77+
78+
static void cl_git_hook_check_(git_hook_env *env, struct hook_data *data)
79+
{
80+
size_t arg_id;
81+
82+
(data->calls)++;
83+
84+
cl_assert_equal_i(env->args.count, data->args.count);
85+
86+
for (arg_id = 0; arg_id < data->args.count; arg_id++)
87+
cl_assert_equal_s(data->args.strings[arg_id], env->args.strings[arg_id]);
88+
}
89+
90+
#define cl_git_hook_check(env, data) cl_git_hook_check_(env, data)
91+
92+
int hook_exec__check(git_hook_env *env, void *payload)
93+
{
94+
cl_git_hook_check(env, payload);
95+
return 0;
96+
}
97+
98+
void test_hook_call__pre_commit(void)
99+
{
100+
struct hook_data data = {0, {NULL, 0}};
101+
102+
make_dummy_hook("pre-commit");
103+
cl_git_pass(git_hook_register_callback(g_repo, hook_exec__check, NULL, &data));
104+
105+
cl_git_pass(git_hook_call_pre_commit(g_repo));
106+
cl_assert_equal_i(data.calls, 1);
107+
}
108+
109+
void test_hook_call__prepare_commit_message(void)
110+
{
111+
git_buf path = GIT_BUF_INIT;
112+
char *args_str[2];
113+
struct hook_data data = {0, {args_str, 2}};
114+
115+
git_buf_sets(&path, git_repository_path(g_repo));
116+
git_buf_joinpath(&path, path.ptr, "COMMIT_MSG");
117+
118+
args_str[0] = path.ptr;
119+
args_str[1] = "message";
120+
121+
make_dummy_hook("prepare-commit-msg");
122+
cl_git_pass(git_hook_register_callback(g_repo, hook_exec__check, NULL, &data));
123+
124+
cl_git_pass(git_hook_call_prepare_commit_message(g_repo, "nice message"));
125+
cl_assert_equal_i(data.calls, 1);
126+
127+
git_buf_dispose(&path);
128+
}
129+
130+
void test_hook_call__prepare_commit_template(void)
131+
{
132+
git_buf path = GIT_BUF_INIT;
133+
char *args_str[2];
134+
struct hook_data data = {0, {args_str, 2}};
135+
136+
git_buf_sets(&path, git_repository_path(g_repo));
137+
git_buf_joinpath(&path, path.ptr, "COMMIT_MSG");
138+
139+
args_str[0] = path.ptr;
140+
args_str[1] = "template";
141+
E377
142+
make_dummy_hook("prepare-commit-msg");
143+
cl_git_pass(git_hook_register_callback(g_repo, hook_exec__check, NULL, &data));
144+
145+
cl_git_pass(git_hook_call_prepare_commit_template(g_repo, "tmpl-file.txt"));
146+
cl_assert_equal_i(data.calls, 1);
147+
148+
git_buf_dispose(&path);
149+
}
150+
151+
void test_hook_call__commit_msg(void)
152+
{
153+
git_buf path = GIT_BUF_INIT;
154+
char *args_str[1];
155+
struct hook_data data = {0, {args_str, 1}};
156+
157+
git_buf_sets(&path, git_repository_path(g_repo));
158+
git_buf_joinpath(&path, path.ptr, "COMMIT_MSG");
159+
160+
args_str[0] = path.ptr;
161+
162+
make_dummy_hook("commit-msg");
163+
cl_git_pass(git_hook_register_callback(g_repo, hook_exec__check, NULL, &data));
164+
165+
cl_git_pass(git_hook_call_commit_msg(g_repo, "my message"));
166+
cl_assert_equal_i(data.calls, 1);
167+
168+
git_buf_dispose(&path);
169+
}
170+
171+
void test_hook_call__post_commit(void)
172+
{
173+
struct hook_data data = {0, {NULL, 0}};
174+
175+
make_dummy_hook("post-commit");
176+
cl_git_pass(git_hook_register_callback(g_repo, hook_exec__check, NULL, &data));
177+
178+
cl_git_pass(git_hook_call_post_commit(g_repo));
179+
cl_assert_equal_i(data.calls, 1);
180+
}

0 commit comments

Comments
 (0)
0