Re: Git and buildworld running at the same time

From: Chris Torek <chris.torek_at_gmail.com>
Date: Mon, 15 Sep 2025 04:38:29 UTC
On Sun, Sep 14, 2025 at 9:17 PM bob prohaska <fbsd@www.zefox.net> wrote:

> Knowing that a git pull will be followed by some
> background work it isn't really a problem. I was
> fooled into starting buildworld before git finished,
> now I know enough to let it finish. However, for a
> script the --no-detach is a useful addition, at
> least when confident git will finish successfully.
>

The problem here is that you can't know whether
a `git fetch` will launch a `git gc --auto`, and there is
no `--no-detach` option for `git fetch`. But:

[Mark Millard, I think]

> > > # git -C /usr/src/ config maintenance.autoDetach false
> > > # git -C /usr/src/ config          gc.autoDetach false
>
> I'm a little confused here: are the two commands above equivalent
> in action to
>  git -C /usr/src/ gc --no-detach --auto
> when used in a one-line script?
>

No. The `git config` command (now preferably spelled
`git config set` for this particular purpose) writes the
desired configuration to your specified Git configuration
file (system, user-global, repository-local, worktree-local,
or specified file) , where it resides until changed.

Meanwhile `git gc --no-detach --auto` means "run the
gc command now, with flags auto and no-detach"; the
"no-detach" overrides whichever configuration file
setting would take effect without it. But as I noted above,
the problem is that "git fetch" itself runs the GC for you.

Your options are therefore one or both of these:

1. Set it in your configuration (you probably want to use
the default local config for this, or perhaps user-global
so that if it's not set locally your user-global setting gets
used).

2. All Git commands take `-c` options. These set internal
environment variables that get passed on to future internally-
executed Git commands, so you can force a "git fetch" to
run a "git gc" with the environment setting (note that the
env setting overrides all config file settings but not any
command-line-flag settings). So you could run:

    git -c maintenance.autoDetach=false pull

to run both `git fetch` and `git merge` with any background
gc step run with wait-for-completion.

Note that the `-c` spelling uses the equals sign form,
which differs from the `git config set` form.

(This is all kind of a pain but is all part of the
backwards compatibility stuff... see, e.g., the
`gc.packRefs` setting, which exists for compatibility
with Git 1.5.1.1 and earlier! I doubt anyone has
needed it in 15 years now.)

If you use option 1 and `git config set --global`, you
don't have to change any of your other existing
workflow, you just have to be ready for any Git
command you run to take an hour-plus unexpectedly
(on your system).

(You could also tune some of the packing options
so that you run `gc` less frequently. This also has
its own set of tradeoffs...)

Chris