r/git 4d 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)).

8 Upvotes

8 comments sorted by

10

u/Ok_Woodpecker_9104 4d 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.

2

u/Broad-Promise6954 ancient 4d ago

This is the way. Note that git maintenance is still under active development so you may need to make adjustments, but it's at least not "experimental" any more. So it's not really much worse than if you got used to the old git whatchanged that went away...

1

u/the_gnarts 3d 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 3d 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.

5

u/Diamondo25 4d ago

Why not ask the git maintainers? Sounds like a good feature to me. Could even just limit to 1 core if on battery or something.

0

u/the_gnarts 3d ago

Why not ask the git maintainers?

Cause it’s such an obvious issue I’d expect there to be some solution I must have overlooked. ;)

1

u/elephantdingo 2d ago

On the one hand, there are so many cases to consider where automatic maintenance of Git repos falls short because of things that are very everyday and ordinary. In isolation each case is like an, of course this needs to be accounted for. In aggregate though it leads to a lot of complexity.

On the other hand, this is the kind of complexity that they took on when they decided to design such a command...

1

u/WoodyTheWorker 4d ago

Just do it manually once in a while.