Code

foreach_ref: make ref argument const
[tig.git] / tig.c
diff --git a/tig.c b/tig.c
index af8e19695425162eed687d2bdf14330137b4bdb3..bd30997c00ede3035271484f5cb18326fe64c34c 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -137,7 +137,7 @@ struct ref_list {
 };
 
 static struct ref_list *get_ref_list(const char *id);
-static void foreach_ref(bool (*visitor)(void *data, struct ref *ref), void *data);
+static void foreach_ref(bool (*visitor)(void *data, const struct ref *ref), void *data);
 static int load_refs(void);
 
 enum format_flags {
@@ -497,9 +497,22 @@ init_io_rd(struct io *io, const char *argv[], const char *dir,
 }
 
 static bool
-io_open(struct io *io, const char *name)
+io_open(struct io *io, const char *fmt, ...)
 {
+       char name[SIZEOF_STR] = "";
+       bool fits;
+       va_list args;
+
        init_io(io, NULL, IO_FD);
+
+       va_start(args, fmt);
+       fits = vsnprintf(name, sizeof(name), fmt, args) < sizeof(name);
+       va_end(args);
+
+       if (!fits) {
+               io->error = ENAMETOOLONG;
+               return FALSE;
+       }
        io->pipe = *name ? open(name, O_RDONLY) : STDIN_FILENO;
        if (io->pipe == -1)
                io->error = errno;
@@ -645,13 +658,7 @@ run_io_append(const char **argv, enum format_flags flags, int fd)
 }
 
 static bool
-run_io_rd(struct io *io, const char **argv, enum format_flags flags)
-{
-       return init_io_rd(io, argv, NULL, flags) && start_io(io);
-}
-
-static bool
-run_io_rd_dir(struct io *io, const char **argv, const char *dir, enum format_flags flags)
+run_io_rd(struct io *io, const char **argv, const char *dir, enum format_flags flags)
 {
        return init_io_rd(io, argv, dir, flags) && start_io(io);
 }
@@ -790,7 +797,8 @@ run_io_buf(const char **argv, char buf[], size_t bufsize)
 {
        struct io io = {};
 
-       return run_io_rd(&io, argv, FORMAT_NONE) && io_read_buf(&io, buf, bufsize);
+       return run_io_rd(&io, argv, NULL, FORMAT_NONE)
+           && io_read_buf(&io, buf, bufsize);
 }
 
 static int
@@ -1857,7 +1865,7 @@ load_option_file(const char *path)
        struct io io = {};
 
        /* It's OK that the file doesn't exist. */
-       if (!io_open(&io, path))
+       if (!io_open(&io, "%s", path))
                return;
 
        config_lineno = 0;
@@ -2988,7 +2996,7 @@ prepare_update_file(struct view *view, const char *name)
 {
        if (view->pipe)
                end_update(view, TRUE);
-       return io_open(&view->io, name);
+       return io_open(&view->io, "%s", name);
 }
 
 static bool
@@ -4256,7 +4264,7 @@ tree_read_date(struct view *view, char *text, bool *read_date)
                        return TRUE;
                }
 
-               if (!run_io_rd_dir(&io, log_file, opt_cdup, FORMAT_NONE)) {
+               if (!run_io_rd(&io, log_file, opt_cdup, FORMAT_NONE)) {
                        report("Failed to load tree data");
                        return TRUE;
                }
@@ -4647,11 +4655,8 @@ blame_open(struct view *view)
                        return FALSE;
        }
 
-       if (!string_format(path, "%s%s", opt_cdup, opt_file))
-               return FALSE;
-
-       if (*opt_ref || !io_open(&view->io, path)) {
-               if (!run_io_rd_dir(&view->io, blame_cat_file_argv, opt_cdup, FORMAT_ALL))
+       if (*opt_ref || !io_open(&view->io, "%s%s", opt_cdup, opt_file)) {
+               if (!run_io_rd(&view->io, blame_cat_file_argv, opt_cdup, FORMAT_ALL))
                        return FALSE;
        }
 
@@ -4747,7 +4752,7 @@ blame_read_file(struct view *view, const char *line, bool *read_file)
                if (view->lines == 0 && !view->parent)
                        die("No blame exist for %s", view->vid);
 
-               if (view->lines == 0 || !run_io_rd_dir(&io, argv, opt_cdup, FORMAT_ALL)) {
+               if (view->lines == 0 || !run_io_rd(&io, argv, opt_cdup, FORMAT_ALL)) {
                        report("Failed to load blame data");
                        return TRUE;
                }
@@ -5031,7 +5036,7 @@ static struct view_ops blame_ops = {
 struct branch {
        const char *author;             /* Author of the last commit. */
        time_t time;                    /* Date of the last activity. */
-       struct ref *ref;                /* Name and commit ID information. */
+       const struct ref *ref;          /* Name and commit ID information. */
 };
 
 static const enum sort_field branch_sort_fields[] = {
@@ -5139,7 +5144,7 @@ branch_read(struct view *view, char *line)
 }
 
 static bool
-branch_open_visitor(void *data, struct ref *ref)
+branch_open_visitor(void *data, const struct ref *ref)
 {
        struct view *view = data;
        struct branch *branch;
@@ -5163,7 +5168,7 @@ branch_open(struct view *view)
                        "--simplify-by-decoration", "--all", NULL
        };
 
-       if (!run_io_rd(&view->io, branch_log, FORMAT_NONE)) {
+       if (!run_io_rd(&view->io, branch_log, NULL, FORMAT_NONE)) {
                report("Failed to load branch data");
                return TRUE;
        }
@@ -5432,8 +5437,7 @@ status_update_onbranch(void)
                if (!*opt_head) {
                        struct io io = {};
 
-                       if (string_format(buf, "%s/rebase-merge/head-name", opt_git_dir) &&
-                           io_open(&io, buf) &&
+                       if (io_open(&io, "%s/rebase-merge/head-name", opt_git_dir) &&
                            io_read_buf(&io, buf, sizeof(buf))) {
                                head = buf;
                                if (!prefixcmp(head, "refs/heads/"))
@@ -5810,9 +5814,8 @@ status_revert(struct status *status, enum line_type type, bool has_none)
                } else {
                        report("Cannot revert changes to multiple files");
                }
-               return FALSE;
 
-       } else {
+       } else if (prompt_yesno("Are you sure you want to revert changes?")) {
                char mode[10] = "100644";
                const char *reset_argv[] = {
                        "git", "update-index", "--cacheinfo", mode,
@@ -5822,12 +5825,25 @@ status_revert(struct status *status, enum line_type type, bool has_none)
                        "git", "checkout", "--", status->old.name, NULL
                };
 
-               if (!prompt_yesno("Are you sure you want to overwrite any changes?"))
-                       return FALSE;
-               string_format(mode, "%o", status->old.mode);
-               return (status->status != 'U' || run_io_fg(reset_argv, opt_cdup)) &&
-                       run_io_fg(checkout_argv, opt_cdup);
+               if (status->status == 'U') {
+                       string_format(mode, "%5o", status->old.mode);
+
+                       if (status->old.mode == 0 && status->new.mode == 0) {
+                               reset_argv[2] = "--force-remove";
+                               reset_argv[3] = status->old.name;
+                               reset_argv[4] = NULL;
+                       }
+
+                       if (!run_io_fg(reset_argv, opt_cdup))
+                               return FALSE;
+                       if (status->old.mode == 0 && status->new.mode == 0)
+                               return TRUE;
+               }
+
+               return run_io_fg(checkout_argv, opt_cdup);
        }
+
+       return FALSE;
 }
 
 static enum request
@@ -5866,10 +5882,8 @@ status_request(struct view *view, enum request request, struct line *line)
                break;
 
        case REQ_VIEW_BLAME:
-               if (status) {
-                       string_copy(opt_file, status->new.name);
+               if (status)
                        opt_ref[0] = 0;
-               }
                return request;
 
        case REQ_ENTER:
@@ -5936,6 +5950,8 @@ status_select(struct view *view, struct line *line)
        }
 
        string_format(view->ref, text, key, file);
+       if (status)
+               string_copy(opt_file, status->new.name);
 }
 
 static bool
@@ -7191,7 +7207,7 @@ compare_refs(const void *ref1_, const void *ref2_)
 }
 
 static void
-foreach_ref(bool (*visitor)(void *data, struct ref *ref), void *data)
+foreach_ref(bool (*visitor)(void *data, const struct ref *ref), void *data)
 {
        size_t i;