Update draft release notes for 1.5.5
[gitweb.git] / builtin-gc.c
index 956c32d1af66444dae26a705159beba9adb7aba7..8cef36f6a4445b163b299f282785f66af9662cb8 100644 (file)
 
 #include "builtin.h"
 #include "cache.h"
+#include "parse-options.h"
 #include "run-command.h"
 
 #define FAILED_RUN "failed to run %s"
 
-static const char builtin_gc_usage[] = "git-gc [--prune] [--aggressive]";
+static const char * const builtin_gc_usage[] = {
+       "git-gc [options]",
+       NULL
+};
 
 static int pack_refs = 1;
 static int aggressive_window = -1;
 static int gc_auto_threshold = 6700;
-static int gc_auto_pack_limit = 20;
+static int gc_auto_pack_limit = 50;
+static char *prune_expire = "2.weeks.ago";
 
 #define MAX_ADD 10
 static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
 static const char *argv_reflog[] = {"reflog", "expire", "--all", NULL};
 static const char *argv_repack[MAX_ADD] = {"repack", "-d", "-l", NULL};
-static const char *argv_prune[] = {"prune", NULL};
+static const char *argv_prune[] = {"prune", "--expire", NULL, NULL};
 static const char *argv_rerere[] = {"rerere", "gc", NULL};
 
 static int gc_config(const char *var, const char *value)
 {
        if (!strcmp(var, "gc.packrefs")) {
-               if (!strcmp(value, "notbare"))
+               if (value && !strcmp(value, "notbare"))
                        pack_refs = -1;
                else
                        pack_refs = git_config_bool(var, value);
@@ -51,6 +56,17 @@ static int gc_config(const char *var, const char *value)
                gc_auto_pack_limit = git_config_int(var, value);
                return 0;
        }
+       if (!strcmp(var, "gc.pruneexpire")) {
+               if (!value)
+                       return config_error_nonbool(var);
+               if (strcmp(value, "now")) {
+                       unsigned long now = approxidate("now");
+                       if (approxidate(value) >= now)
+                               return error("Invalid %s: '%s'", var, value);
+               }
+               prune_expire = xstrdup(value);
+               return 0;
+       }
        return git_default_config(var, value);
 }
 
@@ -144,10 +160,10 @@ static int too_many_packs(void)
 static int need_to_gc(void)
 {
        /*
-        * Setting gc.auto and gc.autopacklimit to 0 or negative can
-        * disable the automatic gc.
+        * Setting gc.auto to 0 or negative can disable the
+        * automatic gc.
         */
-       if (gc_auto_threshold <= 0 && gc_auto_pack_limit <= 0)
+       if (gc_auto_threshold <= 0)
                return 0;
 
        /*
@@ -165,38 +181,38 @@ static int need_to_gc(void)
 
 int cmd_gc(int argc, const char **argv, const char *prefix)
 {
-       int i;
        int prune = 0;
+       int aggressive = 0;
        int auto_gc = 0;
+       int quiet = 0;
        char buf[80];
 
+       struct option builtin_gc_options[] = {
+               OPT_BOOLEAN(0, "prune", &prune, "prune unreferenced objects"),
+               OPT_BOOLEAN(0, "aggressive", &aggressive, "be more thorough (increased runtime)"),
+               OPT_BOOLEAN(0, "auto", &auto_gc, "enable auto-gc mode"),
+               OPT_BOOLEAN('q', "quiet", &quiet, "suppress progress reports"),
+               OPT_END()
+       };
+
        git_config(gc_config);
 
        if (pack_refs < 0)
                pack_refs = !is_bare_repository();
 
-       for (i = 1; i < argc; i++) {
-               const char *arg = argv[i];
-               if (!strcmp(arg, "--prune")) {
-                       prune = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "--aggressive")) {
-                       append_option(argv_repack, "-f", MAX_ADD);
-                       if (aggressive_window > 0) {
-                               sprintf(buf, "--window=%d", aggressive_window);
-                               append_option(argv_repack, buf, MAX_ADD);
-                       }
-                       continue;
-               }
-               if (!strcmp(arg, "--auto")) {
-                       auto_gc = 1;
-                       continue;
+       argc = parse_options(argc, argv, builtin_gc_options, builtin_gc_usage, 0);
+       if (argc > 0)
+               usage_with_options(builtin_gc_usage, builtin_gc_options);
+
+       if (aggressive) {
+               append_option(argv_repack, "-f", MAX_ADD);
+               if (aggressive_window > 0) {
+                       sprintf(buf, "--window=%d", aggressive_window);
+                       append_option(argv_repack, buf, MAX_ADD);
                }
-               break;
        }
-       if (i != argc)
-               usage(builtin_gc_usage);
+       if (quiet)
+               append_option(argv_repack, "-q", MAX_ADD);
 
        if (auto_gc) {
                /*
@@ -205,6 +221,10 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                prune = 0;
                if (!need_to_gc())
                        return 0;
+               fprintf(stderr, "Auto packing your repository for optimum "
+                       "performance. You may also\n"
+                       "run \"git gc\" manually. See "
+                       "\"git help gc\" for more information.\n");
        } else {
                /*
                 * Use safer (for shared repos) "-A" option to
@@ -226,7 +246,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
        if (run_command_v_opt(argv_repack, RUN_GIT_CMD))
                return error(FAILED_RUN, argv_repack[0]);
 
-       if (prune && run_command_v_opt(argv_prune, RUN_GIT_CMD))
+       argv_prune[2] = prune_expire;
+       if (run_command_v_opt(argv_prune, RUN_GIT_CMD))
                return error(FAILED_RUN, argv_prune[0]);
 
        if (run_command_v_opt(argv_rerere, RUN_GIT_CMD))