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 <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Thomas Rast committed
Mar 12, 2010 at 18:04 UTC
6f6bee3ba9260137f27bdcad2f8d0fac026f2b6d
3 files changed
+92
-1
builtin-commit.c
+39
@@ -66,6 +66,7 @@ static char *edit_message, *use_message;
66
static char *author_name, *author_email, *author_date;
67
static int all, edit_flag, also, interactive, only, amend, signoff;
68
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
69
+static int no_post_rewrite;
70
static char *untracked_files_arg, *force_date;
71
/*
72
* The default commit message cleanup mode will remove the lines
@@ -137,6 +138,7 @@ static struct option builtin_commit_options[] = {
138
OPT_BOOLEAN('z', "null", &null_termination,
139
"terminate entries with NUL"),
140
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
141
+ OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
142
{ 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" },
143
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
144
/* end commit contents options */
@@ -1160,6 +1162,40 @@ static int git_commit_config(const char *k, const char *v, void *cb)
1162
return git_status_config(k, v, s);
1163
}
1164
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
+
1199
int cmd_commit(int argc, const char **argv, const char *prefix)
1200
{
1201
struct strbuf sb = STRBUF_INIT;
@@ -1303,6 +1339,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
1339
1340
rerere(0);
1341
run_hook(get_index_file(), "post-commit", NULL);
1342
+ if (amend && !no_post_rewrite) {
1343
+ run_rewrite_hook(head_sha1, commit_sha1);
1344
+ }
1345
if (!quiet)
1346
print_summary(prefix, commit_sha1);
1347
git-rebase--interactive.sh
+1
-1
@@ -445,7 +445,7 @@ do_next () {
445
mark_action_done
446
pick_one $sha1 ||
447
die_with_patch $sha1 "Could not apply $sha1... $rest"
448
- git commit --amend
448
+ git commit --amend --no-post-rewrite
449
;;
450
edit|e)
451
comment_for_reflog edit
t/t5407-post-rewrite-hook.sh
new
+52
@@ -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