Merge branch 'nd/daemonize-gc'
authorJunio C Hamano <gitster@pobox.com>
Wed, 5 Mar 2014 23:06:38 +0000 (15:06 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 5 Mar 2014 23:06:39 +0000 (15:06 -0800)
Allow running "gc --auto" in the background.

* nd/daemonize-gc:
gc: config option for running --auto in background
daemon: move daemonize() to libgit.a

Documentation/config.txt
builtin/gc.c
cache.h
daemon.c
setup.c
t/t5400-send-pack.sh
index 040197b10ea5a46e6ba643b28de17d2100cb129b..02776e51c8c1abfc151d245259f61546e4ff598c 100644 (file)
@@ -1175,6 +1175,10 @@ gc.autopacklimit::
        --auto` consolidates them into one larger pack.  The
        default value is 50.  Setting this to 0 disables it.
 
+gc.autodetach::
+       Make `git gc --auto` return immediately andrun in background
+       if the system supports it. Default is true.
+
 gc.packrefs::
        Running `git pack-refs` in a repository renders it
        unclonable by Git versions prior to 1.5.1.2 over dumb
index 5bbb5e3cc6e3c75ad41a0a92594006a659459634..63d400bcb2092b1751427994b35057f72b04de17 100644 (file)
@@ -29,6 +29,7 @@ static int pack_refs = 1;
 static int aggressive_window = 250;
 static int gc_auto_threshold = 6700;
 static int gc_auto_pack_limit = 50;
+static int detach_auto = 1;
 static const char *prune_expire = "2.weeks.ago";
 
 static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT;
@@ -73,6 +74,10 @@ static int gc_config(const char *var, const char *value, void *cb)
                gc_auto_pack_limit = git_config_int(var, value);
                return 0;
        }
+       if (!strcmp(var, "gc.autodetach")) {
+               detach_auto = git_config_bool(var, value);
+               return 0;
+       }
        if (!strcmp(var, "gc.pruneexpire")) {
                if (value && strcmp(value, "now")) {
                        unsigned long now = approxidate("now");
@@ -302,11 +307,19 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                 */
                if (!need_to_gc())
                        return 0;
-               if (!quiet)
-                       fprintf(stderr,
-                                       _("Auto packing the repository for optimum performance. You may also\n"
-                                       "run \"git gc\" manually. See "
-                                       "\"git help gc\" for more information.\n"));
+               if (!quiet) {
+                       if (detach_auto)
+                               fprintf(stderr, _("Auto packing the repository in background for optimum performance.\n"));
+                       else
+                               fprintf(stderr, _("Auto packing the repository for optimum performance.\n"));
+                       fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
+               }
+               if (detach_auto)
+                       /*
+                        * failure to daemonize is ok, we'll continue
+                        * in foreground
+                        */
+                       daemonize();
        } else
                add_repack_all_option();
 
diff --git a/cache.h b/cache.h
index db223e8048a50d9f37d523226dfdda05a4f5dd8e..b7d82e5d52bb09aed15e43d34e89871e3735df5c 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -433,6 +433,7 @@ extern int set_git_dir_init(const char *git_dir, const char *real_git_dir, int);
 extern int init_db(const char *template_dir, unsigned int flags);
 
 extern void sanitize_stdfds(void);
+extern int daemonize(void);
 
 #define alloc_nr(x) (((x)+16)*3/2)
 
index 503e03906c5c7f921e4d67a53835f771ea695d0c..eba12556848e975cd6f1a55ae25760823e90cdc8 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -1056,11 +1056,6 @@ static void drop_privileges(struct credentials *cred)
        /* nothing */
 }
 
-static void daemonize(void)
-{
-       die("--detach not supported on this platform");
-}
-
 static struct credentials *prepare_credentials(const char *user_name,
     const char *group_name)
 {
@@ -1102,24 +1097,6 @@ static struct credentials *prepare_credentials(const char *user_name,
 
        return &c;
 }
-
-static void daemonize(void)
-{
-       switch (fork()) {
-               case 0:
-                       break;
-               case -1:
-                       die_errno("fork failed");
-               default:
-                       exit(0);
-       }
-       if (setsid() == -1)
-               die_errno("setsid failed");
-       close(0);
-       close(1);
-       close(2);
-       sanitize_stdfds();
-}
 #endif
 
 static void store_pid(const char *path)
@@ -1333,9 +1310,10 @@ int main(int argc, char **argv)
        if (inetd_mode || serve_mode)
                return execute();
 
-       if (detach)
-               daemonize();
-       else
+       if (detach) {
+               if (daemonize())
+                       die("--detach not supported on this platform");
+       } else
                sanitize_stdfds();
 
        if (pid_file)
diff --git a/setup.c b/setup.c
index cffb6d605e7893a3f9ff83f427732f6b7f3443ff..613e3b3c13b3f09bce07c54dc440d03c0b5beb0c 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -841,3 +841,27 @@ void sanitize_stdfds(void)
        if (fd > 2)
                close(fd);
 }
+
+int daemonize(void)
+{
+#ifdef NO_POSIX_GOODIES
+       errno = ENOSYS;
+       return -1;
+#else
+       switch (fork()) {
+               case 0:
+                       break;
+               case -1:
+                       die_errno("fork failed");
+               default:
+                       exit(0);
+       }
+       if (setsid() == -1)
+               die_errno("setsid failed");
+       close(0);
+       close(1);
+       close(2);
+       sanitize_stdfds();
+       return 0;
+#endif
+}
index 129fc88bd28e8ea85e81310aec860df808949447..0736bcbcd52a76ef3400c046e7d3558dd1a866c7 100755 (executable)
@@ -164,6 +164,7 @@ test_expect_success 'receive-pack runs auto-gc in remote repo' '
            # Set the child to auto-pack if more than one pack exists
            cd child &&
            git config gc.autopacklimit 1 &&
+           git config gc.autodetach false &&
            git branch test_auto_gc &&
            # And create a file that follows the temporary object naming
            # convention for the auto-gc to remove