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 <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Nov 7, 2011 at 09:59 UTC
1e49f22f07881dffc04f8f09d4ad4e4a65b85b09
4 files changed
+61
-7
Documentation/git-fsck.txt
+10
-1
@@ -10,7 +10,8 @@ SYNOPSIS
10
--------
11
[verse]
12
'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>*]
15
16
DESCRIPTION
17
-----------
@@ -72,6 +73,14 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
73
a blob, the contents are written into the file, rather than
74
its object name.
75
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
+
84
It tests SHA1 and general object sanity, and it does full tracking of
85
the resulting reachability and everything else. It prints out any
86
corruption it finds (missing or bad objects), and if you use the
builtin/fsck.c
+38
-2
@@ -11,6 +11,7 @@
11
#include "fsck.h"
12
#include "parse-options.h"
13
#include "dir.h"
14
+#include "progress.h"
15
16
#define REACHABLE 0x0001
17
#define SEEN 0x0002
@@ -27,6 +28,7 @@ static const char *head_points_at;
28
static int errors_found;
29
static int write_lost_and_found;
30
static int verbose;
31
+static int show_progress = -1;
32
#define ERROR_OBJECT 01
33
#define ERROR_REACHABLE 02
34
#define ERROR_PACK 04
@@ -138,7 +140,11 @@ static int traverse_one_object(struct object *obj)
140
141
static int traverse_reachable(void)
142
{
143
+ struct progress *progress = NULL;
144
+ unsigned int nr = 0;
145
int result = 0;
146
+ if (show_progress)
147
+ progress = start_progress_delay("Checking connectivity", 0, 0, 2);
148
while (pending.nr) {
149
struct object_array_entry *entry;
150
struct object *obj;
@@ -146,7 +152,9 @@ static int traverse_reachable(void)
152
entry = pending.objects + --pending.nr;
153
obj = entry->item;
154
result |= traverse_one_object(obj);
155
+ display_progress(progress, ++nr);
156
}
157
+ stop_progress(&progress);
158
return !!result;
159
}
160
@@ -530,15 +538,20 @@ static void get_default_heads(void)
538
static void fsck_object_dir(const char *path)
539
{
540
int i;
541
+ struct progress *progress = NULL;
542
543
if (verbose)
544
fprintf(stderr, "Checking object directory\n");
545
546
+ if (show_progress)
547
+ progress = start_progress("Checking object directories", 256);
548
for (i = 0; i < 256; i++) {
549
static char dir[4096];
550
sprintf(dir, "%s/%02x", path, i);
551
fsck_dir(i, dir);
552
+ display_progress(progress, i+1);
553
}
554
+ stop_progress(&progress);
555
fsck_sha1_list();
556
}
557
@@ -609,6 +622,7 @@ static struct option fsck_opts[] = {
622
OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"),
623
OPT_BOOLEAN(0, "lost-found", &write_lost_and_found,
624
"write dangling objects in .git/lost-found"),
625
+ OPT_BOOL(0, "progress", &show_progress, "show progress"),
626
OPT_END(),
627
};
628
@@ -621,6 +635,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
635
read_replace_refs = 0;
636
637
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
+
644
if (write_lost_and_found) {
645
check_full = 1;
646
include_reflogs = 0;
@@ -640,12 +660,28 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
660
661
if (check_full) {
662
struct packed_git *p;
663
+ uint32_t total = 0, count = 0;
664
+ struct progress *progress = NULL;
665
666
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) {
678
/* verify gives error messages itself */
647
- if (verify_pack(p, fsck_obj_buffer))
679
+ if (verify_pack(p, fsck_obj_buffer,
680
+ progress, count))
681
errors_found |= ERROR_PACK;
682
+ count += p->num_objects;
683
+ }
684
+ stop_progress(&progress);
685
}
686
687
heads = 0;
pack-check.c
+11
-3
@@ -1,6 +1,7 @@
1
#include "cache.h"
2
#include "pack.h"
3
#include "pack-revindex.h"
4
+#include "progress.h"
5
6
struct idx_entry {
7
off_t offset;
@@ -43,7 +44,9 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
44
45
static int verify_packfile(struct packed_git *p,
46
struct pack_window **w_curs,
46
- verify_fn fn)
47
+ verify_fn fn,
48
+ struct progress *progress, uint32_t base_count)
49
+
50
{
51
off_t index_size = p->index_size;
52
const unsigned char *index_base = p->index_data;
@@ -127,8 +130,12 @@ static int verify_packfile(struct packed_git *p,
130
if (eaten)
131
data = NULL;
132
}
133
+ if (((base_count + i) & 1023) == 0)
134
+ display_progress(progress, base_count + i);
135
free(data);
136
+
137
}
138
+ display_progress(progress, base_count + i);
139
free(entries);
140
141
return err;
@@ -157,7 +164,8 @@ int verify_pack_index(struct packed_git *p)
164
return err;
165
}
166
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)
169
{
170
int err = 0;
171
struct pack_window *w_curs = NULL;
@@ -166,7 +174,7 @@ int verify_pack(struct packed_git *p, verify_fn fn)
174
if (!p->index_data)
175
return -1;
176
169
- err |= verify_packfile(p, &w_curs, fn);
177
+ err |= verify_packfile(p, &w_curs, fn, progress, base_count);
178
unuse_pack(&w_curs);
179
180
return err;
pack.h
+2
-1
@@ -71,12 +71,13 @@ struct pack_idx_entry {
71
};
72
73
74
+struct progress;
75
typedef int (*verify_fn)(const unsigned char*, enum object_type, unsigned long, void*, int*);
76
77
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);
78
extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
79
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);
81
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
82
extern char *index_pack_lockfile(int fd);
83
extern int encode_in_pack_object_header(enum object_type, uintmax_t, unsigned char *);