#define SCALE_SPLIT_VIEW(height) ((height) * 2 / 3)
#define TIG_LS_REMOTE \
- "git ls-remote . 2>/dev/null"
+ "git ls-remote $(git rev-parse --git-dir) 2>/dev/null"
#define TIG_DIFF_CMD \
"git show --root --patch-with-stat --find-copies-harder -B -C %s 2>/dev/null"
if (opt_request == REQ_VIEW_MAIN)
/* XXX: This is vulnerable to the user overriding
* options required for the main view parser. */
- string_copy(opt_cmd, "git log --stat --pretty=raw");
+ string_copy(opt_cmd, "git log --pretty=raw");
else
string_copy(opt_cmd, "git");
buf_size = strlen(opt_cmd);
die("command too long");
opt_cmd[buf_size] = 0;
-
}
if (*opt_encoding && strcasecmp(opt_encoding, "UTF-8"))
{ 'g', REQ_TOGGLE_REV_GRAPH },
{ ':', REQ_PROMPT },
- /* wgetch() with nodelay() enabled returns ERR when there's no input. */
- { ERR, REQ_NONE },
-
/* Using the ncurses SIGWINCH handler. */
{ KEY_RESIZE, REQ_SCREEN_RESIZE },
};
char *ref = NULL;
FILE *pipe;
- if (!string_format(refbuf, "git describe %s", commit_id))
+ if (!string_format(refbuf, "git describe %s 2>/dev/null", commit_id))
return TRUE;
pipe = popen(refbuf, "r");
static bool
tree_enter(struct view *view, struct line *line)
{
- enum open_flags flags = display[0] == view ? OPEN_SPLIT : OPEN_DEFAULT;
+ enum open_flags flags;
enum request request;
switch (line->type) {
/* Trees and subtrees share the same ID, so they are not not
* unique like blobs. */
- flags |= OPEN_RELOAD;
+ flags = OPEN_RELOAD;
request = REQ_VIEW_TREE;
break;
case LINE_TREE_FILE:
+ flags = display[0] == view ? OPEN_SPLIT : OPEN_DEFAULT;
request = REQ_VIEW_BLOB;
break;
struct commit {
char id[SIZEOF_REV]; /* SHA1 ID. */
- char title[75]; /* First line of the commit message. */
+ char title[128]; /* First line of the commit message. */
char author[75]; /* Author of the commit. */
struct tm time; /* Date from the author ident. */
struct ref **refs; /* Repository references. */
case LINE_AUTHOR:
{
+ /* Parse author lines where the name may be empty:
+ * author <email@address.tld> 1138474660 +0100
+ */
char *ident = line + STRING_SIZE("author ");
- char *end = strchr(ident, '<');
+ char *nameend = strchr(ident, '<');
+ char *emailend = strchr(ident, '>');
- if (!commit)
+ if (!commit || !nameend || !emailend)
break;
- if (end) {
- char *email = end + 1;
-
- for (; end > ident && isspace(end[-1]); end--) ;
-
- if (end == ident && *email) {
- ident = email;
- end = strchr(ident, '>');
- for (; end > ident && isspace(end[-1]); end--) ;
- }
- *end = 0;
+ *nameend = *emailend = 0;
+ ident = chomp_string(ident);
+ if (!*ident) {
+ ident = chomp_string(nameend + 1);
+ if (!*ident)
+ ident = "Unknown";
}
- /* End is NULL or ident meaning there's no author. */
- if (end <= ident)
- ident = "Unknown";
-
string_copy(commit->author, ident);
/* Parse epoch and timezone */
- if (end) {
- char *secs = strchr(end + 1, '>');
- char *zone;
- time_t time;
+ if (emailend[1] == ' ') {
+ char *secs = emailend + 2;
+ char *zone = strchr(secs, ' ');
+ time_t time = (time_t) atol(secs);
- if (!secs || secs[1] != ' ')
- break;
-
- secs += 2;
- time = (time_t) atol(secs);
- zone = strchr(secs, ' ');
if (zone && strlen(zone) == STRING_SIZE(" +0700")) {
long tz;
time -= tz;
}
+
gmtime_r(&time, &commit->time);
}
break;
/* Require titles to start with a non-space character at the
* offset used by git log. */
- /* FIXME: More gracefull handling of titles; append "..." to
- * shortened titles, etc. */
- if (strncmp(line, " ", 4) ||
- isspace(line[4]))
+ if (strncmp(line, " ", 4))
+ break;
+ line += 4;
+ /* Well, if the title starts with a whitespace character,
+ * try to be forgiving. Otherwise we end up with no title. */
+ while (isspace(*line))
+ line++;
+ if (*line == '\0')
break;
+ /* FIXME: More graceful handling of titles; append "..." to
+ * shortened titles, etc. */
- string_copy(commit->title, line + 4);
+ string_copy(commit->title, line);
}
return TRUE;
/* Refresh, accept single keystroke of input */
key = wgetch(status_win);
- if (key == ERR)
+
+ /* wgetch() with nodelay() enabled returns ERR when there's no
+ * input. */
+ if (key == ERR) {
+ request = REQ_NONE;
continue;
+ }
request = get_keybinding(display[current_view]->keymap, key);