From b510f0beab2e251175ea3d021129b6029c370aa4 Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:21 +0100 Subject: t7600: clean up style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up the 'merge --squash c3 with c7' test by removing some unnecessary braces and removing a pipe. Also, generally cleanup style by unindenting a here-doc, removing stray spaces after a redirection operator and allowing sed to open its own input instead of redirecting input from the shell. Helped-by: SZEDER Gábor Helped-by: Eric Sunshine Helped-by: Junio C Hamano Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 1061482..2f4c280 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -233,17 +233,16 @@ test_expect_success 'merge --squash c3 with c7' ' cat result.9z >file && git commit --no-edit -a && - { - cat <<-EOF - Squashed commit of the following: + cat >expect <<-EOF && + Squashed commit of the following: - $(git show -s c7) + $(git show -s c7) - # Conflicts: - # file - EOF - } >expect && - git cat-file commit HEAD | sed -e '1,/^$/d' >actual && + # Conflicts: + # file + EOF + git cat-file commit HEAD >raw && + sed -e '1,/^$/d' raw >actual && test_cmp expect actual ' @@ -680,10 +679,10 @@ cat >editor <<\EOF ( echo "Merge work done on the side branch c1" echo - cat <"$1" + cat "$1" ) >"$1.tmp" && mv "$1.tmp" "$1" # strip comments and blank lines from end of message -sed -e '/^#/d' < "$1" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' > expected +sed -e '/^#/d' "$1" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' >expected EOF chmod 755 editor @@ -768,14 +767,14 @@ test_expect_success 'set up mod-256 conflict scenario' ' git commit -m base && # one side changes the first line of each to "master" - sed s/-1/-master/ tmp && + sed s/-1/-master/ file >tmp && mv tmp file && git commit -am master && # and the other to "side"; merging the two will # yield 256 separate conflicts git checkout -b side HEAD^ && - sed s/-1/-side/ tmp && + sed s/-1/-side/ file >tmp && mv tmp file && git commit -am side ' @@ -814,7 +813,7 @@ EOF test_expect_success EXECKEEPSPID 'killed merge can be completed with --continue' ' git reset --hard c0 && ! "$SHELL_PATH" -c '\'' - echo kill -TERM $$ >> .git/FAKE_EDITOR + echo kill -TERM $$ >>.git/FAKE_EDITOR GIT_EDITOR=.git/FAKE_EDITOR export GIT_EDITOR exec git merge --no-ff --edit c1'\'' && -- cgit v0.10.2-6-g49f6 From 5caab8de8a8861e977ffa6e66f2a5ebfe5b8e56c Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:22 +0100 Subject: t3507: clean up style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove space after redirection operators for style. Also, remove a git command which was upstream of a pipe. Finally, let grep and sed open their own input instead of letting the shell redirect the input. Helped-by: SZEDER Gábor Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 0db1661..777fb23 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -88,7 +88,7 @@ test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' ' test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' ' pristine_detach initial && - echo foo > foo && + echo foo >foo && test_must_fail git cherry-pick base && test_must_fail git rev-parse --verify CHERRY_PICK_HEAD ' @@ -96,7 +96,7 @@ test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' ' test_expect_success \ 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' ' pristine_detach initial && - echo foo > foo && + echo foo >foo && test_must_fail git cherry-pick --strategy=resolve base && test_must_fail git rev-parse --verify CHERRY_PICK_HEAD ' @@ -175,23 +175,23 @@ test_expect_success 'failed cherry-pick registers participants in index' ' git ls-files --stage foo && git checkout picked -- foo && git ls-files --stage foo - } > stages && + } >stages && sed " 1 s/ 0 / 1 / 2 s/ 0 / 2 / 3 s/ 0 / 3 / - " < stages > expected && + " stages >expected && git read-tree -u --reset HEAD && test_must_fail git cherry-pick picked && - git ls-files --stage --unmerged > actual && + git ls-files --stage --unmerged >actual && test_cmp expected actual ' test_expect_success 'failed cherry-pick describes conflict in work tree' ' pristine_detach initial && - cat <<-EOF > expected && + cat <<-EOF >expected && <<<<<<< HEAD a ======= @@ -201,14 +201,14 @@ test_expect_success 'failed cherry-pick describes conflict in work tree' ' test_must_fail git cherry-pick picked && - sed "s/[a-f0-9]*\.\.\./objid/" foo > actual && + sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && test_cmp expected actual ' test_expect_success 'diff3 -m style' ' pristine_detach initial && git config merge.conflictstyle diff3 && - cat <<-EOF > expected && + cat <<-EOF >expected && <<<<<<< HEAD a ||||||| parent of objid picked @@ -220,14 +220,14 @@ test_expect_success 'diff3 -m style' ' test_must_fail git cherry-pick picked && - sed "s/[a-f0-9]*\.\.\./objid/" foo > actual && + sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && test_cmp expected actual ' test_expect_success 'revert also handles conflicts sanely' ' git config --unset merge.conflictstyle && pristine_detach initial && - cat <<-EOF > expected && + cat <<-EOF >expected && <<<<<<< HEAD a ======= @@ -241,24 +241,24 @@ test_expect_success 'revert also handles conflicts sanely' ' git ls-files --stage foo && git checkout base -- foo && git ls-files --stage foo - } > stages && + } >stages && sed " 1 s/ 0 / 1 / 2 s/ 0 / 2 / 3 s/ 0 / 3 / - " < stages > expected-stages && + " stages >expected-stages && git read-tree -u --reset HEAD && head=$(git rev-parse HEAD) && test_must_fail git revert picked && newhead=$(git rev-parse HEAD) && - git ls-files --stage --unmerged > actual-stages && + git ls-files --stage --unmerged >actual-stages && test "$head" = "$newhead" && test_must_fail git update-index --refresh -q && test_must_fail git diff-index --exit-code HEAD && test_cmp expected-stages actual-stages && - sed "s/[a-f0-9]*\.\.\./objid/" foo > actual && + sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && test_cmp expected actual ' @@ -284,7 +284,7 @@ test_expect_success 'revert --no-commit sets REVERT_HEAD' ' test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' ' pristine_detach base && - echo foo > foo && + echo foo >foo && test_must_fail git revert base && test_must_fail git rev-parse --verify CHERRY_PICK_HEAD && test_must_fail git rev-parse --verify REVERT_HEAD @@ -319,7 +319,7 @@ test_expect_success 'failed commit does not clear REVERT_HEAD' ' test_expect_success 'revert conflict, diff3 -m style' ' pristine_detach initial && git config merge.conflictstyle diff3 && - cat <<-EOF > expected && + cat <<-EOF >expected && <<<<<<< HEAD a ||||||| objid picked @@ -331,7 +331,7 @@ test_expect_success 'revert conflict, diff3 -m style' ' test_must_fail git revert picked && - sed "s/[a-f0-9]*\.\.\./objid/" foo > actual && + sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && test_cmp expected actual ' @@ -345,7 +345,7 @@ test_expect_success 'commit after failed cherry-pick does not add duplicated -s' pristine_detach initial && test_must_fail git cherry-pick -s picked-signed && git commit -a -s && - test $(git show -s |grep -c "Signed-off-by") = 1 + test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1 ' test_expect_success 'commit after failed cherry-pick adds -s at the right place' ' @@ -359,7 +359,7 @@ test_expect_success 'commit after failed cherry-pick adds -s at the right place' Signed-off-by: C O Mitter # Conflicts: EOF - grep -e "^# Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual && + grep -e "^# Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual && test_cmp expect actual && cat <<-\EOF >expected && @@ -378,7 +378,7 @@ test_expect_success 'commit --amend -s places the sign-off at the right place' ' # emulate old-style conflicts block mv .git/MERGE_MSG .git/MERGE_MSG+ && - sed -e "/^# Conflicts:/,\$s/^# *//" <.git/MERGE_MSG+ >.git/MERGE_MSG && + sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG && git commit -a && git commit --amend -s && @@ -388,7 +388,7 @@ test_expect_success 'commit --amend -s places the sign-off at the right place' ' Signed-off-by: C O Mitter Conflicts: EOF - grep -e "^Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual && + grep -e "^Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual && test_cmp expect actual ' -- cgit v0.10.2-6-g49f6 From b720e1e3c3156a46ad1c4f5bbe13c7aeefb25c29 Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:23 +0100 Subject: t7604: clean up style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before, we had some Git commands which were upstream of the pipe. This meant that if it produced an error, it would've gone unnoticed. Refactor to place Git commands on their own. Also, while we're at it, remove spaces after redirection operators. Helped-by: Eric Sunshine Helped-by: SZEDER Gábor Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh index 89619cf..aba1279 100755 --- a/t/t7604-merge-custom-message.sh +++ b/t/t7604-merge-custom-message.sh @@ -16,16 +16,16 @@ create_merge_msgs() { } test_expect_success 'setup' ' - echo c0 > c0.c && + echo c0 >c0.c && git add c0.c && git commit -m c0 && git tag c0 && - echo c1 > c1.c && + echo c1 >c1.c && git add c1.c && git commit -m c1 && git tag c1 && git reset --hard c0 && - echo c2 > c2.c && + echo c2 >c2.c && git add c2.c && git commit -m c2 && git tag c2 && @@ -36,14 +36,16 @@ test_expect_success 'setup' ' test_expect_success 'merge c2 with a custom message' ' git reset --hard c1 && git merge -m "$(cat exp.subject)" c2 && - git cat-file commit HEAD | sed -e "1,/^$/d" >actual && + git cat-file commit HEAD >raw && + sed -e "1,/^$/d" raw >actual && test_cmp exp.subject actual ' test_expect_success 'merge --log appends to custom message' ' git reset --hard c1 && git merge --log -m "$(cat exp.subject)" c2 && - git cat-file commit HEAD | sed -e "1,/^$/d" >actual && + git cat-file commit HEAD >raw && + sed -e "1,/^$/d" raw >actual && test_cmp exp.log actual ' -- cgit v0.10.2-6-g49f6 From 94ca361bfb87b00fad7c19cbb518656279e4329d Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:24 +0100 Subject: t7502: clean up style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor out Git commands that were upstream of a pipe. Remove spaces after "> ". Indent here-docs appropriately. Convert echo chains to use the test_write_lines function. Refactor 'sign off' test to use test_cmp instead of comparing variables. Helped-by: Eric Sunshine Helped-by: SZEDER Gábor Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/t/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh index ca4a740..5733d9c 100755 --- a/t/t7502-commit-porcelain.sh +++ b/t/t7502-commit-porcelain.sh @@ -16,7 +16,8 @@ commit_msg_is () { # Arguments: [] [] check_summary_oneline() { test_tick && - git commit ${3+"$3"} -m "$2" | head -1 > act && + git commit ${3+"$3"} -m "$2" >raw && + head -n 1 raw >act && # branch name SUMMARY_PREFIX="$(git name-rev --name-only HEAD)" && @@ -68,7 +69,7 @@ test_expect_success 'output summary format for merges' ' git checkout recursive-a && test_must_fail git merge recursive-b && # resolve the conflict - echo commit-a > file1 && + echo commit-a >file1 && git add file1 && check_summary_oneline "" "Merge" ' @@ -142,9 +143,11 @@ test_expect_success 'sign off' ' >positive && git add positive && git commit -s -m "thank you" && - actual=$(git cat-file commit HEAD | sed -ne "s/Signed-off-by: //p") && - expected=$(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/") && - test "z$actual" = "z$expected" + git cat-file commit HEAD >commit.msg && + sed -ne "s/Signed-off-by: //p" commit.msg >actual && + git var GIT_COMMITTER_IDENT >ident && + sed -e "s/>.*/>/" ident >expected && + test_cmp expected actual ' @@ -153,8 +156,8 @@ test_expect_success 'multiple -m' ' >negative && git add negative && git commit -m "one" -m "two" -m "three" && - actual=$(git cat-file commit HEAD | sed -e "1,/^\$/d") && - expected=$(echo one; echo; echo two; echo; echo three) && + actual=$(git cat-file commit HEAD >tmp && sed -e "1,/^\$/d" tmp && rm tmp) && + expected=$(test_write_lines "one" "" "two" "" "three") && test "z$actual" = "z$expected" ' @@ -163,7 +166,8 @@ test_expect_success 'verbose' ' echo minus >negative && git add negative && - git status -v | sed -ne "/^diff --git /p" >actual && + git status -v >raw && + sed -ne "/^diff --git /p" raw >actual && echo "diff --git a/negative b/negative" >expect && test_cmp expect actual @@ -189,7 +193,8 @@ test_expect_success 'cleanup commit messages (verbatim option,-t)' ' echo >>negative && git commit --cleanup=verbatim --no-status -t expect -a && - git cat-file -p HEAD |sed -e "1,/^\$/d" >actual && + git cat-file -p HEAD >raw && + sed -e "1,/^\$/d" raw >actual && test_cmp expect actual ' @@ -198,7 +203,8 @@ test_expect_success 'cleanup commit messages (verbatim option,-F)' ' echo >>negative && git commit --cleanup=verbatim -F expect -a && - git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + git cat-file -p HEAD >raw && + sed -e "1,/^\$/d" raw >actual && test_cmp expect actual ' @@ -207,7 +213,8 @@ test_expect_success 'cleanup commit messages (verbatim option,-m)' ' echo >>negative && git commit --cleanup=verbatim -m "$mesg_with_comment_and_newlines" -a && - git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + git cat-file -p HEAD >raw && + sed -e "1,/^\$/d" raw >actual && test_cmp expect actual ' @@ -215,10 +222,11 @@ test_expect_success 'cleanup commit messages (verbatim option,-m)' ' test_expect_success 'cleanup commit messages (whitespace option,-F)' ' echo >>negative && - { echo;echo "# text";echo; } >text && + test_write_lines "" "# text" "" >text && echo "# text" >expect && git commit --cleanup=whitespace -F text -a && - git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + git cat-file -p HEAD >raw && + sed -e "1,/^\$/d" raw >actual && test_cmp expect actual ' @@ -226,48 +234,51 @@ test_expect_success 'cleanup commit messages (whitespace option,-F)' ' test_expect_success 'cleanup commit messages (scissors option,-F,-e)' ' echo >>negative && - cat >text <text <<-\EOF && -# to be kept + # to be kept - # ------------------------ >8 ------------------------ -# to be kept, too -# ------------------------ >8 ------------------------ -to be removed -# ------------------------ >8 ------------------------ -to be removed, too -EOF + # ------------------------ >8 ------------------------ + # to be kept, too + # ------------------------ >8 ------------------------ + to be removed + # ------------------------ >8 ------------------------ + to be removed, too + EOF - cat >expect <expect <<-\EOF && + # to be kept - # ------------------------ >8 ------------------------ -# to be kept, too -EOF + # ------------------------ >8 ------------------------ + # to be kept, too + EOF git commit --cleanup=scissors -e -F text -a && - git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + git cat-file -p HEAD >raw && + sed -e "1,/^\$/d" raw >actual && test_cmp expect actual ' test_expect_success 'cleanup commit messages (scissors option,-F,-e, scissors on first line)' ' echo >>negative && - cat >text <8 ------------------------ -to be removed -EOF + cat >text <<-\EOF && + # ------------------------ >8 ------------------------ + to be removed + EOF git commit --cleanup=scissors -e -F text -a --allow-empty-message && - git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + git cat-file -p HEAD >raw && + sed -e "1,/^\$/d" raw >actual && test_must_be_empty actual ' test_expect_success 'cleanup commit messages (strip option,-F)' ' echo >>negative && - { echo;echo "# text";echo sample;echo; } >text && + test_write_lines "" "# text" "sample" "" >text && echo sample >expect && git commit --cleanup=strip -F text -a && - git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + git cat-file -p HEAD >raw && + sed -e "1,/^\$/d" raw >actual && test_cmp expect actual ' @@ -275,7 +286,7 @@ test_expect_success 'cleanup commit messages (strip option,-F)' ' test_expect_success 'cleanup commit messages (strip option,-F,-e)' ' echo >>negative && - { echo;echo sample;echo; } >text && + test_write_lines "" "sample" "" >text && git commit -e -F text -a && head -n 4 .git/COMMIT_EDITMSG >actual ' @@ -387,7 +398,7 @@ test_expect_success AUTOIDENT 'message shows committer when it is automatic' ' ' write_script .git/FAKE_EDITOR < "$(pwd)/.git/result" +echo editor started >"$(pwd)/.git/result" exit 0 EOF @@ -455,7 +466,7 @@ EOF test_expect_success EXECKEEPSPID 'a SIGTERM should break locks' ' echo >>negative && ! "$SHELL_PATH" -c '\'' - echo kill -TERM $$ >> .git/FAKE_EDITOR + echo kill -TERM $$ >>.git/FAKE_EDITOR GIT_EDITOR=.git/FAKE_EDITOR export GIT_EDITOR exec git commit -a'\'' && @@ -471,7 +482,8 @@ test_expect_success 'Hand committing of a redundant merge removes dups' ' test_must_fail git merge second master && git checkout master g && EDITOR=: git commit -a && - git cat-file commit HEAD | sed -n -e "s/^parent //p" -e "/^$/q" >actual && + git cat-file commit HEAD >raw && + sed -n -e "s/^parent //p" -e "/^$/q" raw >actual && test_cmp expect actual ' @@ -480,7 +492,8 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo git reset --hard && git commit -s -m "hello: kitty" --allow-empty && - git cat-file commit HEAD | sed -e "1,/^$/d" >actual && + git cat-file commit HEAD >raw && + sed -e "1,/^$/d" raw >actual && test_line_count = 3 actual ' -- cgit v0.10.2-6-g49f6 From f29cd8620d85543dbef572f522c71991b3736387 Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:25 +0100 Subject: commit: extract cleanup_mode functions to sequencer Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/builtin/commit.c b/builtin/commit.c index f175374..0df15e4 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1172,24 +1172,7 @@ static int parse_and_validate_options(int argc, const char *argv[], die(_("Only one of --include/--only/--all/--interactive/--patch can be used.")); if (argc == 0 && (also || (only && !amend && !allow_empty))) die(_("No paths with --include/--only does not make sense.")); - if (!cleanup_arg || !strcmp(cleanup_arg, "default")) - cleanup_mode = use_editor ? COMMIT_MSG_CLEANUP_ALL : - COMMIT_MSG_CLEANUP_SPACE; - else if (!strcmp(cleanup_arg, "verbatim")) - cleanup_mode = COMMIT_MSG_CLEANUP_NONE; - else if (!strcmp(cleanup_arg, "whitespace")) - cleanup_mode = COMMIT_MSG_CLEANUP_SPACE; - else if (!strcmp(cleanup_arg, "strip")) - cleanup_mode = COMMIT_MSG_CLEANUP_ALL; - else if (!strcmp(cleanup_arg, "scissors")) - cleanup_mode = use_editor ? COMMIT_MSG_CLEANUP_SCISSORS : - COMMIT_MSG_CLEANUP_SPACE; - /* - * Please update _git_commit() in git-completion.bash when you - * add new options. - */ - else - die(_("Invalid cleanup mode %s"), cleanup_arg); + cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor); handle_untracked_files_arg(s); @@ -1626,11 +1609,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) die(_("could not read commit message: %s"), strerror(saved_errno)); } - if (verbose || /* Truncate the message just before the diff, if any. */ - cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) - strbuf_setlen(&sb, wt_status_locate_end(sb.buf, sb.len)); - if (cleanup_mode != COMMIT_MSG_CLEANUP_NONE) - strbuf_stripspace(&sb, cleanup_mode == COMMIT_MSG_CLEANUP_ALL); + cleanup_message(&sb, cleanup_mode, verbose); if (message_is_empty(&sb, cleanup_mode) && !allow_empty_message) { rollback_index_files(); diff --git a/sequencer.c b/sequencer.c index ca0d750..71636a3 100644 --- a/sequencer.c +++ b/sequencer.c @@ -516,6 +516,25 @@ static int fast_forward_to(struct repository *r, return 0; } +enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg, + int use_editor) +{ + if (!cleanup_arg || !strcmp(cleanup_arg, "default")) + return use_editor ? COMMIT_MSG_CLEANUP_ALL : + COMMIT_MSG_CLEANUP_SPACE; + else if (!strcmp(cleanup_arg, "verbatim")) + return COMMIT_MSG_CLEANUP_NONE; + else if (!strcmp(cleanup_arg, "whitespace")) + return COMMIT_MSG_CLEANUP_SPACE; + else if (!strcmp(cleanup_arg, "strip")) + return COMMIT_MSG_CLEANUP_ALL; + else if (!strcmp(cleanup_arg, "scissors")) + return use_editor ? COMMIT_MSG_CLEANUP_SCISSORS : + COMMIT_MSG_CLEANUP_SPACE; + else + die(_("Invalid cleanup mode %s"), cleanup_arg); +} + void append_conflicts_hint(struct index_state *istate, struct strbuf *msgbuf) { @@ -1018,6 +1037,16 @@ static int rest_is_empty(const struct strbuf *sb, int start) return 1; } +void cleanup_message(struct strbuf *msgbuf, + enum commit_msg_cleanup_mode cleanup_mode, int verbose) +{ + if (verbose || /* Truncate the message just before the diff, if any. */ + cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) + strbuf_setlen(msgbuf, wt_status_locate_end(msgbuf->buf, msgbuf->len)); + if (cleanup_mode != COMMIT_MSG_CLEANUP_NONE) + strbuf_stripspace(msgbuf, cleanup_mode == COMMIT_MSG_CLEANUP_ALL); +} + /* * Find out if the message in the strbuf contains only whitespace and * Signed-off-by lines. diff --git a/sequencer.h b/sequencer.h index 82bc7a4..8295c84 100644 --- a/sequencer.h +++ b/sequencer.h @@ -117,6 +117,12 @@ int rearrange_squash(struct repository *r); void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag); void append_conflicts_hint(struct index_state *istate, struct strbuf *msgbuf); +enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg, + int use_editor); + +void cleanup_message(struct strbuf *msgbuf, + enum commit_msg_cleanup_mode cleanup_mode, int verbose); + int message_is_empty(const struct strbuf *sb, enum commit_msg_cleanup_mode cleanup_mode); int template_untouched(const struct strbuf *sb, const char *template_file, -- cgit v0.10.2-6-g49f6 From ca04dc96d13cbe5aead17a936e3b8695b20abb55 Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:26 +0100 Subject: parse-options.h: extract common --cleanup option The --cleanup option is commonly used. Extract it so that its definition is not repeated. Helped-by: Phillip Wood Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/builtin/commit.c b/builtin/commit.c index 0df15e4..8277da8 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1473,7 +1473,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) OPT_BOOL('s', "signoff", &signoff, N_("add Signed-off-by:")), OPT_FILENAME('t', "template", &template_file, N_("use specified template file")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")), - OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")), + OPT_CLEANUP(&cleanup_arg), OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")), { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"), N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, diff --git a/builtin/tag.c b/builtin/tag.c index 02f6bd1..a3870fb 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -397,8 +397,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_FILENAME('F', "file", &msgfile, N_("read message from file")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")), OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")), - OPT_STRING(0, "cleanup", &cleanup_arg, N_("mode"), - N_("how to strip spaces and #comments from message")), + OPT_CLEANUP(&cleanup_arg), OPT_STRING('u', "local-user", &keyid, N_("key-id"), N_("use another key to sign the tag")), OPT__FORCE(&force, N_("replace the tag if exists"), 0), diff --git a/parse-options.h b/parse-options.h index 74cce4e..b931693 100644 --- a/parse-options.h +++ b/parse-options.h @@ -314,5 +314,6 @@ int parse_opt_passthru_argv(const struct option *, const char *, int); #define OPT_NO_CONTAINS(v, h) _OPT_CONTAINS_OR_WITH("no-contains", v, h, PARSE_OPT_NONEG) #define OPT_WITH(v, h) _OPT_CONTAINS_OR_WITH("with", v, h, PARSE_OPT_HIDDEN | PARSE_OPT_NONEG) #define OPT_WITHOUT(v, h) _OPT_CONTAINS_OR_WITH("without", v, h, PARSE_OPT_HIDDEN | PARSE_OPT_NONEG) +#define OPT_CLEANUP(v) OPT_STRING(0, "cleanup", v, N_("mode"), N_("how to strip spaces and #comments from message")) #endif -- cgit v0.10.2-6-g49f6 From d540b70c85ccd08507348785fd210ef8317a864d Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:27 +0100 Subject: merge: cleanup messages like commit This change allows git-merge messages to be cleaned up with the commit.cleanup configuration or --cleanup option, just like how git-commit does it. We also give git-pull the option of --cleanup so that it can also take advantage of this change. Finally, add testing to ensure that messages are properly cleaned up. Note that some newlines that were added to the commit message were removed so that if a file were read via -F, it would be copied faithfully. Helped-by: Eric Sunshine Signed-off-by: Phillip Wood Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 92a7d93..bcf0b3e 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -32,6 +32,10 @@ they run `git merge`. To make it easier to adjust such scripts to the updated behaviour, the environment variable `GIT_MERGE_AUTOEDIT` can be set to `no` at the beginning of them. +--cleanup=:: + This option determines how the merge message will be cleaned up + before commiting. See linkgit:git-commit[1] for more details. + --ff:: When the merge resolves as a fast-forward, only update the branch pointer, without creating a merge commit. This is the default diff --git a/builtin/merge.c b/builtin/merge.c index 5ce8946..e1f7b73 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -38,6 +38,7 @@ #include "tag.h" #include "alias.h" #include "commit-reach.h" +#include "wt-status.h" #define DEFAULT_TWOHEAD (1<<0) #define DEFAULT_OCTOPUS (1<<1) @@ -98,6 +99,9 @@ enum ff_type { static enum ff_type fast_forward = FF_ALLOW; +static const char *cleanup_arg; +static enum commit_msg_cleanup_mode cleanup_mode; + static int option_parse_message(const struct option *opt, const char *arg, int unset) { @@ -249,6 +253,7 @@ static struct option builtin_merge_options[] = { N_("perform a commit if the merge succeeds (default)")), OPT_BOOL('e', "edit", &option_edit, N_("edit message before committing")), + OPT_CLEANUP(&cleanup_arg), OPT_SET_INT(0, "ff", &fast_forward, N_("allow fast-forward (default)"), FF_ALLOW), OPT_SET_INT_F(0, "ff-only", &fast_forward, N_("abort if fast-forward is not possible"), @@ -612,6 +617,8 @@ static int git_merge_config(const char *k, const char *v, void *cb) return git_config_string(&pull_twohead, k, v); else if (!strcmp(k, "pull.octopus")) return git_config_string(&pull_octopus, k, v); + else if (!strcmp(k, "commit.cleanup")) + return git_config_string(&cleanup_arg, k, v); else if (!strcmp(k, "merge.renormalize")) option_renormalize = git_config_bool(k, v); else if (!strcmp(k, "merge.ff")) { @@ -800,8 +807,13 @@ static void abort_commit(struct commit_list *remoteheads, const char *err_msg) static const char merge_editor_comment[] = N_("Please enter a commit message to explain why this merge is necessary,\n" "especially if it merges an updated upstream into a topic branch.\n" - "\n" - "Lines starting with '%c' will be ignored, and an empty message aborts\n" + "\n"); + +static const char scissors_editor_comment[] = +N_("An empty message aborts the commit.\n"); + +static const char no_scissors_editor_comment[] = +N_("Lines starting with '%c' will be ignored, and an empty message aborts\n" "the commit.\n"); static void write_merge_heads(struct commit_list *); @@ -809,11 +821,19 @@ static void prepare_to_commit(struct commit_list *remoteheads) { struct strbuf msg = STRBUF_INIT; strbuf_addbuf(&msg, &merge_msg); - strbuf_addch(&msg, '\n'); if (squash) BUG("the control must not reach here under --squash"); - if (0 < option_edit) - strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char); + if (0 < option_edit) { + strbuf_addch(&msg, '\n'); + if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) { + wt_status_append_cut_line(&msg); + strbuf_commented_addf(&msg, "\n"); + } + strbuf_commented_addf(&msg, _(merge_editor_comment)); + strbuf_commented_addf(&msg, _(cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS ? + scissors_editor_comment : + no_scissors_editor_comment), comment_line_char); + } if (signoff) append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0); write_merge_heads(remoteheads); @@ -832,7 +852,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) abort_commit(remoteheads, NULL); read_merge_msg(&msg); - strbuf_stripspace(&msg, 0 < option_edit); + cleanup_message(&msg, cleanup_mode, 0); if (!msg.len) abort_commit(remoteheads, _("Empty commit message.")); strbuf_release(&merge_msg); @@ -880,7 +900,6 @@ static int finish_automerge(struct commit *head, parents = remoteheads; if (!head_subsumed || fast_forward == FF_NO) commit_list_insert(head, &parents); - strbuf_addch(&merge_msg, '\n'); prepare_to_commit(remoteheads); if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents, &result_commit, NULL, sign_commit)) @@ -1301,6 +1320,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } resolve_undo_clear(); + if (option_edit < 0) + option_edit = default_edit_option(); + + cleanup_mode = get_cleanup_mode(cleanup_arg, 0 < option_edit); + if (verbosity < 0) show_diffstat = 0; @@ -1386,9 +1410,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix) fast_forward = FF_NO; } - if (option_edit < 0) - option_edit = default_edit_option(); - if (!use_strategies) { if (!remoteheads) ; /* already up-to-date */ diff --git a/builtin/pull.c b/builtin/pull.c index 33db889..5bf82b4 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -24,6 +24,7 @@ #include "lockfile.h" #include "wt-status.h" #include "commit-reach.h" +#include "sequencer.h" enum rebase_type { REBASE_INVALID = -1, @@ -101,6 +102,7 @@ static char *opt_signoff; static char *opt_squash; static char *opt_commit; static char *opt_edit; +static char *cleanup_arg; static char *opt_ff; static char *opt_verify_signatures; static int opt_autostash = -1; @@ -168,6 +170,7 @@ static struct option pull_options[] = { OPT_PASSTHRU(0, "edit", &opt_edit, NULL, N_("edit message before committing"), PARSE_OPT_NOARG), + OPT_CLEANUP(&cleanup_arg), OPT_PASSTHRU(0, "ff", &opt_ff, NULL, N_("allow fast-forward"), PARSE_OPT_NOARG), @@ -644,6 +647,8 @@ static int run_merge(void) argv_array_push(&args, opt_commit); if (opt_edit) argv_array_push(&args, opt_edit); + if (cleanup_arg) + argv_array_pushf(&args, "--cleanup=%s", cleanup_arg); if (opt_ff) argv_array_push(&args, opt_ff); if (opt_verify_signatures) @@ -875,6 +880,13 @@ int cmd_pull(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0); + if (cleanup_arg) + /* + * this only checks the validity of cleanup_arg; we don't need + * a valid value for use_editor + */ + get_cleanup_mode(cleanup_arg, 0); + parse_repo_refspecs(argc, argv, &repo, &refspecs); if (!opt_ff) diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index c19d8db..ccde8ba 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -77,6 +77,14 @@ test_expect_success 'git pull -q -v' ' test_must_be_empty out && test -s err) ' +test_expect_success 'git pull --cleanup errors early on invalid argument' ' + mkdir clonedcleanup && + (cd clonedcleanup && git init && + test_must_fail git pull --cleanup invalid "../parent" >out 2>err && + test_must_be_empty out && + test -s err) +' + test_expect_success 'git pull --force' ' mkdir clonedoldstyle && diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh index aba1279..cd4f960 100755 --- a/t/t7604-merge-custom-message.sh +++ b/t/t7604-merge-custom-message.sh @@ -49,4 +49,67 @@ test_expect_success 'merge --log appends to custom message' ' test_cmp exp.log actual ' +mesg_with_comment_and_newlines=' +# text + +' + +test_expect_success 'prepare file with comment line and trailing newlines' ' + printf "%s" "$mesg_with_comment_and_newlines" >expect +' + +test_expect_success 'cleanup commit messages (verbatim option)' ' + git reset --hard c1 && + git merge --cleanup=verbatim -F expect c2 && + git cat-file commit HEAD >raw && + sed -e "1,/^$/d" raw >actual && + test_cmp expect actual +' + +test_expect_success 'cleanup commit messages (whitespace option)' ' + git reset --hard c1 && + test_write_lines "" "# text" "" >text && + echo "# text" >expect && + git merge --cleanup=whitespace -F text c2 && + git cat-file commit HEAD >raw && + sed -e "1,/^$/d" raw >actual && + test_cmp expect actual +' + +test_expect_success 'cleanup merge messages (scissors option)' ' + git reset --hard c1 && + cat >text <<-\EOF && + + # to be kept + + # ------------------------ >8 ------------------------ + # to be kept, too + # ------------------------ >8 ------------------------ + to be removed + # ------------------------ >8 ------------------------ + to be removed, too + EOF + + cat >expect <<-\EOF && + # to be kept + + # ------------------------ >8 ------------------------ + # to be kept, too + EOF + git merge --cleanup=scissors -e -F text c2 && + git cat-file commit HEAD >raw && + sed -e "1,/^$/d" raw >actual && + test_cmp expect actual +' + +test_expect_success 'cleanup commit messages (strip option)' ' + git reset --hard c1 && + test_write_lines "" "# text" "sample" "" >text && + echo sample >expect && + git merge --cleanup=strip -F text c2 && + git cat-file commit HEAD >raw && + sed -e "1,/^$/d" raw >actual && + test_cmp expect actual +' + test_done diff --git a/wt-status.c b/wt-status.c index 445a362..b81fcd4 100644 --- a/wt-status.c +++ b/wt-status.c @@ -1006,13 +1006,19 @@ size_t wt_status_locate_end(const char *s, size_t len) return len; } -void wt_status_add_cut_line(FILE *fp) +void wt_status_append_cut_line(struct strbuf *buf) { const char *explanation = _("Do not modify or remove the line above.\nEverything below it will be ignored."); + + strbuf_commented_addf(buf, "%s", cut_line); + strbuf_add_commented_lines(buf, explanation, strlen(explanation)); +} + +void wt_status_add_cut_line(FILE *fp) +{ struct strbuf buf = STRBUF_INIT; - fprintf(fp, "%c %s", comment_line_char, cut_line); - strbuf_add_commented_lines(&buf, explanation, strlen(explanation)); + wt_status_append_cut_line(&buf); fputs(buf.buf, fp); strbuf_release(&buf); } diff --git a/wt-status.h b/wt-status.h index 3a95975..64f1ddc 100644 --- a/wt-status.h +++ b/wt-status.h @@ -129,6 +129,7 @@ struct wt_status { }; size_t wt_status_locate_end(const char *s, size_t len); +void wt_status_append_cut_line(struct strbuf *buf); void wt_status_add_cut_line(FILE *fp); void wt_status_prepare(struct repository *r, struct wt_status *s); void wt_status_print(struct wt_status *s); -- cgit v0.10.2-6-g49f6 From 1055997e2fc707a15baf232df2ac481055c14321 Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:28 +0100 Subject: merge: add scissors line on merge conflict This fixes a bug where the scissors line is placed after the Conflicts: section, in the case where a merge conflict occurs and commit.cleanup = scissors. Next, if commit.cleanup = scissors is specified, don't produce a scissors line in commit if one already exists in the MERGE_MSG file. Helped-by: Eric Sunshine Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index bcf0b3e..61876db 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -33,8 +33,11 @@ updated behaviour, the environment variable `GIT_MERGE_AUTOEDIT` can be set to `no` at the beginning of them. --cleanup=:: - This option determines how the merge message will be cleaned up - before commiting. See linkgit:git-commit[1] for more details. + This option determines how the merge message will be cleaned up before + commiting. See linkgit:git-commit[1] for more details. In addition, if + the '' is given a value of `scissors`, scissors will be appended + to `MERGE_MSG` before being passed on to the commit machinery in the + case of a merge conflict. --ff:: When the merge resolves as a fast-forward, only update the branch diff --git a/builtin/commit.c b/builtin/commit.c index 8277da8..5401a60 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -668,6 +668,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, const char *hook_arg2 = NULL; int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE); int old_display_comment_prefix; + int merge_contains_scissors = 0; /* This checks and barfs if author is badly specified */ determine_author_info(author_ident); @@ -728,6 +729,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, strbuf_addbuf(&sb, &message); hook_arg1 = "message"; } else if (!stat(git_path_merge_msg(the_repository), &statbuf)) { + size_t merge_msg_start; + /* * prepend SQUASH_MSG here if it exists and a * "merge --squash" was originally performed @@ -738,8 +741,16 @@ static int prepare_to_commit(const char *index_file, const char *prefix, hook_arg1 = "squash"; } else hook_arg1 = "merge"; + + merge_msg_start = sb.len; if (strbuf_read_file(&sb, git_path_merge_msg(the_repository), 0) < 0) die_errno(_("could not read MERGE_MSG")); + + if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS && + wt_status_locate_end(sb.buf + merge_msg_start, + sb.len - merge_msg_start) < + sb.len - merge_msg_start) + merge_contains_scissors = 1; } else if (!stat(git_path_squash_msg(the_repository), &statbuf)) { if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0) die_errno(_("could not read SQUASH_MSG")); @@ -807,7 +818,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, struct ident_split ci, ai; if (whence != FROM_COMMIT) { - if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) + if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS && + !merge_contains_scissors) wt_status_add_cut_line(s->fp); status_printf_ln(s, GIT_COLOR_NORMAL, whence == FROM_MERGE @@ -832,10 +844,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix, _("Please enter the commit message for your changes." " Lines starting\nwith '%c' will be ignored, and an empty" " message aborts the commit.\n"), comment_line_char); - else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS && - whence == FROM_COMMIT) - wt_status_add_cut_line(s->fp); - else /* COMMIT_MSG_CLEANUP_SPACE, that is. */ + else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) { + if (whence == FROM_COMMIT && !merge_contains_scissors) + wt_status_add_cut_line(s->fp); + } else /* COMMIT_MSG_CLEANUP_SPACE, that is. */ status_printf(s, GIT_COLOR_NORMAL, _("Please enter the commit message for your changes." " Lines starting\n" diff --git a/builtin/merge.c b/builtin/merge.c index e1f7b73..03b9f72 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -920,6 +920,20 @@ static int suggest_conflicts(void) filename = git_path_merge_msg(the_repository); fp = xfopen(filename, "a"); + /* + * We can't use cleanup_mode because if we're not using the editor, + * get_cleanup_mode will return COMMIT_MSG_CLEANUP_SPACE instead, even + * though the message is meant to be processed later by git-commit. + * Thus, we will get the cleanup mode which is returned when we _are_ + * using an editor. + */ + if (get_cleanup_mode(cleanup_arg, 1) == COMMIT_MSG_CLEANUP_SCISSORS) { + fputc('\n', fp); + wt_status_add_cut_line(fp); + /* comments out the newline from append_conflicts_hint */ + fputc(comment_line_char, fp); + } + append_conflicts_hint(&the_index, &msgbuf); fputs(msgbuf.buf, fp); strbuf_release(&msgbuf); diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 2f4c280..7f9c68c 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -246,6 +246,52 @@ test_expect_success 'merge --squash c3 with c7' ' test_cmp expect actual ' +test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' ' + git config commit.cleanup scissors && + git reset --hard c3 && + test_must_fail git merge c7 && + cat result.9z >file && + git commit --no-edit -a && + + cat >expect <<-\EOF && + Merge tag '"'"'c7'"'"' + + # ------------------------ >8 ------------------------ + # Do not modify or remove the line above. + # Everything below it will be ignored. + # + # Conflicts: + # file + EOF + git cat-file commit HEAD >raw && + sed -e '1,/^$/d' raw >actual && + test_i18ncmp expect actual +' + +test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' ' + git config commit.cleanup scissors && + git reset --hard c3 && + test_must_fail git merge --squash c7 && + cat result.9z >file && + git commit --no-edit -a && + + cat >expect <<-EOF && + Squashed commit of the following: + + $(git show -s c7) + + # ------------------------ >8 ------------------------ + # Do not modify or remove the line above. + # Everything below it will be ignored. + # + # Conflicts: + # file + EOF + git cat-file commit HEAD >raw && + sed -e '1,/^$/d' raw >actual && + test_i18ncmp expect actual +' + test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 and c3' ' -- cgit v0.10.2-6-g49f6 From dc42e9a83a9e9206566b6bc9b57f431b98682b29 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Wed, 17 Apr 2019 11:23:29 +0100 Subject: sequencer.c: save and restore cleanup mode If the user specifies an explicit cleanup mode then save and restore it so that it is preserved by 'git cherry-pick --continue'. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano diff --git a/sequencer.c b/sequencer.c index 71636a3..501d99f 100644 --- a/sequencer.c +++ b/sequencer.c @@ -535,6 +535,24 @@ enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg, die(_("Invalid cleanup mode %s"), cleanup_arg); } +/* + * NB using int rather than enum cleanup_mode to stop clang's + * -Wtautological-constant-out-of-range-compare complaining that the comparison + * is always true. + */ +static const char *describe_cleanup_mode(int cleanup_mode) +{ + static const char *modes[] = { "whitespace", + "verbatim", + "scissors", + "strip" }; + + if (cleanup_mode < ARRAY_SIZE(modes)) + return modes[cleanup_mode]; + + BUG("invalid cleanup_mode provided (%d)", cleanup_mode); +} + void append_conflicts_hint(struct index_state *istate, struct strbuf *msgbuf) { @@ -2367,7 +2385,10 @@ static int populate_opts_cb(const char *key, const char *value, void *data) opts->allow_rerere_auto = git_config_bool_or_int(key, value, &error_flag) ? RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE; - else + else if (!strcmp(key, "options.default-msg-cleanup")) { + opts->explicit_cleanup = 1; + opts->default_msg_cleanup = get_cleanup_mode(value, 1); + } else return error(_("invalid key: %s"), key); if (!error_flag) @@ -2771,6 +2792,11 @@ static int save_opts(struct replay_opts *opts) res |= git_config_set_in_file_gently(opts_file, "options.allow-rerere-auto", opts->allow_rerere_auto == RERERE_AUTOUPDATE ? "true" : "false"); + + if (opts->explicit_cleanup) + res |= git_config_set_in_file_gently(opts_file, + "options.default-msg-cleanup", + describe_cleanup_mode(opts->default_msg_cleanup)); return res; } -- cgit v0.10.2-6-g49f6 From 1a2b985fb375e7ce14932bfc59365024af2fb6ab Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Wed, 17 Apr 2019 11:23:30 +0100 Subject: cherry-pick/revert: add scissors line on merge conflict Fix a bug where the scissors line is placed after the Conflicts: section, in the case where a merge conflict occurs and commit.cleanup = scissors. Helped-by: Phillip Wood Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt index d64e724..754b16c 100644 --- a/Documentation/git-cherry-pick.txt +++ b/Documentation/git-cherry-pick.txt @@ -57,6 +57,13 @@ OPTIONS With this option, 'git cherry-pick' will let you edit the commit message prior to committing. +--cleanup=:: + This option determines how the commit message will be cleaned up before + being passed on to the commit machinery. See linkgit:git-commit[1] for more + details. In particular, if the '' is given a value of `scissors`, + scissors will be appended to `MERGE_MSG` before being passed on in the case + of a conflict. + -x:: When recording the commit, append a line that says "(cherry picked from commit ...)" to the original commit diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt index 6afccb2..0c82ca5 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.txt @@ -66,6 +66,13 @@ more details. With this option, 'git revert' will not start the commit message editor. +--cleanup=:: + This option determines how the commit message will be cleaned up before + being passed on to the commit machinery. See linkgit:git-commit[1] for more + details. In particular, if the '' is given a value of `scissors`, + scissors will be appended to `MERGE_MSG` before being passed on in the case + of a conflict. + -n:: --no-commit:: Usually the command automatically creates some commits with diff --git a/builtin/merge.c b/builtin/merge.c index 03b9f72..e96f72a 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -927,14 +927,8 @@ static int suggest_conflicts(void) * Thus, we will get the cleanup mode which is returned when we _are_ * using an editor. */ - if (get_cleanup_mode(cleanup_arg, 1) == COMMIT_MSG_CLEANUP_SCISSORS) { - fputc('\n', fp); - wt_status_add_cut_line(fp); - /* comments out the newline from append_conflicts_hint */ - fputc(comment_line_char, fp); - } - - append_conflicts_hint(&the_index, &msgbuf); + append_conflicts_hint(&the_index, &msgbuf, + get_cleanup_mode(cleanup_arg, 1)); fputs(msgbuf.buf, fp); strbuf_release(&msgbuf); fclose(fp); diff --git a/builtin/revert.c b/builtin/revert.c index a47b53c..d4dcedb 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -96,11 +96,13 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) { const char * const * usage_str = revert_or_cherry_pick_usage(opts); const char *me = action_name(opts); + const char *cleanup_arg = NULL; int cmd = 0; struct option base_options[] = { OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'), OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'), OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'), + OPT_CLEANUP(&cleanup_arg), OPT_BOOL('n', "no-commit", &opts->no_commit, N_("don't automatically commit")), OPT_BOOL('e', "edit", &opts->edit, N_("edit the commit message")), OPT_NOOP_NOARG('r', NULL), @@ -137,6 +139,11 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) if (opts->keep_redundant_commits) opts->allow_empty = 1; + if (cleanup_arg) { + opts->default_msg_cleanup = get_cleanup_mode(cleanup_arg, 1); + opts->explicit_cleanup = 1; + } + /* Check for incompatible command line arguments */ if (cmd) { char *this_operation; diff --git a/sequencer.c b/sequencer.c index 501d99f..0375648 100644 --- a/sequencer.c +++ b/sequencer.c @@ -182,7 +182,7 @@ static int git_sequencer_config(const char *k, const char *v, void *cb) opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_ALL; opts->explicit_cleanup = 1; } else if (!strcmp(s, "scissors")) { - opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_SPACE; + opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_SCISSORS; opts->explicit_cleanup = 1; } else { warning(_("invalid commit message cleanup mode '%s'"), @@ -554,10 +554,16 @@ static const char *describe_cleanup_mode(int cleanup_mode) } void append_conflicts_hint(struct index_state *istate, - struct strbuf *msgbuf) + struct strbuf *msgbuf, enum commit_msg_cleanup_mode cleanup_mode) { int i; + if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) { + strbuf_addch(msgbuf, '\n'); + wt_status_append_cut_line(msgbuf); + strbuf_addch(msgbuf, comment_line_char); + } + strbuf_addch(msgbuf, '\n'); strbuf_commented_addf(msgbuf, "Conflicts:\n"); for (i = 0; i < istate->cache_nr;) { @@ -625,7 +631,8 @@ static int do_recursive_merge(struct repository *r, _(action_name(opts))); if (!clean) - append_conflicts_hint(r->index, msgbuf); + append_conflicts_hint(r->index, msgbuf, + opts->default_msg_cleanup); return !clean; } @@ -944,7 +951,6 @@ static int run_git_commit(struct repository *r, unsigned int flags) { struct child_process cmd = CHILD_PROCESS_INIT; - const char *value; if ((flags & CREATE_ROOT_COMMIT) && !(flags & AMEND_MSG)) { struct strbuf msg = STRBUF_INIT, script = STRBUF_INIT; @@ -1014,7 +1020,7 @@ static int run_git_commit(struct repository *r, argv_array_push(&cmd.args, "-e"); else if (!(flags & CLEANUP_MSG) && !opts->signoff && !opts->record_origin && - git_config_get_value("commit.cleanup", &value)) + !opts->explicit_cleanup) argv_array_push(&cmd.args, "--cleanup=verbatim"); if ((flags & ALLOW_EMPTY)) diff --git a/sequencer.h b/sequencer.h index 8295c84..7023da9 100644 --- a/sequencer.h +++ b/sequencer.h @@ -116,7 +116,8 @@ int rearrange_squash(struct repository *r); */ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag); -void append_conflicts_hint(struct index_state *istate, struct strbuf *msgbuf); +void append_conflicts_hint(struct index_state *istate, + struct strbuf *msgbuf, enum commit_msg_cleanup_mode cleanup_mode); enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg, int use_editor); diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 777fb23..a584b11 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -189,6 +189,46 @@ test_expect_success 'failed cherry-pick registers participants in index' ' test_cmp expected actual ' +test_expect_success \ + 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' ' + pristine_detach initial && + git config commit.cleanup scissors && + cat <<-EOF >expected && + picked + + # ------------------------ >8 ------------------------ + # Do not modify or remove the line above. + # Everything below it will be ignored. + # + # Conflicts: + # foo + EOF + + test_must_fail git cherry-pick picked && + + test_i18ncmp expected .git/MERGE_MSG +' + +test_expect_success \ + 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' ' + pristine_detach initial && + git config --unset commit.cleanup && + cat <<-EOF >expected && + picked + + # ------------------------ >8 ------------------------ + # Do not modify or remove the line above. + # Everything below it will be ignored. + # + # Conflicts: + # foo + EOF + + test_must_fail git cherry-pick --cleanup=scissors picked && + + test_i18ncmp expected .git/MERGE_MSG +' + test_expect_success 'failed cherry-pick describes conflict in work tree' ' pristine_detach initial && cat <<-EOF >expected && @@ -335,6 +375,52 @@ test_expect_success 'revert conflict, diff3 -m style' ' test_cmp expected actual ' +test_expect_success \ + 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' ' + pristine_detach initial && + git config commit.cleanup scissors && + cat >expected <<-EOF && + Revert "picked" + + This reverts commit OBJID. + + # ------------------------ >8 ------------------------ + # Do not modify or remove the line above. + # Everything below it will be ignored. + # + # Conflicts: + # foo + EOF + + test_must_fail git revert picked && + + sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual && + test_i18ncmp expected actual +' + +test_expect_success \ + 'revert conflict, ensure cleanup=scissors places scissors line properly' ' + pristine_detach initial && + git config --unset commit.cleanup && + cat >expected <<-EOF && + Revert "picked" + + This reverts commit OBJID. + + # ------------------------ >8 ------------------------ + # Do not modify or remove the line above. + # Everything below it will be ignored. + # + # Conflicts: + # foo + EOF + + test_must_fail git revert --cleanup=scissors picked && + + sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual && + test_i18ncmp expected actual +' + test_expect_success 'failed cherry-pick does not forget -s' ' pristine_detach initial && test_must_fail git cherry-pick -s picked && -- cgit v0.10.2-6-g49f6