summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 1a797ac)
raw | patch | inline | side by side (parent: 1a797ac)
author | Jonas Fonseca <fonseca@diku.dk> | |
Sun, 21 Sep 2008 11:15:25 +0000 (13:15 +0200) | ||
committer | Jonas Fonseca <fonseca@diku.dk> | |
Sun, 21 Sep 2008 11:15:25 +0000 (13:15 +0200) |
NEWS | patch | blob | history | |
manual.txt | patch | blob | history | |
tig.c | patch | blob | history |
index 8f7100b0a8b6faf6fd599eff3b2951efe89612a5..59274da232460f89610968da7e6a436b12fd0a24 100644 (file)
--- a/NEWS
+++ b/NEWS
Release notes
=============
+tig master
+----------
+
+Improvements:
+
+ - Checkout files with unstaged changes. Bound to '!' by default.
+
tig-0.12
--------
diff --git a/manual.txt b/manual.txt
index 3157eb3949b250302d01b2f09ba384441ec51467..f11b77a1c60126cb075f67859a975d8f98d4850f 100644 (file)
--- a/manual.txt
+++ b/manual.txt
M Resolve unmerged file by launching git-mergetool(1). Note, to work \
correctly this might require some initial configuration of your \
preferred merge tool. See the manpage of git-mergetool(1).
+! Checkout file with unstaged changes. This will reset the file to \
+ contain the content it had at last commit.
@ Move to next chunk in the stage view.
',' Move tree view to the parent tree.
e Open file in editor.
index a830412a6e5b0ff601b69f4a7f3f22beb5feab6b..6b90f998373c481ba5480579ab0b637ad04e85ac 100644 (file)
--- a/tig.c
+++ b/tig.c
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, int *width, size_t max_width, int *trimmed, bool reserve);
+static bool prompt_yesno(const char *prompt);
#define ABS(x) ((x) >= 0 ? (x) : -(x))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
REQ_(TOGGLE_REV_GRAPH, "Toggle revision graph visualization"), \
REQ_(TOGGLE_REFS, "Toggle reference display (tags/branches)"), \
REQ_(STATUS_UPDATE, "Update file status"), \
+ REQ_(STATUS_CHECKOUT, "Checkout file"), \
REQ_(STATUS_MERGE, "Merge file using external tool"), \
REQ_(STAGE_NEXT, "Find next chunk to stage"), \
REQ_(TREE_PARENT, "Switch to parent directory in tree view"), \
{ 'F', REQ_TOGGLE_REFS },
{ ':', REQ_PROMPT },
{ 'u', REQ_STATUS_UPDATE },
+ { '!', REQ_STATUS_CHECKOUT },
{ 'M', REQ_STATUS_MERGE },
{ '@', REQ_STAGE_NEXT },
{ ',', REQ_TREE_PARENT },
update_view_title(view);
}
+static void
+run_confirm(const char *cmd, const char *prompt)
+{
+ if (prompt_yesno(prompt)) {
+ system(cmd);
+ }
+}
+
static void
open_external_viewer(const char *cmd)
{
return TRUE;
}
+static bool
+status_checkout(struct view *view)
+{
+ struct line *line = &view->line[view->lineno];
+
+ assert(view->lines);
+
+ if (!line->data || line->type != LINE_STAT_UNSTAGED) {
+ /* This should work even for the "On branch" line. */
+ if (line < view->line + view->lines && !line[1].data) {
+ report("Nothing to checkout");
+ } else if (line->type == LINE_STAT_UNTRACKED) {
+ report("Cannot checkout untracked files");
+ } else if (line->type == LINE_STAT_STAGED) {
+ report("Cannot checkout staged files");
+ } else {
+ report("Cannot checkout multiple files");
+ }
+ return FALSE;
+
+ } else {
+ struct status *status = line->data;
+ char cmd[SIZEOF_STR];
+ 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)) {
+ run_confirm(cmd, "Are you sure you want to overwrite any changes?");
+ }
+
+ return TRUE;
+ }
+}
+
static enum request
status_request(struct view *view, enum request request, struct line *line)
{
return REQ_NONE;
break;
+ case REQ_STATUS_CHECKOUT:
+ if (!status_checkout(view))
+ return REQ_NONE;
+ break;
+
case REQ_STATUS_MERGE:
if (!status || status->status != 'U') {
report("Merging only possible for files with unmerged status ('U').");
}
}
+static bool
+prompt_yesno(const char *prompt)
+{
+ enum { WAIT, STOP, CANCEL } status = WAIT;
+ bool answer = FALSE;
+
+ while (status == WAIT) {
+ struct view *view;
+ int i, key;
+
+ input_mode = TRUE;
+
+ foreach_view (view, i)
+ update_view(view);
+
+ input_mode = FALSE;
+
+ mvwprintw(status_win, 0, 0, "%s [Yy]/[Nn]", prompt);
+ wclrtoeol(status_win);
+
+ /* Refresh, accept single keystroke of input */
+ key = wgetch(status_win);
+ switch (key) {
+ case ERR:
+ break;
+
+ case 'y':
+ case 'Y':
+ answer = TRUE;
+ status = STOP;
+ break;
+
+ case KEY_ESC:
+ case KEY_RETURN:
+ case KEY_ENTER:
+ case KEY_BACKSPACE:
+ case 'n':
+ case 'N':
+ case '\n':
+ default:
+ answer = FALSE;
+ status = CANCEL;
+ }
+ }
+
+ /* Clear the status window */
+ status_empty = FALSE;
+ report("");
+
+ return answer;
+}
+
static char *
read_prompt(const char *prompt)
{