From: Ramkumar Ramachandra <artagnon@gmail.com>
To: Git List <git@vger.kernel.org>
Cc: Jonathan Nieder <jrnieder@gmail.com>, Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 4/4] revert: report fine-grained errors from insn parser
Date: Thu, 29 Mar 2012 19:28:15 +0530 [thread overview]
Message-ID: <1333029495-10034-5-git-send-email-artagnon@gmail.com> (raw)
In-Reply-To: <1333029495-10034-1-git-send-email-artagnon@gmail.com>
The infrastructure that parses '.git/sequencer/todo' is meant to
handle arbitrary user input some day, so it can be used as the
implementation of 'git rebase --interactive' and 'git sequencer
--edit'. It is currently sub-optimal for that purpose because the
parse error messages just say:
error: Could not parse line 5.
This patch shifts responsibility to parse_insn_line(), which can come
up with a more detailed message like:
error: .git/sequencer/todo:5: unrecognized action: frobnicate
Once the operator is allowed to edit the sequence, the message might
be adjusted to something like:
error: <sequence you just gave me>:5: unrecognized action: frobnicate
instead of exposing an implementation detail. Some day 'git sequencer
--edit' could even re-launch the editor with an error message in a
comment before the problematic line and the cursor pointing there.
For now, pointing to the explicit filename is useful since this should
only happen if there was filesystem corruption, tampering, or a git
bug.
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
sequencer.c | 45 +++++++++++++++++++++++++++++++++------------
1 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 02e58ad..cb93ee8 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -513,7 +513,22 @@ static int format_todo(struct strbuf *buf, struct commit_list *todo_list,
return 0;
}
-static struct commit *parse_insn_line(char *bol, char *eol, struct replay_opts *opts)
+static int parse_error(const char *message, const char *file,
+ int lineno, char *error_line)
+{
+ const char *suffix = "";
+ int error_len = strcspn(error_line, " \t\n");
+
+ if (error_len > 20) {
+ error_len = 20;
+ suffix = "...";
+ }
+ return error(_("%s:%d: %s: %.*s%s"), file, lineno, message,
+ error_len, error_line, suffix);
+}
+
+int parse_insn_line(char *bol, char *eol, struct replay_opts *opts,
+ struct commit_list *list, int lineno)
{
unsigned char commit_sha1[20];
enum replay_action action;
@@ -526,7 +541,8 @@ static struct commit *parse_insn_line(char *bol, char *eol, struct replay_opts *
action = REPLAY_REVERT;
bol += strlen("revert");
} else
- return NULL;
+ return parse_error(_("unrecognized action"),
+ git_path(SEQ_TODO_FILE), lineno, bol);
/* Eat up extra spaces/ tabs before object name */
bol += strspn(bol, " \t");
@@ -538,32 +554,36 @@ static struct commit *parse_insn_line(char *bol, char *eol, struct replay_opts *
if (action != opts->action) {
const char *action_str;
action_str = action == REPLAY_REVERT ? "revert" : "cherry-pick";
- error(_("Cannot %s during a %s"), action_str, action_name(opts));
- return NULL;
+ return parse_error(_("invalid action"),
+ git_path(SEQ_TODO_FILE), lineno, bol);
}
namelen = strcspn(bol, " \t\n");
if (getn_sha1(bol, namelen, commit_sha1))
- return NULL;
-
- return lookup_commit_reference(commit_sha1);
+ return parse_error(_("malformed object name"),
+ git_path(SEQ_TODO_FILE), lineno, bol);
+
+ list->item = lookup_commit_reference(commit_sha1);
+ if (!list->item)
+ return parse_error(_("not a valid commit"),
+ git_path(SEQ_TODO_FILE), lineno, bol);
+ list->next = NULL;
+ return 0;
}
static int parse_insn_buffer(char *buf, struct commit_list **todo_list,
struct replay_opts *opts)
{
struct commit_list **next = todo_list;
- struct commit *commit;
+ struct commit_list list;
char *p = buf;
int i;
for (i = 1; *p; i++) {
char *eol = strchrnul(p, '\n');
- commit = parse_insn_line(p, eol, opts);
- if (!commit)
- return error(_("Could not parse line %d."), i);
- next = commit_list_append(commit, next);
+ if (parse_insn_line(p, eol, opts, &list, i))
+ return -1;
+ next = commit_list_append(list.item, next);
p = *eol ? eol + 1 : eol;
}
if (!*todo_list)
--
1.7.8.1.362.g5d6df.dirty
prev parent reply other threads:[~2012-03-29 13:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-29 13:58 [PATCH 0/4] Minor sequencer.c cleanups Ramkumar Ramachandra
2012-03-29 13:58 ` [PATCH 1/4] sha1_name: introduce getn_sha1() to take length Ramkumar Ramachandra
2012-04-03 22:08 ` Jonathan Nieder
2012-04-04 7:35 ` Matthieu Moy
2012-04-04 15:40 ` Ramkumar Ramachandra
2012-04-04 20:53 ` Jonathan Nieder
2012-03-29 13:58 ` [PATCH 2/4] revert: use getn_sha1() to simplify insn parsing Ramkumar Ramachandra
2012-03-29 13:58 ` [PATCH 3/4] revert: simplify insn parsing logic Ramkumar Ramachandra
2012-04-02 20:33 ` Junio C Hamano
2012-04-03 4:50 ` Ramkumar Ramachandra
2012-03-29 13:58 ` Ramkumar Ramachandra [this message]
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=1333029495-10034-5-git-send-email-artagnon@gmail.com \
--to=artagnon@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jrnieder@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).