From 234918423a4fac44375317e6c9e7ee54ea09379c Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Fri, 4 Apr 2008 01:03:21 +0200 Subject: [PATCH] Improve staging of diff chunks As suggested by Petr Baudis some year ago, make updating of chunks work stage the chunk the cursor line is within instead of the whole file. Still stage everything when the cursor is in the diff --stat header. --- tig.c | 89 +++++++++++++++++++++-------------------------------------- 1 file changed, 31 insertions(+), 58 deletions(-) diff --git a/tig.c b/tig.c index 0ceeb80..7ca509c 100644 --- a/tig.c +++ b/tig.c @@ -4473,36 +4473,39 @@ stage_diff_line(FILE *pipe, struct line *line) return written == bufsize; } -static struct line * -stage_diff_hdr(struct view *view, struct line *line) +static bool +stage_diff_write(FILE *pipe, struct line *line, struct line *end) { - int diff_hdr_dir = line->type == LINE_DIFF_CHUNK ? -1 : 1; - struct line *diff_hdr; - - if (line->type == LINE_DIFF_CHUNK) - diff_hdr = line - 1; - else - diff_hdr = view->line + 1; + while (line < end) { + if (!stage_diff_line(pipe, line++)) + return FALSE; + if (line->type == LINE_DIFF_CHUNK || + line->type == LINE_DIFF_HEADER) + break; + } - while (diff_hdr > view->line && diff_hdr < view->line + view->lines) { - if (diff_hdr->type == LINE_DIFF_HEADER) - return diff_hdr; + return TRUE; +} - diff_hdr += diff_hdr_dir; - } +static struct line * +stage_diff_find(struct view *view, struct line *line, enum line_type type) +{ + for (; view->line < line; line--) + if (line->type == type) + return line; return NULL; } static bool -stage_update_chunk(struct view *view, struct line *line) +stage_update_chunk(struct view *view, struct line *chunk) { char cmd[SIZEOF_STR]; size_t cmdsize = 0; - struct line *diff_hdr, *diff_chunk, *diff_end; + struct line *diff_hdr; FILE *pipe; - diff_hdr = stage_diff_hdr(view, line); + diff_hdr = stage_diff_find(view, chunk, LINE_DIFF_HEADER); if (!diff_hdr) return FALSE; @@ -4520,55 +4523,25 @@ stage_update_chunk(struct view *view, struct line *line) if (!pipe) return FALSE; - diff_end = view->line + view->lines; - if (line->type != LINE_DIFF_CHUNK) { - diff_chunk = diff_hdr; - - } else { - for (diff_chunk = line + 1; diff_chunk < diff_end; diff_chunk++) - if (diff_chunk->type == LINE_DIFF_CHUNK || - diff_chunk->type == LINE_DIFF_HEADER) - diff_end = diff_chunk; - - diff_chunk = line; - - while (diff_hdr->type != LINE_DIFF_CHUNK) { - switch (diff_hdr->type) { - case LINE_DIFF_HEADER: - case LINE_DIFF_INDEX: - case LINE_DIFF_ADD: - case LINE_DIFF_DEL: - break; - - default: - diff_hdr++; - continue; - } - - if (!stage_diff_line(pipe, diff_hdr++)) { - pclose(pipe); - return FALSE; - } - } - } - - while (diff_chunk < diff_end && stage_diff_line(pipe, diff_chunk)) - diff_chunk++; + if (!stage_diff_write(pipe, diff_hdr, chunk) || + !stage_diff_write(pipe, chunk, view->line + view->lines)) + chunk = NULL; pclose(pipe); - if (diff_chunk != diff_end) - return FALSE; - - return TRUE; + return chunk ? TRUE : FALSE; } static bool stage_update(struct view *view, struct line *line) { - if (!opt_no_head && stage_line_type != LINE_STAT_UNTRACKED && - (line->type == LINE_DIFF_CHUNK || !stage_status.status)) { - if (!stage_update_chunk(view, line)) { + struct line *chunk = NULL; + + if (!opt_no_head && stage_line_type != LINE_STAT_UNTRACKED) + chunk = stage_diff_find(view, line, LINE_DIFF_CHUNK); + + if (chunk) { + if (!stage_update_chunk(view, chunk)) { report("Failed to apply chunk"); return FALSE; } -- 2.30.2