Skip to content

Commit 6f6bee3

Browse files
trastgitster
authored andcommitted
commit --amend: invoke post-rewrite hook
The rough structure of run_rewrite_hook() comes from run_receive_hook() in receive-pack. We introduce a --no-post-rewrite option and use it to avoid the hook when called from git-rebase -i 'edit'. The next patch will add full support in git-rebase, and we only want to invoke the hook once. Signed-off-by: Thomas Rast <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c0fc686 commit 6f6bee3

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

builtin-commit.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ static char *edit_message, *use_message;
6666
static char *author_name, *author_email, *author_date;
6767
static int all, edit_flag, also, interactive, only, amend, signoff;
6868
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
69+
static int no_post_rewrite;
6970
static char *untracked_files_arg, *force_date;
7071
/*
7172
* The default commit message cleanup mode will remove the lines
@@ -137,6 +138,7 @@ static struct option builtin_commit_options[] = {
137138
OPT_BOOLEAN('z', "null", &null_termination,
138139
"terminate entries with NUL"),
139140
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
141+
OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
140142
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
141143
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
142144
/* end commit contents options */
@@ -1160,6 +1162,40 @@ static int git_commit_config(const char *k, const char *v, void *cb)
11601162
return git_status_config(k, v, s);
11611163
}
11621164

1165+
static const char post_rewrite_hook[] = "hooks/post-rewrite";
1166+
1167+
static int run_rewrite_hook(const unsigned char *oldsha1,
1168+
const unsigned char *newsha1)
1169+
{
1170+
/* oldsha1 SP newsha1 LF NUL */
1171+
static char buf[2*40 + 3];
1172+
struct child_process proc;
1173+
const char *argv[3];
1174+
int code;
1175+
size_t n;
1176+
1177+
if (access(git_path(post_rewrite_hook), X_OK) < 0)
1178+
return 0;
1179+
1180+
argv[0] = git_path(post_rewrite_hook);
1181+
argv[1] = "amend";
1182+
argv[2] = NULL;
1183+
1184+
memset(&proc, 0, sizeof(proc));
1185+
proc.argv = argv;
1186+
proc.in = -1;
1187+
proc.stdout_to_stderr = 1;
1188+
1189+
code = start_command(&proc);
1190+
if (code)
1191+
return code;
1192+
n = snprintf(buf, sizeof(buf), "%s %s\n",
1193+
sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
1194+
write_in_full(proc.in, buf, n);
1195+
close(proc.in);
1196+
return finish_command(&proc);
1197+
}
1198+
11631199
int cmd_commit(int argc, const char **argv, const char *prefix)
11641200
{
11651201
struct strbuf sb = STRBUF_INIT;
@@ -1303,6 +1339,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
13031339

13041340
rerere(0);
13051341
run_hook(get_index_file(), "post-commit", NULL);
1342+
if (amend && !no_post_rewrite) {
1343+
run_rewrite_hook(head_sha1, commit_sha1);
1344+
}
13061345
if (!quiet)
13071346
print_summary(prefix, commit_sha1);
13081347

git-rebase--interactive.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ do_next () {
445445
mark_action_done
446446
pick_one $sha1 ||
447447
die_with_patch $sha1 "Could not apply $sha1... $rest"
448-
git commit --amend
448+
git commit --amend --no-post-rewrite
449449
;;
450450
edit|e)
451451
comment_for_reflog edit

t/t5407-post-rewrite-hook.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2010 Thomas Rast
4+
#
5+
6+
test_description='Test the post-rewrite hook.'
7+
. ./test-lib.sh
8+
9+
test_expect_success 'setup' '
10+
test_commit A foo A &&
11+
test_commit B foo B &&
12+
test_commit C foo C &&
13+
test_commit D foo D
14+
'
15+
16+
mkdir .git/hooks
17+
18+
cat >.git/hooks/post-rewrite <<EOF
19+
#!/bin/sh
20+
echo \$@ > "$TRASH_DIRECTORY"/post-rewrite.args
21+
cat > "$TRASH_DIRECTORY"/post-rewrite.data
22+
EOF
23+
chmod u+x .git/hooks/post-rewrite
24+
25+
clear_hook_input () {
26+
rm -f post-rewrite.args post-rewrite.data
27+
}
28+
29+
verify_hook_input () {
30+
test_cmp "$TRASH_DIRECTORY"/post-rewrite.args expected.args &&
31+
test_cmp "$TRASH_DIRECTORY"/post-rewrite.data expected.data
32+
}
33+
34+
test_expect_success 'git commit --amend' '
35+
clear_hook_input &&
36+
echo "D new message" > newmsg &&
37+
oldsha=$(git rev-parse HEAD^0) &&
38+
git commit -Fnewmsg --amend &&
39+
echo amend > expected.args &&
40+
echo $oldsha $(git rev-parse HEAD^0) > expected.data &&
41+
verify_hook_input
42+
'
43+
44+
test_expect_success 'git commit --amend --no-post-rewrite' '
45+
clear_hook_input &&
46+
echo "D new message again" > newmsg &&
47+
git commit --no-post-rewrite -Fnewmsg --amend &&
48+
test ! -f post-rewrite.args &&
49+
test ! -f post-rewrite.data
50+
'
51+
52+
test_done

0 commit comments

Comments
 (0)