@@ -218,6 +218,122 @@ Further, the `git gc` command should not be combined with
218218but does not take the lock in the same way as `git maintenance run`. If
219219possible, use `git maintenance run --task=gc` instead of `git gc`.
220220
221+ The following sections describe the mechanisms put in place to run
222+ background maintenance by `git maintenance start` and how to customize
223+ them.
224+
225+ BACKGROUND MAINTENANCE ON POSIX SYSTEMS
226+ ---------------------------------------
227+
228+ The standard mechanism for scheduling background tasks on POSIX systems
229+ is cron(8). This tool executes commands based on a given schedule. The
230+ current list of user-scheduled tasks can be found by running `crontab -l`.
231+ The schedule written by `git maintenance start` is similar to this:
232+
233+ -----------------------------------------------------------------------
234+ # BEGIN GIT MAINTENANCE SCHEDULE
235+ # The following schedule was created by Git
236+ # Any edits made in this region might be
237+ # replaced in the future by a Git command.
238+
239+ 0 1-23 * * * "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=hourly
240+ 0 0 * * 1-6 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=daily
241+ 0 0 * * 0 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=weekly
242+
243+ # END GIT MAINTENANCE SCHEDULE
244+ -----------------------------------------------------------------------
245+
246+ The comments are used as a region to mark the schedule as written by Git.
247+ Any modifications within this region will be completely deleted by
248+ `git maintenance stop` or overwritten by `git maintenance start`.
249+
250+ The `crontab` entry specifies the full path of the `git` executable to
251+ ensure that the executed `git` command is the same one with which
252+ `git maintenance start` was issued independent of `PATH`. If the same user
253+ runs `git maintenance start` with multiple Git executables, then only the
254+ latest executable is used.
255+
256+ These commands use `git for-each-repo --config=maintenance.repo` to run
257+ `git maintenance run --schedule=<frequency>` on each repository listed in
258+ the multi-valued `maintenance.repo` config option. These are typically
259+ loaded from the user-specific global config. The `git maintenance` process
260+ then determines which maintenance tasks are configured to run on each
261+ repository with each `<frequency>` using the `maintenance.<task>.schedule`
262+ config options. These values are loaded from the global or repository
263+ config values.
264+
265+ If the config values are insufficient to achieve your desired background
266+ maintenance schedule, then you can create your own schedule. If you run
267+ `crontab -e`, then an editor will load with your user-specific `cron`
268+ schedule. In that editor, you can add your own schedule lines. You could
269+ start by adapting the default schedule listed earlier, or you could read
270+ the crontab(5) documentation for advanced scheduling techniques. Please
271+ do use the full path and `--exec-path` techniques from the default
272+ schedule to ensure you are executing the correct binaries in your
273+ schedule.
274+
275+
276+ BACKGROUND MAINTENANCE ON MACOS SYSTEMS
277+ ---------------------------------------
278+
279+ While macOS technically supports `cron`, using `crontab -e` requires
280+ elevated privileges and the executed process does not have a full user
281+ context. Without a full user context, Git and its credential helpers
282+ cannot access stored credentials, so some maintenance tasks are not
283+ functional.
284+
285+ Instead, `git maintenance start` interacts with the `launchctl` tool,
286+ which is the recommended way to schedule timed jobs in macOS. Scheduling
287+ maintenance through `git maintenance (start|stop)` requires some
288+ `launchctl` features available only in macOS 10.11 or later.
289+
290+ Your user-specific scheduled tasks are stored as XML-formatted `.plist`
291+ files in `~/Library/LaunchAgents/`. You can see the currently-registered
292+ tasks using the following command:
293+
294+ -----------------------------------------------------------------------
295+ $ ls ~/Library/LaunchAgents/org.git-scm.git*
296+ org.git-scm.git.daily.plist
297+ org.git-scm.git.hourly.plist
298+ org.git-scm.git.weekly.plist
299+ -----------------------------------------------------------------------
300+
301+ One task is registered for each `--schedule=<frequency>` option. To
302+ inspect how the XML format describes each schedule, open one of these
303+ `.plist` files in an editor and inspect the `<array>` element following
304+ the `<key>StartCalendarInterval</key>` element.
305+
306+ `git maintenance start` will overwrite these files and register the
307+ tasks again with `launchctl`, so any customizations should be done by
308+ creating your own `.plist` files with distinct names. Similarly, the
309+ `git maintenance stop` command will unregister the tasks with `launchctl`
310+ and delete the `.plist` files.
311+
312+ To create more advanced customizations to your background tasks, see
313+ launchctl.plist(5) for more information.
314+
315+
316+ BACKGROUND MAINTENANCE ON WINDOWS SYSTEMS
317+ -----------------------------------------
318+
319+ Windows does not support `cron` and instead has its own system for
320+ scheduling background tasks. The `git maintenance start` command uses
321+ the `schtasks` command to submit tasks to this system. You can inspect
322+ all background tasks using the Task Scheduler application. The tasks
323+ added by Git have names of the form `Git Maintenance (<frequency>)`.
324+ The Task Scheduler GUI has ways to inspect these tasks, but you can also
325+ export the tasks to XML files and view the details there.
326+
327+ Note that since Git is a console application, these background tasks
328+ create a console window visible to the current user. This can be changed
329+ manually by selecting the "Run whether user is logged in or not" option
330+ in Task Scheduler. This change requires a password input, which is why
331+ `git maintenance start` does not select it by default.
332+
333+ If you want to customize the background tasks, please rename the tasks
334+ so future calls to `git maintenance (start|stop)` do not overwrite your
335+ custom tasks.
336+
221337
222338GIT
223339---
0 commit comments