blob: 03373c3050d920b5a350528ab1cf3a30029f513b [file] [log] [blame]
Junio C Hamano0df92712011-12-21 22:30:441<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6<meta name="generator" content="AsciiDoc 8.5.2" />
7<title>credentials API</title>
8<style type="text/css">
9/* Debug borders */
10p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
11/*
12 border: 1px solid red;
13*/
14}
15
16body {
17 margin: 1em 5% 1em 5%;
18}
19
20a {
21 color: blue;
22 text-decoration: underline;
23}
24a:visited {
25 color: fuchsia;
26}
27
28em {
29 font-style: italic;
30 color: navy;
31}
32
33strong {
34 font-weight: bold;
35 color: #083194;
36}
37
38tt {
39 color: navy;
40}
41
42h1, h2, h3, h4, h5, h6 {
43 color: #527bbd;
44 font-family: sans-serif;
45 margin-top: 1.2em;
46 margin-bottom: 0.5em;
47 line-height: 1.3;
48}
49
50h1, h2, h3 {
51 border-bottom: 2px solid silver;
52}
53h2 {
54 padding-top: 0.5em;
55}
56h3 {
57 float: left;
58}
59h3 + * {
60 clear: left;
61}
62
63div.sectionbody {
64 font-family: serif;
65 margin-left: 0;
66}
67
68hr {
69 border: 1px solid silver;
70}
71
72p {
73 margin-top: 0.5em;
74 margin-bottom: 0.5em;
75}
76
77ul, ol, li > p {
78 margin-top: 0;
79}
80
81pre {
82 padding: 0;
83 margin: 0;
84}
85
86span#author {
87 color: #527bbd;
88 font-family: sans-serif;
89 font-weight: bold;
90 font-size: 1.1em;
91}
92span#email {
93}
94span#revnumber, span#revdate, span#revremark {
95 font-family: sans-serif;
96}
97
98div#footer {
99 font-family: sans-serif;
100 font-size: small;
101 border-top: 2px solid silver;
102 padding-top: 0.5em;
103 margin-top: 4.0em;
104}
105div#footer-text {
106 float: left;
107 padding-bottom: 0.5em;
108}
109div#footer-badges {
110 float: right;
111 padding-bottom: 0.5em;
112}
113
114div#preamble {
115 margin-top: 1.5em;
116 margin-bottom: 1.5em;
117}
118div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
119div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
120div.admonitionblock {
121 margin-top: 1.0em;
122 margin-bottom: 1.5em;
123}
124div.admonitionblock {
125 margin-top: 2.0em;
126 margin-bottom: 2.0em;
127 margin-right: 10%;
128 color: #606060;
129}
130
131div.content { /* Block element content. */
132 padding: 0;
133}
134
135/* Block element titles. */
136div.title, caption.title {
137 color: #527bbd;
138 font-family: sans-serif;
139 font-weight: bold;
140 text-align: left;
141 margin-top: 1.0em;
142 margin-bottom: 0.5em;
143}
144div.title + * {
145 margin-top: 0;
146}
147
148td div.title:first-child {
149 margin-top: 0.0em;
150}
151div.content div.title:first-child {
152 margin-top: 0.0em;
153}
154div.content + div.title {
155 margin-top: 0.0em;
156}
157
158div.sidebarblock > div.content {
159 background: #ffffee;
160 border: 1px solid silver;
161 padding: 0.5em;
162}
163
164div.listingblock > div.content {
165 border: 1px solid silver;
166 background: #f4f4f4;
167 padding: 0.5em;
168}
169
170div.quoteblock, div.verseblock {
171 padding-left: 1.0em;
172 margin-left: 1.0em;
173 margin-right: 10%;
174 border-left: 5px solid #dddddd;
175 color: #777777;
176}
177
178div.quoteblock > div.attribution {
179 padding-top: 0.5em;
180 text-align: right;
181}
182
183div.verseblock > div.content {
184 white-space: pre;
185}
186div.verseblock > div.attribution {
187 padding-top: 0.75em;
188 text-align: left;
189}
190/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
191div.verseblock + div.attribution {
192 text-align: left;
193}
194
195div.admonitionblock .icon {
196 vertical-align: top;
197 font-size: 1.1em;
198 font-weight: bold;
199 text-decoration: underline;
200 color: #527bbd;
201 padding-right: 0.5em;
202}
203div.admonitionblock td.content {
204 padding-left: 0.5em;
205 border-left: 3px solid #dddddd;
206}
207
208div.exampleblock > div.content {
209 border-left: 3px solid #dddddd;
210 padding-left: 0.5em;
211}
212
213div.imageblock div.content { padding-left: 0; }
214span.image img { border-style: none; }
215a.image:visited { color: white; }
216
217dl {
218 margin-top: 0.8em;
219 margin-bottom: 0.8em;
220}
221dt {
222 margin-top: 0.5em;
223 margin-bottom: 0;
224 font-style: normal;
225 color: navy;
226}
227dd > *:first-child {
228 margin-top: 0.1em;
229}
230
231ul, ol {
232 list-style-position: outside;
233}
234ol.arabic {
235 list-style-type: decimal;
236}
237ol.loweralpha {
238 list-style-type: lower-alpha;
239}
240ol.upperalpha {
241 list-style-type: upper-alpha;
242}
243ol.lowerroman {
244 list-style-type: lower-roman;
245}
246ol.upperroman {
247 list-style-type: upper-roman;
248}
249
250div.compact ul, div.compact ol,
251div.compact p, div.compact p,
252div.compact div, div.compact div {
253 margin-top: 0.1em;
254 margin-bottom: 0.1em;
255}
256
257div.tableblock > table {
258 border: 3px solid #527bbd;
259}
260thead, p.table.header {
261 font-family: sans-serif;
262 font-weight: bold;
263}
264tfoot {
265 font-weight: bold;
266}
267td > div.verse {
268 white-space: pre;
269}
270p.table {
271 margin-top: 0;
272}
273/* Because the table frame attribute is overriden by CSS in most browsers. */
274div.tableblock > table[frame="void"] {
275 border-style: none;
276}
277div.tableblock > table[frame="hsides"] {
278 border-left-style: none;
279 border-right-style: none;
280}
281div.tableblock > table[frame="vsides"] {
282 border-top-style: none;
283 border-bottom-style: none;
284}
285
286
287div.hdlist {
288 margin-top: 0.8em;
289 margin-bottom: 0.8em;
290}
291div.hdlist tr {
292 padding-bottom: 15px;
293}
294dt.hdlist1.strong, td.hdlist1.strong {
295 font-weight: bold;
296}
297td.hdlist1 {
298 vertical-align: top;
299 font-style: normal;
300 padding-right: 0.8em;
301 color: navy;
302}
303td.hdlist2 {
304 vertical-align: top;
305}
306div.hdlist.compact tr {
307 margin: 0;
308 padding-bottom: 0;
309}
310
311.comment {
312 background: yellow;
313}
314
315.footnote, .footnoteref {
316 font-size: 0.8em;
317}
318
319span.footnote, span.footnoteref {
320 vertical-align: super;
321}
322
323#footnotes {
324 margin: 20px 0 20px 0;
325 padding: 7px 0 0 0;
326}
327
328#footnotes div.footnote {
329 margin: 0 0 5px 0;
330}
331
332#footnotes hr {
333 border: none;
334 border-top: 1px solid silver;
335 height: 1px;
336 text-align: left;
337 margin-left: 0;
338 width: 20%;
339 min-width: 100px;
340}
341
342
343@media print {
344 div#footer-badges { display: none; }
345}
346
347div#toc {
348 margin-bottom: 2.5em;
349}
350
351div#toctitle {
352 color: #527bbd;
353 font-family: sans-serif;
354 font-size: 1.1em;
355 font-weight: bold;
356 margin-top: 1.0em;
357 margin-bottom: 0.1em;
358}
359
360div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
361 margin-top: 0;
362 margin-bottom: 0;
363}
364div.toclevel2 {
365 margin-left: 2em;
366 font-size: 0.9em;
367}
368div.toclevel3 {
369 margin-left: 4em;
370 font-size: 0.9em;
371}
372div.toclevel4 {
373 margin-left: 6em;
374 font-size: 0.9em;
375}
376/* Workarounds for IE6's broken and incomplete CSS2. */
377
378div.sidebar-content {
379 background: #ffffee;
380 border: 1px solid silver;
381 padding: 0.5em;
382}
383div.sidebar-title, div.image-title {
384 color: #527bbd;
385 font-family: sans-serif;
386 font-weight: bold;
387 margin-top: 0.0em;
388 margin-bottom: 0.5em;
389}
390
391div.listingblock div.content {
392 border: 1px solid silver;
393 background: #f4f4f4;
394 padding: 0.5em;
395}
396
397div.quoteblock-attribution {
398 padding-top: 0.5em;
399 text-align: right;
400}
401
402div.verseblock-content {
403 white-space: pre;
404}
405div.verseblock-attribution {
406 padding-top: 0.75em;
407 text-align: left;
408}
409
410div.exampleblock-content {
411 border-left: 3px solid #dddddd;
412 padding-left: 0.5em;
413}
414
415/* IE6 sets dynamically generated links as visited. */
416div#toc a:visited { color: blue; }
417</style>
418<script type="text/javascript">
419/*<![CDATA[*/
420window.onload = function(){asciidoc.footnotes();}
421var asciidoc = { // Namespace.
422
423/////////////////////////////////////////////////////////////////////
424// Table Of Contents generator
425/////////////////////////////////////////////////////////////////////
426
427/* Author: Mihai Bazon, September 2002
428 * http://students.infoiasi.ro/~mishoo
429 *
430 * Table Of Content generator
431 * Version: 0.4
432 *
433 * Feel free to use this script under the terms of the GNU General Public
434 * License, as long as you do not remove or alter this notice.
435 */
436
437 /* modified by Troy D. Hanson, September 2006. License: GPL */
438 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
439
440// toclevels = 1..4.
441toc: function (toclevels) {
442
443 function getText(el) {
444 var text = "";
445 for (var i = el.firstChild; i != null; i = i.nextSibling) {
446 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
447 text += i.data;
448 else if (i.firstChild != null)
449 text += getText(i);
450 }
451 return text;
452 }
453
454 function TocEntry(el, text, toclevel) {
455 this.element = el;
456 this.text = text;
457 this.toclevel = toclevel;
458 }
459
460 function tocEntries(el, toclevels) {
461 var result = new Array;
462 var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
463 // Function that scans the DOM tree for header elements (the DOM2
464 // nodeIterator API would be a better technique but not supported by all
465 // browsers).
466 var iterate = function (el) {
467 for (var i = el.firstChild; i != null; i = i.nextSibling) {
468 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
469 var mo = re.exec(i.tagName);
470 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
471 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
472 }
473 iterate(i);
474 }
475 }
476 }
477 iterate(el);
478 return result;
479 }
480
481 var toc = document.getElementById("toc");
482 var entries = tocEntries(document.getElementById("content"), toclevels);
483 for (var i = 0; i < entries.length; ++i) {
484 var entry = entries[i];
485 if (entry.element.id == "")
486 entry.element.id = "_toc_" + i;
487 var a = document.createElement("a");
488 a.href = "#" + entry.element.id;
489 a.appendChild(document.createTextNode(entry.text));
490 var div = document.createElement("div");
491 div.appendChild(a);
492 div.className = "toclevel" + entry.toclevel;
493 toc.appendChild(div);
494 }
495 if (entries.length == 0)
496 toc.parentNode.removeChild(toc);
497},
498
499
500/////////////////////////////////////////////////////////////////////
501// Footnotes generator
502/////////////////////////////////////////////////////////////////////
503
504/* Based on footnote generation code from:
505 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
506 */
507
508footnotes: function () {
509 var cont = document.getElementById("content");
510 var noteholder = document.getElementById("footnotes");
511 var spans = cont.getElementsByTagName("span");
512 var refs = {};
513 var n = 0;
514 for (i=0; i<spans.length; i++) {
515 if (spans[i].className == "footnote") {
516 n++;
517 // Use [\s\S] in place of . so multi-line matches work.
518 // Because JavaScript has no s (dotall) regex flag.
519 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
520 noteholder.innerHTML +=
521 "<div class='footnote' id='_footnote_" + n + "'>" +
522 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
523 n + "</a>. " + note + "</div>";
524 spans[i].innerHTML =
525 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
526 "' title='View footnote' class='footnote'>" + n + "</a>]";
527 var id =spans[i].getAttribute("id");
528 if (id != null) refs["#"+id] = n;
529 }
530 }
531 if (n == 0)
532 noteholder.parentNode.removeChild(noteholder);
533 else {
534 // Process footnoterefs.
535 for (i=0; i<spans.length; i++) {
536 if (spans[i].className == "footnoteref") {
537 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
538 href = href.match(/#.*/)[0]; // Because IE return full URL.
539 n = refs[href];
540 spans[i].innerHTML =
541 "[<a href='#_footnote_" + n +
542 "' title='View footnote' class='footnote'>" + n + "</a>]";
543 }
544 }
545 }
546}
547
548}
549/*]]>*/
550</script>
551</head>
552<body>
553<div id="header">
554<h1>credentials API</h1>
555</div>
556<div id="content">
557<div id="preamble">
558<div class="sectionbody">
559<div class="paragraph"><p>The credentials API provides an abstracted way of gathering username and
560password credentials from the user (even though credentials in the wider
561world can take many forms, in this document the word "credential" always
562refers to a username and password pair).</p></div>
Junio C Hamano022bd342012-06-07 20:15:35563<div class="paragraph"><p>This document describes two interfaces: the C API that the credential
564subsystem provides to the rest of git, and the protocol that git uses to
565communicate with system-specific "credential helpers". If you are
566writing git code that wants to look up or prompt for credentials, see
567the section "C API" below. If you want to write your own helper, see
568the section on "Credential Helpers" below.</p></div>
Junio C Hamano0df92712011-12-21 22:30:44569</div>
570</div>
Junio C Hamano022bd342012-06-07 20:15:35571<h2 id="_typical_setup">Typical setup</h2>
Junio C Hamano0df92712011-12-21 22:30:44572<div class="sectionbody">
Junio C Hamano022bd342012-06-07 20:15:35573<div class="listingblock">
574<div class="content">
575<pre><tt>+-----------------------+
576| git code (C) |--- to server requiring ---&gt;
577| | authentication
578|.......................|
579| C credential API |--- prompt ---&gt; User
580+-----------------------+
581 ^ |
582 | pipe |
583 | v
584+-----------------------+
585| git credential helper |
586+-----------------------+</tt></pre>
587</div></div>
588<div class="paragraph"><p>The git code (typically a remote-helper) will call the C API to obtain
589credential data like a login/password pair (credential_fill). The
590API will itself call a remote helper (e.g. "git credential-cache" or
591"git credential-store") that may retrieve credential data from a
592store. If the credential helper cannot find the information, the C API
593will prompt the user. Then, the caller of the API takes care of
594contacting the server, and does the actual authentication.</p></div>
595</div>
596<h2 id="_c_api">C API</h2>
597<div class="sectionbody">
598<div class="paragraph"><p>The credential C API is meant to be called by git code which needs to
599acquire or store a credential. It is centered around an object
600representing a single credential and provides three basic operations:
601fill (acquire credentials by calling helpers and/or prompting the user),
602approve (mark a credential as successfully used so that it can be stored
603for later use), and reject (mark a credential as unsuccessful so that it
604can be erased from any persistent storage).</p></div>
605<h3 id="_data_structures">Data Structures</h3><div style="clear:left"></div>
Junio C Hamano0df92712011-12-21 22:30:44606<div class="dlist"><dl>
607<dt class="hdlist1">
608<tt>struct credential</tt>
609</dt>
610<dd>
611<p>
612 This struct represents a single username/password combination
613 along with any associated context. All string fields should be
614 heap-allocated (or NULL if they are not known or not applicable).
615 The meaning of the individual context fields is the same as
616 their counterparts in the helper protocol; see the section below
617 for a description of each field.
618</p>
619<div class="paragraph"><p>The <tt>helpers</tt> member of the struct is a <tt>string_list</tt> of helpers. Each
620string specifies an external helper which will be run, in order, to
621either acquire or store credentials. See the section on credential
Junio C Hamano9f9ed8b2012-06-13 07:21:43622helpers below. This list is filled-in by the API functions
623according to the corresponding configuration variables before
624consulting helpers, so there usually is no need for a caller to
625modify the helpers field at all.</p></div>
Junio C Hamano0df92712011-12-21 22:30:44626<div class="paragraph"><p>This struct should always be initialized with <tt>CREDENTIAL_INIT</tt> or
627<tt>credential_init</tt>.</p></div>
628</dd>
629</dl></div>
Junio C Hamano022bd342012-06-07 20:15:35630<h3 id="_functions">Functions</h3><div style="clear:left"></div>
Junio C Hamano0df92712011-12-21 22:30:44631<div class="dlist"><dl>
632<dt class="hdlist1">
633<tt>credential_init</tt>
634</dt>
635<dd>
636<p>
637 Initialize a credential structure, setting all fields to empty.
638</p>
639</dd>
640<dt class="hdlist1">
641<tt>credential_clear</tt>
642</dt>
643<dd>
644<p>
645 Free any resources associated with the credential structure,
646 returning it to a pristine initialized state.
647</p>
648</dd>
649<dt class="hdlist1">
650<tt>credential_fill</tt>
651</dt>
652<dd>
653<p>
654 Instruct the credential subsystem to fill the username and
655 password fields of the passed credential struct by first
656 consulting helpers, then asking the user. After this function
657 returns, the username and password fields of the credential are
658 guaranteed to be non-NULL. If an error occurs, the function will
659 die().
660</p>
661</dd>
662<dt class="hdlist1">
663<tt>credential_reject</tt>
664</dt>
665<dd>
666<p>
667 Inform the credential subsystem that the provided credentials
668 have been rejected. This will cause the credential subsystem to
669 notify any helpers of the rejection (which allows them, for
670 example, to purge the invalid credentials from storage). It
671 will also free() the username and password fields of the
672 credential and set them to NULL (readying the credential for
673 another call to <tt>credential_fill</tt>). Any errors from helpers are
674 ignored.
675</p>
676</dd>
677<dt class="hdlist1">
678<tt>credential_approve</tt>
679</dt>
680<dd>
681<p>
682 Inform the credential subsystem that the provided credentials
683 were successfully used for authentication. This will cause the
684 credential subsystem to notify any helpers of the approval, so
685 that they may store the result to be used again. Any errors
686 from helpers are ignored.
687</p>
688</dd>
689<dt class="hdlist1">
690<tt>credential_from_url</tt>
691</dt>
692<dd>
693<p>
694 Parse a URL into broken-down credential fields.
695</p>
696</dd>
697</dl></div>
Junio C Hamano022bd342012-06-07 20:15:35698<h3 id="_example">Example</h3><div style="clear:left"></div>
Junio C Hamano0df92712011-12-21 22:30:44699<div class="paragraph"><p>The example below shows how the functions of the credential API could be
700used to login to a fictitious "foo" service on a remote host:</p></div>
701<div class="listingblock">
702<div class="content">
703<pre><tt>int foo_login(struct foo_connection *f)
704{
705 int status;
706 /*
707 * Create a credential with some context; we don't yet know the
708 * username or password.
709 */
710
711 struct credential c = CREDENTIAL_INIT;
712 c.protocol = xstrdup("foo");
713 c.host = xstrdup(f-&gt;hostname);
714
715 /*
716 * Fill in the username and password fields by contacting
717 * helpers and/or asking the user. The function will die if it
718 * fails.
719 */
720 credential_fill(&amp;c);
721
722 /*
723 * Otherwise, we have a username and password. Try to use it.
724 */
725 status = send_foo_login(f, c.username, c.password);
726 switch (status) {
727 case FOO_OK:
728 /* It worked. Store the credential for later use. */
729 credential_accept(&amp;c);
730 break;
731 case FOO_BAD_LOGIN:
732 /* Erase the credential from storage so we don't try it
733 * again. */
734 credential_reject(&amp;c);
735 break;
736 default:
737 /*
738 * Some other error occured. We don't know if the
739 * credential is good or bad, so report nothing to the
740 * credential subsystem.
741 */
742 }
743
744 /* Free any associated resources. */
745 credential_clear(&amp;c);
746
747 return status;
748}</tt></pre>
749</div></div>
750</div>
751<h2 id="_credential_helpers">Credential Helpers</h2>
752<div class="sectionbody">
753<div class="paragraph"><p>Credential helpers are programs executed by git to fetch or save
754credentials from and to long-term storage (where "long-term" is simply
755longer than a single git process; e.g., credentials may be stored
756in-memory for a few minutes, or indefinitely on disk).</p></div>
Junio C Hamano022bd342012-06-07 20:15:35757<div class="paragraph"><p>Each helper is specified by a single string in the configuration
Junio C Hamano719b8a32012-06-08 18:40:53758variable <tt>credential.helper</tt> (and others, see <a href="../git-config.html">git-config(1)</a>).
Junio C Hamano022bd342012-06-07 20:15:35759The string is transformed by git into a command to be executed using
760these rules:</p></div>
Junio C Hamano0df92712011-12-21 22:30:44761<div class="olist arabic"><ol class="arabic">
762<li>
763<p>
764If the helper string begins with "!", it is considered a shell
765 snippet, and everything after the "!" becomes the command.
766</p>
767</li>
768<li>
769<p>
770Otherwise, if the helper string begins with an absolute path, the
771 verbatim helper string becomes the command.
772</p>
773</li>
774<li>
775<p>
776Otherwise, the string "git credential-" is prepended to the helper
777 string, and the result becomes the command.
778</p>
779</li>
780</ol></div>
781<div class="paragraph"><p>The resulting command then has an "operation" argument appended to it
782(see below for details), and the result is executed by the shell.</p></div>
783<div class="paragraph"><p>Here are some example specifications:</p></div>
784<div class="listingblock">
785<div class="content">
786<pre><tt># run "git credential-foo"
787foo
788
789# same as above, but pass an argument to the helper
790foo --bar=baz
791
792# the arguments are parsed by the shell, so use shell
793# quoting if necessary
794foo --bar="whitespace arg"
795
796# you can also use an absolute path, which will not use the git wrapper
797/path/to/my/helper --with-arguments
798
799# or you can specify your own shell snippet
800!f() { echo "password=`cat $HOME/.secret`"; }; f</tt></pre>
801</div></div>
802<div class="paragraph"><p>Generally speaking, rule (3) above is the simplest for users to specify.
803Authors of credential helpers should make an effort to assist their
804users by naming their program "git-credential-$NAME", and putting it in
805the $PATH or $GIT_EXEC_PATH during installation, which will allow a user
806to enable it with <tt>git config credential.helper $NAME</tt>.</p></div>
807<div class="paragraph"><p>When a helper is executed, it will have one "operation" argument
808appended to its command line, which is one of:</p></div>
809<div class="dlist"><dl>
810<dt class="hdlist1">
811<tt>get</tt>
812</dt>
813<dd>
814<p>
815 Return a matching credential, if any exists.
816</p>
817</dd>
818<dt class="hdlist1">
819<tt>store</tt>
820</dt>
821<dd>
822<p>
823 Store the credential, if applicable to the helper.
824</p>
825</dd>
826<dt class="hdlist1">
827<tt>erase</tt>
828</dt>
829<dd>
830<p>
831 Remove a matching credential, if any, from the helper&#8217;s storage.
832</p>
833</dd>
834</dl></div>
835<div class="paragraph"><p>The details of the credential will be provided on the helper&#8217;s stdin
836stream. The credential is split into a set of named attributes.
837Attributes are provided to the helper, one per line. Each attribute is
838specified by a key-value pair, separated by an <tt>=</tt> (equals) sign,
839followed by a newline. The key may contain any bytes except <tt>=</tt>,
840newline, or NUL. The value may contain any bytes except newline or NUL.
841In both cases, all bytes are treated as-is (i.e., there is no quoting,
842and one cannot transmit a value with newline or NUL in it). The list of
843attributes is terminated by a blank line or end-of-file.</p></div>
844<div class="paragraph"><p>Git will send the following attributes (but may not send all of
845them for a given credential; for example, a <tt>host</tt> attribute makes no
846sense when dealing with a non-network protocol):</p></div>
847<div class="dlist"><dl>
848<dt class="hdlist1">
849<tt>protocol</tt>
850</dt>
851<dd>
852<p>
853 The protocol over which the credential will be used (e.g.,
854 <tt>https</tt>).
855</p>
856</dd>
857<dt class="hdlist1">
858<tt>host</tt>
859</dt>
860<dd>
861<p>
862 The remote hostname for a network credential.
863</p>
864</dd>
865<dt class="hdlist1">
866<tt>path</tt>
867</dt>
868<dd>
869<p>
870 The path with which the credential will be used. E.g., for
871 accessing a remote https repository, this will be the
872 repository&#8217;s path on the server.
873</p>
874</dd>
875<dt class="hdlist1">
876<tt>username</tt>
877</dt>
878<dd>
879<p>
880 The credential&#8217;s username, if we already have one (e.g., from a
881 URL, from the user, or from a previously run helper).
882</p>
883</dd>
884<dt class="hdlist1">
885<tt>password</tt>
886</dt>
887<dd>
888<p>
889 The credential&#8217;s password, if we are asking it to be stored.
890</p>
891</dd>
892</dl></div>
893<div class="paragraph"><p>For a <tt>get</tt> operation, the helper should produce a list of attributes
894on stdout in the same format. A helper is free to produce a subset, or
895even no values at all if it has nothing useful to provide. Any provided
896attributes will overwrite those already known about by git.</p></div>
897<div class="paragraph"><p>For a <tt>store</tt> or <tt>erase</tt> operation, the helper&#8217;s output is ignored.
898If it fails to perform the requested operation, it may complain to
899stderr to inform the user. If it does not support the requested
900operation (e.g., a read-only store), it should silently ignore the
901request.</p></div>
902<div class="paragraph"><p>If a helper receives any other operation, it should silently ignore the
903request. This leaves room for future operations to be added (older
904helpers will just ignore the new requests).</p></div>
905</div>
Junio C Hamano022bd342012-06-07 20:15:35906<h2 id="_see_also">See also</h2>
907<div class="sectionbody">
Junio C Hamano719b8a32012-06-08 18:40:53908<div class="paragraph"><p><a href="../gitcredentials.html">gitcredentials(7)</a></p></div>
909<div class="paragraph"><p><a href="../git-config.html">git-config(5)</a> (See configuration variables <tt>credential.*</tt>)</p></div>
Junio C Hamano022bd342012-06-07 20:15:35910</div>
Junio C Hamano0df92712011-12-21 22:30:44911</div>
912<div id="footnotes"><hr /></div>
913<div id="footer">
914<div id="footer-text">
Junio C Hamano9f9ed8b2012-06-13 07:21:43915Last updated 2012-06-13 00:21:29 PDT
Junio C Hamano0df92712011-12-21 22:30:44916</div>
917</div>
918</body>
919</html>