+++ /dev/null
-diff --git a/NEWS b/NEWS
-index 7e219af..a0f75c6 100644
---- a/NEWS
-+++ b/NEWS
-@@ -1,6 +1,21 @@
- Release notes
- =============
-
-+tig master
-+----------
-+
-+Improvements:
-+
-+ - Display repository references in the sorted order: tags, heads,
-+ tracked remotes, remotes.
-+ - Add bash completion for blame.
-+
-+Bug fixes:
-+
-+ - Separate blame revision and file argument by "--" to avoid problems.
-+ - Main view: fix redrawing of the last commit wrt. the revision graph.
-+ - Fix waiting for input after executing a run request in pager mode.
-+
- tig-0.12.1
- ----------
-
-diff --git a/contrib/tig-completion.bash b/contrib/tig-completion.bash
-index 79b414b..40bfcfa 100755
---- a/contrib/tig-completion.bash
-+++ b/contrib/tig-completion.bash
-@@ -182,6 +182,26 @@ _tig_options ()
- __tig_complete_revlist
- }
-
-+_tig_blame ()
-+{
-+ local reply="" ref=HEAD cur="${COMP_WORDS[COMP_CWORD]}"
-+
-+ if test "$COMP_CWORD" -lt 3; then
-+ reply="$(__tig_refs)"
-+ else
-+ ref="${COMP_WORDS[2]}"
-+ fi
-+
-+ reply="$reply $(git --git-dir="$(__tigdir)" ls-tree "$ref" \
-+ | sed '/^100... blob /s,^.* ,,
-+ /^040000 tree /{
-+ s,^.* ,,
-+ s,$,/,
-+ }
-+ s/^.* //')"
-+ _tigcomp "$reply"
-+}
-+
- _tig_show ()
- {
- local cur="${COMP_WORDS[COMP_CWORD]}"
-@@ -218,12 +238,13 @@ _tig ()
- case "${COMP_WORDS[COMP_CWORD]}" in
- --*=*) COMPREPLY=() ;;
- -*) _tig_options ;;
-- *) _tigcomp "status show $(__tig_refs)" ;;
-+ *) _tigcomp "blame status show $(__tig_refs)" ;;
- esac
- return
- fi
-
- case "$command" in
-+ blame) _tig_blame ;;
- show) _tig_show ;;
- status) ;;
- *) _tigcomp "
-diff --git a/manual.txt b/manual.txt
-index f11b77a..447dec0 100644
---- a/manual.txt
-+++ b/manual.txt
-@@ -44,7 +44,7 @@ given command and all will be shell quoted before they are passed to the
- shell.
-
- NOTE: If you specify options for the main view, you should not use the
--`--pretty` option as this option will be set automatically to the format
-+`\--pretty` option as this option will be set automatically to the format
- expected by the main view.
-
- Example on how to view a commit and show both author and committer
-@@ -54,100 +54,10 @@ information:
- $ tig show --pretty=fuller
- -----------------------------------------------------------------------------
-
--See the <<refspec, "Specifying revisions">> section below for an introduction
--to revision options supported by the git commands. For details on specific git
-+See the section on <<refspec, specifying revisions>> for an introduction to
-+revision options supported by the git commands. For details on specific git
- command options, refer to the man page of the command in question.
-
--[[env-variables]]
--Environment Variables
-----------------------
--
--Several options related to the interface with git can be configured via
--environment options.
--
--[[configuration-files]]
--Configuration Files
--~~~~~~~~~~~~~~~~~~~
--
--Upon startup, tig first reads the system wide configuration file
--(`{sysconfdir}/tigrc` by default) and then proceeds to read the user's
--configuration file (`~/.tigrc` by default). The paths to either of these files
--can be overridden through the following environment variables:
--
--TIGRC_USER::
-- Path of the user configuration file.
--
--TIGRC_SYSTEM::
-- Path of the system wide configuration file.
--
--[[repo-refs]]
--Repository References
--~~~~~~~~~~~~~~~~~~~~~
--
--Commits that are referenced by tags and branch heads will be marked by the
--reference name surrounded by '[' and ']':
--
-------------------------------------------------------------------------------
--2006-03-26 19:42 Petr Baudis | [cogito-0.17.1] Cogito 0.17.1
-------------------------------------------------------------------------------
--
--If you want to filter out certain directories under `.git/refs/`, say `tmp`
--you can do it by setting the following variable:
--
-------------------------------------------------------------------------------
--$ TIG_LS_REMOTE="git ls-remote . | sed /\/tmp\//d" tig
-------------------------------------------------------------------------------
--
--Or set the variable permanently in your environment.
--
--TIG_LS_REMOTE::
-- Set command for retrieving all repository references. The command
-- should output data in the same format as git-ls-remote(1).
--
--[[history-commands]]
--History Commands
--~~~~~~~~~~~~~~~~
--
--It is possible to alter which commands are used for the different views. If
--for example you prefer commits in the main view to be sorted by date and only
--show 500 commits, use:
--
-------------------------------------------------------------------------------
--$ TIG_MAIN_CMD="git log --date-order -n500 --pretty=raw %s" tig
-------------------------------------------------------------------------------
--
--Or set the variable permanently in your environment.
--
--Notice, how `%s` is used to specify the commit reference. There can be a
--maximum of 5 `%s` ref specifications.
--
--TIG_DIFF_CMD::
-- The command used for the diff view. By default, git show is used
-- as a backend.
--
--TIG_LOG_CMD::
-- The command used for the log view. If you prefer to have both
-- author and committer shown in the log view be sure to pass
-- `--pretty=fuller` to git log.
--
--TIG_MAIN_CMD::
-- The command used for the main view. Note, you must always specify
-- the option: `--pretty=raw` since the main view parser expects to
-- read that format.
--
--[[tree-commands]]
--Tree Commands
--~~~~~~~~~~~~~
--
--TIG_TREE_CMD::
-- The command used for the tree view. Takes two arguments, the first
-- is the revision ID and the second is the path of the directory tree,
-- empty for the root directory. Defaults to "git ls-tree %s %s".
--
--TIG_BLOB_CMD::
-- The command used for the blob view. Takes one argument which is
-- the blob ID. Defaults to "git cat-file blob %s".
--
- [[viewer]]
- The Viewer
- ----------
-@@ -167,18 +77,6 @@ You will split the view so that the log view is displayed in the top window
- and the diff view in the bottom window. You can switch between the two views
- by pressing 'Tab'. To maximize the log view again, simply press 'l'.
-
--[[commit-id]]
--Current Head and Commit ID
--~~~~~~~~~~~~~~~~~~~~~~~~~~
--
--The viewer keeps track of both what head and commit ID you are currently
--viewing. The commit ID will follow the cursor line and change every time
--you highlight a different commit. Whenever you reopen the diff view it will be
--reloaded, if the commit ID changed.
--
--The head ID is used when opening the main and log view to indicate from what
--revision to show history.
--
- [[views]]
- Views
- ~~~~~
-@@ -226,7 +124,30 @@ The pager view::
- commands entered in the internal prompt.
-
- The help view::
-- Displays key binding quick reference.
-+ Displays a quick reference of key bindings.
-+
-+[[commit-id]]
-+Browsing State and User-defined Commands
-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+
-+The viewer keeps track of both what head and commit ID you are currently
-+viewing. The commit ID will follow the cursor line and change every time you
-+highlight a different commit. Whenever you reopen the diff view it will be
-+reloaded, if the commit ID changed. The head ID is used when opening the main
-+and log view to indicate from what revision to show history.
-+
-+Some of the commands used or provided by tig can be configured. This goes for
-+the <<external-commands, external commands>>. These user-defined commands can
-+use arguments that refer to the current browsing state by using one of the
-+following variables.
-+
-+`-----------------------`-----------------------------------------------------
-+Browsing state variables
-+------------------------------------------------------------------------------
-+%(head) The currently viewed 'head' ID. Defaults to HEAD
-+%(commit) The currently selected commit ID.
-+%(blob) The currently selected blob ID.
-+------------------------------------------------------------------------------
-
- [[title-window]]
- Title Windows
-@@ -247,6 +168,134 @@ be appended:
- [main] 77d9e40fbcea3238015aea403e06f61542df9a31 - commit 1 of 779 (0%) 5s
- -----------------------------------------------------------------------------
-
-+[[env-variables]]
-+Environment Variables
-+---------------------
-+
-+Several options related to the interface with git can be configured via
-+environment options.
-+
-+[[configuration-files]]
-+Configuration Files
-+~~~~~~~~~~~~~~~~~~~
-+
-+Upon startup, tig first reads the system wide configuration file
-+(`{sysconfdir}/tigrc` by default) and then proceeds to read the user's
-+configuration file (`~/.tigrc` by default). The paths to either of these files
-+can be overridden through the following environment variables:
-+
-+TIGRC_USER::
-+ Path of the user configuration file.
-+
-+TIGRC_SYSTEM::
-+ Path of the system wide configuration file.
-+
-+[[repo-refs]]
-+Repository References
-+~~~~~~~~~~~~~~~~~~~~~
-+
-+Commits that are referenced by tags and branch heads will be marked by the
-+reference name surrounded by '[' and ']':
-+
-+-----------------------------------------------------------------------------
-+2006-03-26 19:42 Petr Baudis | [cogito-0.17.1] Cogito 0.17.1
-+-----------------------------------------------------------------------------
-+
-+If you want to filter what branches gets shown, say limit to only show
-+branches named `master` or which starts with the `jf/` prefix, you can
-+do it by setting the following variable:
-+
-+-----------------------------------------------------------------------------
-+$ TIG_LS_REMOTE="git ls-remote . master jf/*" tig
-+-----------------------------------------------------------------------------
-+
-+Or set the variable permanently in your environment.
-+
-+--
-+
-+TIG_LS_REMOTE::
-+
-+ Set command for retrieving all repository references. The command
-+ should output data in the same format as git-ls-remote(1). Defaults
-+ to:
-+-----------------------------------------------------------------------------
-+git ls-remote .
-+-----------------------------------------------------------------------------
-+
-+--
-+
-+[[history-commands]]
-+History Commands
-+~~~~~~~~~~~~~~~~
-+
-+It is possible to alter which commands are used for the different views. If
-+for example you prefer commits in the main view to be sorted by date and only
-+show 500 commits, use:
-+
-+-----------------------------------------------------------------------------
-+$ TIG_MAIN_CMD="git log --date-order -n500 --pretty=raw %s" tig
-+-----------------------------------------------------------------------------
-+
-+Or set the variable permanently in your environment.
-+
-+Notice, how `%s` is used to specify the commit reference. There can be a
-+maximum of 5 `%s` ref specifications.
-+
-+--
-+
-+TIG_DIFF_CMD::
-+
-+ The command used for the diff view. Defaults to:
-+-----------------------------------------------------------------------------
-+git show --pretty=fuller --no-color --root
-+ --patch-with-stat --find-copies-harder -C %s
-+-----------------------------------------------------------------------------
-+
-+TIG_LOG_CMD::
-+
-+ The command used for the log view. If you prefer to have both
-+ author and committer shown in the log view be sure to pass
-+ `\--pretty=fuller` to git log. Defaults to:
-+-----------------------------------------------------------------------------
-+git log --no-color --cc --stat -n100 %s
-+-----------------------------------------------------------------------------
-+
-+TIG_MAIN_CMD::
-+
-+ The command used for the main view. Note, you must always specify
-+ the option: `\--pretty=raw` since the main view parser expects to
-+ read that format.
-+-----------------------------------------------------------------------------
-+git log --no-color --pretty=raw --parents --topo-order %s
-+-----------------------------------------------------------------------------
-+
-+--
-+
-+[[tree-commands]]
-+Tree Commands
-+~~~~~~~~~~~~~
-+
-+--
-+
-+TIG_TREE_CMD::
-+
-+ The command used for the tree view. Takes two arguments, the first is
-+ the revision ID and the second is the path of the directory tree,
-+ empty for the root directory. Defaults to:
-+-----------------------------------------------------------------------------
-+git ls-tree %s %s
-+-----------------------------------------------------------------------------
-+
-+TIG_BLOB_CMD::
-+
-+ The command used for the blob view. Takes one argument which is the
-+ blob ID. Defaults to:
-+-----------------------------------------------------------------------------
-+git cat-file blob %s
-+-----------------------------------------------------------------------------
-+
-+--
-+
- [[keys]]
- Default Keybindings
- -------------------
-@@ -377,9 +426,10 @@ e Open file in editor.
- External Commands
- ~~~~~~~~~~~~~~~~~
-
--Tig also comes with a few builtin external commands. These are simple shell
--commands that are run and can take arguments from the current browsing state,
--such as the current commit ID. The default commands are:
-+For more custom needs, external commands provide a way to easily execute
-+a script or program. They are bound to keys and use information from the
-+current browsing state, such as the current commit ID. Tig comes with
-+the following builtin external commands:
-
- `-------`--------------------------------------------------------------------
- Key Action
-@@ -400,7 +450,7 @@ git-rev-list(1).
-
- You can tune the interaction with git by making use of the options explained
- in this section. For example, by configuring the environment variables
--described in the <<history-commands, "History commands">> section.
-+described in the section on <<history-commands, history commands>>.
-
- [[path-limiting]]
- Limit by Path Name
-@@ -422,17 +472,13 @@ thus you will have to use:
- $ tig -- status
- -----------------------------------------------------------------------------
-
--NOTE: For the main view, avoiding ambiguity will in some cases require you to
--specify two "\--" options. The first will make tig stop option processing
--and the latter will be passed to git log.
--
- [[date-number-limiting]]
- Limit by Date or Number
- ~~~~~~~~~~~~~~~~~~~~~~~
-
- To speed up interaction with git, you can limit the amount of commits to show
- both for the log and main view. Either limit by date using e.g.
--`--since=1.month` or limit by the number of commits using `-n400`.
-+`\--since=1.month` or limit by the number of commits using `-n400`.
-
- If you are only interested in changed that happened between two dates you can
- use:
-@@ -442,7 +488,7 @@ $ tig --after="May 5th" --before="2006-05-16 15:44"
- -----------------------------------------------------------------------------
-
- NOTE: If you want to avoid having to quote dates containing spaces you can use
--"." instead, e.g. `--after=May.5th`.
-+"." instead, e.g. `\--after=May.5th`.
-
- [[commit-range-limiting]]
- Limiting by Commit Ranges
-diff --git a/tig.c b/tig.c
-index 5c456e7..3394d40 100644
---- a/tig.c
-+++ b/tig.c
-@@ -164,7 +164,7 @@ struct ref {
- unsigned int next:1; /* For ref lists: are there more refs? */
- };
-
--static struct ref **get_refs(char *id);
-+static struct ref **get_refs(const char *id);
-
- struct int_map {
- const char *name;
-@@ -277,6 +277,9 @@ string_enum_compare(const char *str1, const char *str2, int len)
- return 0;
- }
-
-+#define prefixcmp(str1, str2) \
-+ strncmp(str1, str2, STRING_SIZE(str2))
-+
- /* Shell quoting
- *
- * NOTE: The following is a slightly modified copy of the git project's shell
-@@ -408,9 +411,9 @@ enum request {
-
- struct request_info {
- enum request request;
-- char *name;
-+ const char *name;
- int namelen;
-- char *help;
-+ const char *help;
- };
-
- static struct request_info req_info[] = {
-@@ -480,13 +483,14 @@ static char opt_cdup[SIZEOF_STR] = "";
- static char opt_git_dir[SIZEOF_STR] = "";
- static signed char opt_is_inside_work_tree = -1; /* set to TRUE or FALSE */
- static char opt_editor[SIZEOF_STR] = "";
-+static FILE *opt_tty = NULL;
-
- static enum request
--parse_options(int argc, char *argv[])
-+parse_options(int argc, const char *argv[])
- {
- enum request request = REQ_VIEW_MAIN;
- size_t buf_size;
-- char *subcommand;
-+ const char *subcommand;
- bool seen_dashdash = FALSE;
- int i;
-
-@@ -540,7 +544,7 @@ parse_options(int argc, char *argv[])
- buf_size = strlen(opt_cmd);
-
- for (i = 1 + !!subcommand; i < argc; i++) {
-- char *opt = argv[i];
-+ const char *opt = argv[i];
-
- if (seen_dashdash || !strcmp(opt, "--")) {
- seen_dashdash = TRUE;
-@@ -867,7 +871,7 @@ get_keybinding(enum keymap keymap, int key)
-
-
- struct key {
-- char *name;
-+ const char *name;
- int value;
- };
-
-@@ -917,11 +921,11 @@ get_key_value(const char *name)
- return ERR;
- }
-
--static char *
-+static const char *
- get_key_name(int key_value)
- {
- static char key_char[] = "'X'";
-- char *seq = NULL;
-+ const char *seq = NULL;
- int key;
-
- for (key = 0; key < ARRAY_SIZE(key_table); key++)
-@@ -938,7 +942,7 @@ get_key_name(int key_value)
- return seq ? seq : "(no key)";
- }
-
--static char *
-+static const char *
- get_key(enum request request)
- {
- static char buf[BUFSIZ];
-@@ -1062,7 +1066,7 @@ static struct int_map attr_map[] = {
-
- static int config_lineno;
- static bool config_errors;
--static char *config_msg;
-+static const char *config_msg;
-
- /* Wants: object fgcolor bgcolor [attr] */
- static int
-@@ -1249,7 +1253,7 @@ option_bind_command(int argc, const char *argv[])
- }
-
- static int
--set_option(char *opt, char *value)
-+set_option(const char *opt, char *value)
- {
- const char *argv[SIZEOF_ARG];
- int valuelen;
-@@ -1343,9 +1347,9 @@ load_option_file(const char *path)
- static int
- load_options(void)
- {
-- char *home = getenv("HOME");
-- char *tigrc_user = getenv("TIGRC_USER");
-- char *tigrc_system = getenv("TIGRC_SYSTEM");
-+ const char *home = getenv("HOME");
-+ const char *tigrc_user = getenv("TIGRC_USER");
-+ const char *tigrc_system = getenv("TIGRC_SYSTEM");
- char buf[SIZEOF_STR];
-
- add_builtin_run_requests();
-@@ -1639,7 +1643,7 @@ draw_graphic(struct view *view, enum line_type type, chtype graphic[], size_t si
- }
-
- static bool
--draw_field(struct view *view, enum line_type type, char *text, int len, bool trim)
-+draw_field(struct view *view, enum line_type type, const char *text, int len, bool trim)
- {
- int max = MIN(view->width - view->col, len);
- int col;
-@@ -2375,8 +2379,14 @@ update_view(struct view *view)
- }
- }
-
-- if (!view_is_displayed(view))
-- goto check_pipe;
-+ if (ferror(view->pipe) && errno != 0) {
-+ report("Failed to read: %s", strerror(errno));
-+ end_update(view, TRUE);
-+
-+ } else if (feof(view->pipe)) {
-+ report("");
-+ end_update(view, FALSE);
-+ }
-
- if (view == VIEW(REQ_VIEW_TREE)) {
- /* Clear the view and redraw everything since the tree sorting
-@@ -2406,17 +2416,6 @@ update_view(struct view *view)
- /* Update the title _after_ the redraw so that if the redraw picks up a
- * commit reference in view->ref it'll be available here. */
- update_view_title(view);
--
--check_pipe:
-- if (ferror(view->pipe) && errno != 0) {
-- report("Failed to read: %s", strerror(errno));
-- end_update(view, TRUE);
--
-- } else if (feof(view->pipe)) {
-- report("");
-- end_update(view, FALSE);
-- }
--
- return TRUE;
-
- alloc_error:
-@@ -2438,10 +2437,9 @@ add_line_data(struct view *view, void *data, enum line_type type)
- }
-
- static struct line *
--add_line_text(struct view *view, char *data, enum line_type type)
-+add_line_text(struct view *view, const char *text, enum line_type type)
- {
-- if (data)
-- data = strdup(data);
-+ char *data = text ? strdup(text) : NULL;
-
- return data ? add_line_data(view, data, type) : NULL;
- }
-@@ -2565,7 +2563,7 @@ open_external_viewer(const char *cmd)
- endwin(); /* restore original tty modes */
- system(cmd);
- fprintf(stderr, "Press Enter to continue");
-- getc(stdin);
-+ getc(opt_tty);
- reset_prog_mode();
- redraw_display();
- }
-@@ -2587,7 +2585,7 @@ open_editor(bool from_root, const char *file)
- {
- char cmd[SIZEOF_STR];
- char file_sq[SIZEOF_STR];
-- char *editor;
-+ const char *editor;
- char *prefix = from_root ? opt_cdup : "";
-
- editor = getenv("GIT_EDITOR");
-@@ -2893,7 +2891,6 @@ view_driver(struct view *view, enum request request)
- return FALSE;
-
- default:
-- /* An unknown key will show most commonly used commands. */
- report("Unknown key, press 'h' for help");
- return TRUE;
- }
-@@ -2919,7 +2916,7 @@ pager_draw(struct view *view, struct line *line, unsigned int lineno)
- }
-
- static bool
--add_describe_ref(char *buf, size_t *bufpos, char *commit_id, const char *sep)
-+add_describe_ref(char *buf, size_t *bufpos, const char *commit_id, const char *sep)
- {
- char refbuf[SIZEOF_STR];
- char *ref = NULL;
-@@ -2967,8 +2964,8 @@ add_pager_refs(struct view *view, struct line *line)
-
- do {
- struct ref *ref = refs[refpos];
-- char *fmt = ref->tag ? "%s[%s]" :
-- ref->remote ? "%s<%s>" : "%s%s";
-+ const char *fmt = ref->tag ? "%s[%s]" :
-+ ref->remote ? "%s<%s>" : "%s%s";
-
- if (!string_format_from(buf, &bufpos, fmt, sep, ref->name))
- return;
-@@ -3130,7 +3127,7 @@ help_open(struct view *view)
- add_line_text(view, "Quick reference for tig keybindings:", LINE_DEFAULT);
-
- for (i = 0; i < ARRAY_SIZE(req_info); i++) {
-- char *key;
-+ const char *key;
-
- if (req_info[i].request == REQ_NONE)
- continue;
-@@ -3158,7 +3155,7 @@ help_open(struct view *view)
-
- for (i = 0; i < run_requests; i++) {
- struct run_request *req = get_run_request(REQ_NONE + i + 1);
-- char *key;
-+ const char *key;
-
- if (!req)
- continue;
-@@ -3215,7 +3212,7 @@ pop_tree_stack_entry(void)
- }
-
- static void
--push_tree_stack_entry(char *name, unsigned long lineno)
-+push_tree_stack_entry(const char *name, unsigned long lineno)
- {
- struct tree_stack_entry *entry = calloc(1, sizeof(*entry));
- size_t pathlen = strlen(opt_path);
-@@ -3251,8 +3248,8 @@ push_tree_stack_entry(char *name, unsigned long lineno)
- #define TREE_UP_FORMAT "040000 tree %s\t.."
-
- static int
--tree_compare_entry(enum line_type type1, char *name1,
-- enum line_type type2, char *name2)
-+tree_compare_entry(enum line_type type1, const char *name1,
-+ enum line_type type2, const char *name2)
- {
- if (type1 != type2) {
- if (type1 == LINE_TREE_DIR)
-@@ -3263,10 +3260,10 @@ tree_compare_entry(enum line_type type1, char *name1,
- return strcmp(name1, name2);
- }
-
--static char *
-+static const char *
- tree_path(struct line *line)
- {
-- char *path = line->data;
-+ const char *path = line->data;
-
- return path + SIZEOF_TREE_ATTR;
- }
-@@ -3318,7 +3315,7 @@ tree_read(struct view *view, char *text)
- /* Skip "Directory ..." and ".." line. */
- for (pos = 1 + !!*opt_path; pos < view->lines; pos++) {
- struct line *line = &view->line[pos];
-- char *path1 = tree_path(line);
-+ const char *path1 = tree_path(line);
- char *path2 = text + SIZEOF_TREE_ATTR;
- int cmp = tree_compare_entry(line->type, path1, type, path2);
-
-@@ -3357,7 +3354,7 @@ tree_request(struct view *view, enum request request, struct line *line)
- enum open_flags flags;
-
- if (request == REQ_VIEW_BLAME) {
-- char *filename = tree_path(line);
-+ const char *filename = tree_path(line);
-
- if (line->type == LINE_TREE_DIR) {
- report("Cannot show blame for directory %s", opt_path);
-@@ -3393,7 +3390,7 @@ tree_request(struct view *view, enum request request, struct line *line)
- pop_tree_stack_entry();
-
- } else {
-- char *basename = tree_path(line);
-+ const char *basename = tree_path(line);
-
- push_tree_stack_entry(basename, view->lineno);
- }
-@@ -3490,7 +3487,7 @@ struct blame {
- };
-
- #define BLAME_CAT_FILE_CMD "git cat-file blob %s:%s"
--#define BLAME_INCREMENTAL_CMD "git blame --incremental %s %s"
-+#define BLAME_INCREMENTAL_CMD "git blame --incremental %s -- %s"
-
- static bool
- blame_open(struct view *view)
-@@ -3556,9 +3553,9 @@ get_blame_commit(struct view *view, const char *id)
- }
-
- static bool
--parse_number(char **posref, size_t *number, size_t min, size_t max)
-+parse_number(const char **posref, size_t *number, size_t min, size_t max)
- {
-- char *pos = *posref;
-+ const char *pos = *posref;
-
- *posref = NULL;
- pos = strchr(pos + 1, ' ');
-@@ -3573,11 +3570,11 @@ parse_number(char **posref, size_t *number, size_t min, size_t max)
- }
-
- static struct blame_commit *
--parse_blame_commit(struct view *view, char *text, int *blamed)
-+parse_blame_commit(struct view *view, const char *text, int *blamed)
- {
- struct blame_commit *commit;
- struct blame *blame;
-- char *pos = text + SIZEOF_REV - 1;
-+ const char *pos = text + SIZEOF_REV - 1;
- size_t lineno;
- size_t group;
-
-@@ -3606,7 +3603,7 @@ parse_blame_commit(struct view *view, char *text, int *blamed)
- }
-
- static bool
--blame_read_file(struct view *view, char *line)
-+blame_read_file(struct view *view, const char *line)
- {
- if (!line) {
- FILE *pipe = NULL;
-@@ -3711,7 +3708,7 @@ blame_draw(struct view *view, struct line *line, unsigned int lineno)
- {
- struct blame *blame = line->data;
- struct tm *time = NULL;
-- char *id = NULL, *author = NULL;
-+ const char *id = NULL, *author = NULL;
-
- if (blame->commit && *blame->commit->filename) {
- id = blame->commit->id;
-@@ -3855,13 +3852,13 @@ status_has_none(struct view *view, struct line *line)
- * :100644 100644 06a5d6ae9eca55be2e0e585a152e6b1336f2b20e 0000000000000000000000000000000000000000 M
- */
- static inline bool
--status_get_diff(struct status *file, char *buf, size_t bufsize)
-+status_get_diff(struct status *file, const char *buf, size_t bufsize)
- {
-- char *old_mode = buf + 1;
-- char *new_mode = buf + 8;
-- char *old_rev = buf + 15;
-- char *new_rev = buf + 56;
-- char *status = buf + 97;
-+ const char *old_mode = buf + 1;
-+ const char *new_mode = buf + 8;
-+ const char *old_rev = buf + 15;
-+ const char *new_rev = buf + 56;
-+ const char *status = buf + 97;
-
- if (bufsize < 99 ||
- old_mode[-1] != ':' ||
-@@ -4078,7 +4075,7 @@ status_draw(struct view *view, struct line *line, unsigned int lineno)
- {
- struct status *status = line->data;
- enum line_type type;
-- char *text;
-+ const char *text;
-
- if (!status) {
- switch (line->type) {
-@@ -4130,7 +4127,7 @@ status_enter(struct view *view, struct line *line)
- struct status *status = line->data;
- char oldpath[SIZEOF_STR] = "";
- char newpath[SIZEOF_STR] = "";
-- char *info;
-+ const char *info;
- size_t cmdsize = 0;
- enum open_flags split;
-
-@@ -4393,7 +4390,7 @@ status_revert(struct status *status, enum line_type type, bool has_none)
- char file_sq[SIZEOF_STR];
-
- if (sq_quote(file_sq, 0, status->old.name) >= sizeof(file_sq) ||
-- !string_format(cmd, "git checkout %s%s", opt_cdup, file_sq))
-+ !string_format(cmd, "git checkout -- %s%s", opt_cdup, file_sq))
- return FALSE;
-
- return run_confirm(cmd, "Are you sure you want to overwrite any changes?");
-@@ -4463,8 +4460,8 @@ status_select(struct view *view, struct line *line)
- {
- struct status *status = line->data;
- char file[SIZEOF_STR] = "all files";
-- char *text;
-- char *key;
-+ const char *text;
-+ const char *key;
-
- if (status && !string_format(file, "'%s'", status->new.name))
- return;
-@@ -4517,7 +4514,7 @@ status_grep(struct view *view, struct line *line)
- return FALSE;
-
- for (state = S_STATUS; state < S_END; state++) {
-- char *text;
-+ const char *text;
-
- switch (state) {
- case S_NAME: text = status->new.name; break;
-@@ -4551,7 +4548,7 @@ static struct view_ops status_ops = {
- static bool
- stage_diff_line(FILE *pipe, struct line *line)
- {
-- char *buf = line->data;
-+ const char *buf = line->data;
- size_t bufsize = strlen(buf);
- size_t written = 0;
-
-@@ -4874,7 +4871,7 @@ done_rev_graph(struct rev_graph *graph)
- }
-
- static void
--push_rev_graph(struct rev_graph *graph, char *parent)
-+push_rev_graph(struct rev_graph *graph, const char *parent)
- {
- int i;
-
-@@ -5531,13 +5528,13 @@ init_display(void)
- /* Initialize the curses library */
- if (isatty(STDIN_FILENO)) {
- cursed = !!initscr();
-+ opt_tty = stdin;
- } else {
- /* Leave stdin and stdout alone when acting as a pager. */
-- FILE *io = fopen("/dev/tty", "r+");
--
-- if (!io)
-+ opt_tty = fopen("/dev/tty", "r+");
-+ if (!opt_tty)
- die("Failed to open /dev/tty");
-- cursed = !!newterm(NULL, io, io);
-+ cursed = !!newterm(NULL, opt_tty, opt_tty);
- }
-
- if (!cursed)
-@@ -5698,8 +5695,27 @@ static struct ref ***id_refs = NULL;
- static size_t id_refs_alloc = 0;
- static size_t id_refs_size = 0;
-
-+static int
-+compare_refs(const void *ref1_, const void *ref2_)
-+{
-+ const struct ref *ref1 = *(const struct ref **)ref1_;
-+ const struct ref *ref2 = *(const struct ref **)ref2_;
-+
-+ if (ref1->tag != ref2->tag)
-+ return ref2->tag - ref1->tag;
-+ if (ref1->ltag != ref2->ltag)
-+ return ref2->ltag - ref2->ltag;
-+ if (ref1->head != ref2->head)
-+ return ref2->head - ref1->head;
-+ if (ref1->tracked != ref2->tracked)
-+ return ref2->tracked - ref1->tracked;
-+ if (ref1->remote != ref2->remote)
-+ return ref2->remote - ref1->remote;
-+ return strcmp(ref1->name, ref2->name);
-+}
-+
- static struct ref **
--get_refs(char *id)
-+get_refs(const char *id)
- {
- struct ref ***tmp_id_refs;
- struct ref **ref_list = NULL;
-@@ -5733,19 +5749,20 @@ get_refs(char *id)
- }
-
- ref_list = tmp;
-- if (ref_list_size > 0)
-- ref_list[ref_list_size - 1]->next = 1;
- ref_list[ref_list_size] = &refs[i];
--
- /* XXX: The properties of the commit chains ensures that we can
- * safely modify the shared ref. The repo references will
- * always be similar for the same id. */
-- ref_list[ref_list_size]->next = 0;
-+ ref_list[ref_list_size]->next = 1;
-+
- ref_list_size++;
- }
-
-- if (ref_list)
-+ if (ref_list) {
-+ qsort(ref_list, ref_list_size, sizeof(*ref_list), compare_refs);
-+ ref_list[ref_list_size - 1]->next = 0;
- id_refs[id_refs_size++] = ref_list;
-+ }
-
- return ref_list;
- }
-@@ -5761,7 +5778,7 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
- bool check_replace = FALSE;
- bool head = FALSE;
-
-- if (!strncmp(name, "refs/tags/", STRING_SIZE("refs/tags/"))) {
-+ if (!prefixcmp(name, "refs/tags/")) {
- if (!strcmp(name + namelen - 3, "^{}")) {
- namelen -= 3;
- name[namelen] = 0;
-@@ -5775,13 +5792,13 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
- namelen -= STRING_SIZE("refs/tags/");
- name += STRING_SIZE("refs/tags/");
-
-- } else if (!strncmp(name, "refs/remotes/", STRING_SIZE("refs/remotes/"))) {
-+ } else if (!prefixcmp(name, "refs/remotes/")) {
- remote = TRUE;
- namelen -= STRING_SIZE("refs/remotes/");
- name += STRING_SIZE("refs/remotes/");
- tracked = !strcmp(opt_remote, name);
-
-- } else if (!strncmp(name, "refs/heads/", STRING_SIZE("refs/heads/"))) {
-+ } else if (!prefixcmp(name, "refs/heads/")) {
- namelen -= STRING_SIZE("refs/heads/");
- name += STRING_SIZE("refs/heads/");
- head = !strncmp(opt_head, name, namelen);
-@@ -5794,7 +5811,7 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
- 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
-+ * the commit id of an annotated tag right before the commit id
- * it points to. */
- refs[refs_size - 1].ltag = ltag;
- string_copy_rev(refs[refs_size - 1].id, id);
-@@ -5861,7 +5878,7 @@ read_repo_config_option(char *name, size_t namelen, char *value, size_t valuelen
- !strcmp(name + 7 + strlen(opt_head), ".merge")) {
- size_t from = strlen(opt_remote);
-
-- if (!strncmp(value, "refs/heads/", STRING_SIZE("refs/heads/"))) {
-+ if (!prefixcmp(value, "refs/heads/")) {
- value += STRING_SIZE("refs/heads/");
- valuelen -= STRING_SIZE("refs/heads/");
- }
-@@ -5897,7 +5914,7 @@ read_repo_info(char *name, size_t namelen, char *value, size_t valuelen)
- } else if (opt_cdup[0] == ' ') {
- string_ncopy(opt_cdup, name, namelen);
- } else {
-- if (!strncmp(name, "refs/heads/", STRING_SIZE("refs/heads/"))) {
-+ if (!prefixcmp(name, "refs/heads/")) {
- namelen -= STRING_SIZE("refs/heads/");
- name += STRING_SIZE("refs/heads/");
- string_ncopy(opt_head, name, namelen);
-@@ -6009,7 +6026,7 @@ warn(const char *msg, ...)
- }
-
- int
--main(int argc, char *argv[])
-+main(int argc, const char *argv[])
- {
- struct view *view;
- enum request request;
-@@ -6052,7 +6069,7 @@ main(int argc, char *argv[])
- if (load_refs() == ERR)
- die("Failed to load refs.");
-
-- for (i = 0; i < ARRAY_SIZE(views) && (view = &views[i]); i++)
-+ foreach_view (view, i)
- view->cmd_env = getenv(view->cmd_env);
-
- init_display();
-@@ -6063,6 +6080,7 @@ main(int argc, char *argv[])
-
- foreach_view (view, i)
- update_view(view);
-+ view = display[current_view];
-
- /* Refresh, accept single keystroke of input */
- key = wgetch(status_win);
-@@ -6074,7 +6092,7 @@ main(int argc, char *argv[])
- continue;
- }
-
-- request = get_keybinding(display[current_view]->keymap, key);
-+ request = get_keybinding(view->keymap, key);
-
- /* Some low-level request handling. This keeps access to
- * status_win restricted. */
-@@ -6100,8 +6118,7 @@ main(int argc, char *argv[])
- case REQ_SEARCH:
- case REQ_SEARCH_BACK:
- {
-- const char *prompt = request == REQ_SEARCH
-- ? "/" : "?";
-+ const char *prompt = request == REQ_SEARCH ? "/" : "?";
- char *search = read_prompt(prompt);
-
- if (search)