rerere: make sorting really stable.
[git] / builtin-gc.c
1 /*
2  * git gc builtin command
3  *
4  * Cleanup unreachable files and optimize the repository.
5  *
6  * Copyright (c) 2007 James Bowes
7  *
8  * Based on git-gc.sh, which is
9  *
10  * Copyright (c) 2006 Shawn O. Pearce
11  */
12
13 #include "cache.h"
14 #include "run-command.h"
15
16 #define FAILED_RUN "failed to run %s"
17
18 static const char builtin_gc_usage[] = "git-gc [--prune]";
19
20 static int pack_refs = -1;
21
22 static const char *argv_pack_refs[] = {"pack-refs", "--prune", NULL};
23 static const char *argv_reflog[] = {"reflog", "expire", "--all", NULL};
24 static const char *argv_repack[] = {"repack", "-a", "-d", "-l", NULL};
25 static const char *argv_prune[] = {"prune", NULL};
26 static const char *argv_rerere[] = {"rerere", "gc", NULL};
27
28 static int gc_config(const char *var, const char *value)
29 {
30         if (!strcmp(var, "gc.packrefs")) {
31                 if (!strcmp(value, "notbare"))
32                         pack_refs = -1;
33                 else
34                         pack_refs = git_config_bool(var, value);
35                 return 0;
36         }
37         return git_default_config(var, value);
38 }
39
40 int cmd_gc(int argc, const char **argv, const char *prefix)
41 {
42         int i;
43         int prune = 0;
44
45         git_config(gc_config);
46
47         if (pack_refs < 0)
48                 pack_refs = !is_bare_repository();
49
50         for (i = 1; i < argc; i++) {
51                 const char *arg = argv[i];
52                 if (!strcmp(arg, "--prune")) {
53                         prune = 1;
54                         continue;
55                 }
56                 /* perhaps other parameters later... */
57                 break;
58         }
59         if (i != argc)
60                 usage(builtin_gc_usage);
61
62         if (pack_refs && run_command_v_opt(argv_pack_refs, RUN_GIT_CMD))
63                 return error(FAILED_RUN, argv_pack_refs[0]);
64
65         if (run_command_v_opt(argv_reflog, RUN_GIT_CMD))
66                 return error(FAILED_RUN, argv_reflog[0]);
67
68         if (run_command_v_opt(argv_repack, RUN_GIT_CMD))
69                 return error(FAILED_RUN, argv_repack[0]);
70
71         if (prune && run_command_v_opt(argv_prune, RUN_GIT_CMD))
72                 return error(FAILED_RUN, argv_prune[0]);
73
74         if (run_command_v_opt(argv_rerere, RUN_GIT_CMD))
75                 return error(FAILED_RUN, argv_rerere[0]);
76
77         return 0;
78 }