--- /dev/null
+diff --git a/TODO b/TODO
+index adf9129..464e122 100644
+--- a/TODO
++++ b/TODO
+@@ -24,10 +24,8 @@ Features that should be explored.
+
+ - Split sources of tig.c into multiple files.
+
+- - Rewrite revgraph handling to use --parents and --boundary. The former
+- should help to cleanup this messy part of the code, while the latter
+- is nice for general repository inspection when revision limiters are
+- used.
++ - Rewrite revgraph handling to use --parents, which should help to
++ cleanup this messy part of the code.
+
+ - Color the revgraph to make it easier to follow branches. Idea by
+ Dominik Vogt
+diff --git a/VERSION b/VERSION
+index 5712157..91e2525 100644
+--- a/VERSION
++++ b/VERSION
+@@ -1 +1 @@
+-0.10.1
++0.11.git
+diff --git a/configure.ac b/configure.ac
+index 65b5af3..764190a 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -12,12 +12,14 @@ AC_SEARCH_LIBS([wclear], [ncursesw ncurses curses], [],
+ AM_ICONV
+
+ AC_PROG_CC
+-AC_CHECK_PROGS(GIT_CONFIG, [git-config git-repo-config])
+-if test "${ac_cv_prog_GIT_CONFIG}" = ""; then
+- AC_CHECK_PROGS(GIT, [git])
+- GIT_CONFIG="${ac_cv_prog_GIT} config"
+-fi
++
++AC_CHECK_PROG(GIT, [git], [git], [AC_ERROR([git not found])])
++AC_MSG_CHECKING([which config command git supports])
++GIT_CONFIG="git repo-config"
++git config --list >/dev/null && GIT_CONFIG="git config"
++AC_MSG_RESULT([$GIT_CONFIG])
+ AC_DEFINE_UNQUOTED(GIT_CONFIG,"$GIT_CONFIG",[git config program])
++
+ AC_CHECK_PROGS(ASCIIDOC, [asciidoc false])
+ AC_CHECK_PROGS(XMLTO, [xmlto false])
+ AC_CHECK_PROGS(DOCBOOK2PDF, [docbook2pdf false])
+diff --git a/manual.txt b/manual.txt
+index ca01561..fd466db 100644
+--- a/manual.txt
++++ b/manual.txt
+@@ -347,7 +347,10 @@ z Stop all background loading. This can be useful if you use \
+ the revision log.
+ v Show version.
+ '.' Toggle line numbers on/off.
++D Toggle date display on/off.
++A Toggle author display on/off.
+ g Toggle revision graph visualization on/off.
++F Toggle reference display on/off (tag and branch names).
+ ':' Open prompt. This allows you to specify what git command \
+ to run. Example `:log -p`
+ u Update status of file. In the status view, this allows you to add an \
+diff --git a/tig.c b/tig.c
+index 1eb028b..36f03c2 100644
+--- a/tig.c
++++ b/tig.c
+@@ -58,7 +58,7 @@ static void warn(const char *msg, ...);
+ static void report(const char *msg, ...);
+ static int read_properties(FILE *pipe, const char *separators, int (*read)(char *, size_t, char *, size_t));
+ static void set_nonblocking_input(bool loading);
+-static size_t utf8_length(const char *string, size_t max_width, int *coloffset, int *trimmed);
++static size_t utf8_length(const char *string, size_t max_width, int *trimmed, bool reserve);
+
+ #define ABS(x) ((x) >= 0 ? (x) : -(x))
+ #define MIN(x, y) ((x) < (y) ? (x) : (y))
+@@ -140,6 +140,7 @@ struct ref {
+ char *name; /* Ref name; tag or head names are shortened. */
+ char id[SIZEOF_REV]; /* Commit SHA1 ID */
+ unsigned int tag:1; /* Is it a tag? */
++ unsigned int ltag:1; /* If so, is the tag local? */
+ unsigned int remote:1; /* Is it a remote ref? */
+ unsigned int next:1; /* For ref lists: are there more refs? */
+ };
+@@ -354,7 +355,10 @@ sq_quote(char buf[SIZEOF_STR], size_t bufsize, const char *src)
+ REQ_(SHOW_VERSION, "Show version information"), \
+ REQ_(STOP_LOADING, "Stop all loading views"), \
+ REQ_(TOGGLE_LINENO, "Toggle line numbers"), \
++ REQ_(TOGGLE_DATE, "Toggle date display"), \
++ REQ_(TOGGLE_AUTHOR, "Toggle author display"), \
+ REQ_(TOGGLE_REV_GRAPH, "Toggle revision graph visualization"), \
++ REQ_(TOGGLE_REFS, "Toggle reference display (tags/branches)"), \
+ REQ_(STATUS_UPDATE, "Update file status"), \
+ REQ_(STATUS_MERGE, "Merge file using external tool"), \
+ REQ_(TREE_PARENT, "Switch to parent directory in tree view"), \
+@@ -422,8 +426,11 @@ static const char usage[] =
+ " -h, --help Show help message and exit\n";
+
+ /* Option and state variables. */
++static bool opt_date = TRUE;
++static bool opt_author = TRUE;
+ static bool opt_line_number = FALSE;
+ static bool opt_rev_graph = FALSE;
++static bool opt_show_refs = TRUE;
+ static int opt_num_interval = NUMBER_INTERVAL;
+ static int opt_tab_size = TABSIZE;
+ static enum request opt_request = REQ_VIEW_MAIN;
+@@ -598,9 +605,6 @@ parse_options(int argc, char *argv[])
+ opt_cmd[buf_size] = 0;
+ }
+
+- if (*opt_encoding && strcasecmp(opt_encoding, "UTF-8"))
+- opt_utf8 = FALSE;
+-
+ return TRUE;
+ }
+
+@@ -648,6 +652,7 @@ LINE(MAIN_AUTHOR, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
+ LINE(MAIN_COMMIT, "", COLOR_DEFAULT, COLOR_DEFAULT, 0), \
+ LINE(MAIN_DELIM, "", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
+ LINE(MAIN_TAG, "", COLOR_MAGENTA, COLOR_DEFAULT, A_BOLD), \
++LINE(MAIN_LOCAL_TAG,"", COLOR_MAGENTA, COLOR_DEFAULT, A_BOLD), \
+ LINE(MAIN_REMOTE, "", COLOR_YELLOW, COLOR_DEFAULT, A_BOLD), \
+ LINE(MAIN_REF, "", COLOR_CYAN, COLOR_DEFAULT, A_BOLD), \
+ LINE(MAIN_REVGRAPH,"", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
+@@ -808,7 +813,10 @@ static struct keybinding default_keybindings[] = {
+ { 'v', REQ_SHOW_VERSION },
+ { 'r', REQ_SCREEN_REDRAW },
+ { '.', REQ_TOGGLE_LINENO },
++ { 'D', REQ_TOGGLE_DATE },
++ { 'A', REQ_TOGGLE_AUTHOR },
+ { 'g', REQ_TOGGLE_REV_GRAPH },
++ { 'F', REQ_TOGGLE_REFS },
+ { ':', REQ_PROMPT },
+ { 'u', REQ_STATUS_UPDATE },
+ { 'M', REQ_STATUS_MERGE },
+@@ -1115,6 +1123,12 @@ option_color_command(int argc, char *argv[])
+ return OK;
+ }
+
++static bool parse_bool(const char *s)
++{
++ return (!strcmp(s, "1") || !strcmp(s, "true") ||
++ !strcmp(s, "yes")) ? TRUE : FALSE;
++}
++
+ /* Wants: name = value */
+ static int
+ option_set_command(int argc, char *argv[])
+@@ -1129,10 +1143,28 @@ option_set_command(int argc, char *argv[])
+ return ERR;
+ }
+
++ if (!strcmp(argv[0], "show-author")) {
++ opt_author = parse_bool(argv[2]);
++ return OK;
++ }
++
++ if (!strcmp(argv[0], "show-date")) {
++ opt_date = parse_bool(argv[2]);
++ return OK;
++ }
++
+ if (!strcmp(argv[0], "show-rev-graph")) {
+- opt_rev_graph = (!strcmp(argv[2], "1") ||
+- !strcmp(argv[2], "true") ||
+- !strcmp(argv[2], "yes"));
++ opt_rev_graph = parse_bool(argv[2]);
++ return OK;
++ }
++
++ if (!strcmp(argv[0], "show-refs")) {
++ opt_show_refs = parse_bool(argv[2]);
++ return OK;
++ }
++
++ if (!strcmp(argv[0], "show-line-numbers")) {
++ opt_line_number = parse_bool(argv[2]);
+ return OK;
+ }
+
+@@ -1394,9 +1426,10 @@ struct view {
+ struct view *parent;
+
+ /* Buffering */
+- unsigned long lines; /* Total number of lines */
++ size_t lines; /* Total number of lines */
+ struct line *line; /* Line index */
+- unsigned long line_size;/* Total number of allocated lines */
++ size_t line_alloc; /* Total number of allocated lines */
++ size_t line_size; /* Total number of used lines */
+ unsigned int digits; /* Number of digits in the lines member. */
+
+ /* Loading */
+@@ -1460,44 +1493,34 @@ static int
+ draw_text(struct view *view, const char *string, int max_len, int col,
+ bool use_tilde, int tilde_attr)
+ {
+- int n;
+-
+- n = 0;
+- if (max_len > 0) {
+- int len;
+- int trimmed = FALSE;
++ int len = 0;
++ int trimmed = FALSE;
+
+- if (opt_utf8) {
+- int pad = 0;
++ if (max_len <= 0)
++ return 0;
+
+- len = utf8_length(string, max_len, &pad, &trimmed);
+- if (trimmed && use_tilde) {
++ if (opt_utf8) {
++ len = utf8_length(string, max_len, &trimmed, use_tilde);
++ } else {
++ len = strlen(string);
++ if (len > max_len) {
++ if (use_tilde) {
+ max_len -= 1;
+- len = utf8_length(
+- string, max_len, &pad, &trimmed);
+ }
+- n = len;
+- } else {
+- len = strlen(string);
+- if (len > max_len) {
+- if (use_tilde) {
+- max_len -= 1;
+- }
+- len = max_len;
+- trimmed = TRUE;
+- }
+- n = len;
+- }
+- waddnstr(view->win, string, n);
+- if (trimmed && use_tilde) {
+- if (tilde_attr != -1)
+- wattrset(view->win, tilde_attr);
+- waddch(view->win, '~');
+- n++;
++ len = max_len;
++ trimmed = TRUE;
+ }
+ }
+
+- return n;
++ waddnstr(view->win, string, len);
++ if (trimmed && use_tilde) {
++ if (tilde_attr != -1)
++ wattrset(view->win, tilde_attr);
++ waddch(view->win, '~');
++ len++;
++ }
++
++ return len;
+ }
+
+ static bool
+@@ -2076,15 +2099,33 @@ begin_update(struct view *view)
+ return TRUE;
+ }
+
++#define ITEM_CHUNK_SIZE 256
++static void *
++realloc_items(void *mem, size_t *size, size_t new_size, size_t item_size)
++{
++ size_t num_chunks = *size / ITEM_CHUNK_SIZE;
++ size_t num_chunks_new = (new_size + ITEM_CHUNK_SIZE - 1) / ITEM_CHUNK_SIZE;
++
++ if (mem == NULL || num_chunks != num_chunks_new) {
++ *size = num_chunks_new * ITEM_CHUNK_SIZE;
++ mem = realloc(mem, *size * item_size);
++ }
++
++ return mem;
++}
++
+ static struct line *
+ realloc_lines(struct view *view, size_t line_size)
+ {
+- struct line *tmp = realloc(view->line, sizeof(*view->line) * line_size);
++ size_t alloc = view->line_alloc;
++ struct line *tmp = realloc_items(view->line, &alloc, line_size,
++ sizeof(*view->line));
+
+ if (!tmp)
+ return NULL;
+
+ view->line = tmp;
++ view->line_alloc = alloc;
+ view->line_size = line_size;
+ return view->line;
+ }
+@@ -2550,11 +2591,26 @@ view_driver(struct view *view, enum request request)
+ redraw_display();
+ break;
+
++ case REQ_TOGGLE_DATE:
++ opt_date = !opt_date;
++ redraw_display();
++ break;
++
++ case REQ_TOGGLE_AUTHOR:
++ opt_author = !opt_author;
++ redraw_display();
++ break;
++
+ case REQ_TOGGLE_REV_GRAPH:
+ opt_rev_graph = !opt_rev_graph;
+ redraw_display();
+ break;
+
++ case REQ_TOGGLE_REFS:
++ opt_show_refs = !opt_show_refs;
++ redraw_display();
++ break;
++
+ case REQ_PROMPT:
+ /* Always reload^Wrerun commands from the prompt. */
+ open_view(view, opt_request, OPEN_RELOAD);
+@@ -3366,7 +3422,7 @@ error_out:
+
+ /* Don't show unmerged entries in the staged section. */
+ #define STATUS_DIFF_INDEX_CMD "git diff-index -z --diff-filter=ACDMRTXB --cached -M HEAD"
+-#define STATUS_DIFF_FILES_CMD "git update-index -q --refresh && git diff-files -z"
++#define STATUS_DIFF_FILES_CMD "git diff-files -z"
+ #define STATUS_LIST_OTHER_CMD \
+ "git ls-files -z --others --exclude-per-directory=.gitignore"
+
+@@ -3391,7 +3447,7 @@ status_open(struct view *view)
+ for (i = 0; i < view->lines; i++)
+ free(view->line[i].data);
+ free(view->line);
+- view->lines = view->line_size = view->lineno = 0;
++ view->lines = view->line_alloc = view->line_size = view->lineno = 0;
+ view->line = NULL;
+
+ if (!realloc_lines(view, view->line_size + 6))
+@@ -3410,6 +3466,8 @@ status_open(struct view *view)
+ return FALSE;
+ }
+
++ system("git update-index -q --refresh");
++
+ if (!status_run(view, STATUS_DIFF_INDEX_CMD, TRUE, LINE_STAT_STAGED) ||
+ !status_run(view, STATUS_DIFF_FILES_CMD, TRUE, LINE_STAT_UNSTAGED) ||
+ !status_run(view, cmd, FALSE, LINE_STAT_UNTRACKED))
+@@ -4183,7 +4241,7 @@ main_draw(struct view *view, struct line *line, unsigned int lineno, bool select
+ tilde_attr = get_line_attr(LINE_MAIN_DELIM);
+ }
+
+- {
++ if (opt_date) {
+ int n;
+
+ timelen = strftime(buf, sizeof(buf), DATE_FORMAT, &commit->time);
+@@ -4201,7 +4259,7 @@ main_draw(struct view *view, struct line *line, unsigned int lineno, bool select
+ if (type != LINE_CURSOR)
+ wattrset(view->win, get_line_attr(LINE_MAIN_AUTHOR));
+
+- {
++ if (opt_author) {
+ int max_len;
+
+ max_len = view->width - col;
+@@ -4238,12 +4296,14 @@ main_draw(struct view *view, struct line *line, unsigned int lineno, bool select
+
+ wmove(view->win, lineno, col);
+
+- if (commit->refs) {
++ if (opt_show_refs && commit->refs) {
+ size_t i = 0;
+
+ do {
+ if (type == LINE_CURSOR)
+ ;
++ else if (commit->refs[i]->ltag)
++ wattrset(view->win, get_line_attr(LINE_MAIN_LOCAL_TAG));
+ else if (commit->refs[i]->tag)
+ wattrset(view->win, get_line_attr(LINE_MAIN_TAG));
+ else if (commit->refs[i]->remote)
+@@ -4559,19 +4619,16 @@ utf8_to_unicode(const char *string, size_t length)
+
+ /* Calculates how much of string can be shown within the given maximum width
+ * and sets trimmed parameter to non-zero value if all of string could not be
+- * shown.
+- *
+- * Additionally, adds to coloffset how many many columns to move to align with
+- * the expected position. Takes into account how multi-byte and double-width
+- * characters will effect the cursor position.
++ * shown. If the reserve flag is TRUE, it will reserve at least one
++ * trailing character, which can be useful when drawing a delimiter.
+ *
+ * Returns the number of bytes to output from string to satisfy max_width. */
+ static size_t
+-utf8_length(const char *string, size_t max_width, int *coloffset, int *trimmed)
++utf8_length(const char *string, size_t max_width, int *trimmed, bool reserve)
+ {
+ const char *start = string;
+ const char *end = strchr(string, '\0');
+- size_t mbwidth = 0;
++ unsigned char last_bytes = 0;
+ size_t width = 0;
+
+ *trimmed = 0;
+@@ -4597,27 +4654,16 @@ utf8_length(const char *string, size_t max_width, int *coloffset, int *trimmed)
+ width += ucwidth;
+ if (width > max_width) {
+ *trimmed = 1;
++ if (reserve && width - ucwidth == max_width) {
++ string -= last_bytes;
++ }
+ break;
+ }
+
+- /* The column offset collects the differences between the
+- * number of bytes encoding a character and the number of
+- * columns will be used for rendering said character.
+- *
+- * So if some character A is encoded in 2 bytes, but will be
+- * represented on the screen using only 1 byte this will and up
+- * adding 1 to the multi-byte column offset.
+- *
+- * Assumes that no double-width character can be encoding in
+- * less than two bytes. */
+- if (bytes > ucwidth)
+- mbwidth += bytes - ucwidth;
+-
+ string += bytes;
++ last_bytes = bytes;
+ }
+
+- *coloffset += mbwidth;
+-
+ return string - start;
+ }
+
+@@ -4800,18 +4846,21 @@ read_prompt(const char *prompt)
+ * Repository references
+ */
+
+-static struct ref *refs;
+-static size_t refs_size;
++static struct ref *refs = NULL;
++static size_t refs_alloc = 0;
++static size_t refs_size = 0;
+
+ /* Id <-> ref store */
+-static struct ref ***id_refs;
+-static size_t id_refs_size;
++static struct ref ***id_refs = NULL;
++static size_t id_refs_alloc = 0;
++static size_t id_refs_size = 0;
+
+ static struct ref **
+ get_refs(char *id)
+ {
+ struct ref ***tmp_id_refs;
+ struct ref **ref_list = NULL;
++ size_t ref_list_alloc = 0;
+ size_t ref_list_size = 0;
+ size_t i;
+
+@@ -4819,7 +4868,8 @@ get_refs(char *id)
+ if (!strcmp(id, id_refs[i][0]->id))
+ return id_refs[i];
+
+- tmp_id_refs = realloc(id_refs, (id_refs_size + 1) * sizeof(*id_refs));
++ tmp_id_refs = realloc_items(id_refs, &id_refs_alloc, id_refs_size + 1,
++ sizeof(*id_refs));
+ if (!tmp_id_refs)
+ return NULL;
+
+@@ -4831,7 +4881,8 @@ get_refs(char *id)
+ if (strcmp(id, refs[i].id))
+ continue;
+
+- tmp = realloc(ref_list, (ref_list_size + 1) * sizeof(*ref_list));
++ tmp = realloc_items(ref_list, &ref_list_alloc,
++ ref_list_size + 1, sizeof(*ref_list));
+ if (!tmp) {
+ if (ref_list)
+ free(ref_list);
+@@ -4861,15 +4912,19 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
+ {
+ struct ref *ref;
+ bool tag = FALSE;
++ bool ltag = FALSE;
+ bool remote = FALSE;
++ bool check_replace = FALSE;
+
+ if (!strncmp(name, "refs/tags/", STRING_SIZE("refs/tags/"))) {
+- /* Commits referenced by tags has "^{}" appended. */
+- if (name[namelen - 1] != '}')
+- return OK;
+-
+- while (namelen > 0 && name[namelen] != '^')
+- namelen--;
++ if (!strcmp(name + namelen - 3, "^{}")) {
++ namelen -= 3;
++ name[namelen] = 0;
++ if (refs_size > 0 && refs[refs_size - 1].ltag == TRUE)
++ check_replace = TRUE;
++ } else {
++ ltag = TRUE;
++ }
+
+ tag = TRUE;
+ namelen -= STRING_SIZE("refs/tags/");
+@@ -4888,7 +4943,17 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
+ return OK;
+ }
+
+- refs = realloc(refs, sizeof(*refs) * (refs_size + 1));
++ if (check_replace && !strcmp(name, refs[refs_size - 1].name)) {
++ /* it's an annotated tag, replace the previous sha1 with the
++ * resolved commit id; relies on the fact git-ls-remote lists
++ * the commit id of an annotated tag right beofre the commit id
++ * it points to. */
++ refs[refs_size - 1].ltag = ltag;
++ string_copy_rev(refs[refs_size - 1].id, id);
++
++ return OK;
++ }
++ refs = realloc_items(refs, &refs_alloc, refs_size + 1, sizeof(*refs));
+ if (!refs)
+ return ERR;
+
+@@ -4900,6 +4965,7 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
+ strncpy(ref->name, name, namelen);
+ ref->name[namelen] = 0;
+ ref->tag = tag;
++ ref->ltag = ltag;
+ ref->remote = remote;
+ string_copy_rev(ref->id, id);
+
+@@ -5079,6 +5145,9 @@ main(int argc, char *argv[])
+ if (!opt_git_dir[0])
+ die("Not a git repository");
+
++ if (*opt_encoding && strcasecmp(opt_encoding, "UTF-8"))
++ opt_utf8 = FALSE;
++
+ if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) {
+ opt_iconv = iconv_open(opt_codeset, opt_encoding);
+ if (opt_iconv == ICONV_NONE)
+diff --git a/tigrc.5.txt b/tigrc.5.txt
+index f7d7bed..bed3116 100644
+--- a/tigrc.5.txt
++++ b/tigrc.5.txt
+@@ -42,7 +42,11 @@ is:
+ Examples:
+
+ --------------------------------------------------------------------------
++set show-author = yes # Show author?
++set show-date = yes # Show commit date?
+ set show-rev-graph = yes # Show revision graph?
++set show-refs = yes # Show references?
++set show-line-numbers = no # Show line numbers?
+ set line-number-interval = 5 # Interval between line numbers
+ set tab-size = 8 # Number of spaces per tab
+ set encoding = "UTF-8" # Commit encoding
+@@ -68,10 +72,14 @@ Variables
+
+ The following variables can be set:
+
++'show-author' (bool)::
++'show-date' (bool)::
+ 'show-rev-graph' (bool)::
++'show-refs' (bool)::
+
+- Show revision graph in the main view on start-up. Can be toggled with
+- 'g'.
++ Whether to show author, date, revision graph, and references
++ (branches, tags, and remotes) in the main view on start-up. Can all be
++ toggled.
+
+ 'line-number-interval' (int)::
+
+@@ -243,7 +251,10 @@ screen-resize Resize the screen
+ show-version Show version information
+ stop-loading Stop all loading views
+ toggle-lineno Toggle line numbers
++toggle-date Toggle date display
++toggle-author Toggle author display
+ toggle-rev-graph Toggle revision graph visualization
++toggle-refs Toggle reference display
+ status-update Update file status
+ status-merge Resolve unmerged file
+ tree-parent Switch to parent directory in tree view
+@@ -336,7 +347,7 @@ Appearance of the various columns in the main view, including the '~' used for
+ delimiting long author names and labels for tag and branch references.
+
+ *main-date*, *main-author*, *main-commit*, *main-delim*, *main-tag*,
+-*main-ref*, *main-remote*, *main-revgraph*
++*main-local-tag*, *main-ref*, *main-remote*, *main-revgraph*
+
+ --
+