Skip to content

Commit

Permalink
Include recent command history in fast-import crash reports
Browse files Browse the repository at this point in the history
When we crash the frontend developer (or end-user) may need to know
roughly around what part of the input stream we had a problem with
and aborted on.  Because line numbers aren't very useful in this
sort of application we instead just keep the last 100 commands in
a FIFO queue and print them as part of the crash report.

Currently one problem with this design is a commit that has
more than 100 modified files in it will flood the FIFO and any
context regarding branch/from/committer/mark/comments will be lost.
We really should save only the last few (10?) file changes for the
current commit, ensuring we have some prior higher level commands
in the FIFO when we crash on a file M/D/C/R command.

Another issue with this approach is the FIFO only includes the
commands, it does not include the commit messages.  Yet having a
commit message may be useful to help locate the relevant change in
the source material.  In practice I don't think this is going to be a
major concern as the frontend can always embed its own source change
set identifier as a comment (which will appear in the crash report)
and the commit message(s) for the most recent commits of any given
branch should be obtainable from the (packed) commit objects.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
  • Loading branch information
Shawn O. Pearce committed Aug 19, 2007
1 parent 8acb329 commit 904b194
Showing 1 changed file with 58 additions and 4 deletions.
62 changes: 58 additions & 4 deletions fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ typedef enum {
WHENSPEC_NOW,
} whenspec_type;

struct recent_command
{
struct recent_command *prev;
struct recent_command *next;
char *buf;
};

/* Configured limits on output */
static unsigned long max_depth = 10;
static off_t max_packsize = (1LL << 32) - 1;
Expand Down Expand Up @@ -335,6 +342,10 @@ static struct tag *last_tag;
static whenspec_type whenspec = WHENSPEC_RAW;
static struct strbuf command_buf;
static int unread_command_buf;
static struct recent_command cmd_hist = {&cmd_hist, &cmd_hist, NULL};
static struct recent_command *cmd_tail = &cmd_hist;
static struct recent_command *rc_free;
static unsigned int cmd_save = 100;
static uintmax_t next_mark;
static struct dbuf new_data;

Expand Down Expand Up @@ -370,6 +381,7 @@ static void write_crash_report(const char *err, va_list params)
FILE *rpt = fopen(loc, "w");
struct branch *b;
unsigned long lu;
struct recent_command *rc;

if (!rpt) {
error("can't write crash report %s: %s", loc, strerror(errno));
Expand All @@ -388,6 +400,18 @@ static void write_crash_report(const char *err, va_list params)
vfprintf(rpt, err, params);
fputc('\n', rpt);

fputc('\n', rpt);
fputs("Most Recent Commands Before Crash\n", rpt);
fputs("---------------------------------\n", rpt);
for (rc = cmd_hist.next; rc != &cmd_hist; rc = rc->next) {
if (rc->next == &cmd_hist)
fputs("* ", rpt);
else
fputs(" ", rpt);
fputs(rc->buf, rpt);
fputc('\n', rpt);
}

fputc('\n', rpt);
fputs("Active Branch LRU\n", rpt);
fputs("-----------------\n", rpt);
Expand Down Expand Up @@ -1563,11 +1587,35 @@ static void dump_marks(void)
static void read_next_command(void)
{
do {
if (unread_command_buf)
if (unread_command_buf) {
unread_command_buf = 0;
else
if (command_buf.eof)
return;
} else {
struct recent_command *rc;

command_buf.buf = NULL;
read_line(&command_buf, stdin, '\n');
} while (!command_buf.eof && command_buf.buf[0] == '#');
if (command_buf.eof)
return;

rc = rc_free;
if (rc)
rc_free = rc->next;
else {
rc = cmd_hist.next;
cmd_hist.next = rc->next;
cmd_hist.next->prev = &cmd_hist;
free(rc->buf);
}

rc->buf = command_buf.buf;
rc->prev = cmd_tail;
rc->next = cmd_hist.prev;
rc->prev->next = rc;
cmd_tail = rc;
}
} while (command_buf.buf[0] == '#');
}

static void skip_optional_lf()
Expand Down Expand Up @@ -1600,6 +1648,7 @@ static void *cmd_data (size_t *size)
size_t sz = 8192, term_len = command_buf.len - 5 - 2;
length = 0;
buffer = xmalloc(sz);
command_buf.buf = NULL;
for (;;) {
read_line(&command_buf, stdin, '\n');
if (command_buf.eof)
Expand Down Expand Up @@ -2269,7 +2318,7 @@ static const char fast_import_usage[] =

int main(int argc, const char **argv)
{
int i, show_stats = 1;
unsigned int i, show_stats = 1;

git_config(git_default_config);
alloc_objects(object_entry_alloc);
Expand Down Expand Up @@ -2323,6 +2372,11 @@ int main(int argc, const char **argv)
if (i != argc)
usage(fast_import_usage);

rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
for (i = 0; i < (cmd_save - 1); i++)
rc_free[i].next = &rc_free[i + 1];
rc_free[cmd_save - 1].next = NULL;

prepare_packed_git();
start_packfile();
set_die_routine(die_nicely);
Expand Down

0 comments on commit 904b194

Please sign in to comment.