From: Jonas Fonseca Date: Thu, 15 Jan 2009 21:41:58 +0000 (+0100) Subject: Add support for loading blame for parent commits X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=a2cebdb88437086d5083c893e472275e1cdf1957;p=tig.git Add support for loading blame for parent commits Requested by Jeff King in <20080410040213.GA29618@sigill.intra.peff.net> --- diff --git a/NEWS b/NEWS index 6109737..d8e1468 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ Improvements: - Tree view: annotate entries with commit information. - Tree & blob view: open any blob in an editor. - Stage & main view: restore view position when reloading. + - Blame view: load blame for parent commit. For merge commits the parent + is queried. Bound to ',' by default via the existing "parent" action. Bug fixes: diff --git a/TODO b/TODO index 082c637..1b88728 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,3 @@ Features that should be explored. - Blame view: Allow names in the author column to be abbreviated to initials. Will optimize screen usage for the blame view. - - - Blame view: make it possible to jump/load blame for parents. Idea by - Jeff King. diff --git a/manual.txt b/manual.txt index 87f9492..fe4d311 100644 --- a/manual.txt +++ b/manual.txt @@ -345,7 +345,8 @@ Up This key is "context sensitive" and will move the cursor one \ to display it. Down Similar to 'Up' but will move down. ',' Move to parent. In the tree view, this means switch to the parent \ - directory. + directory. In the blame view it will load blame for the parent \ + commit. For merges the parent is queried. ----------------------------------------------------------------------------- [[cursor-nav]] diff --git a/tig.c b/tig.c index 7997091..095e9c6 100644 --- a/tig.c +++ b/tig.c @@ -3337,6 +3337,60 @@ parse_author_line(char *ident, char *author, size_t authorsize, struct tm *tm) } } +static enum input_status +select_commit_parent_handler(void *data, char *buf, int c) +{ + size_t parents = *(size_t *) data; + int parent = 0; + + if (!isdigit(c)) + return INPUT_SKIP; + + if (*buf) + parent = atoi(buf) * 10; + parent += c - '0'; + + if (parent > parents) + return INPUT_SKIP; + return INPUT_OK; +} + +static bool +select_commit_parent(const char *id, char rev[SIZEOF_REV]) +{ + char buf[SIZEOF_STR * 4]; + const char *revlist_argv[] = { + "git", "rev-list", "-1", "--parents", id, NULL + }; + int parents; + + if (!run_io_buf(revlist_argv, buf, sizeof(buf)) || + !*chomp_string(buf) || + (parents = (strlen(buf) / 40) - 1) < 0) { + report("Failed to get parent information"); + return FALSE; + + } else if (parents == 0) { + report("The selected commit has no parents"); + return FALSE; + } + + if (parents > 1) { + char prompt[SIZEOF_STR]; + char *result; + + if (!string_format(prompt, "Which parent? [1..%d] ", parents)) + return FALSE; + result = prompt_input(prompt, select_commit_parent_handler, &parents); + if (!result) + return FALSE; + parents = atoi(result); + } + + string_copy_rev(rev, &buf[41 * parents]); + return TRUE; +} + /* * Pager backend */ @@ -4365,6 +4419,12 @@ blame_request(struct view *view, enum request request, struct line *line) } break; + case REQ_PARENT: + if (check_blame_commit(blame) && + select_commit_parent(blame->commit->id, opt_ref)) + open_view(view, REQ_VIEW_BLAME, OPEN_REFRESH); + break; + case REQ_ENTER: if (!blame->commit) { report("No commit loaded yet");