<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" | |
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> | |
<head> | |
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" /> | |
<meta name="generator" content="AsciiDoc 10.2.0" /> | |
<title>git-maintenance(1)</title> | |
<style type="text/css"> | |
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */ | |
/* Default font. */ | |
body { | |
font-family: Georgia,serif; | |
} | |
/* Title font. */ | |
h1, h2, h3, h4, h5, h6, | |
div.title, caption.title, | |
thead, p.table.header, | |
#toctitle, | |
#author, #revnumber, #revdate, #revremark, | |
#footer { | |
font-family: Arial,Helvetica,sans-serif; | |
} | |
body { | |
margin: 1em 5% 1em 5%; | |
} | |
a { | |
color: blue; | |
text-decoration: underline; | |
} | |
a:visited { | |
color: fuchsia; | |
} | |
em { | |
font-style: italic; | |
color: navy; | |
} | |
strong { | |
font-weight: bold; | |
color: #083194; | |
} | |
h1, h2, h3, h4, h5, h6 { | |
color: #527bbd; | |
margin-top: 1.2em; | |
margin-bottom: 0.5em; | |
line-height: 1.3; | |
} | |
h1, h2, h3 { | |
border-bottom: 2px solid silver; | |
} | |
h2 { | |
padding-top: 0.5em; | |
} | |
h3 { | |
float: left; | |
} | |
h3 + * { | |
clear: left; | |
} | |
h5 { | |
font-size: 1.0em; | |
} | |
div.sectionbody { | |
margin-left: 0; | |
} | |
hr { | |
border: 1px solid silver; | |
} | |
p { | |
margin-top: 0.5em; | |
margin-bottom: 0.5em; | |
} | |
ul, ol, li > p { | |
margin-top: 0; | |
} | |
ul > li { color: #aaa; } | |
ul > li > * { color: black; } | |
.monospaced, code, pre { | |
font-family: "Courier New", Courier, monospace; | |
font-size: inherit; | |
color: navy; | |
padding: 0; | |
margin: 0; | |
} | |
pre { | |
white-space: pre-wrap; | |
} | |
#author { | |
color: #527bbd; | |
font-weight: bold; | |
font-size: 1.1em; | |
} | |
#email { | |
} | |
#revnumber, #revdate, #revremark { | |
} | |
#footer { | |
font-size: small; | |
border-top: 2px solid silver; | |
padding-top: 0.5em; | |
margin-top: 4.0em; | |
} | |
#footer-text { | |
float: left; | |
padding-bottom: 0.5em; | |
} | |
#footer-badges { | |
float: right; | |
padding-bottom: 0.5em; | |
} | |
#preamble { | |
margin-top: 1.5em; | |
margin-bottom: 1.5em; | |
} | |
div.imageblock, div.exampleblock, div.verseblock, | |
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock, | |
div.admonitionblock { | |
margin-top: 1.0em; | |
margin-bottom: 1.5em; | |
} | |
div.admonitionblock { | |
margin-top: 2.0em; | |
margin-bottom: 2.0em; | |
margin-right: 10%; | |
color: #606060; | |
} | |
div.content { /* Block element content. */ | |
padding: 0; | |
} | |
/* Block element titles. */ | |
div.title, caption.title { | |
color: #527bbd; | |
font-weight: bold; | |
text-align: left; | |
margin-top: 1.0em; | |
margin-bottom: 0.5em; | |
} | |
div.title + * { | |
margin-top: 0; | |
} | |
td div.title:first-child { | |
margin-top: 0.0em; | |
} | |
div.content div.title:first-child { | |
margin-top: 0.0em; | |
} | |
div.content + div.title { | |
margin-top: 0.0em; | |
} | |
div.sidebarblock > div.content { | |
background: #ffffee; | |
border: 1px solid #dddddd; | |
border-left: 4px solid #f0f0f0; | |
padding: 0.5em; | |
} | |
div.listingblock > div.content { | |
border: 1px solid #dddddd; | |
border-left: 5px solid #f0f0f0; | |
background: #f8f8f8; | |
padding: 0.5em; | |
} | |
div.quoteblock, div.verseblock { | |
padding-left: 1.0em; | |
margin-left: 1.0em; | |
margin-right: 10%; | |
border-left: 5px solid #f0f0f0; | |
color: #888; | |
} | |
div.quoteblock > div.attribution { | |
padding-top: 0.5em; | |
text-align: right; | |
} | |
div.verseblock > pre.content { | |
font-family: inherit; | |
font-size: inherit; | |
} | |
div.verseblock > div.attribution { | |
padding-top: 0.75em; | |
text-align: left; | |
} | |
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */ | |
div.verseblock + div.attribution { | |
text-align: left; | |
} | |
div.admonitionblock .icon { | |
vertical-align: top; | |
font-size: 1.1em; | |
font-weight: bold; | |
text-decoration: underline; | |
color: #527bbd; | |
padding-right: 0.5em; | |
} | |
div.admonitionblock td.content { | |
padding-left: 0.5em; | |
border-left: 3px solid #dddddd; | |
} | |
div.exampleblock > div.content { | |
border-left: 3px solid #dddddd; | |
padding-left: 0.5em; | |
} | |
div.imageblock div.content { padding-left: 0; } | |
span.image img { border-style: none; vertical-align: text-bottom; } | |
a.image:visited { color: white; } | |
dl { | |
margin-top: 0.8em; | |
margin-bottom: 0.8em; | |
} | |
dt { | |
margin-top: 0.5em; | |
margin-bottom: 0; | |
font-style: normal; | |
color: navy; | |
} | |
dd > *:first-child { | |
margin-top: 0.1em; | |
} | |
ul, ol { | |
list-style-position: outside; | |
} | |
ol.arabic { | |
list-style-type: decimal; | |
} | |
ol.loweralpha { | |
list-style-type: lower-alpha; | |
} | |
ol.upperalpha { | |
list-style-type: upper-alpha; | |
} | |
ol.lowerroman { | |
list-style-type: lower-roman; | |
} | |
ol.upperroman { | |
list-style-type: upper-roman; | |
} | |
div.compact ul, div.compact ol, | |
div.compact p, div.compact p, | |
div.compact div, div.compact div { | |
margin-top: 0.1em; | |
margin-bottom: 0.1em; | |
} | |
tfoot { | |
font-weight: bold; | |
} | |
td > div.verse { | |
white-space: pre; | |
} | |
div.hdlist { | |
margin-top: 0.8em; | |
margin-bottom: 0.8em; | |
} | |
div.hdlist tr { | |
padding-bottom: 15px; | |
} | |
dt.hdlist1.strong, td.hdlist1.strong { | |
font-weight: bold; | |
} | |
td.hdlist1 { | |
vertical-align: top; | |
font-style: normal; | |
padding-right: 0.8em; | |
color: navy; | |
} | |
td.hdlist2 { | |
vertical-align: top; | |
} | |
div.hdlist.compact tr { | |
margin: 0; | |
padding-bottom: 0; | |
} | |
.comment { | |
background: yellow; | |
} | |
.footnote, .footnoteref { | |
font-size: 0.8em; | |
} | |
span.footnote, span.footnoteref { | |
vertical-align: super; | |
} | |
#footnotes { | |
margin: 20px 0 20px 0; | |
padding: 7px 0 0 0; | |
} | |
#footnotes div.footnote { | |
margin: 0 0 5px 0; | |
} | |
#footnotes hr { | |
border: none; | |
border-top: 1px solid silver; | |
height: 1px; | |
text-align: left; | |
margin-left: 0; | |
width: 20%; | |
min-width: 100px; | |
} | |
div.colist td { | |
padding-right: 0.5em; | |
padding-bottom: 0.3em; | |
vertical-align: top; | |
} | |
div.colist td img { | |
margin-top: 0.3em; | |
} | |
@media print { | |
#footer-badges { display: none; } | |
} | |
#toc { | |
margin-bottom: 2.5em; | |
} | |
#toctitle { | |
color: #527bbd; | |
font-size: 1.1em; | |
font-weight: bold; | |
margin-top: 1.0em; | |
margin-bottom: 0.1em; | |
} | |
div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 { | |
margin-top: 0; | |
margin-bottom: 0; | |
} | |
div.toclevel2 { | |
margin-left: 2em; | |
font-size: 0.9em; | |
} | |
div.toclevel3 { | |
margin-left: 4em; | |
font-size: 0.9em; | |
} | |
div.toclevel4 { | |
margin-left: 6em; | |
font-size: 0.9em; | |
} | |
span.aqua { color: aqua; } | |
span.black { color: black; } | |
span.blue { color: blue; } | |
span.fuchsia { color: fuchsia; } | |
span.gray { color: gray; } | |
span.green { color: green; } | |
span.lime { color: lime; } | |
span.maroon { color: maroon; } | |
span.navy { color: navy; } | |
span.olive { color: olive; } | |
span.purple { color: purple; } | |
span.red { color: red; } | |
span.silver { color: silver; } | |
span.teal { color: teal; } | |
span.white { color: white; } | |
span.yellow { color: yellow; } | |
span.aqua-background { background: aqua; } | |
span.black-background { background: black; } | |
span.blue-background { background: blue; } | |
span.fuchsia-background { background: fuchsia; } | |
span.gray-background { background: gray; } | |
span.green-background { background: green; } | |
span.lime-background { background: lime; } | |
span.maroon-background { background: maroon; } | |
span.navy-background { background: navy; } | |
span.olive-background { background: olive; } | |
span.purple-background { background: purple; } | |
span.red-background { background: red; } | |
span.silver-background { background: silver; } | |
span.teal-background { background: teal; } | |
span.white-background { background: white; } | |
span.yellow-background { background: yellow; } | |
span.big { font-size: 2em; } | |
span.small { font-size: 0.6em; } | |
span.underline { text-decoration: underline; } | |
span.overline { text-decoration: overline; } | |
span.line-through { text-decoration: line-through; } | |
div.unbreakable { page-break-inside: avoid; } | |
/* | |
* xhtml11 specific | |
* | |
* */ | |
div.tableblock { | |
margin-top: 1.0em; | |
margin-bottom: 1.5em; | |
} | |
div.tableblock > table { | |
border: 3px solid #527bbd; | |
} | |
thead, p.table.header { | |
font-weight: bold; | |
color: #527bbd; | |
} | |
p.table { | |
margin-top: 0; | |
} | |
/* Because the table frame attribute is overridden by CSS in most browsers. */ | |
div.tableblock > table[frame="void"] { | |
border-style: none; | |
} | |
div.tableblock > table[frame="hsides"] { | |
border-left-style: none; | |
border-right-style: none; | |
} | |
div.tableblock > table[frame="vsides"] { | |
border-top-style: none; | |
border-bottom-style: none; | |
} | |
/* | |
* html5 specific | |
* | |
* */ | |
table.tableblock { | |
margin-top: 1.0em; | |
margin-bottom: 1.5em; | |
} | |
thead, p.tableblock.header { | |
font-weight: bold; | |
color: #527bbd; | |
} | |
p.tableblock { | |
margin-top: 0; | |
} | |
table.tableblock { | |
border-width: 3px; | |
border-spacing: 0px; | |
border-style: solid; | |
border-color: #527bbd; | |
border-collapse: collapse; | |
} | |
th.tableblock, td.tableblock { | |
border-width: 1px; | |
padding: 4px; | |
border-style: solid; | |
border-color: #527bbd; | |
} | |
table.tableblock.frame-topbot { | |
border-left-style: hidden; | |
border-right-style: hidden; | |
} | |
table.tableblock.frame-sides { | |
border-top-style: hidden; | |
border-bottom-style: hidden; | |
} | |
table.tableblock.frame-none { | |
border-style: hidden; | |
} | |
th.tableblock.halign-left, td.tableblock.halign-left { | |
text-align: left; | |
} | |
th.tableblock.halign-center, td.tableblock.halign-center { | |
text-align: center; | |
} | |
th.tableblock.halign-right, td.tableblock.halign-right { | |
text-align: right; | |
} | |
th.tableblock.valign-top, td.tableblock.valign-top { | |
vertical-align: top; | |
} | |
th.tableblock.valign-middle, td.tableblock.valign-middle { | |
vertical-align: middle; | |
} | |
th.tableblock.valign-bottom, td.tableblock.valign-bottom { | |
vertical-align: bottom; | |
} | |
/* | |
* manpage specific | |
* | |
* */ | |
body.manpage h1 { | |
padding-top: 0.5em; | |
padding-bottom: 0.5em; | |
border-top: 2px solid silver; | |
border-bottom: 2px solid silver; | |
} | |
body.manpage h2 { | |
border-style: none; | |
} | |
body.manpage div.sectionbody { | |
margin-left: 3em; | |
} | |
@media print { | |
body.manpage div#toc { display: none; } | |
} | |
</style> | |
<script type="text/javascript"> | |
/*<![CDATA[*/ | |
var asciidoc = { // Namespace. | |
///////////////////////////////////////////////////////////////////// | |
// Table Of Contents generator | |
///////////////////////////////////////////////////////////////////// | |
/* Author: Mihai Bazon, September 2002 | |
* http://students.infoiasi.ro/~mishoo | |
* | |
* Table Of Content generator | |
* Version: 0.4 | |
* | |
* Feel free to use this script under the terms of the GNU General Public | |
* License, as long as you do not remove or alter this notice. | |
*/ | |
/* modified by Troy D. Hanson, September 2006. License: GPL */ | |
/* modified by Stuart Rackham, 2006, 2009. License: GPL */ | |
// toclevels = 1..4. | |
toc: function (toclevels) { | |
function getText(el) { | |
var text = ""; | |
for (var i = el.firstChild; i != null; i = i.nextSibling) { | |
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants. | |
text += i.data; | |
else if (i.firstChild != null) | |
text += getText(i); | |
} | |
return text; | |
} | |
function TocEntry(el, text, toclevel) { | |
this.element = el; | |
this.text = text; | |
this.toclevel = toclevel; | |
} | |
function tocEntries(el, toclevels) { | |
var result = new Array; | |
var re = new RegExp('[hH]([1-'+(toclevels+1)+'])'); | |
// Function that scans the DOM tree for header elements (the DOM2 | |
// nodeIterator API would be a better technique but not supported by all | |
// browsers). | |
var iterate = function (el) { | |
for (var i = el.firstChild; i != null; i = i.nextSibling) { | |
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) { | |
var mo = re.exec(i.tagName); | |
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") { | |
result[result.length] = new TocEntry(i, getText(i), mo[1]-1); | |
} | |
iterate(i); | |
} | |
} | |
} | |
iterate(el); | |
return result; | |
} | |
var toc = document.getElementById("toc"); | |
if (!toc) { | |
return; | |
} | |
// Delete existing TOC entries in case we're reloading the TOC. | |
var tocEntriesToRemove = []; | |
var i; | |
for (i = 0; i < toc.childNodes.length; i++) { | |
var entry = toc.childNodes[i]; | |
if (entry.nodeName.toLowerCase() == 'div' | |
&& entry.getAttribute("class") | |
&& entry.getAttribute("class").match(/^toclevel/)) | |
tocEntriesToRemove.push(entry); | |
} | |
for (i = 0; i < tocEntriesToRemove.length; i++) { | |
toc.removeChild(tocEntriesToRemove[i]); | |
} | |
// Rebuild TOC entries. | |
var entries = tocEntries(document.getElementById("content"), toclevels); | |
for (var i = 0; i < entries.length; ++i) { | |
var entry = entries[i]; | |
if (entry.element.id == "") | |
entry.element.id = "_toc_" + i; | |
var a = document.createElement("a"); | |
a.href = "#" + entry.element.id; | |
a.appendChild(document.createTextNode(entry.text)); | |
var div = document.createElement("div"); | |
div.appendChild(a); | |
div.className = "toclevel" + entry.toclevel; | |
toc.appendChild(div); | |
} | |
if (entries.length == 0) | |
toc.parentNode.removeChild(toc); | |
}, | |
///////////////////////////////////////////////////////////////////// | |
// Footnotes generator | |
///////////////////////////////////////////////////////////////////// | |
/* Based on footnote generation code from: | |
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html | |
*/ | |
footnotes: function () { | |
// Delete existing footnote entries in case we're reloading the footnodes. | |
var i; | |
var noteholder = document.getElementById("footnotes"); | |
if (!noteholder) { | |
return; | |
} | |
var entriesToRemove = []; | |
for (i = 0; i < noteholder.childNodes.length; i++) { | |
var entry = noteholder.childNodes[i]; | |
if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote") | |
entriesToRemove.push(entry); | |
} | |
for (i = 0; i < entriesToRemove.length; i++) { | |
noteholder.removeChild(entriesToRemove[i]); | |
} | |
// Rebuild footnote entries. | |
var cont = document.getElementById("content"); | |
var spans = cont.getElementsByTagName("span"); | |
var refs = {}; | |
var n = 0; | |
for (i=0; i<spans.length; i++) { | |
if (spans[i].className == "footnote") { | |
n++; | |
var note = spans[i].getAttribute("data-note"); | |
if (!note) { | |
// Use [\s\S] in place of . so multi-line matches work. | |
// Because JavaScript has no s (dotall) regex flag. | |
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1]; | |
spans[i].innerHTML = | |
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n + | |
"' title='View footnote' class='footnote'>" + n + "</a>]"; | |
spans[i].setAttribute("data-note", note); | |
} | |
noteholder.innerHTML += | |
"<div class='footnote' id='_footnote_" + n + "'>" + | |
"<a href='#_footnoteref_" + n + "' title='Return to text'>" + | |
n + "</a>. " + note + "</div>"; | |
var id =spans[i].getAttribute("id"); | |
if (id != null) refs["#"+id] = n; | |
} | |
} | |
if (n == 0) | |
noteholder.parentNode.removeChild(noteholder); | |
else { | |
// Process footnoterefs. | |
for (i=0; i<spans.length; i++) { | |
if (spans[i].className == "footnoteref") { | |
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href"); | |
href = href.match(/#.*/)[0]; // Because IE return full URL. | |
n = refs[href]; | |
spans[i].innerHTML = | |
"[<a href='#_footnote_" + n + | |
"' title='View footnote' class='footnote'>" + n + "</a>]"; | |
} | |
} | |
} | |
}, | |
install: function(toclevels) { | |
var timerId; | |
function reinstall() { | |
asciidoc.footnotes(); | |
if (toclevels) { | |
asciidoc.toc(toclevels); | |
} | |
} | |
function reinstallAndRemoveTimer() { | |
clearInterval(timerId); | |
reinstall(); | |
} | |
timerId = setInterval(reinstall, 500); | |
if (document.addEventListener) | |
document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false); | |
else | |
window.onload = reinstallAndRemoveTimer; | |
} | |
} | |
asciidoc.install(); | |
/*]]>*/ | |
</script> | |
</head> | |
<body class="manpage"> | |
<div id="header"> | |
<h1> | |
git-maintenance(1) Manual Page | |
</h1> | |
<h2>NAME</h2> | |
<div class="sectionbody"> | |
<p>git-maintenance - | |
Run tasks to optimize Git repository data | |
</p> | |
</div> | |
</div> | |
<div id="content"> | |
<div class="sect1"> | |
<h2 id="_synopsis">SYNOPSIS</h2> | |
<div class="sectionbody"> | |
<div class="verseblock"> | |
<pre class="content"><em>git maintenance</em> run [<options>] | |
<em>git maintenance</em> start [--scheduler=<scheduler>] | |
<em>git maintenance</em> (stop|register|unregister) [<options>]</pre> | |
<div class="attribution"> | |
</div></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_description">DESCRIPTION</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>Run tasks to optimize Git repository data, speeding up other Git commands | |
and reducing storage requirements for the repository.</p></div> | |
<div class="paragraph"><p>Git commands that add repository data, such as <code>git add</code> or <code>git fetch</code>, | |
are optimized for a responsive user experience. These commands do not take | |
time to optimize the Git data, since such optimizations scale with the full | |
size of the repository while these user commands each perform a relatively | |
small action.</p></div> | |
<div class="paragraph"><p>The <code>git maintenance</code> command provides flexibility for how to optimize the | |
Git repository.</p></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_subcommands">SUBCOMMANDS</h2> | |
<div class="sectionbody"> | |
<div class="dlist"><dl> | |
<dt class="hdlist1"> | |
run | |
</dt> | |
<dd> | |
<p> | |
Run one or more maintenance tasks. If one or more <code>--task</code> options | |
are specified, then those tasks are run in that order. Otherwise, | |
the tasks are determined by which <code>maintenance.<task>.enabled</code> | |
config options are true. By default, only <code>maintenance.gc.enabled</code> | |
is true. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
start | |
</dt> | |
<dd> | |
<p> | |
Start running maintenance on the current repository. This performs | |
the same config updates as the <code>register</code> subcommand, then updates | |
the background scheduler to run <code>git maintenance run --scheduled</code> | |
on an hourly basis. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
stop | |
</dt> | |
<dd> | |
<p> | |
Halt the background maintenance schedule. The current repository | |
is not removed from the list of maintained repositories, in case | |
the background maintenance is restarted later. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
register | |
</dt> | |
<dd> | |
<p> | |
Initialize Git config values so any scheduled maintenance will start | |
running on this repository. This adds the repository to the | |
<code>maintenance.repo</code> config variable in the current user’s global config, | |
or the config specified by --config-file option, and enables some | |
recommended configuration values for <code>maintenance.<task>.schedule</code>. The | |
tasks that are enabled are safe for running in the background without | |
disrupting foreground processes. | |
</p> | |
<div class="paragraph"><p>The <code>register</code> subcommand will also set the <code>maintenance.strategy</code> config | |
value to <code>incremental</code>, if this value is not previously set. The | |
<code>incremental</code> strategy uses the following schedule for each maintenance | |
task:</p></div> | |
<div class="openblock"> | |
<div class="content"> | |
<div class="ulist"><ul> | |
<li> | |
<p> | |
<code>gc</code>: disabled. | |
</p> | |
</li> | |
<li> | |
<p> | |
<code>commit-graph</code>: hourly. | |
</p> | |
</li> | |
<li> | |
<p> | |
<code>prefetch</code>: hourly. | |
</p> | |
</li> | |
<li> | |
<p> | |
<code>loose-objects</code>: daily. | |
</p> | |
</li> | |
<li> | |
<p> | |
<code>incremental-repack</code>: daily. | |
</p> | |
</li> | |
</ul></div> | |
</div></div> | |
<div class="paragraph"><p><code>git maintenance register</code> will also disable foreground maintenance by | |
setting <code>maintenance.auto = false</code> in the current repository. This config | |
setting will remain after a <code>git maintenance unregister</code> command.</p></div> | |
</dd> | |
<dt class="hdlist1"> | |
unregister | |
</dt> | |
<dd> | |
<p> | |
Remove the current repository from background maintenance. This | |
only removes the repository from the configured list. It does not | |
stop the background maintenance processes from running. | |
</p> | |
<div class="paragraph"><p>The <code>unregister</code> subcommand will report an error if the current repository | |
is not already registered. Use the <code>--force</code> option to return success even | |
when the current repository is not registered.</p></div> | |
</dd> | |
</dl></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_tasks">TASKS</h2> | |
<div class="sectionbody"> | |
<div class="dlist"><dl> | |
<dt class="hdlist1"> | |
commit-graph | |
</dt> | |
<dd> | |
<p> | |
The <code>commit-graph</code> job updates the <code>commit-graph</code> files incrementally, | |
then verifies that the written data is correct. The incremental | |
write is safe to run alongside concurrent Git processes since it | |
will not expire <code>.graph</code> files that were in the previous | |
<code>commit-graph-chain</code> file. They will be deleted by a later run based | |
on the expiration delay. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
prefetch | |
</dt> | |
<dd> | |
<p> | |
The <code>prefetch</code> task updates the object directory with the latest | |
objects from all registered remotes. For each remote, a <code>git fetch</code> | |
command is run. The configured refspec is modified to place all | |
requested refs within <code>refs/prefetch/</code>. Also, tags are not updated. | |
</p> | |
<div class="paragraph"><p>This is done to avoid disrupting the remote-tracking branches. The end users | |
expect these refs to stay unmoved unless they initiate a fetch. However, | |
with the prefetch task, the objects necessary to complete a later real fetch | |
would already be obtained, making the real fetch faster. In the ideal case, | |
it will just become an update to a bunch of remote-tracking branches without | |
any object transfer.</p></div> | |
</dd> | |
<dt class="hdlist1"> | |
gc | |
</dt> | |
<dd> | |
<p> | |
Clean up unnecessary files and optimize the local repository. "GC" | |
stands for "garbage collection," but this task performs many | |
smaller tasks. This task can be expensive for large repositories, | |
as it repacks all Git objects into a single pack-file. It can also | |
be disruptive in some situations, as it deletes stale data. See | |
<a href="git-gc.html">git-gc(1)</a> for more details on garbage collection in Git. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
loose-objects | |
</dt> | |
<dd> | |
<p> | |
The <code>loose-objects</code> job cleans up loose objects and places them into | |
pack-files. In order to prevent race conditions with concurrent Git | |
commands, it follows a two-step process. First, it deletes any loose | |
objects that already exist in a pack-file; concurrent Git processes | |
will examine the pack-file for the object data instead of the loose | |
object. Second, it creates a new pack-file (starting with "loose-") | |
containing a batch of loose objects. The batch size is limited to 50 | |
thousand objects to prevent the job from taking too long on a | |
repository with many loose objects. The <code>gc</code> task writes unreachable | |
objects as loose objects to be cleaned up by a later step only if | |
they are not re-added to a pack-file; for this reason it is not | |
advisable to enable both the <code>loose-objects</code> and <code>gc</code> tasks at the | |
same time. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
incremental-repack | |
</dt> | |
<dd> | |
<p> | |
The <code>incremental-repack</code> job repacks the object directory | |
using the <code>multi-pack-index</code> feature. In order to prevent race | |
conditions with concurrent Git commands, it follows a two-step | |
process. First, it calls <code>git multi-pack-index expire</code> to delete | |
pack-files unreferenced by the <code>multi-pack-index</code> file. Second, it | |
calls <code>git multi-pack-index repack</code> to select several small | |
pack-files and repack them into a bigger one, and then update the | |
<code>multi-pack-index</code> entries that refer to the small pack-files to | |
refer to the new pack-file. This prepares those small pack-files | |
for deletion upon the next run of <code>git multi-pack-index expire</code>. | |
The selection of the small pack-files is such that the expected | |
size of the big pack-file is at least the batch size; see the | |
<code>--batch-size</code> option for the <code>repack</code> subcommand in | |
<a href="git-multi-pack-index.html">git-multi-pack-index(1)</a>. The default batch-size is zero, | |
which is a special case that attempts to repack all pack-files | |
into a single pack-file. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
pack-refs | |
</dt> | |
<dd> | |
<p> | |
The <code>pack-refs</code> task collects the loose reference files and | |
collects them into a single file. This speeds up operations that | |
need to iterate across many references. See <a href="git-pack-refs.html">git-pack-refs(1)</a> | |
for more information. | |
</p> | |
</dd> | |
</dl></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_options">OPTIONS</h2> | |
<div class="sectionbody"> | |
<div class="dlist"><dl> | |
<dt class="hdlist1"> | |
--auto | |
</dt> | |
<dd> | |
<p> | |
When combined with the <code>run</code> subcommand, run maintenance tasks | |
only if certain thresholds are met. For example, the <code>gc</code> task | |
runs when the number of loose objects exceeds the number stored | |
in the <code>gc.auto</code> config setting, or when the number of pack-files | |
exceeds the <code>gc.autoPackLimit</code> config setting. Not compatible with | |
the <code>--schedule</code> option. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
--schedule | |
</dt> | |
<dd> | |
<p> | |
When combined with the <code>run</code> subcommand, run maintenance tasks | |
only if certain time conditions are met, as specified by the | |
<code>maintenance.<task>.schedule</code> config value for each <code><task></code>. | |
This config value specifies a number of seconds since the last | |
time that task ran, according to the <code>maintenance.<task>.lastRun</code> | |
config value. The tasks that are tested are those provided by | |
the <code>--task=<task></code> option(s) or those with | |
<code>maintenance.<task>.enabled</code> set to true. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
--quiet | |
</dt> | |
<dd> | |
<p> | |
Do not report progress or other information over <code>stderr</code>. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
--task=<task> | |
</dt> | |
<dd> | |
<p> | |
If this option is specified one or more times, then only run the | |
specified tasks in the specified order. If no <code>--task=<task></code> | |
arguments are specified, then only the tasks with | |
<code>maintenance.<task>.enabled</code> configured as <code>true</code> are considered. | |
See the <em>TASKS</em> section for the list of accepted <code><task></code> values. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
--scheduler=auto|crontab|systemd-timer|launchctl|schtasks | |
</dt> | |
<dd> | |
<p> | |
When combined with the <code>start</code> subcommand, specify the scheduler | |
for running the hourly, daily and weekly executions of | |
<code>git maintenance run</code>. | |
Possible values for <code><scheduler></code> are <code>auto</code>, <code>crontab</code> | |
(POSIX), <code>systemd-timer</code> (Linux), <code>launchctl</code> (macOS), and | |
<code>schtasks</code> (Windows). When <code>auto</code> is specified, the | |
appropriate platform-specific scheduler is used; on Linux, | |
<code>systemd-timer</code> is used if available, otherwise | |
<code>crontab</code>. Default is <code>auto</code>. | |
</p> | |
</dd> | |
</dl></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_troubleshooting">TROUBLESHOOTING</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>The <code>git maintenance</code> command is designed to simplify the repository | |
maintenance patterns while minimizing user wait time during Git commands. | |
A variety of configuration options are available to allow customizing this | |
process. The default maintenance options focus on operations that complete | |
quickly, even on large repositories.</p></div> | |
<div class="paragraph"><p>Users may find some cases where scheduled maintenance tasks do not run as | |
frequently as intended. Each <code>git maintenance run</code> command takes a lock on | |
the repository’s object database, and this prevents other concurrent | |
<code>git maintenance run</code> commands from running on the same repository. Without | |
this safeguard, competing processes could leave the repository in an | |
unpredictable state.</p></div> | |
<div class="paragraph"><p>The background maintenance schedule runs <code>git maintenance run</code> processes | |
on an hourly basis. Each run executes the "hourly" tasks. At midnight, | |
that process also executes the "daily" tasks. At midnight on the first day | |
of the week, that process also executes the "weekly" tasks. A single | |
process iterates over each registered repository, performing the scheduled | |
tasks for that frequency. Depending on the number of registered | |
repositories and their sizes, this process may take longer than an hour. | |
In this case, multiple <code>git maintenance run</code> commands may run on the same | |
repository at the same time, colliding on the object database lock. This | |
results in one of the two tasks not running.</p></div> | |
<div class="paragraph"><p>If you find that some maintenance windows are taking longer than one hour | |
to complete, then consider reducing the complexity of your maintenance | |
tasks. For example, the <code>gc</code> task is much slower than the | |
<code>incremental-repack</code> task. However, this comes at a cost of a slightly | |
larger object database. Consider moving more expensive tasks to be run | |
less frequently.</p></div> | |
<div class="paragraph"><p>Expert users may consider scheduling their own maintenance tasks using a | |
different schedule than is available through <code>git maintenance start</code> and | |
Git configuration options. These users should be aware of the object | |
database lock and how concurrent <code>git maintenance run</code> commands behave. | |
Further, the <code>git gc</code> command should not be combined with | |
<code>git maintenance run</code> commands. <code>git gc</code> modifies the object database | |
but does not take the lock in the same way as <code>git maintenance run</code>. If | |
possible, use <code>git maintenance run --task=gc</code> instead of <code>git gc</code>.</p></div> | |
<div class="paragraph"><p>The following sections describe the mechanisms put in place to run | |
background maintenance by <code>git maintenance start</code> and how to customize | |
them.</p></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_background_maintenance_on_posix_systems">BACKGROUND MAINTENANCE ON POSIX SYSTEMS</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>The standard mechanism for scheduling background tasks on POSIX systems | |
is cron(8). This tool executes commands based on a given schedule. The | |
current list of user-scheduled tasks can be found by running <code>crontab -l</code>. | |
The schedule written by <code>git maintenance start</code> is similar to this:</p></div> | |
<div class="listingblock"> | |
<div class="content"> | |
<pre><code># BEGIN GIT MAINTENANCE SCHEDULE | |
# The following schedule was created by Git | |
# Any edits made in this region might be | |
# replaced in the future by a Git command. | |
0 1-23 * * * "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=hourly | |
0 0 * * 1-6 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=daily | |
0 0 * * 0 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=weekly | |
# END GIT MAINTENANCE SCHEDULE</code></pre> | |
</div></div> | |
<div class="paragraph"><p>The comments are used as a region to mark the schedule as written by Git. | |
Any modifications within this region will be completely deleted by | |
<code>git maintenance stop</code> or overwritten by <code>git maintenance start</code>.</p></div> | |
<div class="paragraph"><p>The <code>crontab</code> entry specifies the full path of the <code>git</code> executable to | |
ensure that the executed <code>git</code> command is the same one with which | |
<code>git maintenance start</code> was issued independent of <code>PATH</code>. If the same user | |
runs <code>git maintenance start</code> with multiple Git executables, then only the | |
latest executable is used.</p></div> | |
<div class="paragraph"><p>These commands use <code>git for-each-repo --config=maintenance.repo</code> to run | |
<code>git maintenance run --schedule=<frequency></code> on each repository listed in | |
the multi-valued <code>maintenance.repo</code> config option. These are typically | |
loaded from the user-specific global config. The <code>git maintenance</code> process | |
then determines which maintenance tasks are configured to run on each | |
repository with each <code><frequency></code> using the <code>maintenance.<task>.schedule</code> | |
config options. These values are loaded from the global or repository | |
config values.</p></div> | |
<div class="paragraph"><p>If the config values are insufficient to achieve your desired background | |
maintenance schedule, then you can create your own schedule. If you run | |
<code>crontab -e</code>, then an editor will load with your user-specific <code>cron</code> | |
schedule. In that editor, you can add your own schedule lines. You could | |
start by adapting the default schedule listed earlier, or you could read | |
the crontab(5) documentation for advanced scheduling techniques. Please | |
do use the full path and <code>--exec-path</code> techniques from the default | |
schedule to ensure you are executing the correct binaries in your | |
schedule.</p></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_background_maintenance_on_linux_systemd_systems">BACKGROUND MAINTENANCE ON LINUX SYSTEMD SYSTEMS</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>While Linux supports <code>cron</code>, depending on the distribution, <code>cron</code> may | |
be an optional package not necessarily installed. On modern Linux | |
distributions, systemd timers are superseding it.</p></div> | |
<div class="paragraph"><p>If user systemd timers are available, they will be used as a replacement | |
of <code>cron</code>.</p></div> | |
<div class="paragraph"><p>In this case, <code>git maintenance start</code> will create user systemd timer units | |
and start the timers. The current list of user-scheduled tasks can be found | |
by running <code>systemctl --user list-timers</code>. The timers written by <code>git | |
maintenance start</code> are similar to this:</p></div> | |
<div class="listingblock"> | |
<div class="content"> | |
<pre><code>$ systemctl --user list-timers | |
NEXT LEFT LAST PASSED UNIT ACTIVATES | |
Thu 2021-04-29 19:00:00 CEST 42min left Thu 2021-04-29 18:00:11 CEST 17min ago git-maintenance@hourly.timer git-maintenance@hourly.service | |
Fri 2021-04-30 00:00:00 CEST 5h 42min left Thu 2021-04-29 00:00:11 CEST 18h ago git-maintenance@daily.timer git-maintenance@daily.service | |
Mon 2021-05-03 00:00:00 CEST 3 days left Mon 2021-04-26 00:00:11 CEST 3 days ago git-maintenance@weekly.timer git-maintenance@weekly.service</code></pre> | |
</div></div> | |
<div class="paragraph"><p>One timer is registered for each <code>--schedule=<frequency></code> option.</p></div> | |
<div class="paragraph"><p>The definition of the systemd units can be inspected in the following files:</p></div> | |
<div class="listingblock"> | |
<div class="content"> | |
<pre><code>~/.config/systemd/user/git-maintenance@.timer | |
~/.config/systemd/user/git-maintenance@.service | |
~/.config/systemd/user/timers.target.wants/git-maintenance@hourly.timer | |
~/.config/systemd/user/timers.target.wants/git-maintenance@daily.timer | |
~/.config/systemd/user/timers.target.wants/git-maintenance@weekly.timer</code></pre> | |
</div></div> | |
<div class="paragraph"><p><code>git maintenance start</code> will overwrite these files and start the timer | |
again with <code>systemctl --user</code>, so any customization should be done by | |
creating a drop-in file, i.e. a <code>.conf</code> suffixed file in the | |
<code>~/.config/systemd/user/git-maintenance@.service.d</code> directory.</p></div> | |
<div class="paragraph"><p><code>git maintenance stop</code> will stop the user systemd timers and delete | |
the above mentioned files.</p></div> | |
<div class="paragraph"><p>For more details, see <code>systemd.timer(5)</code>.</p></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_background_maintenance_on_macos_systems">BACKGROUND MAINTENANCE ON MACOS SYSTEMS</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>While macOS technically supports <code>cron</code>, using <code>crontab -e</code> requires | |
elevated privileges and the executed process does not have a full user | |
context. Without a full user context, Git and its credential helpers | |
cannot access stored credentials, so some maintenance tasks are not | |
functional.</p></div> | |
<div class="paragraph"><p>Instead, <code>git maintenance start</code> interacts with the <code>launchctl</code> tool, | |
which is the recommended way to schedule timed jobs in macOS. Scheduling | |
maintenance through <code>git maintenance (start|stop)</code> requires some | |
<code>launchctl</code> features available only in macOS 10.11 or later.</p></div> | |
<div class="paragraph"><p>Your user-specific scheduled tasks are stored as XML-formatted <code>.plist</code> | |
files in <code>~/Library/LaunchAgents/</code>. You can see the currently-registered | |
tasks using the following command:</p></div> | |
<div class="listingblock"> | |
<div class="content"> | |
<pre><code>$ ls ~/Library/LaunchAgents/org.git-scm.git* | |
org.git-scm.git.daily.plist | |
org.git-scm.git.hourly.plist | |
org.git-scm.git.weekly.plist</code></pre> | |
</div></div> | |
<div class="paragraph"><p>One task is registered for each <code>--schedule=<frequency></code> option. To | |
inspect how the XML format describes each schedule, open one of these | |
<code>.plist</code> files in an editor and inspect the <code><array></code> element following | |
the <code><key>StartCalendarInterval</key></code> element.</p></div> | |
<div class="paragraph"><p><code>git maintenance start</code> will overwrite these files and register the | |
tasks again with <code>launchctl</code>, so any customizations should be done by | |
creating your own <code>.plist</code> files with distinct names. Similarly, the | |
<code>git maintenance stop</code> command will unregister the tasks with <code>launchctl</code> | |
and delete the <code>.plist</code> files.</p></div> | |
<div class="paragraph"><p>To create more advanced customizations to your background tasks, see | |
launchctl.plist(5) for more information.</p></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_background_maintenance_on_windows_systems">BACKGROUND MAINTENANCE ON WINDOWS SYSTEMS</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>Windows does not support <code>cron</code> and instead has its own system for | |
scheduling background tasks. The <code>git maintenance start</code> command uses | |
the <code>schtasks</code> command to submit tasks to this system. You can inspect | |
all background tasks using the Task Scheduler application. The tasks | |
added by Git have names of the form <code>Git Maintenance (<frequency>)</code>. | |
The Task Scheduler GUI has ways to inspect these tasks, but you can also | |
export the tasks to XML files and view the details there.</p></div> | |
<div class="paragraph"><p>Note that since Git is a console application, these background tasks | |
create a console window visible to the current user. This can be changed | |
manually by selecting the "Run whether user is logged in or not" option | |
in Task Scheduler. This change requires a password input, which is why | |
<code>git maintenance start</code> does not select it by default.</p></div> | |
<div class="paragraph"><p>If you want to customize the background tasks, please rename the tasks | |
so future calls to <code>git maintenance (start|stop)</code> do not overwrite your | |
custom tasks.</p></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_configuration">CONFIGURATION</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>Everything below this line in this section is selectively included | |
from the <a href="git-config.html">git-config(1)</a> documentation. The content is the same | |
as what’s found there:</p></div> | |
<div class="dlist"><dl> | |
<dt class="hdlist1"> | |
maintenance.auto | |
</dt> | |
<dd> | |
<p> | |
This boolean config option controls whether some commands run | |
<code>git maintenance run --auto</code> after doing their normal work. Defaults | |
to true. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
maintenance.strategy | |
</dt> | |
<dd> | |
<p> | |
This string config option provides a way to specify one of a few | |
recommended schedules for background maintenance. This only affects | |
which tasks are run during <code>git maintenance run --schedule=X</code> | |
commands, provided no <code>--task=<task></code> arguments are provided. | |
Further, if a <code>maintenance.<task>.schedule</code> config value is set, | |
then that value is used instead of the one provided by | |
<code>maintenance.strategy</code>. The possible strategy strings are: | |
</p> | |
<div class="ulist"><ul> | |
<li> | |
<p> | |
<code>none</code>: This default setting implies no tasks are run at any schedule. | |
</p> | |
</li> | |
<li> | |
<p> | |
<code>incremental</code>: This setting optimizes for performing small maintenance | |
activities that do not delete any data. This does not schedule the <code>gc</code> | |
task, but runs the <code>prefetch</code> and <code>commit-graph</code> tasks hourly, the | |
<code>loose-objects</code> and <code>incremental-repack</code> tasks daily, and the <code>pack-refs</code> | |
task weekly. | |
</p> | |
</li> | |
</ul></div> | |
</dd> | |
<dt class="hdlist1"> | |
maintenance.<task>.enabled | |
</dt> | |
<dd> | |
<p> | |
This boolean config option controls whether the maintenance task | |
with name <code><task></code> is run when no <code>--task</code> option is specified to | |
<code>git maintenance run</code>. These config values are ignored if a | |
<code>--task</code> option exists. By default, only <code>maintenance.gc.enabled</code> | |
is true. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
maintenance.<task>.schedule | |
</dt> | |
<dd> | |
<p> | |
This config option controls whether or not the given <code><task></code> runs | |
during a <code>git maintenance run --schedule=<frequency></code> command. The | |
value must be one of "hourly", "daily", or "weekly". | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
maintenance.commit-graph.auto | |
</dt> | |
<dd> | |
<p> | |
This integer config option controls how often the <code>commit-graph</code> task | |
should be run as part of <code>git maintenance run --auto</code>. If zero, then | |
the <code>commit-graph</code> task will not run with the <code>--auto</code> option. A | |
negative value will force the task to run every time. Otherwise, a | |
positive value implies the command should run when the number of | |
reachable commits that are not in the commit-graph file is at least | |
the value of <code>maintenance.commit-graph.auto</code>. The default value is | |
100. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
maintenance.loose-objects.auto | |
</dt> | |
<dd> | |
<p> | |
This integer config option controls how often the <code>loose-objects</code> task | |
should be run as part of <code>git maintenance run --auto</code>. If zero, then | |
the <code>loose-objects</code> task will not run with the <code>--auto</code> option. A | |
negative value will force the task to run every time. Otherwise, a | |
positive value implies the command should run when the number of | |
loose objects is at least the value of <code>maintenance.loose-objects.auto</code>. | |
The default value is 100. | |
</p> | |
</dd> | |
<dt class="hdlist1"> | |
maintenance.incremental-repack.auto | |
</dt> | |
<dd> | |
<p> | |
This integer config option controls how often the <code>incremental-repack</code> | |
task should be run as part of <code>git maintenance run --auto</code>. If zero, | |
then the <code>incremental-repack</code> task will not run with the <code>--auto</code> | |
option. A negative value will force the task to run every time. | |
Otherwise, a positive value implies the command should run when the | |
number of pack-files not in the multi-pack-index is at least the value | |
of <code>maintenance.incremental-repack.auto</code>. The default value is 10. | |
</p> | |
</dd> | |
</dl></div> | |
</div> | |
</div> | |
<div class="sect1"> | |
<h2 id="_git">GIT</h2> | |
<div class="sectionbody"> | |
<div class="paragraph"><p>Part of the <a href="git.html">git(1)</a> suite</p></div> | |
</div> | |
</div> | |
</div> | |
<div id="footnotes"><hr /></div> | |
<div id="footer"> | |
<div id="footer-text"> | |
Last updated | |
2023-10-23 14:43:46 PDT | |
</div> | |
</div> | |
</body> | |
</html> |