commit: avoid redundant scissor line with --cleanup=scissors -v

`git commit --cleanup=scissors -v` prints two scissors lines: one at the start of the comment lines, and the other right before the diff. This is redundant, and pushes the diff further down in the user's editor than it needs to be. Make wt_status_add_cut_line() remember if it has added a cut line before, and avoid adding a redundant one. Add a test for this. Signed-off-by: Josh Triplett <josh@joshtriplett.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Josh Triplett committed Feb 27, 2024 at 01:16 UTC 688a0a751e9ee032be9fb70d7d63220bc85acae1
4 files changed +17 -7
builtin/commit.c
+2 -2
@@ -926,7 +926,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
926 if (whence != FROM_COMMIT) {
927 if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
928 !merge_contains_scissors)
929 - wt_status_add_cut_line(s->fp);
929 + wt_status_add_cut_line(s);
930 status_printf_ln(
931 s, GIT_COLOR_NORMAL,
932 whence == FROM_MERGE ?
@@ -947,7 +947,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
947 status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_all, comment_line_char);
948 else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {
949 if (whence == FROM_COMMIT && !merge_contains_scissors)
950 - wt_status_add_cut_line(s->fp);
950 + wt_status_add_cut_line(s);
951 } else /* COMMIT_MSG_CLEANUP_SPACE, that is. */
952 status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_space, comment_line_char);
953
t/t7502-commit-porcelain.sh
+5
@@ -736,6 +736,11 @@ test_expect_success 'message shows date when it is explicitly set' '
736 .git/COMMIT_EDITMSG
737 '
738
739 +test_expect_success 'message does not have multiple scissors lines' '
740 + git commit --cleanup=scissors -v --allow-empty -e -m foo &&
741 + test $(grep -c -e "--- >8 ---" .git/COMMIT_EDITMSG) -eq 1
742 +'
743 +
744 test_expect_success AUTOIDENT 'message shows committer when it is automatic' '
745
746 echo >>negative &&
wt-status.c
+8 -4
@@ -1107,12 +1107,15 @@ void wt_status_append_cut_line(struct strbuf *buf)
1107 strbuf_add_commented_lines(buf, explanation, strlen(explanation), comment_line_char);
1108 }
1109
1110 -void wt_status_add_cut_line(FILE *fp)
1110 +void wt_status_add_cut_line(struct wt_status *s)
1111 {
1112 struct strbuf buf = STRBUF_INIT;
1113
1114 + if (s->added_cut_line)
1115 + return;
1116 + s->added_cut_line = 1;
1117 wt_status_append_cut_line(&buf);
1115 - fputs(buf.buf, fp);
1118 + fputs(buf.buf, s->fp);
1119 strbuf_release(&buf);
1120 }
1121
@@ -1143,11 +1146,12 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
1146 * file (and even the "auto" setting won't work, since it
1147 * will have checked isatty on stdout). But we then do want
1148 * to insert the scissor line here to reliably remove the
1146 - * diff before committing.
1149 + * diff before committing, if we didn't already include one
1150 + * before.
1151 */
1152 if (s->fp != stdout) {
1153 rev.diffopt.use_color = 0;
1150 - wt_status_add_cut_line(s->fp);
1154 + wt_status_add_cut_line(s);
1155 }
1156 if (s->verbose > 1 && s->committable) {
1157 /* print_updated() printed a header, so do we */
wt-status.h
+2 -1
@@ -130,6 +130,7 @@ struct wt_status {
130 int rename_score;
131 int rename_limit;
132 enum wt_status_format status_format;
133 + unsigned char added_cut_line; /* boolean */
134 struct wt_status_state state;
135 struct object_id oid_commit; /* when not Initial */
136
@@ -147,7 +148,7 @@ struct wt_status {
148
149 size_t wt_status_locate_end(const char *s, size_t len);
150 void wt_status_append_cut_line(struct strbuf *buf);
150 -void wt_status_add_cut_line(FILE *fp);
151 +void wt_status_add_cut_line(struct wt_status *s);
152 void wt_status_prepare(struct repository *r, struct wt_status *s);
153 void wt_status_print(struct wt_status *s);
154 void wt_status_collect(struct wt_status *s);