Skip to content

Commit 9cbad73

Browse files
committed
Merge pull request #2974 from derrickstolee/maintenance-and-headless
Include Windows-specific maintenance and headless-git
2 parents e794d35 + 1287147 commit 9cbad73

File tree

8 files changed

+743
-35
lines changed

8 files changed

+743
-35
lines changed

Documentation/git-maintenance.txt

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,122 @@ Further, the `git gc` command should not be combined with
218218
but does not take the lock in the same way as `git maintenance run`. If
219219
possible, 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

222338
GIT
223339
---

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,6 +2514,13 @@ compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
25142514
compat/nedmalloc/nedmalloc.sp: SP_EXTRA_FLAGS += -Wno-non-pointer-null
25152515
endif
25162516

2517+
headless-git.o: compat/win32/headless.c
2518+
$(QUIET_CC)$(CC) $(ALL_CFLAGS) $(COMPAT_CFLAGS) \
2519+
-fno-stack-protector -o $@ -c -Wall -Wwrite-strings $<
2520+
2521+
headless-git$X: headless-git.o git.res
2522+
$(QUIET_LINK)$(CC) $(ALL_LDFLAGS) -mwindows $(COMPAT_CFLAGS) -o $@ $^
2523+
25172524
git-%$X: %.o GIT-LDFLAGS $(GITLIBS)
25182525
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
25192526

0 commit comments

Comments
 (0)