]> git.pld-linux.org Git - packages/tig.git/blob - tig-git.patch
3c398b9a9cff94ba0caef4f52bdf9f37f40abf90
[packages/tig.git] / tig-git.patch
1 diff --git a/NEWS b/NEWS
2 index 7e219af..a0f75c6 100644
3 --- a/NEWS
4 +++ b/NEWS
5 @@ -1,6 +1,21 @@
6  Release notes
7  =============
8  
9 +tig master
10 +----------
11 +
12 +Improvements:
13 +
14 + - Display repository references in the sorted order: tags, heads,
15 +   tracked remotes, remotes.
16 + - Add bash completion for blame.
17 +
18 +Bug fixes:
19 +
20 + - Separate blame revision and file argument by "--" to avoid problems.
21 + - Main view: fix redrawing of the last commit wrt. the revision graph.
22 + - Fix waiting for input after executing a run request in pager mode.
23 +
24  tig-0.12.1
25  ----------
26  
27 diff --git a/contrib/tig-completion.bash b/contrib/tig-completion.bash
28 index 79b414b..40bfcfa 100755
29 --- a/contrib/tig-completion.bash
30 +++ b/contrib/tig-completion.bash
31 @@ -182,6 +182,26 @@ _tig_options ()
32         __tig_complete_revlist
33  }
34  
35 +_tig_blame ()
36 +{
37 +       local reply="" ref=HEAD cur="${COMP_WORDS[COMP_CWORD]}"
38 +
39 +       if test "$COMP_CWORD" -lt 3; then
40 +               reply="$(__tig_refs)"
41 +       else
42 +               ref="${COMP_WORDS[2]}"
43 +       fi
44 +
45 +       reply="$reply $(git --git-dir="$(__tigdir)" ls-tree "$ref" \
46 +                       | sed '/^100... blob /s,^.*     ,,
47 +                              /^040000 tree /{
48 +                                  s,^.*        ,,
49 +                                  s,$,/,
50 +                              }
51 +                              s/^.*    //')"
52 +       _tigcomp "$reply"
53 +}
54 +
55  _tig_show ()
56  {
57         local cur="${COMP_WORDS[COMP_CWORD]}"
58 @@ -218,12 +238,13 @@ _tig ()
59                 case "${COMP_WORDS[COMP_CWORD]}" in
60                 --*=*) COMPREPLY=() ;;
61                 -*)   _tig_options ;;
62 -               *)    _tigcomp "status show $(__tig_refs)" ;;
63 +               *)    _tigcomp "blame status show $(__tig_refs)" ;;
64                 esac
65                 return
66         fi
67  
68         case "$command" in
69 +       blame)  _tig_blame ;;
70         show)   _tig_show ;;
71         status) ;;
72         *)      _tigcomp "
73 diff --git a/manual.txt b/manual.txt
74 index f11b77a..447dec0 100644
75 --- a/manual.txt
76 +++ b/manual.txt
77 @@ -44,7 +44,7 @@ given command and all will be shell quoted before they are passed to the
78  shell.
79  
80  NOTE: If you specify options for the main view, you should not use the
81 -`--pretty` option as this option will be set automatically to the format
82 +`\--pretty` option as this option will be set automatically to the format
83  expected by the main view.
84  
85  Example on how to view a commit and show both author and committer
86 @@ -54,100 +54,10 @@ information:
87  $ tig show --pretty=fuller
88  -----------------------------------------------------------------------------
89  
90 -See the <<refspec, "Specifying revisions">> section below for an introduction
91 -to revision options supported by the git commands. For details on specific git
92 +See the section on <<refspec, specifying revisions>> for an introduction to
93 +revision options supported by the git commands. For details on specific git
94  command options, refer to the man page of the command in question.
95  
96 -[[env-variables]]
97 -Environment Variables
98 ----------------------
99 -
100 -Several options related to the interface with git can be configured via
101 -environment options.
102 -
103 -[[configuration-files]]
104 -Configuration Files
105 -~~~~~~~~~~~~~~~~~~~
106 -
107 -Upon startup, tig first reads the system wide configuration file
108 -(`{sysconfdir}/tigrc` by default) and then proceeds to read the user's
109 -configuration file (`~/.tigrc` by default). The paths to either of these files
110 -can be overridden through the following environment variables:
111 -
112 -TIGRC_USER::
113 -       Path of the user configuration file.
114 -
115 -TIGRC_SYSTEM::
116 -       Path of the system wide configuration file.
117 -
118 -[[repo-refs]]
119 -Repository References
120 -~~~~~~~~~~~~~~~~~~~~~
121 -
122 -Commits that are referenced by tags and branch heads will be marked by the
123 -reference name surrounded by '[' and ']':
124 -
125 ------------------------------------------------------------------------------
126 -2006-03-26 19:42 Petr Baudis         | [cogito-0.17.1] Cogito 0.17.1
127 ------------------------------------------------------------------------------
128 -
129 -If you want to filter out certain directories under `.git/refs/`, say `tmp`
130 -you can do it by setting the following variable:
131 -
132 ------------------------------------------------------------------------------
133 -$ TIG_LS_REMOTE="git ls-remote . | sed /\/tmp\//d" tig
134 ------------------------------------------------------------------------------
135 -
136 -Or set the variable permanently in your environment.
137 -
138 -TIG_LS_REMOTE::
139 -       Set command for retrieving all repository references. The command
140 -       should output data in the same format as git-ls-remote(1).
141 -
142 -[[history-commands]]
143 -History Commands
144 -~~~~~~~~~~~~~~~~
145 -
146 -It is possible to alter which commands are used for the different views.  If
147 -for example you prefer commits in the main view to be sorted by date and only
148 -show 500 commits, use:
149 -
150 ------------------------------------------------------------------------------
151 -$ TIG_MAIN_CMD="git log --date-order -n500 --pretty=raw %s" tig
152 ------------------------------------------------------------------------------
153 -
154 -Or set the variable permanently in your environment.
155 -
156 -Notice, how `%s` is used to specify the commit reference. There can be a
157 -maximum of 5 `%s` ref specifications.
158 -
159 -TIG_DIFF_CMD::
160 -       The command used for the diff view. By default, git show is used
161 -       as a backend.
162 -
163 -TIG_LOG_CMD::
164 -       The command used for the log view. If you prefer to have both
165 -       author and committer shown in the log view be sure to pass
166 -       `--pretty=fuller` to git log.
167 -
168 -TIG_MAIN_CMD::
169 -       The command used for the main view. Note, you must always specify
170 -       the option: `--pretty=raw` since the main view parser expects to
171 -       read that format.
172 -
173 -[[tree-commands]]
174 -Tree Commands
175 -~~~~~~~~~~~~~
176 -
177 -TIG_TREE_CMD::
178 -       The command used for the tree view. Takes two arguments, the first
179 -       is the revision ID and the second is the path of the directory tree,
180 -       empty for the root directory. Defaults to "git ls-tree %s %s".
181 -
182 -TIG_BLOB_CMD::
183 -       The command used for the blob view. Takes one argument which is
184 -       the blob ID. Defaults to "git cat-file blob %s".
185 -
186  [[viewer]]
187  The Viewer
188  ----------
189 @@ -167,18 +77,6 @@ You will split the view so that the log view is displayed in the top window
190  and the diff view in the bottom window. You can switch between the two views
191  by pressing 'Tab'. To maximize the log view again, simply press 'l'.
192  
193 -[[commit-id]]
194 -Current Head and Commit ID
195 -~~~~~~~~~~~~~~~~~~~~~~~~~~
196 -
197 -The viewer keeps track of both what head and commit ID you are currently
198 -viewing. The commit ID will follow the cursor line and change every time
199 -you highlight a different commit. Whenever you reopen the diff view it will be
200 -reloaded, if the commit ID changed.
201 -
202 -The head ID is used when opening the main and log view to indicate from what
203 -revision to show history.
204 -
205  [[views]]
206  Views
207  ~~~~~
208 @@ -226,7 +124,30 @@ The pager view::
209         commands entered in the internal prompt.
210  
211  The help view::
212 -       Displays key binding quick reference.
213 +       Displays a quick reference of key bindings.
214 +
215 +[[commit-id]]
216 +Browsing State and User-defined Commands
217 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218 +
219 +The viewer keeps track of both what head and commit ID you are currently
220 +viewing. The commit ID will follow the cursor line and change every time you
221 +highlight a different commit. Whenever you reopen the diff view it will be
222 +reloaded, if the commit ID changed. The head ID is used when opening the main
223 +and log view to indicate from what revision to show history.
224 +
225 +Some of the commands used or provided by tig can be configured. This goes for
226 +the <<external-commands, external commands>>. These user-defined commands can
227 +use arguments that refer to the current browsing state by using one of the
228 +following variables.
229 +
230 +`-----------------------`-----------------------------------------------------
231 +Browsing state variables
232 +------------------------------------------------------------------------------
233 +%(head)                        The currently viewed 'head' ID. Defaults to HEAD
234 +%(commit)              The currently selected commit ID.
235 +%(blob)                        The currently selected blob ID.
236 +------------------------------------------------------------------------------
237  
238  [[title-window]]
239  Title Windows
240 @@ -247,6 +168,134 @@ be appended:
241  [main] 77d9e40fbcea3238015aea403e06f61542df9a31 - commit 1 of 779 (0%) 5s
242  -----------------------------------------------------------------------------
243  
244 +[[env-variables]]
245 +Environment Variables
246 +---------------------
247 +
248 +Several options related to the interface with git can be configured via
249 +environment options.
250 +
251 +[[configuration-files]]
252 +Configuration Files
253 +~~~~~~~~~~~~~~~~~~~
254 +
255 +Upon startup, tig first reads the system wide configuration file
256 +(`{sysconfdir}/tigrc` by default) and then proceeds to read the user's
257 +configuration file (`~/.tigrc` by default). The paths to either of these files
258 +can be overridden through the following environment variables:
259 +
260 +TIGRC_USER::
261 +       Path of the user configuration file.
262 +
263 +TIGRC_SYSTEM::
264 +       Path of the system wide configuration file.
265 +
266 +[[repo-refs]]
267 +Repository References
268 +~~~~~~~~~~~~~~~~~~~~~
269 +
270 +Commits that are referenced by tags and branch heads will be marked by the
271 +reference name surrounded by '[' and ']':
272 +
273 +-----------------------------------------------------------------------------
274 +2006-03-26 19:42 Petr Baudis         | [cogito-0.17.1] Cogito 0.17.1
275 +-----------------------------------------------------------------------------
276 +
277 +If you want to filter what branches gets shown, say limit to only show
278 +branches named `master` or which starts with the `jf/` prefix, you can
279 +do it by setting the following variable:
280 +
281 +-----------------------------------------------------------------------------
282 +$ TIG_LS_REMOTE="git ls-remote . master jf/*" tig
283 +-----------------------------------------------------------------------------
284 +
285 +Or set the variable permanently in your environment.
286 +
287 +--
288 +
289 +TIG_LS_REMOTE::
290 +
291 +       Set command for retrieving all repository references. The command
292 +       should output data in the same format as git-ls-remote(1). Defaults
293 +       to:
294 +-----------------------------------------------------------------------------
295 +git ls-remote .
296 +-----------------------------------------------------------------------------
297 +
298 +--
299 +
300 +[[history-commands]]
301 +History Commands
302 +~~~~~~~~~~~~~~~~
303 +
304 +It is possible to alter which commands are used for the different views.  If
305 +for example you prefer commits in the main view to be sorted by date and only
306 +show 500 commits, use:
307 +
308 +-----------------------------------------------------------------------------
309 +$ TIG_MAIN_CMD="git log --date-order -n500 --pretty=raw %s" tig
310 +-----------------------------------------------------------------------------
311 +
312 +Or set the variable permanently in your environment.
313 +
314 +Notice, how `%s` is used to specify the commit reference. There can be a
315 +maximum of 5 `%s` ref specifications.
316 +
317 +--
318 +
319 +TIG_DIFF_CMD::
320 +
321 +       The command used for the diff view. Defaults to:
322 +-----------------------------------------------------------------------------
323 +git show --pretty=fuller --no-color --root 
324 +        --patch-with-stat --find-copies-harder -C %s
325 +-----------------------------------------------------------------------------
326 +
327 +TIG_LOG_CMD::
328 +
329 +       The command used for the log view. If you prefer to have both
330 +       author and committer shown in the log view be sure to pass
331 +       `\--pretty=fuller` to git log. Defaults to:
332 +-----------------------------------------------------------------------------
333 +git log --no-color --cc --stat -n100 %s
334 +-----------------------------------------------------------------------------
335 +
336 +TIG_MAIN_CMD::
337 +
338 +       The command used for the main view. Note, you must always specify
339 +       the option: `\--pretty=raw` since the main view parser expects to
340 +       read that format.
341 +-----------------------------------------------------------------------------
342 +git log --no-color --pretty=raw --parents --topo-order %s
343 +-----------------------------------------------------------------------------
344 +
345 +--
346 +
347 +[[tree-commands]]
348 +Tree Commands
349 +~~~~~~~~~~~~~
350 +
351 +--
352 +
353 +TIG_TREE_CMD::
354 +
355 +       The command used for the tree view. Takes two arguments, the first is
356 +       the revision ID and the second is the path of the directory tree,
357 +       empty for the root directory. Defaults to:
358 +-----------------------------------------------------------------------------
359 +git ls-tree %s %s
360 +-----------------------------------------------------------------------------
361 +
362 +TIG_BLOB_CMD::
363 +
364 +       The command used for the blob view. Takes one argument which is the
365 +       blob ID. Defaults to:
366 +-----------------------------------------------------------------------------
367 +git cat-file blob %s
368 +-----------------------------------------------------------------------------
369 +
370 +--
371 +
372  [[keys]]
373  Default Keybindings
374  -------------------
375 @@ -377,9 +426,10 @@ e  Open file in editor.
376  External Commands
377  ~~~~~~~~~~~~~~~~~
378  
379 -Tig also comes with a few builtin external commands. These are simple shell
380 -commands that are run and can take arguments from the current browsing state,
381 -such as the current commit ID. The default commands are:
382 +For more custom needs, external commands provide a way to easily execute
383 +a script or program. They are bound to keys and use information from the
384 +current browsing state, such as the current commit ID. Tig comes with
385 +the following builtin external commands:
386  
387  `-------`--------------------------------------------------------------------
388  Key    Action
389 @@ -400,7 +450,7 @@ git-rev-list(1).
390  
391  You can tune the interaction with git by making use of the options explained
392  in this section. For example, by configuring the environment variables
393 -described in the  <<history-commands, "History commands">> section.
394 +described in the section on <<history-commands, history commands>>.
395  
396  [[path-limiting]]
397  Limit by Path Name
398 @@ -422,17 +472,13 @@ thus you will have to use:
399  $ tig -- status
400  -----------------------------------------------------------------------------
401  
402 -NOTE: For the main view, avoiding ambiguity will in some cases require you to
403 -specify two "\--" options. The first will make tig stop option processing
404 -and the latter will be passed to git log.
405 -
406  [[date-number-limiting]]
407  Limit by Date or Number
408  ~~~~~~~~~~~~~~~~~~~~~~~
409  
410  To speed up interaction with git, you can limit the amount of commits to show
411  both for the log and main view. Either limit by date using e.g.
412 -`--since=1.month` or limit by the number of commits using `-n400`.
413 +`\--since=1.month` or limit by the number of commits using `-n400`.
414  
415  If you are only interested in changed that happened between two dates you can
416  use:
417 @@ -442,7 +488,7 @@ $ tig --after="May 5th" --before="2006-05-16 15:44"
418  -----------------------------------------------------------------------------
419  
420  NOTE: If you want to avoid having to quote dates containing spaces you can use
421 -"." instead, e.g. `--after=May.5th`.
422 +"." instead, e.g. `\--after=May.5th`.
423  
424  [[commit-range-limiting]]
425  Limiting by Commit Ranges
426 diff --git a/tig.c b/tig.c
427 index 5c456e7..3394d40 100644
428 --- a/tig.c
429 +++ b/tig.c
430 @@ -164,7 +164,7 @@ struct ref {
431         unsigned int next:1;    /* For ref lists: are there more refs? */
432  };
433  
434 -static struct ref **get_refs(char *id);
435 +static struct ref **get_refs(const char *id);
436  
437  struct int_map {
438         const char *name;
439 @@ -277,6 +277,9 @@ string_enum_compare(const char *str1, const char *str2, int len)
440         return 0;
441  }
442  
443 +#define prefixcmp(str1, str2) \
444 +       strncmp(str1, str2, STRING_SIZE(str2))
445 +
446  /* Shell quoting
447   *
448   * NOTE: The following is a slightly modified copy of the git project's shell
449 @@ -408,9 +411,9 @@ enum request {
450  
451  struct request_info {
452         enum request request;
453 -       char *name;
454 +       const char *name;
455         int namelen;
456 -       char *help;
457 +       const char *help;
458  };
459  
460  static struct request_info req_info[] = {
461 @@ -480,13 +483,14 @@ static char opt_cdup[SIZEOF_STR]  = "";
462  static char opt_git_dir[SIZEOF_STR]    = "";
463  static signed char opt_is_inside_work_tree     = -1; /* set to TRUE or FALSE */
464  static char opt_editor[SIZEOF_STR]     = "";
465 +static FILE *opt_tty                   = NULL;
466  
467  static enum request
468 -parse_options(int argc, char *argv[])
469 +parse_options(int argc, const char *argv[])
470  {
471         enum request request = REQ_VIEW_MAIN;
472         size_t buf_size;
473 -       char *subcommand;
474 +       const char *subcommand;
475         bool seen_dashdash = FALSE;
476         int i;
477  
478 @@ -540,7 +544,7 @@ parse_options(int argc, char *argv[])
479         buf_size = strlen(opt_cmd);
480  
481         for (i = 1 + !!subcommand; i < argc; i++) {
482 -               char *opt = argv[i];
483 +               const char *opt = argv[i];
484  
485                 if (seen_dashdash || !strcmp(opt, "--")) {
486                         seen_dashdash = TRUE;
487 @@ -867,7 +871,7 @@ get_keybinding(enum keymap keymap, int key)
488  
489  
490  struct key {
491 -       char *name;
492 +       const char *name;
493         int value;
494  };
495  
496 @@ -917,11 +921,11 @@ get_key_value(const char *name)
497         return ERR;
498  }
499  
500 -static char *
501 +static const char *
502  get_key_name(int key_value)
503  {
504         static char key_char[] = "'X'";
505 -       char *seq = NULL;
506 +       const char *seq = NULL;
507         int key;
508  
509         for (key = 0; key < ARRAY_SIZE(key_table); key++)
510 @@ -938,7 +942,7 @@ get_key_name(int key_value)
511         return seq ? seq : "(no key)";
512  }
513  
514 -static char *
515 +static const char *
516  get_key(enum request request)
517  {
518         static char buf[BUFSIZ];
519 @@ -1062,7 +1066,7 @@ static struct int_map attr_map[] = {
520  
521  static int   config_lineno;
522  static bool  config_errors;
523 -static char *config_msg;
524 +static const char *config_msg;
525  
526  /* Wants: object fgcolor bgcolor [attr] */
527  static int
528 @@ -1249,7 +1253,7 @@ option_bind_command(int argc, const char *argv[])
529  }
530  
531  static int
532 -set_option(char *opt, char *value)
533 +set_option(const char *opt, char *value)
534  {
535         const char *argv[SIZEOF_ARG];
536         int valuelen;
537 @@ -1343,9 +1347,9 @@ load_option_file(const char *path)
538  static int
539  load_options(void)
540  {
541 -       char *home = getenv("HOME");
542 -       char *tigrc_user = getenv("TIGRC_USER");
543 -       char *tigrc_system = getenv("TIGRC_SYSTEM");
544 +       const char *home = getenv("HOME");
545 +       const char *tigrc_user = getenv("TIGRC_USER");
546 +       const char *tigrc_system = getenv("TIGRC_SYSTEM");
547         char buf[SIZEOF_STR];
548  
549         add_builtin_run_requests();
550 @@ -1639,7 +1643,7 @@ draw_graphic(struct view *view, enum line_type type, chtype graphic[], size_t si
551  }
552  
553  static bool
554 -draw_field(struct view *view, enum line_type type, char *text, int len, bool trim)
555 +draw_field(struct view *view, enum line_type type, const char *text, int len, bool trim)
556  {
557         int max = MIN(view->width - view->col, len);
558         int col;
559 @@ -2375,8 +2379,14 @@ update_view(struct view *view)
560                 }
561         }
562  
563 -       if (!view_is_displayed(view))
564 -               goto check_pipe;
565 +       if (ferror(view->pipe) && errno != 0) {
566 +               report("Failed to read: %s", strerror(errno));
567 +               end_update(view, TRUE);
568 +
569 +       } else if (feof(view->pipe)) {
570 +               report("");
571 +               end_update(view, FALSE);
572 +       }
573  
574         if (view == VIEW(REQ_VIEW_TREE)) {
575                 /* Clear the view and redraw everything since the tree sorting
576 @@ -2406,17 +2416,6 @@ update_view(struct view *view)
577         /* Update the title _after_ the redraw so that if the redraw picks up a
578          * commit reference in view->ref it'll be available here. */
579         update_view_title(view);
580 -
581 -check_pipe:
582 -       if (ferror(view->pipe) && errno != 0) {
583 -               report("Failed to read: %s", strerror(errno));
584 -               end_update(view, TRUE);
585 -
586 -       } else if (feof(view->pipe)) {
587 -               report("");
588 -               end_update(view, FALSE);
589 -       }
590 -
591         return TRUE;
592  
593  alloc_error:
594 @@ -2438,10 +2437,9 @@ add_line_data(struct view *view, void *data, enum line_type type)
595  }
596  
597  static struct line *
598 -add_line_text(struct view *view, char *data, enum line_type type)
599 +add_line_text(struct view *view, const char *text, enum line_type type)
600  {
601 -       if (data)
602 -               data = strdup(data);
603 +       char *data = text ? strdup(text) : NULL;
604  
605         return data ? add_line_data(view, data, type) : NULL;
606  }
607 @@ -2565,7 +2563,7 @@ open_external_viewer(const char *cmd)
608         endwin();                  /* restore original tty modes */
609         system(cmd);
610         fprintf(stderr, "Press Enter to continue");
611 -       getc(stdin);
612 +       getc(opt_tty);
613         reset_prog_mode();
614         redraw_display();
615  }
616 @@ -2587,7 +2585,7 @@ open_editor(bool from_root, const char *file)
617  {
618         char cmd[SIZEOF_STR];
619         char file_sq[SIZEOF_STR];
620 -       char *editor;
621 +       const char *editor;
622         char *prefix = from_root ? opt_cdup : "";
623  
624         editor = getenv("GIT_EDITOR");
625 @@ -2893,7 +2891,6 @@ view_driver(struct view *view, enum request request)
626                 return FALSE;
627  
628         default:
629 -               /* An unknown key will show most commonly used commands. */
630                 report("Unknown key, press 'h' for help");
631                 return TRUE;
632         }
633 @@ -2919,7 +2916,7 @@ pager_draw(struct view *view, struct line *line, unsigned int lineno)
634  }
635  
636  static bool
637 -add_describe_ref(char *buf, size_t *bufpos, char *commit_id, const char *sep)
638 +add_describe_ref(char *buf, size_t *bufpos, const char *commit_id, const char *sep)
639  {
640         char refbuf[SIZEOF_STR];
641         char *ref = NULL;
642 @@ -2967,8 +2964,8 @@ add_pager_refs(struct view *view, struct line *line)
643  
644         do {
645                 struct ref *ref = refs[refpos];
646 -               char *fmt = ref->tag    ? "%s[%s]" :
647 -                           ref->remote ? "%s<%s>" : "%s%s";
648 +               const char *fmt = ref->tag    ? "%s[%s]" :
649 +                                 ref->remote ? "%s<%s>" : "%s%s";
650  
651                 if (!string_format_from(buf, &bufpos, fmt, sep, ref->name))
652                         return;
653 @@ -3130,7 +3127,7 @@ help_open(struct view *view)
654         add_line_text(view, "Quick reference for tig keybindings:", LINE_DEFAULT);
655  
656         for (i = 0; i < ARRAY_SIZE(req_info); i++) {
657 -               char *key;
658 +               const char *key;
659  
660                 if (req_info[i].request == REQ_NONE)
661                         continue;
662 @@ -3158,7 +3155,7 @@ help_open(struct view *view)
663  
664         for (i = 0; i < run_requests; i++) {
665                 struct run_request *req = get_run_request(REQ_NONE + i + 1);
666 -               char *key;
667 +               const char *key;
668  
669                 if (!req)
670                         continue;
671 @@ -3215,7 +3212,7 @@ pop_tree_stack_entry(void)
672  }
673  
674  static void
675 -push_tree_stack_entry(char *name, unsigned long lineno)
676 +push_tree_stack_entry(const char *name, unsigned long lineno)
677  {
678         struct tree_stack_entry *entry = calloc(1, sizeof(*entry));
679         size_t pathlen = strlen(opt_path);
680 @@ -3251,8 +3248,8 @@ push_tree_stack_entry(char *name, unsigned long lineno)
681  #define TREE_UP_FORMAT "040000 tree %s\t.."
682  
683  static int
684 -tree_compare_entry(enum line_type type1, char *name1,
685 -                  enum line_type type2, char *name2)
686 +tree_compare_entry(enum line_type type1, const char *name1,
687 +                  enum line_type type2, const char *name2)
688  {
689         if (type1 != type2) {
690                 if (type1 == LINE_TREE_DIR)
691 @@ -3263,10 +3260,10 @@ tree_compare_entry(enum line_type type1, char *name1,
692         return strcmp(name1, name2);
693  }
694  
695 -static char *
696 +static const char *
697  tree_path(struct line *line)
698  {
699 -       char *path = line->data;
700 +       const char *path = line->data;
701  
702         return path + SIZEOF_TREE_ATTR;
703  }
704 @@ -3318,7 +3315,7 @@ tree_read(struct view *view, char *text)
705         /* Skip "Directory ..." and ".." line. */
706         for (pos = 1 + !!*opt_path; pos < view->lines; pos++) {
707                 struct line *line = &view->line[pos];
708 -               char *path1 = tree_path(line);
709 +               const char *path1 = tree_path(line);
710                 char *path2 = text + SIZEOF_TREE_ATTR;
711                 int cmp = tree_compare_entry(line->type, path1, type, path2);
712  
713 @@ -3357,7 +3354,7 @@ tree_request(struct view *view, enum request request, struct line *line)
714         enum open_flags flags;
715  
716         if (request == REQ_VIEW_BLAME) {
717 -               char *filename = tree_path(line);
718 +               const char *filename = tree_path(line);
719  
720                 if (line->type == LINE_TREE_DIR) {
721                         report("Cannot show blame for directory %s", opt_path);
722 @@ -3393,7 +3390,7 @@ tree_request(struct view *view, enum request request, struct line *line)
723                         pop_tree_stack_entry();
724  
725                 } else {
726 -                       char *basename = tree_path(line);
727 +                       const char *basename = tree_path(line);
728  
729                         push_tree_stack_entry(basename, view->lineno);
730                 }
731 @@ -3490,7 +3487,7 @@ struct blame {
732  };
733  
734  #define BLAME_CAT_FILE_CMD "git cat-file blob %s:%s"
735 -#define BLAME_INCREMENTAL_CMD "git blame --incremental %s %s"
736 +#define BLAME_INCREMENTAL_CMD "git blame --incremental %s -- %s"
737  
738  static bool
739  blame_open(struct view *view)
740 @@ -3556,9 +3553,9 @@ get_blame_commit(struct view *view, const char *id)
741  }
742  
743  static bool
744 -parse_number(char **posref, size_t *number, size_t min, size_t max)
745 +parse_number(const char **posref, size_t *number, size_t min, size_t max)
746  {
747 -       char *pos = *posref;
748 +       const char *pos = *posref;
749  
750         *posref = NULL;
751         pos = strchr(pos + 1, ' ');
752 @@ -3573,11 +3570,11 @@ parse_number(char **posref, size_t *number, size_t min, size_t max)
753  }
754  
755  static struct blame_commit *
756 -parse_blame_commit(struct view *view, char *text, int *blamed)
757 +parse_blame_commit(struct view *view, const char *text, int *blamed)
758  {
759         struct blame_commit *commit;
760         struct blame *blame;
761 -       char *pos = text + SIZEOF_REV - 1;
762 +       const char *pos = text + SIZEOF_REV - 1;
763         size_t lineno;
764         size_t group;
765  
766 @@ -3606,7 +3603,7 @@ parse_blame_commit(struct view *view, char *text, int *blamed)
767  }
768  
769  static bool
770 -blame_read_file(struct view *view, char *line)
771 +blame_read_file(struct view *view, const char *line)
772  {
773         if (!line) {
774                 FILE *pipe = NULL;
775 @@ -3711,7 +3708,7 @@ blame_draw(struct view *view, struct line *line, unsigned int lineno)
776  {
777         struct blame *blame = line->data;
778         struct tm *time = NULL;
779 -       char *id = NULL, *author = NULL;
780 +       const char *id = NULL, *author = NULL;
781  
782         if (blame->commit && *blame->commit->filename) {
783                 id = blame->commit->id;
784 @@ -3855,13 +3852,13 @@ status_has_none(struct view *view, struct line *line)
785   * :100644 100644 06a5d6ae9eca55be2e0e585a152e6b1336f2b20e 0000000000000000000000000000000000000000 M
786   */
787  static inline bool
788 -status_get_diff(struct status *file, char *buf, size_t bufsize)
789 +status_get_diff(struct status *file, const char *buf, size_t bufsize)
790  {
791 -       char *old_mode = buf +  1;
792 -       char *new_mode = buf +  8;
793 -       char *old_rev  = buf + 15;
794 -       char *new_rev  = buf + 56;
795 -       char *status   = buf + 97;
796 +       const char *old_mode = buf +  1;
797 +       const char *new_mode = buf +  8;
798 +       const char *old_rev  = buf + 15;
799 +       const char *new_rev  = buf + 56;
800 +       const char *status   = buf + 97;
801  
802         if (bufsize < 99 ||
803             old_mode[-1] != ':' ||
804 @@ -4078,7 +4075,7 @@ status_draw(struct view *view, struct line *line, unsigned int lineno)
805  {
806         struct status *status = line->data;
807         enum line_type type;
808 -       char *text;
809 +       const char *text;
810  
811         if (!status) {
812                 switch (line->type) {
813 @@ -4130,7 +4127,7 @@ status_enter(struct view *view, struct line *line)
814         struct status *status = line->data;
815         char oldpath[SIZEOF_STR] = "";
816         char newpath[SIZEOF_STR] = "";
817 -       char *info;
818 +       const char *info;
819         size_t cmdsize = 0;
820         enum open_flags split;
821  
822 @@ -4393,7 +4390,7 @@ status_revert(struct status *status, enum line_type type, bool has_none)
823                 char file_sq[SIZEOF_STR];
824  
825                 if (sq_quote(file_sq, 0, status->old.name) >= sizeof(file_sq) ||
826 -                   !string_format(cmd, "git checkout %s%s", opt_cdup, file_sq))
827 +                   !string_format(cmd, "git checkout -- %s%s", opt_cdup, file_sq))
828                         return FALSE;
829  
830                 return run_confirm(cmd, "Are you sure you want to overwrite any changes?");
831 @@ -4463,8 +4460,8 @@ status_select(struct view *view, struct line *line)
832  {
833         struct status *status = line->data;
834         char file[SIZEOF_STR] = "all files";
835 -       char *text;
836 -       char *key;
837 +       const char *text;
838 +       const char *key;
839  
840         if (status && !string_format(file, "'%s'", status->new.name))
841                 return;
842 @@ -4517,7 +4514,7 @@ status_grep(struct view *view, struct line *line)
843                 return FALSE;
844  
845         for (state = S_STATUS; state < S_END; state++) {
846 -               char *text;
847 +               const char *text;
848  
849                 switch (state) {
850                 case S_NAME:    text = status->new.name;        break;
851 @@ -4551,7 +4548,7 @@ static struct view_ops status_ops = {
852  static bool
853  stage_diff_line(FILE *pipe, struct line *line)
854  {
855 -       char *buf = line->data;
856 +       const char *buf = line->data;
857         size_t bufsize = strlen(buf);
858         size_t written = 0;
859  
860 @@ -4874,7 +4871,7 @@ done_rev_graph(struct rev_graph *graph)
861  }
862  
863  static void
864 -push_rev_graph(struct rev_graph *graph, char *parent)
865 +push_rev_graph(struct rev_graph *graph, const char *parent)
866  {
867         int i;
868  
869 @@ -5531,13 +5528,13 @@ init_display(void)
870         /* Initialize the curses library */
871         if (isatty(STDIN_FILENO)) {
872                 cursed = !!initscr();
873 +               opt_tty = stdin;
874         } else {
875                 /* Leave stdin and stdout alone when acting as a pager. */
876 -               FILE *io = fopen("/dev/tty", "r+");
877 -
878 -               if (!io)
879 +               opt_tty = fopen("/dev/tty", "r+");
880 +               if (!opt_tty)
881                         die("Failed to open /dev/tty");
882 -               cursed = !!newterm(NULL, io, io);
883 +               cursed = !!newterm(NULL, opt_tty, opt_tty);
884         }
885  
886         if (!cursed)
887 @@ -5698,8 +5695,27 @@ static struct ref ***id_refs = NULL;
888  static size_t id_refs_alloc = 0;
889  static size_t id_refs_size = 0;
890  
891 +static int
892 +compare_refs(const void *ref1_, const void *ref2_)
893 +{
894 +       const struct ref *ref1 = *(const struct ref **)ref1_;
895 +       const struct ref *ref2 = *(const struct ref **)ref2_;
896 +
897 +       if (ref1->tag != ref2->tag)
898 +               return ref2->tag - ref1->tag;
899 +       if (ref1->ltag != ref2->ltag)
900 +               return ref2->ltag - ref2->ltag;
901 +       if (ref1->head != ref2->head)
902 +               return ref2->head - ref1->head;
903 +       if (ref1->tracked != ref2->tracked)
904 +               return ref2->tracked - ref1->tracked;
905 +       if (ref1->remote != ref2->remote)
906 +               return ref2->remote - ref1->remote;
907 +       return strcmp(ref1->name, ref2->name);
908 +}
909 +
910  static struct ref **
911 -get_refs(char *id)
912 +get_refs(const char *id)
913  {
914         struct ref ***tmp_id_refs;
915         struct ref **ref_list = NULL;
916 @@ -5733,19 +5749,20 @@ get_refs(char *id)
917                 }
918  
919                 ref_list = tmp;
920 -               if (ref_list_size > 0)
921 -                       ref_list[ref_list_size - 1]->next = 1;
922                 ref_list[ref_list_size] = &refs[i];
923 -
924                 /* XXX: The properties of the commit chains ensures that we can
925                  * safely modify the shared ref. The repo references will
926                  * always be similar for the same id. */
927 -               ref_list[ref_list_size]->next = 0;
928 +               ref_list[ref_list_size]->next = 1;
929 +
930                 ref_list_size++;
931         }
932  
933 -       if (ref_list)
934 +       if (ref_list) {
935 +               qsort(ref_list, ref_list_size, sizeof(*ref_list), compare_refs);
936 +               ref_list[ref_list_size - 1]->next = 0;
937                 id_refs[id_refs_size++] = ref_list;
938 +       }
939  
940         return ref_list;
941  }
942 @@ -5761,7 +5778,7 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
943         bool check_replace = FALSE;
944         bool head = FALSE;
945  
946 -       if (!strncmp(name, "refs/tags/", STRING_SIZE("refs/tags/"))) {
947 +       if (!prefixcmp(name, "refs/tags/")) {
948                 if (!strcmp(name + namelen - 3, "^{}")) {
949                         namelen -= 3;
950                         name[namelen] = 0;
951 @@ -5775,13 +5792,13 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
952                 namelen -= STRING_SIZE("refs/tags/");
953                 name    += STRING_SIZE("refs/tags/");
954  
955 -       } else if (!strncmp(name, "refs/remotes/", STRING_SIZE("refs/remotes/"))) {
956 +       } else if (!prefixcmp(name, "refs/remotes/")) {
957                 remote = TRUE;
958                 namelen -= STRING_SIZE("refs/remotes/");
959                 name    += STRING_SIZE("refs/remotes/");
960                 tracked  = !strcmp(opt_remote, name);
961  
962 -       } else if (!strncmp(name, "refs/heads/", STRING_SIZE("refs/heads/"))) {
963 +       } else if (!prefixcmp(name, "refs/heads/")) {
964                 namelen -= STRING_SIZE("refs/heads/");
965                 name    += STRING_SIZE("refs/heads/");
966                 head     = !strncmp(opt_head, name, namelen);
967 @@ -5794,7 +5811,7 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen)
968         if (check_replace && !strcmp(name, refs[refs_size - 1].name)) {
969                 /* it's an annotated tag, replace the previous sha1 with the
970                  * resolved commit id; relies on the fact git-ls-remote lists
971 -                * the commit id of an annotated tag right beofre the commit id
972 +                * the commit id of an annotated tag right before the commit id
973                  * it points to. */
974                 refs[refs_size - 1].ltag = ltag;
975                 string_copy_rev(refs[refs_size - 1].id, id);
976 @@ -5861,7 +5878,7 @@ read_repo_config_option(char *name, size_t namelen, char *value, size_t valuelen
977             !strcmp(name + 7 + strlen(opt_head), ".merge")) {
978                 size_t from = strlen(opt_remote);
979  
980 -               if (!strncmp(value, "refs/heads/", STRING_SIZE("refs/heads/"))) {
981 +               if (!prefixcmp(value, "refs/heads/")) {
982                         value += STRING_SIZE("refs/heads/");
983                         valuelen -= STRING_SIZE("refs/heads/");
984                 }
985 @@ -5897,7 +5914,7 @@ read_repo_info(char *name, size_t namelen, char *value, size_t valuelen)
986         } else if (opt_cdup[0] == ' ') {
987                 string_ncopy(opt_cdup, name, namelen);
988         } else {
989 -               if (!strncmp(name, "refs/heads/", STRING_SIZE("refs/heads/"))) {
990 +               if (!prefixcmp(name, "refs/heads/")) {
991                         namelen -= STRING_SIZE("refs/heads/");
992                         name    += STRING_SIZE("refs/heads/");
993                         string_ncopy(opt_head, name, namelen);
994 @@ -6009,7 +6026,7 @@ warn(const char *msg, ...)
995  }
996  
997  int
998 -main(int argc, char *argv[])
999 +main(int argc, const char *argv[])
1000  {
1001         struct view *view;
1002         enum request request;
1003 @@ -6052,7 +6069,7 @@ main(int argc, char *argv[])
1004         if (load_refs() == ERR)
1005                 die("Failed to load refs.");
1006  
1007 -       for (i = 0; i < ARRAY_SIZE(views) && (view = &views[i]); i++)
1008 +       foreach_view (view, i)
1009                 view->cmd_env = getenv(view->cmd_env);
1010  
1011         init_display();
1012 @@ -6063,6 +6080,7 @@ main(int argc, char *argv[])
1013  
1014                 foreach_view (view, i)
1015                         update_view(view);
1016 +               view = display[current_view];
1017  
1018                 /* Refresh, accept single keystroke of input */
1019                 key = wgetch(status_win);
1020 @@ -6074,7 +6092,7 @@ main(int argc, char *argv[])
1021                         continue;
1022                 }
1023  
1024 -               request = get_keybinding(display[current_view]->keymap, key);
1025 +               request = get_keybinding(view->keymap, key);
1026  
1027                 /* Some low-level request handling. This keeps access to
1028                  * status_win restricted. */
1029 @@ -6100,8 +6118,7 @@ main(int argc, char *argv[])
1030                 case REQ_SEARCH:
1031                 case REQ_SEARCH_BACK:
1032                 {
1033 -                       const char *prompt = request == REQ_SEARCH
1034 -                                          ? "/" : "?";
1035 +                       const char *prompt = request == REQ_SEARCH ? "/" : "?";
1036                         char *search = read_prompt(prompt);
1037  
1038                         if (search)
This page took 1.922309 seconds and 2 git commands to generate.