From: Jonathan Nieder <jrnieder@gmail.com>
To: Jay Soffian <jaysoffian@gmail.com>
Cc: git@vger.kernel.org, "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Junio C Hamano" <gitster@pobox.com>
Subject: Re: [PATCH] Teach commit about CHERRY_PICK_HEAD
Date: Thu, 17 Feb 2011 18:29:40 -0600 [thread overview]
Message-ID: <20110218002913.GB12182@elie> (raw)
In-Reply-To: <1297921850-94962-1-git-send-email-jaysoffian@gmail.com>
Jay Soffian wrote:
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -54,9 +54,16 @@ static const char empty_amend_advice[] =
> "it empty. You can repeat your command with --allow-empty, or you can\n"
> "remove the commit entirely with \"git reset HEAD^\".\n";
>
> +static const char empty_cherry_pick_advice[] =
> +"The most recent cherry-pick is empty. If you wish to commit it, use:\n"
> +"\n"
> +" git commit --allow-empty\n"
> +"\n"
> +"Otherwise, please remove the file %s\n";
After scratching my head a little, this seems to mean
After conflict resolution, your last cherry-pick does not
introduce any changes. To commit it as an empty commit, use:\n
\n
git commit --allow-empty\n
\n
Alternatively, you can cancel the cherry-pick by removing\n
the file %s\n
It suspect it might be more intuitive to say
Alternatively, you can cancel the cherry-pick by running\n
"git reset".\n
which works because the index is known to be clean at that point.
> +/*
> + * The _message variables are commit names from which to take
> + * the commit message and/or authorship.
> + */
Makes sense, thanks. I'll think more about an intuitive and
consistent name for these and hopefully send a patch for it later as a
separate topic.
> + if (whence == FROM_CHERRY_PICK && !renew_authorship) {
> + author_message = "CHERRY_PICK_HEAD";
> + author_message_buffer = read_commit_message(author_message);
I mentioned in a side thread that script authors might be happier if
their carefully prepared GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL do not
get overridden in this case, but I was wrong[*]. Might make sense
to add a test for that:
GIT_AUTHOR_NAME="Someone else" &&
GIT_AUTHOR_EMAIL=someone@else.example.com &&
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
git cherry-pick something &&
git diff-tree -s --format="%an <%ae>" >actual &&
test_cmp expect actual
(This is just a side note; the patch is good.)
In the $GIT_CHERRY_PICK_HELP set case, won't the CHERRY_PICK_HEAD
behavior be harmless? rebase --interactive --continue wants to set
GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL but that is only in order to copy
the author identity from the original commit.
> --- a/wt-status.c
> +++ b/wt-status.c
> @@ -60,7 +60,7 @@ static void wt_status_print_unmerged_header(struct wt_status *s)
> color_fprintf_ln(s->fp, c, "# Unmerged paths:");
> if (!advice_status_hints)
> return;
> - if (s->in_merge)
> + if (s->whence != FROM_COMMIT)
> ;
> else if (!s->is_initial)
> color_fprintf_ln(s->fp, c, "# (use \"git reset %s <file>...\" to unstage)", s->reference);
The advice 'use "git reset HEAD -- <file>..." to unstage' makes
perfect sense to me in the cherry-pick case, no? The operator is
replaying an existing commit, and tweaking the result amounts to
pretending she made the change herself and tweaking that.
> @@ -77,7 +77,7 @@ static void wt_status_print_cached_header(struct wt_status *s)
> color_fprintf_ln(s->fp, c, "# Changes to be committed:");
> if (!advice_status_hints)
> return;
> - if (s->in_merge)
> + if (s->whence != FROM_COMMIT)
> ; /* NEEDSWORK: use "git reset --unresolve"??? */
Likewise.
> --- a/wt-status.h
> +++ b/wt-status.h
> @@ -24,6 +24,13 @@ enum untracked_status_type {
> SHOW_ALL_UNTRACKED_FILES
> };
>
> +/* from where does this commit originate */
> +enum commit_whence {
> + FROM_COMMIT, /* normal */
> + FROM_MERGE, /* commit came from merge */
> + FROM_CHERRY_PICK /* commit came from cherry-pick */
> +};
I think these comments are not in a place that will help a person
understand the code, but I don't have the energy to go back and forth
on it.
Everything not mentioned above except the --no-commit case mentioned
by Junio looks good to me, though I haven't tested.
Thanks for your thoughtfulness.
Jonathan
[*]
-- 8< --
Subject: [BAD IDEA] commit: let GIT_AUTHOR_NAME/EMAIL take effect when commiting a cherry-pick
commit -c/-C/--amend to take the commit message and author from
another message has always overridden the GIT_AUTHOR_NAME and
GIT_AUTHOR_EMAIL variables. Letting the command line override the
environment in this way is generally convenient and more intuitive if
a person has forgotten what is in the environment:
GIT_AUTHOR_NAME=me
GIT_AUTHOR_EMAIL=email@example.com
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
...
git commit; # using identity from environment
...
git commit; # another commit as me
...
# commit by someone else
git commit --author='Someone Else <other@example.com>'
...
# commit by someone else
git commit -c someone-elses-commit
The new CHERRY_PICK_HEAD feature inherits the same semantics.
Uncareful scripts that want to commit with a different author name and
email when taking over after a failed cherry-pick use authorship from
the cherry-picked commit instead of the environment:
! git cherry-pick complicated; # failed cherry-pick
... resolve the conflict ...
git commit
While that could theoretically break some scripts, it's worth it for
consistency, the intuitiveness-when-user-forgets-environment issue
mentioned above, and because cherry-pick itself, which internally
does something like
git cherry-pick --no-commit $1; # simple cherry-pick
git commit
has always ignored the GIT_AUTHOR_NAME/EMAIL environment settings.
The patch below makes commit with CHERRY_PICK_HEAD respect
GIT_AUTHOR_NAME/EMAIL anyway, to demonstrate how broken that is. It
breaks tests t3404 and t3506.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
builtin/commit.c | 59 ++++++++++++++++++++++++++++++++---------------------
1 files changed, 36 insertions(+), 23 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index 35eb024..f398910 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -80,6 +80,7 @@ static const char *template_file;
* the commit message and/or authorship.
*/
static const char *author_message, *author_message_buffer;
+static int author_message_overrides_environ;
static char *edit_message, *use_message;
static char *fixup_message, *squash_message;
static int all, edit_flag, also, interactive, only, amend, signoff;
@@ -504,6 +505,38 @@ static int is_a_merge(const unsigned char *sha1)
static const char sign_off_header[] = "Signed-off-by: ";
+static void reuse_author_info(char **name, char **email, char **date)
+{
+ const char *a, *lb, *rb, *eol;
+
+ if (author_message_overrides_environ)
+ *name = *email = *date = NULL;
+
+ a = strstr(author_message_buffer, "\nauthor ");
+ if (!a)
+ die("invalid commit: %s", author_message);
+
+ lb = strchrnul(a + strlen("\nauthor "), '<');
+ rb = strchrnul(lb, '>');
+ eol = strchrnul(rb, '\n');
+ if (!*lb || !*rb || !*eol)
+ die("invalid commit: %s", author_message);
+
+ if (!*name) {
+ if (lb == a + strlen("\nauthor "))
+ /* \nauthor <foo@example.com> */
+ *name = xcalloc(1, 1);
+ else
+ *name = xmemdupz(a + strlen("\nauthor "),
+ (lb - strlen(" ") -
+ (a + strlen("\nauthor "))));
+ }
+ if (!*email)
+ *email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
+ if (!*date)
+ *date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
+}
+
static void determine_author_info(struct strbuf *author_ident)
{
char *name, *email, *date;
@@ -512,29 +545,8 @@ static void determine_author_info(struct strbuf *author_ident)
email = getenv("GIT_AUTHOR_EMAIL");
date = getenv("GIT_AUTHOR_DATE");
- if (author_message) {
- const char *a, *lb, *rb, *eol;
-
- a = strstr(author_message_buffer, "\nauthor ");
- if (!a)
- die("invalid commit: %s", author_message);
-
- lb = strchrnul(a + strlen("\nauthor "), '<');
- rb = strchrnul(lb, '>');
- eol = strchrnul(rb, '\n');
- if (!*lb || !*rb || !*eol)
- die("invalid commit: %s", author_message);
-
- if (lb == a + strlen("\nauthor "))
- /* \nauthor <foo@example.com> */
- name = xcalloc(1, 1);
- else
- name = xmemdupz(a + strlen("\nauthor "),
- (lb - strlen(" ") -
- (a + strlen("\nauthor "))));
- email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
- date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
- }
+ if (author_message)
+ reuse_author_info(&name, &email, &date);
if (force_author) {
const char *lb = strstr(force_author, " <");
@@ -1034,6 +1046,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
author_message = use_message;
author_message_buffer = use_message_buffer;
}
+ author_message_overrides_environ = 1;
}
if (whence == FROM_CHERRY_PICK && !renew_authorship) {
author_message = "CHERRY_PICK_HEAD";
--
1.7.4.1
next prev parent reply other threads:[~2011-02-18 0:29 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-17 4:18 [PATCH v3 0/4] CHERRY_PICK_HEAD Jay Soffian
2011-02-17 4:18 ` [PATCH v3 1/4] Introduce CHERRY_PICK_HEAD Jay Soffian
2011-02-17 20:01 ` Junio C Hamano
2011-02-17 22:32 ` Jonathan Nieder
2011-02-20 2:29 ` Jay Soffian
2011-02-20 2:48 ` Jonathan Nieder
2011-02-20 6:43 ` Junio C Hamano
2011-02-17 21:56 ` Junio C Hamano
2011-02-17 22:42 ` Jay Soffian
2011-02-17 22:48 ` Jonathan Nieder
2011-02-17 4:18 ` [PATCH v3 2/4] bash: teach __git_ps1 about CHERRY_PICK_HEAD Jay Soffian
2011-02-17 4:18 ` [PATCH v3 3/4] commit.c: replace some literal strings with constants Jay Soffian
2011-02-17 5:19 ` Jonathan Nieder
2011-02-17 5:50 ` [PATCH] Teach commit about CHERRY_PICK_HEAD Jay Soffian
2011-02-18 0:29 ` Jonathan Nieder [this message]
2011-02-17 5:49 ` [PATCH v3 3/4] commit.c: replace some literal strings with constants Junio C Hamano
2011-02-17 4:18 ` [PATCH v3 4/4] Teach commit about CHERRY_PICK_HEAD Jay Soffian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110218002913.GB12182@elie \
--to=jrnieder@gmail.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jaysoffian@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).