4 #include "parse-options.h"
6 static const char * const prune_packed_usage
[] = {
7 N_("git prune-packed [-n|--dry-run] [-q|--quiet]"),
11 static struct progress
*progress
;
13 static void prune_dir(int i
, DIR *dir
, struct strbuf
*pathname
, int opts
)
17 int top_len
= pathname
->len
;
19 sprintf(hex
, "%02x", i
);
20 while ((de
= readdir(dir
)) != NULL
) {
21 unsigned char sha1
[20];
22 if (strlen(de
->d_name
) != 38)
24 memcpy(hex
+ 2, de
->d_name
, 38);
25 if (get_sha1_hex(hex
, sha1
))
27 if (!has_sha1_pack(sha1
))
30 strbuf_add(pathname
, de
->d_name
, 38);
31 if (opts
& PRUNE_PACKED_DRY_RUN
)
32 printf("rm -f %s\n", pathname
->buf
);
34 unlink_or_warn(pathname
->buf
);
35 display_progress(progress
, i
+ 1);
36 strbuf_setlen(pathname
, top_len
);
40 void prune_packed_objects(int opts
)
43 const char *dir
= get_object_directory();
44 struct strbuf pathname
= STRBUF_INIT
;
47 strbuf_addstr(&pathname
, dir
);
48 if (opts
& PRUNE_PACKED_VERBOSE
)
49 progress
= start_progress_delay(_("Removing duplicate objects"),
52 if (pathname
.len
&& pathname
.buf
[pathname
.len
- 1] != '/')
53 strbuf_addch(&pathname
, '/');
55 top_len
= pathname
.len
;
56 for (i
= 0; i
< 256; i
++) {
59 display_progress(progress
, i
+ 1);
60 strbuf_setlen(&pathname
, top_len
);
61 strbuf_addf(&pathname
, "%02x/", i
);
62 d
= opendir(pathname
.buf
);
65 prune_dir(i
, d
, &pathname
, opts
);
67 strbuf_setlen(&pathname
, top_len
+ 2);
70 stop_progress(&progress
);
73 int cmd_prune_packed(int argc
, const char **argv
, const char *prefix
)
75 int opts
= isatty(2) ? PRUNE_PACKED_VERBOSE
: 0;
76 const struct option prune_packed_options
[] = {
77 OPT_BIT('n', "dry-run", &opts
, N_("dry run"),
78 PRUNE_PACKED_DRY_RUN
),
79 OPT_NEGBIT('q', "quiet", &opts
, N_("be quiet"),
80 PRUNE_PACKED_VERBOSE
),
84 argc
= parse_options(argc
, argv
, prefix
, prune_packed_options
,
85 prune_packed_usage
, 0);
87 prune_packed_objects(opts
);