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? */
};
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"), \
" -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;
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), \
{ '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 },
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[])
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;
}
bool use_tilde, int tilde_attr)
{
int len = 0;
+ int trimmed = FALSE;
- if (max_len > 0) {
- int trimmed = FALSE;
+ if (max_len <= 0)
+ return 0;
- 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 = max_len;
- trimmed = TRUE;
+ 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 = max_len;
+ trimmed = TRUE;
}
- waddnstr(view->win, string, len);
- if (trimmed && use_tilde) {
- if (tilde_attr != -1)
- wattrset(view->win, tilde_attr);
- waddch(view->win, '~');
- len++;
- }
+ }
+
+ waddnstr(view->win, string, len);
+ if (trimmed && use_tilde) {
+ if (tilde_attr != -1)
+ wattrset(view->win, tilde_attr);
+ waddch(view->win, '~');
+ len++;
}
return len;
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);
/* 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"
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))
tilde_attr = get_line_attr(LINE_MAIN_DELIM);
}
- {
+ if (opt_date) {
int n;
timelen = strftime(buf, sizeof(buf), DATE_FORMAT, &commit->time);
if (type != LINE_CURSOR)
wattrset(view->win, get_line_attr(LINE_MAIN_AUTHOR));
- {
+ if (opt_author) {
int max_len;
max_len = view->width - col;
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)
{
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/");
return OK;
}
+ 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(refs, sizeof(*refs) * (refs_size + 1));
if (!refs)
return ERR;
strncpy(ref->name, name, namelen);
ref->name[namelen] = 0;
ref->tag = tag;
+ ref->ltag = ltag;
ref->remote = remote;
string_copy_rev(ref->id, id);