* [PATCH] clone, progress: add --no-turtle-speed option to abort slow clones
@ 2026-03-06 22:14 Mike Banon
2026-03-06 23:29 ` brian m. carlson
0 siblings, 1 reply; 5+ messages in thread
From: Mike Banon @ 2026-03-06 22:14 UTC (permalink / raw)
To: git
When cloning large repositories from a website with multiple Git servers,
the client may be directed to a "turtle-slow" server, causing the transfer
to proceed at an unusably slow speed. This can lead to stalled downloads,
particularly problematic for automated scripts that clone many
repositories. This option makes Git abort the clone if the download rate
falls below 128 KiB/s while receiving objects, typically catching slow
servers early in the transfer, enabling scripts to retry the clone until
they obtain a fast connection.
Signed-off-by: Mike Banon <mikebdp2@gmail.com>
diff --git a/builtin/clone.c b/builtin/clone.c
index fba3c9c508..a9ed2c193d 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -94,6 +94,13 @@ static int recurse_submodules_cb(const struct option *opt,
return 0;
}
+static int set_turtle_speed_env(const struct option *opt UNUSED,
+ const char *arg UNUSED, int unset UNUSED)
+{
+ setenv(NO_TURTLE_SPEED_ENVIRONMENT, "1", 1);
+ return 0;
+}
+
static const char *get_repo_path_1(struct strbuf *path, int *is_bundle)
{
static const char *suffix[] = { "/.git", "", ".git/.git", ".git" };
@@ -946,6 +953,16 @@ int cmd_clone(int argc,
.callback = recurse_submodules_cb,
.defval = (intptr_t)".",
},
+ {
+ .type = OPTION_CALLBACK,
+ .long_name = "no-turtle-speed",
+ .value = NULL,
+ .argh = NULL,
+ .help = N_("abort clone if speed drops below 128 KiB/s"),
+ .flags = PARSE_OPT_NOARG,
+ .callback = set_turtle_speed_env,
+ .defval = 0,
+ },
OPT_ALIAS(0, "recursive", "recurse-submodules"),
OPT_INTEGER('j', "jobs", &max_jobs,
N_("number of submodules cloned in parallel")),
diff --git a/environment.h b/environment.h
index 123a71cdc8..cb316cf321 100644
--- a/environment.h
+++ b/environment.h
@@ -24,6 +24,7 @@
#define NO_REPLACE_OBJECTS_ENVIRONMENT "GIT_NO_REPLACE_OBJECTS"
#define GIT_REPLACE_REF_BASE_ENVIRONMENT "GIT_REPLACE_REF_BASE"
#define NO_LAZY_FETCH_ENVIRONMENT "GIT_NO_LAZY_FETCH"
+#define NO_TURTLE_SPEED_ENVIRONMENT "GIT_NO_TURTLE_SPEED"
#define GITATTRIBUTES_FILE ".gitattributes"
#define INFOATTRIBUTES_FILE "info/attributes"
#define ATTRIBUTE_MACRO_PREFIX "[attr]"
diff --git a/git.c b/git.c
index 744cb6527e..d0c4909fef 100644
--- a/git.c
+++ b/git.c
@@ -40,9 +40,9 @@ const char git_usage_string[] =
N_("git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path]
[--info-path]\n"
" [-p | --paginate | -P | --no-pager]
[--no-replace-objects] [--no-lazy-fetch]\n"
- " [--no-optional-locks] [--no-advice] [--bare]
[--git-dir=<path>]\n"
- " [--work-tree=<path>] [--namespace=<name>]
[--config-env=<name>=<envvar>]\n"
- " <command> [<args>]");
+ " [--no-turtle-speed] [--no-optional-locks]
[--no-advice] [--bare]\n"
+ " [--git-dir=<path>] [--work-tree=<path>]
[--namespace=<name>]\n"
+ " [--config-env=<name>=<envvar>] <command> [<args>]");
const char git_more_info_string[] =
N_("'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -206,6 +206,10 @@ static int handle_options(const char ***argv, int
*argc, int *envchanged)
setenv(NO_LAZY_FETCH_ENVIRONMENT, "1", 1);
if (envchanged)
*envchanged = 1;
+ } else if (!strcmp(cmd, "--no-turtle-speed")) {
+ setenv(NO_TURTLE_SPEED_ENVIRONMENT, "1", 1);
+ if (envchanged)
+ *envchanged = 1;
} else if (!strcmp(cmd, "--no-replace-objects")) {
disable_replace_refs();
setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1);
diff --git a/progress.c b/progress.c
index 8315bdc3d4..b30c9f11d3 100644
--- a/progress.c
+++ b/progress.c
@@ -195,6 +195,7 @@ void display_throughput(struct progress *progress,
uint64_t total)
struct throughput *tp;
uint64_t now_ns;
unsigned int misecs, count, rate;
+ const char *turtle_env = getenv(NO_TURTLE_SPEED_ENVIRONMENT);
if (!progress)
return;
@@ -245,6 +246,13 @@ void display_throughput(struct progress
*progress, uint64_t total)
tp->last_misecs[tp->idx] = misecs;
tp->idx = (tp->idx + 1) % TP_IDX_MAX;
+ if (turtle_env &&
+ *turtle_env == '1' &&
+ rate < 128 &&
+ progress->title &&
+ strstr(progress->title, "Receiving objects"))
+ die(_("stopping due to a <128 KiB/s turtle speed: %u KiB/s"), rate);
+
throughput_string(&tp->display, total, rate);
if (progress->last_value != -1 && progress_update)
display(progress, progress->last_value, NULL);
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] clone, progress: add --no-turtle-speed option to abort slow clones
2026-03-06 22:14 [PATCH] clone, progress: add --no-turtle-speed option to abort slow clones Mike Banon
@ 2026-03-06 23:29 ` brian m. carlson
2026-03-07 0:29 ` Mike Banon
2026-03-09 9:31 ` Richard Kerry
0 siblings, 2 replies; 5+ messages in thread
From: brian m. carlson @ 2026-03-06 23:29 UTC (permalink / raw)
To: Mike Banon; +Cc: git
[-- Attachment #1: Type: text/plain, Size: 2217 bytes --]
On 2026-03-06 at 22:14:28, Mike Banon wrote:
> When cloning large repositories from a website with multiple Git servers,
> the client may be directed to a "turtle-slow" server, causing the transfer
> to proceed at an unusably slow speed. This can lead to stalled downloads,
> particularly problematic for automated scripts that clone many
> repositories. This option makes Git abort the clone if the download rate
> falls below 128 KiB/s while receiving objects, typically catching slow
> servers early in the transfer, enabling scripts to retry the clone until
> they obtain a fast connection.
I'm not aware of any servers that this option would be useful for, but
I'm willing to assume for the sake of argument that some exist with this
design. I don't think it's a very good design, but I admit that there
are many things on the Internet that are poorly designed.
I think it would be more helpful to provide an option
`--min-speed=128KiB` or something. Assuming Git is still around in a
decade, we might consider 10 MiB/s to be absurdly slow then and an
option that hard-coded the slow speed would be decidedly less useful.
Many users might have different speeds that would be more tailored to
their environment even now.
I also think that the word "turtle" in this context might be poorly
understood by people who are not native English speakers. I agree that
turtles are typically thought of as slow creatures, but they may
epitomize other traits in other languages or cultures (such as wisdom or
longevity[0]) that might not bring to mind slowness.
In addition, I would think we'd want to update the manual page as well.
My guess is that CI would have caught the fact that the option was not
present in the manual page.
I didn't give extensive review to the design, but I would think passing
an option to the child process or using some sort of option message
(such as in the HTTP helper) would be better than passing an environment
variable if that's possible. If it's not, perhaps the commit message
could explain why that wouldn't work.
[0] https://en.wikipedia.org/wiki/Cultural_depictions_of_turtles
--
brian m. carlson (they/them)
Toronto, Ontario, CA
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] clone, progress: add --no-turtle-speed option to abort slow clones
2026-03-06 23:29 ` brian m. carlson
@ 2026-03-07 0:29 ` Mike Banon
2026-03-07 1:34 ` brian m. carlson
2026-03-09 9:31 ` Richard Kerry
1 sibling, 1 reply; 5+ messages in thread
From: Mike Banon @ 2026-03-07 0:29 UTC (permalink / raw)
To: brian m. carlson, Mike Banon, git
Brian, thank you very much for your code review!
This problem has been happening to me for a couple of weeks while
using GitHub: as a part of my "floppinux-amd64net" pet project (2.88
MB Linux floppy image with Ethernet/WiFi – for putting into a coreboot
BIOS image), I wrote a large [1] script that clones a lot of GitHub
repositories and builds everything from scratch. With some non-zero
probability (floating between 5%–30% depending on day/location and
other unknown factors), my git clone operation gets directed to a
really slow Git server with around ~70 KiB/s download speed, which is
especially painful if it tries to clone some large repo like a
linux-firmware. But if I terminate that git clone and start it again,
there is a good chance that my next connection will be fast (at least
a few MiB/s). So with the bash code like [2] below – in case of a slow
connection, it will simply restart until it gets a fast server and
clones successfully.
I agree that more customization ability would be useful and support
your opinion about the turtles, so your "--min-speed=128KiB"
suggestion sounds great and I may try to implement it in the near
future. At the moment I simply wanted to know if such a feature,
initially created for my personal needs, would be welcome upstream. It
is unknown how many people are affected by such problems, i.e. I've
never had this annoying problem until recently.
My reason for using the environmental variable is simple: not being
familiar with the git codebase, this "variable solution" is the most
minimalistic diff I've been able to come up with (just 40 non-dense
lines) that is still working in practice. Another way was adding some
"speed_check" flag variable (either to a "progress" data structure or
as some "extern"ally-exposed variable), but I ran into some problems
with this approach and just did what was more reachable to me as a
newbie here.
Best regards, Mike Banon
Open Source Community Manager of 3mdeb - https://3mdeb.com/
[1] https://github.com/mikebdp2/floppinux-amd64net/blob/main/floppinux-amd64net.sh
[2]
# Formatting
bold="\033[1m"
bred="\033[1;31m"
bgreen="\033[1;32m"
byellow="\033[1;33m"
bend="\033[0m"
# Prints the status message in '$1: $2' format with a green color
highlighting of a '$1'.
printgr () {
printf "${bgreen}$1${bend}: $2\n"
return 0
}
# Git clones a '$1' repository from a '$2' URL, with a '$3' branch if specified.
git_cloner () {
if git clone --no-turtle-speed --depth=1 ${3:+--branch $3} "$2" &&
[ -d "$1/.git/" ] ; then
return 0
else
rm -rf "$1"
printf "\n${byellow}WARNING${bend}: cannot download a
${byellow}$1${bend} repository !"
printf "\n Please check your Internet connection and
try again.\n"
sleep 1
return 1
fi
}
# linux-firmware needed for some Ethernet/WiFi network adapters
firmware_get () {
printgr "LINUX-FIRMWARE" "remove the old directory if it exists"
rm -rf ./linux-firmware/
printgr "LINUX-FIRMWARE" "git clone a repository"
while true; do
git_cloner "./linux-firmware"
"https://github.com/mikebdp2/linux-firmware.git" && break
done
return 0
}
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] clone, progress: add --no-turtle-speed option to abort slow clones
2026-03-07 0:29 ` Mike Banon
@ 2026-03-07 1:34 ` brian m. carlson
0 siblings, 0 replies; 5+ messages in thread
From: brian m. carlson @ 2026-03-07 1:34 UTC (permalink / raw)
To: Mike Banon; +Cc: git
[-- Attachment #1: Type: text/plain, Size: 2842 bytes --]
On 2026-03-07 at 00:29:18, Mike Banon wrote:
> Brian, thank you very much for your code review!
>
> This problem has been happening to me for a couple of weeks while
> using GitHub: as a part of my "floppinux-amd64net" pet project (2.88
> MB Linux floppy image with Ethernet/WiFi – for putting into a coreboot
> BIOS image), I wrote a large [1] script that clones a lot of GitHub
> repositories and builds everything from scratch. With some non-zero
> probability (floating between 5%–30% depending on day/location and
> other unknown factors), my git clone operation gets directed to a
> really slow Git server with around ~70 KiB/s download speed, which is
> especially painful if it tries to clone some large repo like a
> linux-firmware. But if I terminate that git clone and start it again,
> there is a good chance that my next connection will be fast (at least
> a few MiB/s). So with the bash code like [2] below – in case of a slow
> connection, it will simply restart until it gets a fast server and
> clones successfully.
GitHub doesn't throttle speeds once the operation starts, although it
sometimes does delay the _start_ of an operation if there's excessive
use (for example, if you're cloning the same repository too many times,
as in some automated systems). GitHub wants the operation to complete
as quickly as possible once it starts because a clone or fetch will take
the same CPU and memory resources no matter how long it's running and
obviously freeing those resources faster is better than consuming them
for longer periods (since then they can be used for other users).
If you're seeing this, I'd recommend opening a ticket at GitHub and
including the output at https://github-debug.com/, since that will be
helpful in troubleshooting the problem. For instance, it may be that
there's a bad connection between your ISP and GitHub and that can be
addressed. Or, if there is an overloaded server impacting things, that
would be a thing that GitHub would want to look into.
If you can capture the problem with `GIT_TRACE=1 GIT_TRANSFER_TRACE=1
GIT_CURL_VERBOSE=1` before your Git command and you include that output
and the repository you're having problems with, then that will allow
GitHub to look up the request by its ID and find what's going on.
My participation in the list from this email address is in my personal
capacity and my personal capacity alone, but I do work on the Git
services at GitHub and obviously we want everyone to have a good
experience provided they're using a reasonable amount of resources and
otherwise behaving appropriately.
Of course, I think people would still find the `--min-speed` patch
useful, but my hope is that it's not a feature you'll need to make use
of.
--
brian m. carlson (they/them)
Toronto, Ontario, CA
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH] clone, progress: add --no-turtle-speed option to abort slow clones
2026-03-06 23:29 ` brian m. carlson
2026-03-07 0:29 ` Mike Banon
@ 2026-03-09 9:31 ` Richard Kerry
1 sibling, 0 replies; 5+ messages in thread
From: Richard Kerry @ 2026-03-09 9:31 UTC (permalink / raw)
To: brian m. carlson, Mike Banon; +Cc: git@vger.kernel.org
> -----Original Message-----
> From: brian m. carlson <sandals@crustytoothpaste.net>
> Sent: 06 March 2026 23:30
> To: Mike Banon <mikebdp2@gmail.com>
> Cc: git@vger.kernel.org
> Subject: Re: [PATCH] clone, progress: add --no-turtle-speed option to abort slow
> clones
> I also think that the word "turtle" in this context might be poorly understood by
> people who are not native English speakers. I agree that turtles are typically
> thought of as slow creatures, but they may epitomize other traits in other
> languages or cultures (such as wisdom or
> longevity[0]) that might not bring to mind slowness.
I believe American usage tends to lose the distinction between turtle, tortoise and terrapin, where British (and other?) usage distinguishes them.
I think tortoises are land-based, and are the slow-moving ones. Turtles and terrapins are swimmers and whenever I've seen them in documentaries they seem to move quite quickly.
Just my two-penn'orth (not US, or anywhere else that uses cents, so not inclined to say two cents)
Regards,
Richard.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-03-09 9:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-06 22:14 [PATCH] clone, progress: add --no-turtle-speed option to abort slow clones Mike Banon
2026-03-06 23:29 ` brian m. carlson
2026-03-07 0:29 ` Mike Banon
2026-03-07 1:34 ` brian m. carlson
2026-03-09 9:31 ` Richard Kerry
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox