fsck is usually a long process and it would be nice if it prints
progress from time to time.

Progress meter is not printed when --verbose is given because
--verbose prints a lot, there's no need for "alive" indicator.
Progress meter may provide "% complete" information but it would
be lost anyway in the flood of text.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2011-11-07 09:59:26 +07:00 коммит произвёл Junio C Hamano
Родитель c9486eb04d
Коммит 1e49f22f07
4 изменённых файлов: 61 добавлений и 7 удалений

Просмотреть файл

@ -10,7 +10,8 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs] 'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
[--[no-]full] [--strict] [--verbose] [--lost-found] [<object>*] [--[no-]full] [--strict] [--verbose] [--lost-found]
[--[no-]progress] [<object>*]
DESCRIPTION DESCRIPTION
----------- -----------
@ -72,6 +73,14 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
a blob, the contents are written into the file, rather than a blob, the contents are written into the file, rather than
its object name. its object name.
--progress::
--no-progress::
Progress status is reported on the standard error stream by
default when it is attached to a terminal, unless
--no-progress or --verbose is specified. --progress forces
progress status even if the standard error stream is not
directed to a terminal.
It tests SHA1 and general object sanity, and it does full tracking of It tests SHA1 and general object sanity, and it does full tracking of
the resulting reachability and everything else. It prints out any the resulting reachability and everything else. It prints out any
corruption it finds (missing or bad objects), and if you use the corruption it finds (missing or bad objects), and if you use the

Просмотреть файл

@ -11,6 +11,7 @@
#include "fsck.h" #include "fsck.h"
#include "parse-options.h" #include "parse-options.h"
#include "dir.h" #include "dir.h"
#include "progress.h"
#define REACHABLE 0x0001 #define REACHABLE 0x0001
#define SEEN 0x0002 #define SEEN 0x0002
@ -27,6 +28,7 @@ static const char *head_points_at;
static int errors_found; static int errors_found;
static int write_lost_and_found; static int write_lost_and_found;
static int verbose; static int verbose;
static int show_progress = -1;
#define ERROR_OBJECT 01 #define ERROR_OBJECT 01
#define ERROR_REACHABLE 02 #define ERROR_REACHABLE 02
#define ERROR_PACK 04 #define ERROR_PACK 04
@ -138,7 +140,11 @@ static int traverse_one_object(struct object *obj)
static int traverse_reachable(void) static int traverse_reachable(void)
{ {
struct progress *progress = NULL;
unsigned int nr = 0;
int result = 0; int result = 0;
if (show_progress)
progress = start_progress_delay("Checking connectivity", 0, 0, 2);
while (pending.nr) { while (pending.nr) {
struct object_array_entry *entry; struct object_array_entry *entry;
struct object *obj; struct object *obj;
@ -146,7 +152,9 @@ static int traverse_reachable(void)
entry = pending.objects + --pending.nr; entry = pending.objects + --pending.nr;
obj = entry->item; obj = entry->item;
result |= traverse_one_object(obj); result |= traverse_one_object(obj);
display_progress(progress, ++nr);
} }
stop_progress(&progress);
return !!result; return !!result;
} }
@ -530,15 +538,20 @@ static void get_default_heads(void)
static void fsck_object_dir(const char *path) static void fsck_object_dir(const char *path)
{ {
int i; int i;
struct progress *progress = NULL;
if (verbose) if (verbose)
fprintf(stderr, "Checking object directory\n"); fprintf(stderr, "Checking object directory\n");
if (show_progress)
progress = start_progress("Checking object directories", 256);
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
static char dir[4096]; static char dir[4096];
sprintf(dir, "%s/%02x", path, i); sprintf(dir, "%s/%02x", path, i);
fsck_dir(i, dir); fsck_dir(i, dir);
display_progress(progress, i+1);
} }
stop_progress(&progress);
fsck_sha1_list(); fsck_sha1_list();
} }
@ -609,6 +622,7 @@ static struct option fsck_opts[] = {
OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"), OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"),
OPT_BOOLEAN(0, "lost-found", &write_lost_and_found, OPT_BOOLEAN(0, "lost-found", &write_lost_and_found,
"write dangling objects in .git/lost-found"), "write dangling objects in .git/lost-found"),
OPT_BOOL(0, "progress", &show_progress, "show progress"),
OPT_END(), OPT_END(),
}; };
@ -621,6 +635,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
read_replace_refs = 0; read_replace_refs = 0;
argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0); argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
if (show_progress == -1)
show_progress = isatty(2);
if (verbose)
show_progress = 0;
if (write_lost_and_found) { if (write_lost_and_found) {
check_full = 1; check_full = 1;
include_reflogs = 0; include_reflogs = 0;
@ -640,12 +660,28 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
if (check_full) { if (check_full) {
struct packed_git *p; struct packed_git *p;
uint32_t total = 0, count = 0;
struct progress *progress = NULL;
prepare_packed_git(); prepare_packed_git();
for (p = packed_git; p; p = p->next)
if (show_progress) {
for (p = packed_git; p; p = p->next) {
if (open_pack_index(p))
continue;
total += p->num_objects;
}
progress = start_progress("Checking objects", total);
}
for (p = packed_git; p; p = p->next) {
/* verify gives error messages itself */ /* verify gives error messages itself */
if (verify_pack(p, fsck_obj_buffer)) if (verify_pack(p, fsck_obj_buffer,
progress, count))
errors_found |= ERROR_PACK; errors_found |= ERROR_PACK;
count += p->num_objects;
}
stop_progress(&progress);
} }
heads = 0; heads = 0;

Просмотреть файл

@ -1,6 +1,7 @@
#include "cache.h" #include "cache.h"
#include "pack.h" #include "pack.h"
#include "pack-revindex.h" #include "pack-revindex.h"
#include "progress.h"
struct idx_entry { struct idx_entry {
off_t offset; off_t offset;
@ -43,7 +44,9 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
static int verify_packfile(struct packed_git *p, static int verify_packfile(struct packed_git *p,
struct pack_window **w_curs, struct pack_window **w_curs,
verify_fn fn) verify_fn fn,
struct progress *progress, uint32_t base_count)
{ {
off_t index_size = p->index_size; off_t index_size = p->index_size;
const unsigned char *index_base = p->index_data; const unsigned char *index_base = p->index_data;
@ -127,8 +130,12 @@ static int verify_packfile(struct packed_git *p,
if (eaten) if (eaten)
data = NULL; data = NULL;
} }
if (((base_count + i) & 1023) == 0)
display_progress(progress, base_count + i);
free(data); free(data);
} }
display_progress(progress, base_count + i);
free(entries); free(entries);
return err; return err;
@ -157,7 +164,8 @@ int verify_pack_index(struct packed_git *p)
return err; return err;
} }
int verify_pack(struct packed_git *p, verify_fn fn) int verify_pack(struct packed_git *p, verify_fn fn,
struct progress *progress, uint32_t base_count)
{ {
int err = 0; int err = 0;
struct pack_window *w_curs = NULL; struct pack_window *w_curs = NULL;
@ -166,7 +174,7 @@ int verify_pack(struct packed_git *p, verify_fn fn)
if (!p->index_data) if (!p->index_data)
return -1; return -1;
err |= verify_packfile(p, &w_curs, fn); err |= verify_packfile(p, &w_curs, fn, progress, base_count);
unuse_pack(&w_curs); unuse_pack(&w_curs);
return err; return err;

3
pack.h
Просмотреть файл

@ -71,12 +71,13 @@ struct pack_idx_entry {
}; };
struct progress;
typedef int (*verify_fn)(const unsigned char*, enum object_type, unsigned long, void*, int*); typedef int (*verify_fn)(const unsigned char*, enum object_type, unsigned long, void*, int*);
extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *, unsigned char *sha1); extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *, unsigned char *sha1);
extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr); extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
extern int verify_pack_index(struct packed_git *); extern int verify_pack_index(struct packed_git *);
extern int verify_pack(struct packed_git *, verify_fn fn); extern int verify_pack(struct packed_git *, verify_fn fn, struct progress *, uint32_t);
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t); extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
extern char *index_pack_lockfile(int fd); extern char *index_pack_lockfile(int fd);
extern int encode_in_pack_object_header(enum object_type, uintmax_t, unsigned char *); extern int encode_in_pack_object_header(enum object_type, uintmax_t, unsigned char *);