8000 WIP: commit hooks support · libgit2/libgit2@4632523 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4632523

Browse files
committed
WIP: commit hooks support
1 parent a230280 commit 4632523

File tree

3 files changed

+166
-0
lines changed

3 files changed

+166
-0
lines changed

include/git2/hook.h

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

110+
GIT_EXTERN(int) git_hook_call_pre_commit(git_repository *repo);
111+
112+
GIT_EXTERN(int) git_hook_call_prepare_commit_message(git_repository *repo, const char *message);
113+
GIT_EXTERN(int) git_hook_call_prepare_commit_template(git_repository *repo, const char *template_file);
114+
115+
GIT_EXTERN(int) git_hook_call_commit_msg(git_repository *repo, const char *message);
116+
117+
GIT_EXTERN(int) git_hook_call_post_commit(git_repository *repo);
118+
110119
GIT_EXTERN(int) git_hook_call_pre_rebase(
111120
git_repository *repo,
112121
const git_annotated_commit *upstream,

src/hook.c

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

242242
/** High-level hook calls */
243243

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

tests/hook/call.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "clar_libgit2.h"
2+
#include "git2/sys/hook.h"
23

34
static git_repository *g_repo = NULL;
45
static git_signature *signature;
@@ -68,3 +69,52 @@ void test_hook_call__pre_rebase_hook(void)
6869
git_reference_free(upstream_ref);
6970
git_rebase_free(rebase);
7071
}
72+
73+
74+
int hook_exec__pre_commit(git_hook_env *env, void *payload)
75+
{
76+
int *hook_called = payload;
77+
(*hook_called)++;
78+
79+
GIT_UNUSED(env);
80+
81+
// cl_assert_equal_i(env->args.count, 0);
82+
83+
return 0;
84+
}
85+
86+
void test_hook_call__pre_commit(void)
87+
{
88+
int hook_called = 0;
89+
90+
make_dummy_hook("pre-commit");
91+
92+
cl_git_pass(git_hook_register_callback(g_repo, hook_exec__pre_commit, NULL, &hook_called));
93+
94+
cl_git_pass(git_hook_call_pre_commit(g_repo));
95+
96+
cl_assert_equal_i(hook_called, 1);
97+
}
98+
99+
int hook_exec__prepare_commit_message(git_hook_env *env, void *payload)
100+
{
101+
int *hook_called = payload;
102+
103+
(*hook_called)++;
104+
cl_assert_equal_i(env->args.count, 2);
105+
106+
return 0;
107+
}
108+
109+
void test_hook_call__prepare_commit_message(void)
110+
{
111+
int hook_called = 0;
112+
113+
make_dummy_hook("prepare-commit-msg");
114+
115+
cl_git_pass(git_hook_register_callback(g_repo, hook_exec__prepare_commit_message, NULL, &hook_called));
116+
117+
cl_git_pass(git_hook_call_prepare_commit_message(g_repo, "nice message"));
118+
119+
cl_assert_equal_i(hook_called, 1);
120+
}

0 commit comments

Comments
 (0)
0