Skip to content

Commit f8b8635

Browse files
stefanbellergitster
authored andcommitted
builtin/merge: honor commit-msg hook for merges
Similar to 65969d4 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3ec7d70 commit f8b8635

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

builtin/merge.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ static int show_progress = -1;
7373
static int default_to_upstream = 1;
7474
static int signoff;
7575
static const char *sign_commit;
76+
static int verify_msg = 1;
7677

7778
static struct strategy all_strategy[] = {
7879
{ "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -236,6 +237,7 @@ static struct option builtin_merge_options[] = {
236237
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
237238
OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
238239
OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")),
240+
OPT_BOOL(0, "verify", &verify_msg, N_("verify commit-msg hook")),
239241
OPT_END()
240242
};
241243

@@ -780,6 +782,12 @@ static void prepare_to_commit(struct commit_list *remoteheads)
780782
if (launch_editor(git_path_merge_msg(), NULL, NULL))
781783
abort_commit(remoteheads, NULL);
782784
}
785+
786+
if (verify_msg && run_commit_hook(0 < option_edit, get_index_file(),
787+
"commit-msg",
788+
git_path_merge_msg(), NULL))
789+
abort_commit(remoteheads, NULL);
790+
783791
read_merge_msg(&msg);
784792
strbuf_stripspace(&msg, 0 < option_edit);
785793
if (!msg.len)

t/t7504-commit-msg-hook.sh

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ cat > "$HOOK" <<EOF
101101
exit 1
102102
EOF
103103

104+
commit_msg_is () {
105+
test "$(git log --pretty=format:%s%b -1)" = "$1"
106+
}
107+
104108
test_expect_success 'with failing hook' '
105109
106110
echo "another" >> file &&
@@ -135,6 +139,32 @@ test_expect_success '--no-verify with failing hook (editor)' '
135139
136140
'
137141

142+
test_expect_success 'merge fails with failing hook' '
143+
144+
test_when_finished "git branch -D newbranch" &&
145+
test_when_finished "git checkout -f master" &&
146+
git checkout --orphan newbranch &&
147+
: >file2 &&
148+
git add file2 &&
149+
git commit --no-verify file2 -m in-side-branch &&
150+
test_must_fail git merge --allow-unrelated-histories master &&
151+
commit_msg_is "in-side-branch" # HEAD before merge
152+
153+
'
154+
155+
test_expect_success 'merge bypasses failing hook with --no-verify' '
156+
157+
test_when_finished "git branch -D newbranch" &&
158+
test_when_finished "git checkout -f master" &&
159+
git checkout --orphan newbranch &&
160+
: >file2 &&
161+
git add file2 &&
162+
git commit --no-verify file2 -m in-side-branch &&
163+
git merge --no-verify --allow-unrelated-histories master &&
164+
commit_msg_is "Merge branch '\''master'\'' into newbranch"
165+
'
166+
167+
138168
chmod -x "$HOOK"
139169
test_expect_success POSIXPERM 'with non-executable hook' '
140170
@@ -178,10 +208,6 @@ exit 0
178208
EOF
179209
chmod +x "$HOOK"
180210

181-
commit_msg_is () {
182-
test "$(git log --pretty=format:%s%b -1)" = "$1"
183-
}
184-
185211
test_expect_success 'hook edits commit message' '
186212
187213
echo "additional" >> file &&
@@ -217,7 +243,36 @@ test_expect_success "hook doesn't edit commit message (editor)" '
217243
echo "more plus" > FAKE_MSG &&
218244
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify &&
219245
commit_msg_is "more plus"
246+
'
220247

248+
test_expect_success 'hook called in git-merge picks up commit message' '
249+
test_when_finished "git branch -D newbranch" &&
250+
test_when_finished "git checkout -f master" &&
251+
git checkout --orphan newbranch &&
252+
: >file2 &&
253+
git add file2 &&
254+
git commit --no-verify file2 -m in-side-branch &&
255+
git merge --allow-unrelated-histories master &&
256+
commit_msg_is "new message"
257+
'
258+
259+
test_expect_failure 'merge --continue remembers --no-verify' '
260+
test_when_finished "git branch -D newbranch" &&
261+
test_when_finished "git checkout -f master" &&
262+
git checkout master &&
263+
echo a >file2 &&
264+
git add file2 &&
265+
git commit --no-verify -m "add file2 to master" &&
266+
git checkout -b newbranch master^ &&
267+
echo b >file2 &&
268+
git add file2 &&
269+
git commit --no-verify file2 -m in-side-branch &&
270+
git merge --no-verify -m not-rewritten-by-hook master &&
271+
# resolve conflict:
272+
echo c >file2 &&
273+
git add file2 &&
274+
git merge --continue &&
275+
commit_msg_is not-rewritten-by-hook
221276
'
222277

223278
# set up fake editor to replace `pick` by `reword`
@@ -237,4 +292,5 @@ test_expect_success 'hook is called for reword during `rebase -i`' '
237292
238293
'
239294

295+
240296
test_done

0 commit comments

Comments
 (0)