git gc and kernel.org
We have run into two major problems with git on kernel.org. We have discussed workarounds, but I believe they are generally major problems which will affect other sites, and really need to be fixed upstream.
1) git receive-pack doesn't run git gc --auto.
This cause repositories which people thought were being autopacked to not be so. This can be done via a hook, but that is way too painful for people to do -- in fact, it's hard enough just to get people to enable the post-update hook for http fetching.
1b) as per the above, a way to make "git update-server-info" at post-update time a configurable option rather than needing to be done via the hook would be very nice, since a configuration option can be enabled sitewide.
2) When pushing to a repository, it apparently doesn't honor new objects in alternate repositories. This causes massive unnecessary duplication.
I believe these are major issues that need to be addressed. If we are *mistaken* on these, then we would appreciate being corrected.
Thanks,
-hpa
2009/10/20 H. Peter Anvin <[email protected]>:
Quoted 15 lines
We have run into two major problems with git on kernel.org. We have discussed workarounds, but I believe they are generally major problems which will affect other sites, and really need to be fixed upstream.
1) git receive-pack doesn't run git gc --auto.
This cause repositories which people thought were being autopacked to not be so. This can be done via a hook, but that is way too painful for people to do -- in fact, it's hard enough just to get people to enable the post-update hook for http fetching.
1b) as per the above, a way to make "git update-server-info" at post-update time a configurable option rather than needing to be done via the hook would be very nice, since a configuration option can be enabled sitewide.
Quoted 5 lines
2) When pushing to a repository, it apparently doesn't honor new objects in alternate repositories. This causes massive unnecessary duplication.
I believe these are major issues that need to be addressed. If we are *mistaken* on these, then we would appreciate being corrected.
I don't know how you create repos on kernel.org, but by default both git init and git clone uses /usr/share/git-core/templates for the new repo, for example I put a symbolic ref h -> HEAD there to save some typing. You can enable whatever hooks you want there, but they would only take effect for new repos.
Signature · 1 line
Mikael Magnusson
Quoted 7 lines · Mikael Magnusson
I don't know how you create repos on kernel.org, but by default both git init and git clone uses
/usr/share/git-core/templatesfor the new repo, for example I put a symbolic ref h -> HEAD there to save some typing. You can enable whatever hooks you want there, but they would only take effect for new repos.
They only take effect for new repos, and any changes I do there get messed up when git is updated.
-hpa
Quoted 16 lines · H. Peter Anvin
We have run into two major problems with git on kernel.org. We have discussed workarounds, but I believe they are generally major problems which will affect other sites, and really need to be fixed upstream.
1) git receive-pack doesn't run git gc --auto.
This cause repositories which people thought were being autopacked to not be so. This can be done via a hook, but that is way too painful for people to do -- in fact, it's hard enough just to get people to enable the post-update hook for http fetching.
1b) as per the above, a way to make "git update-server-info" at post-update time a configurable option rather than needing to be done via the hook would be very nice, since a configuration option can be enabled sitewide.
Quoted 6 lines
2) When pushing to a repository, it apparently doesn't honor new objects in alternate repositories. This causes massive unnecessary duplication.
I believe these are major issues that need to be addressed. If we are *mistaken* on these, then we would appreciate being corrected.
I actually was wondering if (2) is still true after reading the message from Wilcox. It should be a simple matter of testing, but I think this issue was improved around the end of January this year with v1.6.1.2.
As to (1), I think it is reasonable to do some sort of "gc" in receive-pack, and while I recall that Linus was violently against the idea, I personally think it is reasonable to run update-server-info ourselves at the same time without needing the hook, even if the repository is never going to be served over dumb http [*1*]. At one point, update-server-info used to compute a lot more than what we currently compute and it made some sense to oppose against it on performance ground.
But these days it only lists the refs and packs and does nothing else; the performance impact should be immeasurable and it adds only two files to the repository. It cannot be a big deal, unless you oppose to http transport on a non-technical ground.
Quoted 8 lines · Junio C Hamano
At one point, update-server-info used to compute a lot more than what we currently compute and it made some sense to oppose against it on performance ground.
But these days it only lists the refs and packs and does nothing else; the performance impact should be immeasurable and it adds only two files to the repository. It cannot be a big deal, unless you oppose to http transport on a non-technical ground.
FYI, update-server-info takes ~0.7 seconds in a repo with one pack and ~50000 refs, so I guess it's acceptable to enable it by default, even in those kinds of repos.
...Johan
Signature · 2 lines
Johan Herland, <[email protected]> www.herland.net
Quoted 5 lines · Johan Herland
Quoted 4 lines · Junio C Hamano
At one point, update-server-info used to compute a lot more than what we currently compute and it made some sense to oppose against it on performance ground.
Quoted 8 lines
Quoted 4 lines
But these days it only lists the refs and packs and does nothing else; the performance impact should be immeasurable and it adds only two files to the repository. It cannot be a big deal, unless you oppose to http transport on a non-technical ground.
FYI, update-server-info takes ~0.7 seconds in a repo with one pack and ~50000 refs, so I guess it's acceptable to enable it by default, even in those kinds of repos.
Still... Hopefully this is going to become redundant information in the future with the eventual deployment of smart protocol over HTTP. So I think that as a config option being off by default this is a good compromize. Site administrators can turn it on by default in /etc/gitconfig.
Nicolas
Quoted 5 lines · Nicolas Pitre
Still... Hopefully this is going to become redundant information in the future with the eventual deployment of smart protocol over HTTP. So I think that as a config option being off by default this is a good compromize. Site administrators can turn it on by default in
/etc/gitconfig.
Ok, something like this?
Documentation/config.txt | 8 ++++++++ builtin-receive-pack.c | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 0 deletions(-)
Documentation/config.txt +8 -0
@@ -1320,6 +1320,10 @@ rebase.stat:: Whether to show a diffstat of what changed upstream since the last rebase. False by default. +receive.autogc:: + If set to true, git-receive-pack will run "git-gc --auto" + after receiving data from git-push and updating refs. + receive.fsckObjects:: If it is set to true, git-receive-pack will check all received objects. It will abort in the case of a malformed object or a
@@ -1355,6 +1359,10 @@ receive.denyNonFastForwards:: even if that push is forced. This configuration variable is set when initializing a shared repository. +receive.updateserverinfo:: + If set to true, git-receive-pack will run git-update-server-info + after receiving data from git-push and updating refs. + remote.<name>.url:: The URL of a remote repository. See linkgit:git-fetch[1] or linkgit:git-push[1].
builtin-receive-pack.c +18 -0
@@ -28,6 +28,8 @@ static int transfer_unpack_limit = -1;static int unpack_limit =100 ;static int report_status;static int prefer_ofs_delta =1 ; +static int auto_update_server_info; +static int auto_gc;static const char *head_name;static char *capabilities_to_send;
@@ -88,6 +90,16 @@ static int receive_pack_config(const char *var, const char *value, void *cb)return 0 ; } +if (strcmp (var,"receive.updateserverinfo" ) ==0 ) { + auto_update_server_info =git_config_bool (var, value); +return 0 ; + } + +if (strcmp (var,"receive.autogc" ) ==0 ) { + auto_gc =git_config_bool (var, value); +return 0 ; + } +return git_default_config (var, value, cb); }
@@ -672,6 +684,12 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)report (unpack_status);run_receive_hook (post_receive_hook);run_update_post_hook (commands); +if (auto_update_server_info) +update_server_info (0 ); +if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD ); + } }return 0 ; }
builtin-receive-pack.c int cmd_receive_pack(int argc, const char **argv, const char *prefix) · line 691
Quoted 3 lines · Junio C Hamano
builtin-receive-pack.c +3
-0+if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD );
Am I correct that this will produce progress output? If git-daemon runs receive-pack, then this output will go to the syslog. Do we care?
-- Hannes
Quoted 7 lines · Johannes Sixt
builtin-receive-pack.c int cmd_receive_pack(int argc, const char **argv, const char *prefix) · line 691
Quoted 3 lines · Junio C Hamano
builtin-receive-pack.c +3
-0+if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD );Am I correct that this will produce progress output? If git-daemon runs receive-pack, then this output will go to the syslog. Do we care?
We do, and we don't want that. Thanks for spotting.
Would adding "--quiet" to the mix be enough?
Quoted 10 lines · Junio C Hamano
Quoted 7 lines · Johannes Sixt
builtin-receive-pack.c int cmd_receive_pack(int argc, const char **argv, const char *prefix) · line 691
Quoted 3 lines · Junio C Hamano
builtin-receive-pack.c +3
-0+if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD );Am I correct that this will produce progress output? If git-daemon runs receive-pack, then this output will go to the syslog. Do we care?
Quoted 3 lines
We do, and we don't want that. Thanks for spotting.
Would adding "--quiet" to the mix be enough?
Actually I don't know. This originally came from "we _could_ add gc and update-server-info to hundreds of post-receive hooks, but any repository hosting site that holds many central repositories will exactly have the same issue, so why not do this internally", so it may make sense to do exactly the same thing as what we do to the output from hooks. What do we do to them now? stdout-to-stderr?
Quoted 12 lines · Junio C Hamano
Quoted 10 lines · Junio C Hamano
Quoted 6 lines · Johannes Sixt
builtin-receive-pack.c int cmd_receive_pack(int argc, const char **argv, const char *prefix) · line 691
Quoted 3 lines · Junio C Hamano
builtin-receive-pack.c +3
-0+if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD );Am I correct that this will produce progress output? If git-daemon runs receive-pack, then this output will go to the syslog. Do we care?
We do, and we don't want that. Thanks for spotting.
Quoted 8 lines
Quoted 1 line
Would adding "--quiet" to the mix be enough?
Actually I don't know. This originally came from "we _could_ add gc and update-server-info to hundreds of post-receive hooks, but any repository hosting site that holds many central repositories will exactly have the same issue, so why not do this internally", so it may make sense to do exactly the same thing as what we do to the output from hooks. What do we do to them now? stdout-to-stderr?
Yes.
I'm slightly in favor of adding "--quiet", because even with this option we see some output:
$ git gc --auto --quiet Auto packing your repository for optimum performance. You may also run "git gc" manually. See "git help gc" for more information.
A compromise would be to reduce this message to the first sentence if --quiet was given. This way users who push via ssh or locally get a short explanation why "git push" does not finish immediately[*]; and git-daemon logs only a one-liner in the syslog, which might be useful, too.
[*] Skipping the hint to "run git gc manually" would even be good in this case, because the hint pertains the remote repository, not the one from which "git push" was issued.
-- Hannes
Quoted 7 lines · Johannes Sixt
$ git gc --auto --quiet Auto packing your repository for optimum performance. You may also run "git gc" manually. See "git help gc" for more information. [...] [*] Skipping the hint to "run git gc manually" would even be good in this case, because the hint pertains the remote repository, not the one from which "git push" was issued.
I agree with your suggestions. On the same note, while we're already changing the message, it might make sense to change it to "Auto packing the repository [...]".
Jan
PATCH 1/2 gc --auto --quiet: make the notice a bit less verboase
In reply to Johannes SixtWhen "gc --auto --quiet" decides there is something to do, it tells the user what it is doing, as it is going to make the user wait for a bit.
But the message was a bit too long.
---
Quoted 9 lines · Johannes Sixt
I'm slightly in favor of adding "--quiet", because even with this option we see some output:
$ git gc --auto --quiet Auto packing your repository for optimum performance. You may also run "git gc" manually. See "git help gc" for more information.A compromise would be to reduce this message to the first sentence if --quiet was given.
builtin-gc.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-)
builtin-gc.c +7 -4
@@ -216,10 +216,13 @@ int cmd_gc(int argc, const char **argv, const char *prefix)*/ 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" ); +fprintf (stderr, +"Auto packing the repository for optimum performance.%s\n" , + quiet + ?"" + : (" You may also\n" +"run \"git gc\" manually. See " +"\"git help gc\" for more information." )); }else append_option (argv_repack, prune_expire && !strcmp(prune_expire, "now")
Signature · 1 line
1.6.5.1.107.gba912
PATCH 2/2 receive-pack: run "gc --auto --quiet " and optionally "update-server-info"
In reply to Johannes SixtIntroduce two new configuration variables, receive.autogc (defaults to true) and receive.updateserverinfo (defaults to false). When these are set, receive-pack runs "gc --auto --quiet" and "update-server-info" respectively after it finishes receiving data from "git push" and updating refs.
---
* third round; autogc is default (since v2) and runs "gc --auto" with "--quiet" (change in this round).
Documentation/config.txt | 9 +++++++++ builtin-receive-pack.c | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 0 deletions(-)
Documentation/config.txt +9 -0
@@ -1320,6 +1320,11 @@ rebase.stat:: Whether to show a diffstat of what changed upstream since the last rebase. False by default. +receive.autogc:: + By default, git-receive-pack will run "git-gc --auto" after + receiving data from git-push and updating refs. You can stop + it by setting this variable to false. + receive.fsckObjects:: If it is set to true, git-receive-pack will check all received objects. It will abort in the case of a malformed object or a
@@ -1355,6 +1360,10 @@ receive.denyNonFastForwards:: even if that push is forced. This configuration variable is set when initializing a shared repository. +receive.updateserverinfo:: + If set to true, git-receive-pack will run git-update-server-info + after receiving data from git-push and updating refs. + remote.<name>.url:: The URL of a remote repository. See linkgit:git-fetch[1] or linkgit:git-push[1].
builtin-receive-pack.c +20 -0
@@ -28,6 +28,8 @@ static int transfer_unpack_limit = -1;static int unpack_limit =100 ;static int report_status;static int prefer_ofs_delta =1 ; +static int auto_update_server_info; +static int auto_gc =1 ;static const char *head_name;static char *capabilities_to_send;
@@ -88,6 +90,16 @@ static int receive_pack_config(const char *var, const char *value, void *cb)return 0 ; } +if (strcmp (var,"receive.updateserverinfo" ) ==0 ) { + auto_update_server_info =git_config_bool (var, value); +return 0 ; + } + +if (strcmp (var,"receive.autogc" ) ==0 ) { + auto_gc =git_config_bool (var, value); +return 0 ; + } +return git_default_config (var, value, cb); }
@@ -672,6 +684,14 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)report (unpack_status);run_receive_hook (post_receive_hook);run_update_post_hook (commands); +if (auto_gc) { +const char *argv_gc_auto[] = { +"gc" ,"--auto" ,"--quiet" ,NULL , + }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD ); + } +if (auto_update_server_info) +update_server_info (0 ); }return 0 ; }
Signature · 1 line
1.6.5.1.107.gba912
Quoted 9 lines · Junio C Hamano
Quoted 5 lines · Nicolas Pitre
Still... Hopefully this is going to become redundant information in the future with the eventual deployment of smart protocol over HTTP. So I think that as a config option being off by default this is a good compromize. Site administrators can turn it on by default in
/etc/gitconfig.Ok, something like this?
Looks fine to me, except...
Documentation/config.txt rebase.stat:: · line 1325
Quoted 3 lines
Documentation/config.txt +3
-0+receive.autogc:: + If set to true, git-receive-pack will run "git-gc --auto" + after receiving data from git-push and updating refs.
While I was arguing for automatic git-update-server-info to be off by default, I however think that this one might be worth turning on by default. Most of the time I expect people simply don't log into the server where they push stuff and the kernel.org episode certainly shows this as being a worthwhile thing to do, and contrary to update-server-info this is likely to always be so even in the future.
builtin-receive-pack.c int cmd_receive_pack(int argc, const char **argv, const char *prefix) · line 692
Quoted 10 lines
builtin-receive-pack.c +6
-0@@ -672,6 +684,12 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)report (unpack_status);run_receive_hook (post_receive_hook);run_update_post_hook (commands); +if (auto_update_server_info) +update_server_info (0 ); +if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD ); + }
If git-update-server-info is listing packs, shouldn't it be run after git-gc and not before?
Nicolas
PATCH 1/1 receive-pack: run "gc --auto" and optionally "update-server-info"
Introduce two new configuration variables, receive.autogc (defaults to true) and receive.updateserverinfo (defaults to false). When these are set, receive-pack runs "gc --auto" and "update-server-info" respectively after it finishes receiving data from "git push" and updating refs.
---
Quoted 10 lines · Nicolas Pitre
Quoted 8 lines · Junio C Hamano
Quoted 5 lines · Nicolas Pitre
Still... Hopefully this is going to become redundant information in the future with the eventual deployment of smart protocol over HTTP. So I think that as a config option being off by default this is a good compromize. Site administrators can turn it on by default in
/etc/gitconfig.
Quoted 3 lines
Quoted 1 line
Ok, something like this?
Looks fine to me, except...
Everything you said sounded sensible. Thanks.
Documentation/config.txt | 9 +++++++++ builtin-receive-pack.c | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 0 deletions(-)
Documentation/config.txt +9 -0
@@ -1320,6 +1320,11 @@ rebase.stat:: Whether to show a diffstat of what changed upstream since the last rebase. False by default. +receive.autogc:: + By default, git-receive-pack will run "git-gc --auto" after + receiving data from git-push and updating refs. You can stop + it by setting this variable to false. + receive.fsckObjects:: If it is set to true, git-receive-pack will check all received objects. It will abort in the case of a malformed object or a
@@ -1355,6 +1360,10 @@ receive.denyNonFastForwards:: even if that push is forced. This configuration variable is set when initializing a shared repository. +receive.updateserverinfo:: + If set to true, git-receive-pack will run git-update-server-info + after receiving data from git-push and updating refs. + remote.<name>.url:: The URL of a remote repository. See linkgit:git-fetch[1] or linkgit:git-push[1].
builtin-receive-pack.c +18 -0
@@ -28,6 +28,8 @@ static int transfer_unpack_limit = -1;static int unpack_limit =100 ;static int report_status;static int prefer_ofs_delta =1 ; +static int auto_update_server_info; +static int auto_gc =1 ;static const char *head_name;static char *capabilities_to_send;
@@ -88,6 +90,16 @@ static int receive_pack_config(const char *var, const char *value, void *cb)return 0 ; } +if (strcmp (var,"receive.updateserverinfo" ) ==0 ) { + auto_update_server_info =git_config_bool (var, value); +return 0 ; + } + +if (strcmp (var,"receive.autogc" ) ==0 ) { + auto_gc =git_config_bool (var, value); +return 0 ; + } +return git_default_config (var, value, cb); }
@@ -672,6 +684,12 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)report (unpack_status);run_receive_hook (post_receive_hook);run_update_post_hook (commands); +if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD ); + } +if (auto_update_server_info) +update_server_info (0 ); }return 0 ; }
Signature · 1 line
1.6.5.1.107.gba912
Re: [PATCH] receive-pack: run "gc --auto" and optionally "update-server-info"
Quoted 6 lines · Junio C Hamano
Introduce two new configuration variables, receive.autogc (defaults to true) and receive.updateserverinfo (defaults to false). When these are set, receive-pack runs "gc --auto" and "update-server-info" respectively after it finishes receiving data from "git push" and updating refs.
Signed-off-by Junio C Hamano <[email protected]>
Quoted 97 lines
---
Quoted 10 lines · Nicolas Pitre
Quoted 8 lines · Junio C Hamano
Quoted 5 lines · Nicolas Pitre
Still... Hopefully this is going to become redundant information in the future with the eventual deployment of smart protocol over HTTP. So I think that as a config option being off by default this is a good compromize. Site administrators can turn it on by default in
/etc/gitconfig.Quoted 3 lines
Quoted 1 line
Ok, something like this?
Looks fine to me, except...
Everything you said sounded sensible. Thanks.
Documentation/config.txt | 9 +++++++++ builtin-receive-pack.c | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 0 deletions(-)Documentation/config.txt +9
-0@@ -1320,6 +1320,11 @@ rebase.stat:: Whether to show a diffstat of what changed upstream since the last rebase. False by default. +receive.autogc:: + By default, git-receive-pack will run "git-gc --auto" after + receiving data from git-push and updating refs. You can stop + it by setting this variable to false. + receive.fsckObjects:: If it is set to true, git-receive-pack will check all received objects. It will abort in the case of a malformed object or a@@ -1355,6 +1360,10 @@ receive.denyNonFastForwards:: even if that push is forced. This configuration variable is set when initializing a shared repository. +receive.updateserverinfo:: + If set to true, git-receive-pack will run git-update-server-info + after receiving data from git-push and updating refs. + remote.<name>.url:: The URL of a remote repository. See linkgit:git-fetch[1] or linkgit:git-push[1].builtin-receive-pack.c +18
-0@@ -28,6 +28,8 @@ static int transfer_unpack_limit = -1;static int unpack_limit =100 ;static int report_status;static int prefer_ofs_delta =1 ; +static int auto_update_server_info; +static int auto_gc =1 ;static const char *head_name;static char *capabilities_to_send;@@ -88,6 +90,16 @@ static int receive_pack_config(const char *var, const char *value, void *cb)return 0 ; } +if (strcmp (var,"receive.updateserverinfo" ) ==0 ) { + auto_update_server_info =git_config_bool (var, value); +return 0 ; + } + +if (strcmp (var,"receive.autogc" ) ==0 ) { + auto_gc =git_config_bool (var, value); +return 0 ; + } +return git_default_config (var, value, cb); }@@ -672,6 +684,12 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)report (unpack_status);run_receive_hook (post_receive_hook);run_update_post_hook (commands); +if (auto_gc) { +const char *argv_gc_auto[] = {"gc" ,"--auto" ,NULL }; +run_command_v_opt (argv_gc_auto,RUN_GIT_CMD ); + } +if (auto_update_server_info) +update_server_info (0 ); }return 0 ; }Signature · 1 line
1.6.5.1.107.gba912
Quoted 9 lines · Junio C Hamano
As to (1), I think it is reasonable to do some sort of "gc" in receive-pack, and while I recall that Linus was violently against the idea, I personally think it is reasonable to run update-server-info ourselves at the same time without needing the hook, even if the repository is never going to be served over dumb http [*1*]. At one point, update-server-info used to compute a lot more than what we currently compute and it made some sense to oppose against it on performance ground.
Quoted 4 lines
But these days it only lists the refs and packs and does nothing else; the performance impact should be immeasurable and it adds only two files to the repository. It cannot be a big deal, unless you oppose to http transport on a non-technical ground.
I'm obviously happy with making it a non-default option; we can enable it sitewide on kernel.org.
However, git update-server-info seems to take almost no time even in very large repos.
-hpa