Merge branch 'jk/credentials'
* jk/credentials: t: add test harness for external credential helpers credentials: add "store" helper strbuf: add strbuf_add*_urlencode Makefile: unix sockets may not available on some platforms credentials: add "cache" helper docs: end-user documentation for the credential subsystem credential: make relevance of http path configurable credential: add credential.*.username credential: apply helper config http: use credential API to get passwords credential: add function for parsing url components introduce credentials API t5550: fix typo test-lib: add test_config_global variant Conflicts: strbuf.c
This commit is contained in:
@ -7,6 +7,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
|
||||
MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
|
||||
gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
|
||||
gitdiffcore.txt gitnamespaces.txt gitrevisions.txt gitworkflows.txt
|
||||
MAN7_TXT += gitcredentials.txt
|
||||
|
||||
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
|
||||
MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
|
||||
|
@ -834,6 +834,29 @@ commit.template::
|
||||
"{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
|
||||
specified user's home directory.
|
||||
|
||||
credential.helper::
|
||||
Specify an external helper to be called when a username or
|
||||
password credential is needed; the helper may consult external
|
||||
storage to avoid prompting the user for the credentials. See
|
||||
linkgit:gitcredentials[7] for details.
|
||||
|
||||
credential.useHttpPath::
|
||||
When acquiring credentials, consider the "path" component of an http
|
||||
or https URL to be important. Defaults to false. See
|
||||
linkgit:gitcredentials[7] for more information.
|
||||
|
||||
credential.username::
|
||||
If no username is set for a network authentication, use this username
|
||||
by default. See credential.<context>.* below, and
|
||||
linkgit:gitcredentials[7].
|
||||
|
||||
credential.<url>.*::
|
||||
Any of the credential.* options above can be applied selectively to
|
||||
some credentials. For example "credential.https://example.com.username"
|
||||
would set the default username only for https connections to
|
||||
example.com. See linkgit:gitcredentials[7] for details on how URLs are
|
||||
matched.
|
||||
|
||||
include::diff-config.txt[]
|
||||
|
||||
difftool.<tool>.path::
|
||||
|
26
Documentation/git-credential-cache--daemon.txt
Normal file
26
Documentation/git-credential-cache--daemon.txt
Normal file
@ -0,0 +1,26 @@
|
||||
git-credential-cache--daemon(1)
|
||||
===============================
|
||||
|
||||
NAME
|
||||
----
|
||||
git-credential-cache--daemon - temporarily store user credentials in memory
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
git credential-cache--daemon <socket>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
NOTE: You probably don't want to invoke this command yourself; it is
|
||||
started automatically when you use linkgit:git-credential-cache[1].
|
||||
|
||||
This command listens on the Unix domain socket specified by `<socket>`
|
||||
for `git-credential-cache` clients. Clients may store and retrieve
|
||||
credentials. Each credential is held for a timeout specified by the
|
||||
client; once no credentials are held, the daemon exits.
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
77
Documentation/git-credential-cache.txt
Normal file
77
Documentation/git-credential-cache.txt
Normal file
@ -0,0 +1,77 @@
|
||||
git-credential-cache(1)
|
||||
=======================
|
||||
|
||||
NAME
|
||||
----
|
||||
git-credential-cache - helper to temporarily store passwords in memory
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
-----------------------------
|
||||
git config credential.helper 'cache [options]'
|
||||
-----------------------------
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
This command caches credentials in memory for use by future git
|
||||
programs. The stored credentials never touch the disk, and are forgotten
|
||||
after a configurable timeout. The cache is accessible over a Unix
|
||||
domain socket, restricted to the current user by filesystem permissions.
|
||||
|
||||
You probably don't want to invoke this command directly; it is meant to
|
||||
be used as a credential helper by other parts of git. See
|
||||
linkgit:gitcredentials[7] or `EXAMPLES` below.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
--timeout <seconds>::
|
||||
|
||||
Number of seconds to cache credentials (default: 900).
|
||||
|
||||
--socket <path>::
|
||||
|
||||
Use `<path>` to contact a running cache daemon (or start a new
|
||||
cache daemon if one is not started). Defaults to
|
||||
`~/.git-credential-cache/socket`. If your home directory is on a
|
||||
network-mounted filesystem, you may need to change this to a
|
||||
local filesystem.
|
||||
|
||||
CONTROLLING THE DAEMON
|
||||
----------------------
|
||||
|
||||
If you would like the daemon to exit early, forgetting all cached
|
||||
credentials before their timeout, you can issue an `exit` action:
|
||||
|
||||
--------------------------------------
|
||||
git credential-cache exit
|
||||
--------------------------------------
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
The point of this helper is to reduce the number of times you must type
|
||||
your username or password. For example:
|
||||
|
||||
------------------------------------
|
||||
$ git config credential.helper cache
|
||||
$ git push http://example.com/repo.git
|
||||
Username: <type your username>
|
||||
Password: <type your password>
|
||||
|
||||
[work for 5 more minutes]
|
||||
$ git push http://example.com/repo.git
|
||||
[your credentials are used automatically]
|
||||
------------------------------------
|
||||
|
||||
You can provide options via the credential.helper configuration
|
||||
variable (this example drops the cache time to 5 minutes):
|
||||
|
||||
-------------------------------------------------------
|
||||
$ git config credential.helper 'cache --timeout=300'
|
||||
-------------------------------------------------------
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
75
Documentation/git-credential-store.txt
Normal file
75
Documentation/git-credential-store.txt
Normal file
@ -0,0 +1,75 @@
|
||||
git-credential-store(1)
|
||||
=======================
|
||||
|
||||
NAME
|
||||
----
|
||||
git-credential-store - helper to store credentials on disk
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
-------------------
|
||||
git config credential.helper 'store [options]'
|
||||
-------------------
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
NOTE: Using this helper will store your passwords unencrypted on disk,
|
||||
protected only by filesystem permissions. If this is not an acceptable
|
||||
security tradeoff, try linkgit:git-credential-cache[1], or find a helper
|
||||
that integrates with secure storage provided by your operating system.
|
||||
|
||||
This command stores credentials indefinitely on disk for use by future
|
||||
git programs.
|
||||
|
||||
You probably don't want to invoke this command directly; it is meant to
|
||||
be used as a credential helper by other parts of git. See
|
||||
linkgit:gitcredentials[7] or `EXAMPLES` below.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
--store=<path>::
|
||||
|
||||
Use `<path>` to store credentials. The file will have its
|
||||
filesystem permissions set to prevent other users on the system
|
||||
from reading it, but will not be encrypted or otherwise
|
||||
protected. Defaults to `~/.git-credentials`.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
The point of this helper is to reduce the number of times you must type
|
||||
your username or password. For example:
|
||||
|
||||
------------------------------------------
|
||||
$ git config credential.helper store
|
||||
$ git push http://example.com/repo.git
|
||||
Username: <type your username>
|
||||
Password: <type your password>
|
||||
|
||||
[several days later]
|
||||
$ git push http://example.com/repo.git
|
||||
[your credentials are used automatically]
|
||||
------------------------------------------
|
||||
|
||||
STORAGE FORMAT
|
||||
--------------
|
||||
|
||||
The `.git-credentials` file is stored in plaintext. Each credential is
|
||||
stored on its own line as a URL like:
|
||||
|
||||
------------------------------
|
||||
https://user:pass@example.com
|
||||
------------------------------
|
||||
|
||||
When git needs authentication for a particular URL context,
|
||||
credential-store will consider that context a pattern to match against
|
||||
each entry in the credentials file. If the protocol, hostname, and
|
||||
username (if we already have one) match, then the password is returned
|
||||
to git. See the discussion of configuration in linkgit:gitcredentials[7]
|
||||
for more information.
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
183
Documentation/gitcredentials.txt
Normal file
183
Documentation/gitcredentials.txt
Normal file
@ -0,0 +1,183 @@
|
||||
gitcredentials(7)
|
||||
=================
|
||||
|
||||
NAME
|
||||
----
|
||||
gitcredentials - providing usernames and passwords to git
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
------------------
|
||||
git config credential.https://example.com.username myusername
|
||||
git config credential.helper "$helper $options"
|
||||
------------------
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
Git will sometimes need credentials from the user in order to perform
|
||||
operations; for example, it may need to ask for a username and password
|
||||
in order to access a remote repository over HTTP. This manual describes
|
||||
the mechanisms git uses to request these credentials, as well as some
|
||||
features to avoid inputting these credentials repeatedly.
|
||||
|
||||
REQUESTING CREDENTIALS
|
||||
----------------------
|
||||
|
||||
Without any credential helpers defined, git will try the following
|
||||
strategies to ask the user for usernames and passwords:
|
||||
|
||||
1. If the `GIT_ASKPASS` environment variable is set, the program
|
||||
specified by the variable is invoked. A suitable prompt is provided
|
||||
to the program on the command line, and the user's input is read
|
||||
from its standard output.
|
||||
|
||||
2. Otherwise, if the `core.askpass` configuration variable is set, its
|
||||
value is used as above.
|
||||
|
||||
3. Otherwise, if the `SSH_ASKPASS` environment variable is set, its
|
||||
value is used as above.
|
||||
|
||||
4. Otherwise, the user is prompted on the terminal.
|
||||
|
||||
AVOIDING REPETITION
|
||||
-------------------
|
||||
|
||||
It can be cumbersome to input the same credentials over and over. Git
|
||||
provides two methods to reduce this annoyance:
|
||||
|
||||
1. Static configuration of usernames for a given authentication context.
|
||||
|
||||
2. Credential helpers to cache or store passwords, or to interact with
|
||||
a system password wallet or keychain.
|
||||
|
||||
The first is simple and appropriate if you do not have secure storage available
|
||||
for a password. It is generally configured by adding this to your config:
|
||||
|
||||
---------------------------------------
|
||||
[credential "https://example.com"]
|
||||
username = me
|
||||
---------------------------------------
|
||||
|
||||
Credential helpers, on the other hand, are external programs from which git can
|
||||
request both usernames and passwords; they typically interface with secure
|
||||
storage provided by the OS or other programs.
|
||||
|
||||
To use a helper, you must first select one to use. Git currently
|
||||
includes the following helpers:
|
||||
|
||||
cache::
|
||||
|
||||
Cache credentials in memory for a short period of time. See
|
||||
linkgit:git-credential-cache[1] for details.
|
||||
|
||||
store::
|
||||
|
||||
Store credentials indefinitely on disk. See
|
||||
linkgit:git-credential-store[1] for details.
|
||||
|
||||
You may also have third-party helpers installed; search for
|
||||
`credential-*` in the output of `git help -a`, and consult the
|
||||
documentation of individual helpers. Once you have selected a helper,
|
||||
you can tell git to use it by putting its name into the
|
||||
credential.helper variable.
|
||||
|
||||
1. Find a helper.
|
||||
+
|
||||
-------------------------------------------
|
||||
$ git help -a | grep credential-
|
||||
credential-foo
|
||||
-------------------------------------------
|
||||
|
||||
2. Read its description.
|
||||
+
|
||||
-------------------------------------------
|
||||
$ git help credential-foo
|
||||
-------------------------------------------
|
||||
|
||||
3. Tell git to use it.
|
||||
+
|
||||
-------------------------------------------
|
||||
$ git config --global credential.helper foo
|
||||
-------------------------------------------
|
||||
|
||||
If there are multiple instances of the `credential.helper` configuration
|
||||
variable, each helper will be tried in turn, and may provide a username,
|
||||
password, or nothing. Once git has acquired both a username and a
|
||||
password, no more helpers will be tried.
|
||||
|
||||
|
||||
CREDENTIAL CONTEXTS
|
||||
-------------------
|
||||
|
||||
Git considers each credential to have a context defined by a URL. This context
|
||||
is used to look up context-specific configuration, and is passed to any
|
||||
helpers, which may use it as an index into secure storage.
|
||||
|
||||
For instance, imagine we are accessing `https://example.com/foo.git`. When git
|
||||
looks into a config file to see if a section matches this context, it will
|
||||
consider the two a match if the context is a more-specific subset of the
|
||||
pattern in the config file. For example, if you have this in your config file:
|
||||
|
||||
--------------------------------------
|
||||
[credential "https://example.com"]
|
||||
username = foo
|
||||
--------------------------------------
|
||||
|
||||
then we will match: both protocols are the same, both hosts are the same, and
|
||||
the "pattern" URL does not care about the path component at all. However, this
|
||||
context would not match:
|
||||
|
||||
--------------------------------------
|
||||
[credential "https://kernel.org"]
|
||||
username = foo
|
||||
--------------------------------------
|
||||
|
||||
because the hostnames differ. Nor would it match `foo.example.com`; git
|
||||
compares hostnames exactly, without considering whether two hosts are part of
|
||||
the same domain. Likewise, a config entry for `http://example.com` would not
|
||||
match: git compares the protocols exactly.
|
||||
|
||||
|
||||
CONFIGURATION OPTIONS
|
||||
---------------------
|
||||
|
||||
Options for a credential context can be configured either in
|
||||
`credential.\*` (which applies to all credentials), or
|
||||
`credential.<url>.\*`, where <url> matches the context as described
|
||||
above.
|
||||
|
||||
The following options are available in either location:
|
||||
|
||||
helper::
|
||||
|
||||
The name of an external credential helper, and any associated options.
|
||||
If the helper name is not an absolute path, then the string `git
|
||||
credential-` is prepended. The resulting string is executed by the
|
||||
shell (so, for example, setting this to `foo --option=bar` will execute
|
||||
`git credential-foo --option=bar` via the shell. See the manual of
|
||||
specific helpers for examples of their use.
|
||||
|
||||
username::
|
||||
|
||||
A default username, if one is not provided in the URL.
|
||||
|
||||
useHttpPath::
|
||||
|
||||
By default, git does not consider the "path" component of an http URL
|
||||
to be worth matching via external helpers. This means that a credential
|
||||
stored for `https://example.com/foo.git` will also be used for
|
||||
`https://example.com/bar.git`. If you do want to distinguish these
|
||||
cases, set this option to `true`.
|
||||
|
||||
|
||||
CUSTOM HELPERS
|
||||
--------------
|
||||
|
||||
You can write your own custom helpers to interface with any system in
|
||||
which you keep credentials. See the documentation for git's
|
||||
link:technical/api-credentials.html[credentials API] for details.
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
245
Documentation/technical/api-credentials.txt
Normal file
245
Documentation/technical/api-credentials.txt
Normal file
@ -0,0 +1,245 @@
|
||||
credentials API
|
||||
===============
|
||||
|
||||
The credentials API provides an abstracted way of gathering username and
|
||||
password credentials from the user (even though credentials in the wider
|
||||
world can take many forms, in this document the word "credential" always
|
||||
refers to a username and password pair).
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct credential`::
|
||||
|
||||
This struct represents a single username/password combination
|
||||
along with any associated context. All string fields should be
|
||||
heap-allocated (or NULL if they are not known or not applicable).
|
||||
The meaning of the individual context fields is the same as
|
||||
their counterparts in the helper protocol; see the section below
|
||||
for a description of each field.
|
||||
+
|
||||
The `helpers` member of the struct is a `string_list` of helpers. Each
|
||||
string specifies an external helper which will be run, in order, to
|
||||
either acquire or store credentials. See the section on credential
|
||||
helpers below.
|
||||
+
|
||||
This struct should always be initialized with `CREDENTIAL_INIT` or
|
||||
`credential_init`.
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`credential_init`::
|
||||
|
||||
Initialize a credential structure, setting all fields to empty.
|
||||
|
||||
`credential_clear`::
|
||||
|
||||
Free any resources associated with the credential structure,
|
||||
returning it to a pristine initialized state.
|
||||
|
||||
`credential_fill`::
|
||||
|
||||
Instruct the credential subsystem to fill the username and
|
||||
password fields of the passed credential struct by first
|
||||
consulting helpers, then asking the user. After this function
|
||||
returns, the username and password fields of the credential are
|
||||
guaranteed to be non-NULL. If an error occurs, the function will
|
||||
die().
|
||||
|
||||
`credential_reject`::
|
||||
|
||||
Inform the credential subsystem that the provided credentials
|
||||
have been rejected. This will cause the credential subsystem to
|
||||
notify any helpers of the rejection (which allows them, for
|
||||
example, to purge the invalid credentials from storage). It
|
||||
will also free() the username and password fields of the
|
||||
credential and set them to NULL (readying the credential for
|
||||
another call to `credential_fill`). Any errors from helpers are
|
||||
ignored.
|
||||
|
||||
`credential_approve`::
|
||||
|
||||
Inform the credential subsystem that the provided credentials
|
||||
were successfully used for authentication. This will cause the
|
||||
credential subsystem to notify any helpers of the approval, so
|
||||
that they may store the result to be used again. Any errors
|
||||
from helpers are ignored.
|
||||
|
||||
`credential_from_url`::
|
||||
|
||||
Parse a URL into broken-down credential fields.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
The example below shows how the functions of the credential API could be
|
||||
used to login to a fictitious "foo" service on a remote host:
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
int foo_login(struct foo_connection *f)
|
||||
{
|
||||
int status;
|
||||
/*
|
||||
* Create a credential with some context; we don't yet know the
|
||||
* username or password.
|
||||
*/
|
||||
|
||||
struct credential c = CREDENTIAL_INIT;
|
||||
c.protocol = xstrdup("foo");
|
||||
c.host = xstrdup(f->hostname);
|
||||
|
||||
/*
|
||||
* Fill in the username and password fields by contacting
|
||||
* helpers and/or asking the user. The function will die if it
|
||||
* fails.
|
||||
*/
|
||||
credential_fill(&c);
|
||||
|
||||
/*
|
||||
* Otherwise, we have a username and password. Try to use it.
|
||||
*/
|
||||
status = send_foo_login(f, c.username, c.password);
|
||||
switch (status) {
|
||||
case FOO_OK:
|
||||
/* It worked. Store the credential for later use. */
|
||||
credential_accept(&c);
|
||||
break;
|
||||
case FOO_BAD_LOGIN:
|
||||
/* Erase the credential from storage so we don't try it
|
||||
* again. */
|
||||
credential_reject(&c);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Some other error occured. We don't know if the
|
||||
* credential is good or bad, so report nothing to the
|
||||
* credential subsystem.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Free any associated resources. */
|
||||
credential_clear(&c);
|
||||
|
||||
return status;
|
||||
}
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
Credential Helpers
|
||||
------------------
|
||||
|
||||
Credential helpers are programs executed by git to fetch or save
|
||||
credentials from and to long-term storage (where "long-term" is simply
|
||||
longer than a single git process; e.g., credentials may be stored
|
||||
in-memory for a few minutes, or indefinitely on disk).
|
||||
|
||||
Each helper is specified by a single string. The string is transformed
|
||||
by git into a command to be executed using these rules:
|
||||
|
||||
1. If the helper string begins with "!", it is considered a shell
|
||||
snippet, and everything after the "!" becomes the command.
|
||||
|
||||
2. Otherwise, if the helper string begins with an absolute path, the
|
||||
verbatim helper string becomes the command.
|
||||
|
||||
3. Otherwise, the string "git credential-" is prepended to the helper
|
||||
string, and the result becomes the command.
|
||||
|
||||
The resulting command then has an "operation" argument appended to it
|
||||
(see below for details), and the result is executed by the shell.
|
||||
|
||||
Here are some example specifications:
|
||||
|
||||
----------------------------------------------------
|
||||
# run "git credential-foo"
|
||||
foo
|
||||
|
||||
# same as above, but pass an argument to the helper
|
||||
foo --bar=baz
|
||||
|
||||
# the arguments are parsed by the shell, so use shell
|
||||
# quoting if necessary
|
||||
foo --bar="whitespace arg"
|
||||
|
||||
# you can also use an absolute path, which will not use the git wrapper
|
||||
/path/to/my/helper --with-arguments
|
||||
|
||||
# or you can specify your own shell snippet
|
||||
!f() { echo "password=`cat $HOME/.secret`"; }; f
|
||||
----------------------------------------------------
|
||||
|
||||
Generally speaking, rule (3) above is the simplest for users to specify.
|
||||
Authors of credential helpers should make an effort to assist their
|
||||
users by naming their program "git-credential-$NAME", and putting it in
|
||||
the $PATH or $GIT_EXEC_PATH during installation, which will allow a user
|
||||
to enable it with `git config credential.helper $NAME`.
|
||||
|
||||
When a helper is executed, it will have one "operation" argument
|
||||
appended to its command line, which is one of:
|
||||
|
||||
`get`::
|
||||
|
||||
Return a matching credential, if any exists.
|
||||
|
||||
`store`::
|
||||
|
||||
Store the credential, if applicable to the helper.
|
||||
|
||||
`erase`::
|
||||
|
||||
Remove a matching credential, if any, from the helper's storage.
|
||||
|
||||
The details of the credential will be provided on the helper's stdin
|
||||
stream. The credential is split into a set of named attributes.
|
||||
Attributes are provided to the helper, one per line. Each attribute is
|
||||
specified by a key-value pair, separated by an `=` (equals) sign,
|
||||
followed by a newline. The key may contain any bytes except `=`,
|
||||
newline, or NUL. The value may contain any bytes except newline or NUL.
|
||||
In both cases, all bytes are treated as-is (i.e., there is no quoting,
|
||||
and one cannot transmit a value with newline or NUL in it). The list of
|
||||
attributes is terminated by a blank line or end-of-file.
|
||||
|
||||
Git will send the following attributes (but may not send all of
|
||||
them for a given credential; for example, a `host` attribute makes no
|
||||
sense when dealing with a non-network protocol):
|
||||
|
||||
`protocol`::
|
||||
|
||||
The protocol over which the credential will be used (e.g.,
|
||||
`https`).
|
||||
|
||||
`host`::
|
||||
|
||||
The remote hostname for a network credential.
|
||||
|
||||
`path`::
|
||||
|
||||
The path with which the credential will be used. E.g., for
|
||||
accessing a remote https repository, this will be the
|
||||
repository's path on the server.
|
||||
|
||||
`username`::
|
||||
|
||||
The credential's username, if we already have one (e.g., from a
|
||||
URL, from the user, or from a previously run helper).
|
||||
|
||||
`password`::
|
||||
|
||||
The credential's password, if we are asking it to be stored.
|
||||
|
||||
For a `get` operation, the helper should produce a list of attributes
|
||||
on stdout in the same format. A helper is free to produce a subset, or
|
||||
even no values at all if it has nothing useful to provide. Any provided
|
||||
attributes will overwrite those already known about by git.
|
||||
|
||||
For a `store` or `erase` operation, the helper's output is ignored.
|
||||
If it fails to perform the requested operation, it may complain to
|
||||
stderr to inform the user. If it does not support the requested
|
||||
operation (e.g., a read-only store), it should silently ignore the
|
||||
request.
|
||||
|
||||
If a helper receives any other operation, it should silently ignore the
|
||||
request. This leaves room for future operations to be added (older
|
||||
helpers will just ignore the new requests).
|
Reference in New Issue
Block a user