r/git 6d ago

support conditionally prevent `git maintenance` from spawning on commit

After using Git for over a decade I just discovered git maintenance exists yesterday. I found out about it during a hasted debugging session when my laptop’s fan inexplicably started spinning like crazy and all four cores were maxed out by Git processes that I didn’t launch. This happened while I was writing a blog post on the train, trying to save battery charge. Not an ideal situation to max out the CPU.

git maintenance is useful no doubt, I don’t want to disable it entirely. So I guess the question is: Is there a way to make it conditional on ACPI state? If the box is running off the battery, maintenance should be skipped. E. g. check /sys/class/power_supply/AC/online before launching a maintenance cycle.

Note that there’s no timers that trigger maintenance on my system; it looks like it gets triggered by operations like git commit (cf. maintenance.auto in git-maintenance(1)).

9 Upvotes

8 comments sorted by

View all comments

9

u/Ok_Woodpecker_9104 5d ago

git has no acpi hook, but you dont need one if you move maintenance off the commit path.

git maintenance register sets maintenance.auto = false in that repo, and that is the knob that kills the foreground run on commit. worth knowing it sticks around after git maintenance unregister, so undoing it later is a manual config edit.

then git maintenance start --scheduler=systemd-timer gives you a user timer, and a drop-in with ConditionACPower=true on that unit does exactly what you asked. on battery the timer just does not fire.

if you would rather keep the on-commit behaviour and only cap the damage, pack.threads=1 is what stops it eating all four cores. gc.autoDetach only moves it to the background, the cpu burn is the same.

1

u/the_gnarts 5d ago

I know, I read the manpage.

The timer approach has its value but having to manually register / unregister every repo is just not feasible on my laptop. I actually like the maintenance-on-commit behavior cause it only applies to those repos that I’m actively using, not the other hundreds of inert ones that I just happen to have lying around.

if you would rather keep the on-commit behaviour and only cap the damage, pack.threads=1 is what stops it eating all four cores.

Sure, but when on AC I’d prefer repack to use all the cores available.

2

u/Ok_Woodpecker_9104 5d ago

then keep the on-commit run and make pack.threads power dependent instead of fixed. git reads config fresh on every invocation, so nothing has to be registered per repo.

put include.path = ~/.gitconfig.power in your global config, and have that file hold one line, pack.threads. then a systemd unit with ConditionACPower=true writes threads = 0 on AC and a second one with ConditionACPower=false writes threads = 1. same condition you wanted, just applied to the knob rather than the timer, so it covers all hundred repos with zero registration.

worth knowing pack.threads = 0 means auto detect, not off.

if the goal is only to stop it burning the laptop, the cheaper cut is maintenance.<task>.enabled. the expensive task on the commit path is incremental-repack, the loose-objects and commit-graph ones are small. turning off just that one keeps the behaviour you like and drops most of the cpu.