Teach git diff about Objective-C syntax
[gitweb.git] / builtin-gc.c
index ad4a75eedddb1dfc0ecef2b536727970335673f9..7af65bb31bfbf3e9a0e47901d44168389d736d20 100644 (file)
 #define FAILED_RUN "failed to run %s"
 
 static const char * const builtin_gc_usage[] = {
-       "git-gc [options]",
+       "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 const 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)
+static int gc_config(const char *var, const char *value, void *cb)
 {
        if (!strcmp(var, "gc.packrefs")) {
                if (value && !strcmp(value, "notbare"))
@@ -55,7 +56,15 @@ static int gc_config(const char *var, const char *value)
                gc_auto_pack_limit = git_config_int(var, value);
                return 0;
        }
-       return git_default_config(var, value);
+       if (!strcmp(var, "gc.pruneexpire")) {
+               if (value && strcmp(value, "now")) {
+                       unsigned long now = approxidate("now");
+                       if (approxidate(value) >= now)
+                               return error("Invalid %s: '%s'", var, value);
+               }
+               return git_config_string(&prune_expire, var, value);
+       }
+       return git_default_config(var, value, cb);
 }
 
 static void append_option(const char **cmd, const char *opt, int max_length)
@@ -145,13 +154,41 @@ static int too_many_packs(void)
        return gc_auto_pack_limit <= cnt;
 }
 
+static int run_hook(void)
+{
+       const char *argv[2];
+       struct child_process hook;
+       int ret;
+
+       argv[0] = git_path("hooks/pre-auto-gc");
+       argv[1] = NULL;
+
+       if (access(argv[0], X_OK) < 0)
+               return 0;
+
+       memset(&hook, 0, sizeof(hook));
+       hook.argv = argv;
+       hook.no_stdin = 1;
+       hook.stdout_to_stderr = 1;
+
+       ret = start_command(&hook);
+       if (ret) {
+               warning("Could not spawn %s", argv[0]);
+               return ret;
+       }
+       ret = finish_command(&hook);
+       if (ret == -ERR_RUN_COMMAND_WAITPID_SIGNAL)
+               warning("%s exited due to uncaught signal", argv[0]);
+       return ret;
+}
+
 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;
 
        /*
@@ -164,6 +201,9 @@ static int need_to_gc(void)
                append_option(argv_repack, "-A", MAX_ADD);
        else if (!too_many_loose_objects())
                return 0;
+
+       if (run_hook())
+               return 0;
        return 1;
 }
 
@@ -172,16 +212,18 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
        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, "prune", &prune, "prune unreferenced objects (deprecated)"),
                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);
+       git_config(gc_config, NULL);
 
        if (pack_refs < 0)
                pack_refs = !is_bare_repository();
@@ -197,29 +239,21 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                        append_option(argv_repack, buf, MAX_ADD);
                }
        }
+       if (quiet)
+               append_option(argv_repack, "-q", MAX_ADD);
 
        if (auto_gc) {
                /*
                 * Auto-gc should be least intrusive as possible.
                 */
-               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
-                * repack when not pruning. Auto-gc makes its
-                * own decision.
-                */
-               if (prune)
-                       append_option(argv_repack, "-a", MAX_ADD);
-               else
-                       append_option(argv_repack, "-A", MAX_ADD);
-       }
+       } else
+               append_option(argv_repack, "-A", MAX_ADD);
 
        if (pack_refs && run_command_v_opt(argv_pack_refs, RUN_GIT_CMD))
                return error(FAILED_RUN, argv_pack_refs[0]);
@@ -230,7 +264,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))