Hi *,
$subject since:
4f672ad (wt-status: load diff ui config, 2008-10-26)
I tried to make a test case, but failed. I think because it is a bit tricky the fake_editor/stdin/stdout stuff, so at the end I bisected it by hand
Regards, Santi
threads / discuss / 16250
Subject: git commit -v does not removes the patch
Hi *,
$subject since:
4f672ad (wt-status: load diff ui config, 2008-10-26)
I tried to make a test case, but failed. I think because it is a bit tricky the fake_editor/stdin/stdout stuff, so at the end I bisected it by hand
Regards, Santi
Re: git commit -v does not removes the patch
On Mon, Nov 10, 2008 at 04:20:51PM +0100, Santi Béjar wrote:
> Hi *, > > $subject since: > > 4f672ad (wt-status: load diff ui config, 2008-10-26) > > I tried to make a test case, but failed. I think because it is a bit > tricky the fake_editor/stdin/stdout stuff, so at the end I bisected it > by hand
Sorry, I don't quite understand what the problem is. From reading your subject line, I expected that "git commit -v" would show the diff in your editor, but then accidentally also include it in the final commit message. But I can't seem to reproduce that.
Can you describe the problem in more detail?
-Peff
Re: git commit -v does not removes the patch
On Mon, Nov 10, 2008 at 7:10 PM, Jeff King <peff@peff.net> wrote:
> On Mon, Nov 10, 2008 at 04:20:51PM +0100, Santi Béjar wrote: > >> Hi *, >> >> $subject since: >> >> 4f672ad (wt-status: load diff ui config, 2008-10-26) >> >> I tried to make a test case, but failed. I think because it is a bit >> tricky the fake_editor/stdin/stdout stuff, so at the end I bisected it >> by hand > > Sorry, I don't quite understand what the problem is. From reading your > subject line, I expected that "git commit -v" would show the diff in > your editor, but then accidentally also include it in the final commit > message. But I can't seem to reproduce that. > > Can you describe the problem in more detail?
It is exactly as you described. I'll try in other systems.
Santi
Re: git commit -v does not removes the patch
"Santi Béjar" <santi@agolina.net> writes:
> On Mon, Nov 10, 2008 at 7:10 PM, Jeff King <peff@peff.net> wrote: >> On Mon, Nov 10, 2008 at 04:20:51PM +0100, Santi Béjar wrote: >> >>> Hi *, >>> >>> $subject since: >>> >>> 4f672ad (wt-status: load diff ui config, 2008-10-26) >>> >>> I tried to make a test case, but failed. I think because it is a bit >>> tricky the fake_editor/stdin/stdout stuff, so at the end I bisected it >>> by hand >> >> Sorry, I don't quite understand what the problem is. From reading your >> subject line, I expected that "git commit -v" would show the diff in >> your editor, but then accidentally also include it in the final commit >> message. But I can't seem to reproduce that. >> >> Can you describe the problem in more detail? > > It is exactly as you described. I'll try in other systems.
Guess in the dark... by any chance are you enabling color unconditionally?
Re: git commit -v does not removes the patch
On Mon, Nov 10, 2008 at 03:27:18PM -0800, Junio C Hamano wrote:
> > It is exactly as you described. I'll try in other systems. > > Guess in the dark... by any chance are you enabling color unconditionally?
I thought I covered that case explicitly...
...yes, I can't reproduce with color set to "always". And indeed, looking at the diff for 4f672ad shows that we always turn off color for the message that goes to the editor (since we can't trust our isatty setting _anyway_, since we're not going to the tty).
So that's not it.
-Peff
Re: git commit -v does not removes the patch
On Tue, Nov 11, 2008 at 1:07 AM, Jeff King <peff@peff.net> wrote:
> On Mon, Nov 10, 2008 at 03:27:18PM -0800, Junio C Hamano wrote: > >> > It is exactly as you described. I'll try in other systems. >> >> Guess in the dark... by any chance are you enabling color unconditionally? > > I thought I covered that case explicitly... > > ...yes, I can't reproduce with color set to "always". And indeed, > looking at the diff for 4f672ad shows that we always turn off color for > the message that goes to the editor (since we can't trust our isatty > setting _anyway_, since we're not going to the tty). > > So that's not it.
Almost! I have diff.mnemonicprefix=true, if I unset it everything works.
Santi
Re: git commit -v does not removes the patch
On Tue, Nov 11, 2008 at 08:56:34AM +0100, Santi Béjar wrote:
> Almost! I have diff.mnemonicprefix=true, if I unset it everything works.
Ah, indeed. The obvious fix is just loosening our match a little bit:
diff --git a/builtin-commit.c b/builtin-commit.c index 93ca496..a721990 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -1015,7 +1015,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } /* Truncate the message just before the diff, if any. */ - p = strstr(sb.buf, "\ndiff --git a/"); + p = strstr(sb.buf, "\ndiff --git "); if (p != NULL) strbuf_setlen(&sb, p - sb.buf + 1); But I have to wonder if there is some more robust solution. It seems like this can have false positives if you include diff output in your commit message, and a potential false negative if you delete the newline (e.g., delete everything up to "diff --git", making it the first line). But I guess we haven't seen a lot of complaints, so maybe those conditions aren't worth worrying about. -Peff
Re: git commit -v does not removes the patch
On Tue, Nov 11, 2008 at 11:29 AM, Jeff King <peff@peff.net> wrote:
> On Tue, Nov 11, 2008 at 08:56:34AM +0100, Santi Béjar wrote: > >> Almost! I have diff.mnemonicprefix=true, if I unset it everything works. > > Ah, indeed. The obvious fix is just loosening our match a little bit: > > diff --git a/builtin-commit.c b/builtin-commit.c > index 93ca496..a721990 100644 > --- a/builtin-commit.c > +++ b/builtin-commit.c > @@ -1015,7 +1015,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) > } > > /* Truncate the message just before the diff, if any. */ > - p = strstr(sb.buf, "\ndiff --git a/"); > + p = strstr(sb.buf, "\ndiff --git "); > if (p != NULL) > strbuf_setlen(&sb, p - sb.buf + 1); >
It fixes it, thanks.
> > But I have to wonder if there is some more robust solution. It seems > like this can have false positives if you include diff output in your > commit message, and a potential false negative if you delete the newline > (e.g., delete everything up to "diff --git", making it the first line). > > But I guess we haven't seen a lot of complaints, so maybe those > conditions aren't worth worrying about.
The false positive/negative were already possible, it was just a little more narrow. So not worth worrying about. Also, if you really want a diff in the commit message you can use the --cleanup option.
A more robust solution could be to have a:
# Everything after this line will be removed from the commit message
But, again, not worth.
Santi
> > -Peff >
Re: git commit -v does not removes the patch
Jeff King <peff@peff.net> writes:
> But I have to wonder if there is some more robust solution. It seems > like this can have false positives if you include diff output in your > commit message, and a potential false negative if you delete the newline > (e.g., delete everything up to "diff --git", making it the first line).
Actually, I recall (from my googling quite some time ago) people noticing this, but they learnt to live with it.
We may want to change this. We can say "# Everything under this line is deleted." at the beginning of the "#" block we produce in the commit log message editor, replacing the "Lines starting with '#' will be ignored, " we currently have. When reading back the editor result, make "git commit -v" scan for the "# Everything ..." line. We remove it and everything that follows, but we do not touch anything above that line (including the ones that begin with "diff" or "#") except the usual trailing whitespace removal. That way, people can leave a sample shell session with root prompt, and sample diff, in their message.
If we do not see "# Everything ..." when we read it back, we can do what we currently do as a fallback.
Re: git commit -v does not removes the patch
On Tue, Nov 11, 2008 at 09:13:18AM -0800, Junio C Hamano wrote:
> We may want to change this. We can say "# Everything under this line is > deleted." at the beginning of the "#" block we produce in the commit log > message editor, replacing the "Lines starting with '#' will be ignored, " > we currently have. When reading back the editor result, make "git commit > -v" scan for the "# Everything ..." line. We remove it and everything > that follows, but we do not touch anything above that line (including the > ones that begin with "diff" or "#") except the usual trailing whitespace > removal. That way, people can leave a sample shell session with root > prompt, and sample diff, in their message. > > If we do not see "# Everything ..." when we read it back, we can do what > we currently do as a fallback.
I am little hesitant to do this, because I think people have scripted minorly around the template format (at the very least, for syntax highlighting). I think some people may have pre-written templates, as well, though I guess your "If we do not see..." paragraph is meant to address that. Though that brings some confusion itself, because now the parsing rules for what is kept change if I delete that line.
Here's a patch series that at least improves the situation by turning off the diff-stripping if we never put in a diff in the first place. That way only people who actually _use_ "-v" will have to pay for it. It has the fix I sent to Santi earlier, as well as some related cleanups.
1/5: define empty tree sha1 as a macro
2/5: wt-status: refactor initial commit printing
3/5: status: show "-v" diff even for initial commit
4/5: commit: loosen pattern for matching "-v" diff
5/5: commit: only strip diff from message in verbose mode-Peff
[PATCH 1/5] define empty tree sha1 as a macro
This can potentially be used in a few places, so let's make it available to all parts of the code.
Signed-off-by: Jeff King <peff@peff.net> --- I use the _HEX version in further patches, but since it is such a magic number, I thought it made sense to keep all definitions in the same place.
cache.h | 6 ++++++ sha1_file.c | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/cache.h b/cache.h index bcc57ba..46eb2af 100644 --- a/cache.h +++ b/cache.h @@ -528,6 +528,12 @@ static inline void hashclr(unsigned char *hash) } extern int is_empty_blob_sha1(const unsigned char *sha1); +#define EMPTY_TREE_SHA1_HEX \ + "4b825dc642cb6eb9a060e54bf8d69288fbee4904" +#define EMPTY_TREE_SHA1_BIN \ + "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \ + "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04" + int git_mkstemp(char *path, size_t n, const char *template); /* diff --git a/sha1_file.c b/sha1_file.c index 654d039..037e439 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -2056,9 +2056,7 @@ static struct cached_object { static int cached_object_nr, cached_object_alloc; static struct cached_object empty_tree = { - /* empty tree sha1: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 */ - "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" - "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04", + EMPTY_TREE_SHA1_BIN, OBJ_TREE, "", 0
-- 1.6.0.4.883.g4593ee.dirty
[PATCH 2/5] wt-status: refactor initial commit printing
When we showed the initial commit, we had no reference to diff against, so we went through the cache manually. Nowadays, however, we have a virtual empty tree commit, so we can simply diff against that to get the same results.
Signed-off-by: Jeff King <peff@peff.net> --- I ran across this when I realized I could do the same trick for the verbose diff (which I will do in the next patch). I think it is a worthwhile cleanup. Not only does it remove a lot of lines, but it gives a single codepath for printing, which will be helpful if that codepath ever changes (e.g., with the alternate status formats we talked about a few weeks ago).
This could be made even simpler by setting s->reference to the empty tree when we are on the initial commit, but I think that is a little messy. The caller may have set s->reference to an arbitrary pointer, including one which needs free()d, and we would be overwriting that. As it happens, with the current callers there is no problem, but it seems like a bad interface.
wt-status.c | 28 +++------------------------- 1 files changed, 3 insertions(+), 25 deletions(-)
diff --git a/wt-status.c b/wt-status.c index 6a7645e..c78588e 100644 --- a/wt-status.c +++ b/wt-status.c @@ -185,31 +185,12 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q, wt_status_print_trailer(s); } -static void wt_status_print_initial(struct wt_status *s) -{ - int i; - struct strbuf buf = STRBUF_INIT; - - if (active_nr) { - s->commitable = 1; - wt_status_print_cached_header(s); - } - for (i = 0; i < active_nr; i++) { - color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t"); - color_fprintf_ln(s->fp, color(WT_STATUS_UPDATED), "new file: %s", - quote_path(active_cache[i]->name, -1, - &buf, s->prefix)); - } - if (active_nr) - wt_status_print_trailer(s); - strbuf_release(&buf); -} - static void wt_status_print_updated(struct wt_status *s) { struct rev_info rev; init_revisions(&rev, NULL); - setup_revisions(0, NULL, &rev, s->reference); + setup_revisions(0, NULL, &rev, + s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = wt_status_print_updated_cb; rev.diffopt.format_callback_data = s; @@ -360,12 +341,9 @@ void wt_status_print(struct wt_status *s) color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#"); color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "# Initial commit"); color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#"); - wt_status_print_initial(s); - } - else { - wt_status_print_updated(s); } + wt_status_print_updated(s); wt_status_print_changed(s); if (wt_status_submodule_summary) wt_status_print_submodule_summary(s);
-- 1.6.0.4.883.g4593ee.dirty
[PATCH 3/5] status: show "-v" diff even for initial commit
Since we can use the same "diff against empty tree" trick as we do for the non-initial case, it is trivial to make this work.
Signed-off-by: Jeff King <peff@peff.net> --- I ran across this while writing my test cases for the later patches. I don't see any reason why it shouldn't behave this way, and I suspect the reason was just that the original author saw how we did "wt_status_print_initial" and didn't want to have to do the equivalent for generating diff output.
t/t7507-commit-verbose.sh | 29 +++++++++++++++++++++++++++++ wt-status.c | 5 +++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100755 t/t7507-commit-verbose.sh
diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh new file mode 100755 index 0000000..94b12e9 --- /dev/null +++ b/t/t7507-commit-verbose.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +test_description='verbose commit template' +. ./test-lib.sh + +cat >check-for-diff <<EOF +#!$SHELL_PATH +exec grep '^diff --git' "\$1" +EOF +chmod +x check-for-diff +test_set_editor "$PWD/check-for-diff" + +cat >message <<'EOF' +subject + +body +EOF + +test_expect_success 'setup' ' + echo content >file && + git add file && + git commit -F message +' + +test_expect_success 'initial commit shows verbose diff' ' + git commit --amend -v +' + +test_done diff --git a/wt-status.c b/wt-status.c index c78588e..3edae43 100644 --- a/wt-status.c +++ b/wt-status.c @@ -279,7 +279,8 @@ static void wt_status_print_verbose(struct wt_status *s) struct rev_info rev; init_revisions(&rev, NULL); - setup_revisions(0, NULL, &rev, s->reference); + setup_revisions(0, NULL, &rev, + s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference); rev.diffopt.output_format |= DIFF_FORMAT_PATCH; rev.diffopt.detect_rename = 1; DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV); @@ -352,7 +353,7 @@ void wt_status_print(struct wt_status *s) else if (s->commitable) fprintf(s->fp, "# Untracked files not listed (use -u option to show untracked files)\n"); - if (s->verbose && !s->is_initial) + if (s->verbose) wt_status_print_verbose(s); if (!s->commitable) { if (s->amend)
-- 1.6.0.4.883.g4593ee.dirty
[PATCH 4/5] commit: loosen pattern for matching "-v" diff
When a user asks to see the diff to be applied via "git commit -v", the diff ends up in the commit template, and we must later remove it.
To detect the start of the included diff, we used to search for a line beginning with "diff --git a/". However, in the face of diff.mnemonicprefix, that will actually be "diff --git i/".
So let's just loosen the pattern a bit to handle either case.
Signed-off-by: Jeff King <peff@peff.net> --- And this is the fix from before, with a test case.
builtin-commit.c | 2 +- t/t7507-commit-verbose.sh | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/builtin-commit.c b/builtin-commit.c index 93ca496..a721990 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -1015,7 +1015,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } /* Truncate the message just before the diff, if any. */ - p = strstr(sb.buf, "\ndiff --git a/"); + p = strstr(sb.buf, "\ndiff --git "); if (p != NULL) strbuf_setlen(&sb, p - sb.buf + 1); diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh index 94b12e9..be70166 100755 --- a/t/t7507-commit-verbose.sh +++ b/t/t7507-commit-verbose.sh @@ -26,4 +26,20 @@ test_expect_success 'initial commit shows verbose diff' ' git commit --amend -v ' +check_message() { + git log -1 --pretty=format:%s%n%n%b >actual && + test_cmp "$1" actual +} + +test_expect_success 'verbose diff is stripped out' ' + git commit --amend -v && + check_message message +' + +test_expect_success 'verbose diff is stripped out (mnemonicprefix)' ' + git config diff.mnemonicprefix true && + git commit --amend -v && + check_message message +' + test_done
-- 1.6.0.4.883.g4593ee.dirty
[PATCH 5/5] commit: only strip diff from message in verbose mode
When the "-v" option is given, we put diff of what is to be committed into the commit template, and then strip it back out again after the user has edited it.
We guess at the location of the diff by searching for the "diff --git" header. This means that if the user puts their own diff in the message (e.g., as a sample output), then we will accidentally trigger the pattern, removing part of their output.
We can avoid doing this stripping altogether if the user didn't use "-v" in the first place, so we know that any match we find will be a false positive.
Signed-off-by: Jeff King <peff@peff.net> --- Obviously this doesn't solve the problem entirely, but it at least makes a reasonable rule: if we accidentally eat your sample diff output with "-v", then try without it. :)
But more importantly, I suspect "-v" is used infrequently, so in practice this should fix most cases.
builtin-commit.c | 8 +++++--- t/t7507-commit-verbose.sh | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/builtin-commit.c b/builtin-commit.c index a721990..591d16b 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -1015,9 +1015,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } /* Truncate the message just before the diff, if any. */ - p = strstr(sb.buf, "\ndiff --git "); - if (p != NULL) - strbuf_setlen(&sb, p - sb.buf + 1); + if (verbose) { + p = strstr(sb.buf, "\ndiff --git "); + if (p != NULL) + strbuf_setlen(&sb, p - sb.buf + 1); + } if (cleanup_mode != CLEANUP_NONE) stripspace(&sb, cleanup_mode == CLEANUP_ALL); diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh index be70166..2a3ea7a 100755 --- a/t/t7507-commit-verbose.sh +++ b/t/t7507-commit-verbose.sh @@ -42,4 +42,25 @@ test_expect_success 'verbose diff is stripped out (mnemonicprefix)' ' check_message message ' +cat >diff <<'EOF' +This is an example commit message that contains a diff. + +diff --git c/file i/file +new file mode 100644 +index 0000000..f95c11d +--- /dev/null ++++ i/file +@@ -0,0 +1 @@ ++this is some content +EOF + +test_expect_success 'diff in message is retained without -v' ' + git commit --amend -F diff && + check_message diff +' + +test_expect_failure 'diff in message is retained with -v' ' + git commit --amend -F diff -v && + check_message diff +' test_done
-- 1.6.0.4.883.g4593ee.dirty
Re: [PATCH 5/5] commit: only strip diff from message in verbose mode
On Wed, Nov 12, 2008 at 03:25:52AM -0500, Jeff King wrote:
> +test_expect_success 'diff in message is retained without -v' ' > + git commit --amend -F diff && > + check_message diff > +' > + > +test_expect_failure 'diff in message is retained with -v' ' > + git commit --amend -F diff -v && > + check_message diff > +'
I put in this expect_failure to remind us that we could be doing better. The solution you proposed would fix this test. Another idea I had was to use a bogus diff header, and match on that. Something like:
diff --git --verbose-commit a/file b/file
and searching for "diff --git --verbose-commit", which would not trigger on any diffs (unless, of course, you were trying to explain how the verbose mode worked in your commit message :) ).
But that doesn't cover any other special input (i.e., lines beginning with '#'), and would probably require an ugly hack to the diff machinery (some diff option for "add these bogus diff command line options").
-Peff
Re: git commit -v does not removes the patch
Jeff King <peff@peff.net> writes:
> Here's a patch series that at least improves the situation by turning > off the diff-stripping if we never put in a diff in the first place. > That way only people who actually _use_ "-v" will have to pay for it. > It has the fix I sent to Santi earlier, as well as some related > cleanups. > > 1/5: define empty tree sha1 as a macro > 2/5: wt-status: refactor initial commit printing > 3/5: status: show "-v" diff even for initial commit > 4/5: commit: loosen pattern for matching "-v" diff > 5/5: commit: only strip diff from message in verbose mode
Makes sense. Thanks, will queue for 'master' with minor futzing to lift minimum fix to 'maint'.
Re: git commit -v does not removes the patch
Hi,
On Wed, Nov 12, 2008 at 03:16:09AM -0500, Jeff King wrote:
> Here's a patch series that at least improves the situation by turning > off the diff-stripping if we never put in a diff in the first place. > That way only people who actually _use_ "-v" will have to pay for it.
I always want to see the diff while editing a commit message, even if it's the commit message of a merge, a revert, a squash in rebase. Since these commands do not have an option equivalent to 'git commit -v', I wrote a little prepare-commit-msg hook to always append the appropriate diff to the end of the appropriate commit message file. This worked pretty well for the last couple of months, until 5/5 got into maint.
So, what is the/is there a preferred way to always include the diff in the commit message template and get it removed automatically? Are there any workarounds other than revert that commit locally?
Thanks, Gábor
Re: git commit -v does not removes the patch
On Thu, Nov 20, 2008 at 02:09:28PM +0100, SZEDER Gábor wrote:
> I always want to see the diff while editing a commit message, even if > it's the commit message of a merge, a revert, a squash in rebase. > Since these commands do not have an option equivalent to 'git commit > -v', I wrote a little prepare-commit-msg hook to always append the > appropriate diff to the end of the appropriate commit message file. > This worked pretty well for the last couple of months, until 5/5 got > into maint.
Hmm. I am sad that this change has broken somebody's existing workflow. OTOH, I'm not convinced that workflow wasn't a little crazy to begin with, depending on this undocumented munging.
> So, what is the/is there a preferred way to always include the diff in > the commit message template and get it removed automatically? Are > there any workarounds other than revert that commit locally?
How about:
$ cat .git/hooks/prepare-commit-msg
#!/bin/sh
git diff --cached >>"$1" $ cat .git/hooks/commit-msg
#!/bin/sh
sed -i '/^diff --git/Q' "$1"which is more or less the original behavior. The only downside I see is that "--no-verify" will turn off the commit-msg hook, but not the prepare-commit-msg hook.
-Peff
Re: git commit -v does not removes the patch
Hi Jeff,
On Thu, Nov 20, 2008 at 10:20:16AM -0500, Jeff King wrote:
> On Thu, Nov 20, 2008 at 02:09:28PM +0100, SZEDER Gábor wrote:
> Hmm. I am sad that this change has broken somebody's existing workflow. > OTOH, I'm not convinced that workflow wasn't a little crazy to begin > with, depending on this undocumented munging.
Well, the docs didn't say that the patch is only removed in verbose mode (; But I agree with you that this is (was) an undocumented "feature" that I should not have relied upon.
> > So, what is the/is there a preferred way to always include the diff in > > the commit message template and get it removed automatically? Are > > there any workarounds other than revert that commit locally? > > How about: > > $ cat .git/hooks/prepare-commit-msg > #!/bin/sh > git diff --cached >>"$1" > > $ cat .git/hooks/commit-msg > #!/bin/sh > sed -i '/^diff --git/Q' "$1" > > which is more or less the original behavior. The only downside I see is > that "--no-verify" will turn off the commit-msg hook, but not the > prepare-commit-msg hook.
Thanks for the tip. Junio's suggestion about '# Everything under this line is deleted.' could be implemented this way fairly easily (just an additional echo in prepare-commit-msg, and other pattern in commit-msg). But 'git commit --no-verify' is indeed a problem. Although I never use it explicitly, 'git rebase -i' does so.
However.
'git rebase -i' uses 'git commit --no-verify' since c5b09feb (Avoid update hook during git-rebase --interactive, 2007-12-19) to avoid squashing commits together when the pre-commit hook fails because of whitespace errors. But note that at that time the 'git commit' calls looked like this (after that patch):
$USE_OUTPUT git commit --no-verify -F "$MSG" $EDIT_COMMIT git commit --no-verify -F "$DOTEST"/message -e
Witness that it's not checked whether 'git commit' succeeded or failed. However, nowadays those lines look like this:
$USE_OUTPUT git commit --no-verify $MSG_OPT "$MSG_FILE" $EDIT_COMMIT || failed=t
git commit --no-verify -F "$DOTEST"/message -e || { ...There is a check for failed 'git commit', so if the pre-commit hook finds whitespace errors, then 'git commit' will error out, and, consequently, 'git rebase -i' will error out, too, and commits won't be squashed accidentaly.
So, I wonder whether those '--no-verify' options are still required in 'git rebase -i'.
Any thoughts?
Thanks, Gábor
Re: git commit -v does not removes the patch
On Sat, Nov 22, 2008 at 04:55:41PM +0100, SZEDER Gábor wrote:
> Thanks for the tip. Junio's suggestion about '# Everything under this > line is deleted.' could be implemented this way fairly easily (just an > additional echo in prepare-commit-msg, and other pattern in > commit-msg). But 'git commit --no-verify' is indeed a problem. > Although I never use it explicitly, 'git rebase -i' does so.
One other option would be to munge the editor script instead of using hooks. I.e., something like this:
$ cat ~/local/bin/git-editor #!/bin/sh echo '# Everything under this line is deleted' >>"$1" git diff --cached >>"$1" $EDITOR "$1" || exit $? sed -i '/^# Everything under this line is deleted$/Q' "$1"
$ git config core.editor ~/local/bin/git-editor
Of course, then you end up with the munging for things like "git rebase -i" picking commits, but it should be harmless (since we end up removing it anyway).
-Peff
Re: git commit -v does not removes the patch
SZEDER Gábor <szeder@ira.uka.de> writes:
> So, I wonder whether those '--no-verify' options are still required in > 'git rebase -i'.
The use of --no-verify there does not have anything to do with "whitespace errors". It is to override _any_ validation the users want to do when using "git commit" in their interactive workflow. It so happens that the example hook we ship demonstrates how you hunt for whitespace errors, but you have to remember that it is just an example.
We may want to disable the checking of exit status from commit-msg hook while still calling the hook itself, though. The primary purpose of the hook is to allow users to reformat (say, passing "fmt -64") the message, but it is allowed to interfere and that was meant to happen when using "git commit" but we probably do not want it when rebasing.
Further, we also may want to make the use of --no-verify overridable from the command line when running rebase. The primary purpose of the rebase command is to transplant a sequence of commits to someplace else without molesting its contents and message unnecessarily, and --no-verify is a good thing to use in general for that reason, but people may sometimes want to use it as a way to clean up the changes.