Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 1e49f22

Browse files
pcloudsgitster
authored andcommitted
fsck: print progress
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c9486eb commit 1e49f22

File tree

4 files changed

+61
-7
lines changed

4 files changed

+61
-7
lines changed

Documentation/git-fsck.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ SYNOPSIS
1010
--------
1111
[verse]
1212
'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
13-
[--[no-]full] [--strict] [--verbose] [--lost-found] [<object>*]
13+
[--[no-]full] [--strict] [--verbose] [--lost-found]
14+
[--[no-]progress] [<object>*]
1415

1516
DESCRIPTION
1617
-----------
@@ -72,6 +73,14 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
7273
a blob, the contents are written into the file, rather than
7374
its object name.
7475

76+
--progress::
77+
--no-progress::
78+
Progress status is reported on the standard error stream by
79+
default when it is attached to a terminal, unless
80+
--no-progress or --verbose is specified. --progress forces
81+
progress status even if the standard error stream is not
82+
directed to a terminal.
83+
7584
It tests SHA1 and general object sanity, and it does full tracking of
7685
the resulting reachability and everything else. It prints out any
7786
corruption it finds (missing or bad objects), and if you use the

builtin/fsck.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "fsck.h"
1212
#include "parse-options.h"
1313
#include "dir.h"
14+
#include "progress.h"
1415

1516
#define REACHABLE 0x0001
1617
#define SEEN 0x0002
@@ -27,6 +28,7 @@ static const char *head_points_at;
2728
static int errors_found;
2829
static int write_lost_and_found;
2930
static int verbose;
31+
static int show_progress = -1;
3032
#define ERROR_OBJECT 01
3133
#define ERROR_REACHABLE 02
3234
#define ERROR_PACK 04
@@ -138,15 +140,21 @@ static int traverse_one_object(struct object *obj)
138140

139141
static int traverse_reachable(void)
140142
{
143+
struct progress *progress = NULL;
144+
unsigned int nr = 0;
141145
int result = 0;
146+
if (show_progress)
147+
progress = start_progress_delay("Checking connectivity", 0, 0, 2);
142148
while (pending.nr) {
143149
struct object_array_entry *entry;
144150
struct object *obj;
145151

146152
entry = pending.objects + --pending.nr;
147153
obj = entry->item;
148154
result |= traverse_one_object(obj);
155+
display_progress(progress, ++nr);
149156
}
157+
stop_progress(&progress);
150158
return !!result;
151159
}
152160

@@ -530,15 +538,20 @@ static void get_default_heads(void)
530538
static void fsck_object_dir(const char *path)
531539
{
532540
int i;
541+
struct progress *progress = NULL;
533542

534543
if (verbose)
535544
fprintf(stderr, "Checking object directory\n");
536545

546+
if (show_progress)
547+
progress = start_progress("Checking object directories", 256);
537548
for (i = 0; i < 256; i++) {
538549
static char dir[4096];
539550
sprintf(dir, "%s/%02x", path, i);
540551
fsck_dir(i, dir);
552+
display_progress(progress, i+1);
541553
}
554+
stop_progress(&progress);
542555
fsck_sha1_list();
543556
}
544557

@@ -609,6 +622,7 @@ static struct option fsck_opts[] = {
609622
OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"),
610623
OPT_BOOLEAN(0, "lost-found", &write_lost_and_found,
611624
"write dangling objects in .git/lost-found"),
625+
OPT_BOOL(0, "progress", &show_progress, "show progress"),
612626
OPT_END(),
613627
};
614628

@@ -621,6 +635,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
621635
read_replace_refs = 0;
622636

623637
argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
638+
639+
if (show_progress == -1)
640+
show_progress = isatty(2);
641+
if (verbose)
642+
show_progress = 0;
643+
624644
if (write_lost_and_found) {
625645
check_full = 1;
626646
include_reflogs = 0;
@@ -640,12 +660,28 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
640660

641661
if (check_full) {
642662
struct packed_git *p;
663+
uint32_t total = 0, count = 0;
664+
struct progress *progress = NULL;
643665

644666
prepare_packed_git();
645-
for (p = packed_git; p; p = p->next)
667+
668+
if (show_progress) {
669+
for (p = packed_git; p; p = p->next) {
670+
if (open_pack_index(p))
671+
continue;
672+
total += p->num_objects;
673+
}
674+
675+
progress = start_progress("Checking objects", total);
676+
}
677+
for (p = packed_git; p; p = p->next) {
646678
/* verify gives error messages itself */
647-
if (verify_pack(p, fsck_obj_buffer))
679+
if (verify_pack(p, fsck_obj_buffer,
680+
progress, count))
648681
errors_found |= ERROR_PACK;
682+
count += p->num_objects;
683+
}
684+
stop_progress(&progress);
649685
}
650686

651687
heads = 0;

pack-check.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "cache.h"
22
#include "pack.h"
33
#include "pack-revindex.h"
4+
#include "progress.h"
45

56
struct idx_entry {
67
off_t offset;
@@ -43,7 +44,9 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
4344

4445
static int verify_packfile(struct packed_git *p,
4546
struct pack_window **w_curs,
46-
verify_fn fn)
47+
verify_fn fn,
48+
struct progress *progress, uint32_t base_count)
49+
4750
{
4851
off_t index_size = p->index_size;
4952
const unsigned char *index_base = p->index_data;
@@ -127,8 +130,12 @@ static int verify_packfile(struct packed_git *p,
127130
if (eaten)
128131
data = NULL;
129132
}
133+
if (((base_count + i) & 1023) == 0)
134+
display_progress(progress, base_count + i);
130135
free(data);
136+
131137
}
138+
display_progress(progress, base_count + i);
132139
free(entries);
133140

134141
return err;
@@ -157,7 +164,8 @@ int verify_pack_index(struct packed_git *p)
157164
return err;
158165
}
159166

160-
int verify_pack(struct packed_git *p, verify_fn fn)
167+
int verify_pack(struct packed_git *p, verify_fn fn,
168+
struct progress *progress, uint32_t base_count)
161169
{
162170
int err = 0;
163171
struct pack_window *w_curs = NULL;
@@ -166,7 +174,7 @@ int verify_pack(struct packed_git *p, verify_fn fn)
166174
if (!p->index_data)
167175
return -1;
168176

169-
err |= verify_packfile(p, &w_curs, fn);
177+
err |= verify_packfile(p, &w_curs, fn, progress, base_count);
170178
unuse_pack(&w_curs);
171179

172180
return err;

pack.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,13 @@ struct pack_idx_entry {
7171
};
7272

7373

74+
struct progress;
7475
typedef int (*verify_fn)(const unsigned char*, enum object_type, unsigned long, void*, int*);
7576

7677
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);
7778
extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
7879
extern int verify_pack_index(struct packed_git *);
79-
extern int verify_pack(struct packed_git *, verify_fn fn);
80+
extern int verify_pack(struct packed_git *, verify_fn fn, struct progress *, uint32_t);
8081
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
8182
extern char *index_pack_lockfile(int fd);
8283
extern int encode_in_pack_object_header(enum object_type, uintmax_t, unsigned char *);

0 commit comments

Comments
 (0)