summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 3186281)
raw | patch | inline | side by side (parent: 3186281)
author | Jonas Fonseca <fonseca@diku.dk> | |
Thu, 27 Mar 2008 19:44:23 +0000 (20:44 +0100) | ||
committer | Jonas Fonseca <fonseca@diku.dk> | |
Thu, 27 Mar 2008 19:45:22 +0000 (20:45 +0100) |
Split the update function into one for single file and all files in a
section so that only one fork of update-index is required in both cases.
Show progress for long running updates (e.g. importing the Linux kernel)
where git needs to hash many objects (>20k).
section so that only one fork of update-index is required in both cases.
Show progress for long running updates (e.g. importing the Linux kernel)
where git needs to hash many objects (>20k).
tig.c | patch | blob | history |
index 25a77ff04a730ca7ede52609b3bbf0b6ac66ea06..5c7be40520e4f1449194a69f4cfe5286ffd10f01 100644 (file)
--- a/tig.c
+++ b/tig.c
}
-static bool
-status_update_file(struct view *view, struct status *status, enum line_type type)
+static FILE *
+status_update_prepare(enum line_type type)
{
char cmd[SIZEOF_STR];
- char buf[SIZEOF_STR];
size_t cmdsize = 0;
- size_t bufsize = 0;
- size_t written = 0;
- FILE *pipe;
if (opt_cdup[0] &&
type != LINE_STAT_UNTRACKED &&
!string_format_from(cmd, &cmdsize, "cd %s;", opt_cdup))
- return FALSE;
+ return NULL;
+
+ switch (type) {
+ case LINE_STAT_STAGED:
+ string_add(cmd, cmdsize, "git update-index -z --index-info");
+ break;
+
+ case LINE_STAT_UNSTAGED:
+ case LINE_STAT_UNTRACKED:
+ string_add(cmd, cmdsize, "git update-index -z --add --remove --stdin");
+ break;
+
+ default:
+ die("line type %d not handled in switch", type);
+ }
+
+ return popen(cmd, "w");
+}
+
+static bool
+status_update_write(FILE *pipe, struct status *status, enum line_type type)
+{
+ char buf[SIZEOF_STR];
+ size_t bufsize = 0;
+ size_t written = 0;
switch (type) {
case LINE_STAT_STAGED:
if (!string_format_from(buf, &bufsize, "%06o %s\t%s%c",
- status->old.mode,
+ status->old.mode,
status->old.rev,
status->old.name, 0))
return FALSE;
-
- string_add(cmd, cmdsize, "git update-index -z --index-info");
break;
case LINE_STAT_UNSTAGED:
case LINE_STAT_UNTRACKED:
if (!string_format_from(buf, &bufsize, "%s%c", status->new.name, 0))
return FALSE;
-
- string_add(cmd, cmdsize, "git update-index -z --add --remove --stdin");
break;
- case LINE_STAT_HEAD:
- return TRUE;
-
default:
die("line type %d not handled in switch", type);
}
- pipe = popen(cmd, "w");
- if (!pipe)
- return FALSE;
-
while (!ferror(pipe) && written < bufsize) {
written += fwrite(buf + written, 1, bufsize - written, pipe);
}
+ return written == bufsize;
+}
+
+static bool
+status_update_file(struct status *status, enum line_type type)
+{
+ FILE *pipe = status_update_prepare(type);
+ bool result;
+
+ if (!pipe)
+ return FALSE;
+
+ result = status_update_write(pipe, status, type);
pclose(pipe);
+ return result;
+}
- if (written != bufsize)
+static bool
+status_update_files(struct view *view, struct line *line)
+{
+ FILE *pipe = status_update_prepare(line->type);
+ bool result = TRUE;
+ struct line *pos = view->line + view->lines;
+ int files = 0;
+ int file, done;
+
+ if (!pipe)
return FALSE;
- return TRUE;
+ for (pos = line; pos < view->line + view->lines && pos->data; pos++)
+ files++;
+
+ for (file = 0, done = 0; result && file < files; line++, file++) {
+ int almost_done = file * 100 / files;
+
+ if (almost_done > done) {
+ done = almost_done;
+ string_format(view->ref, "updating file %u of %u (%d%% done)",
+ file, files, done);
+ update_view_title(view);
+ }
+ result = status_update_write(pipe, line->data, line->type);
+ }
+
+ pclose(pipe);
+ return result;
}
static bool
assert(view->lines);
if (!line->data) {
- while (++line < view->line + view->lines && line->data) {
- if (!status_update_file(view, line->data, line->type))
- report("Failed to update file status");
- }
-
- if (!line[-1].data) {
+ /* This should work even for the "On branch" line. */
+ if (line < view->line + view->lines && !line[1].data) {
report("Nothing to update");
return FALSE;
}
- } else if (!status_update_file(view, line->data, line->type)) {
+ if (!status_update_files(view, line + 1))
+ report("Failed to update file status");
+
+ } else if (!status_update_file(line->data, line->type)) {
report("Failed to update file status");
}
return;
}
- } else if (!status_update_file(view, &stage_status, stage_line_type)) {
+ } else if (!status_update_file(&stage_status, stage_line_type)) {
report("Failed to update file");
return;
}