diff options
Diffstat (limited to 'Documentation/technical')
-rw-r--r-- | Documentation/technical/api-config.txt | 140 | ||||
-rw-r--r-- | Documentation/technical/api-credentials.txt | 245 | ||||
-rw-r--r-- | Documentation/technical/api-parse-options.txt | 24 | ||||
-rw-r--r-- | Documentation/technical/api-strbuf.txt | 18 | ||||
-rw-r--r-- | Documentation/technical/api-string-list.txt | 4 | ||||
-rw-r--r-- | Documentation/technical/pack-protocol.txt | 7 |
6 files changed, 430 insertions, 8 deletions
diff --git a/Documentation/technical/api-config.txt b/Documentation/technical/api-config.txt new file mode 100644 index 0000000000..edf8dfb99b --- /dev/null +++ b/Documentation/technical/api-config.txt @@ -0,0 +1,140 @@ +config API +========== + +The config API gives callers a way to access git configuration files +(and files which have the same syntax). See linkgit:git-config[1] for a +discussion of the config file syntax. + +General Usage +------------- + +Config files are parsed linearly, and each variable found is passed to a +caller-provided callback function. The callback function is responsible +for any actions to be taken on the config option, and is free to ignore +some options. It is not uncommon for the configuration to be parsed +several times during the run of a git program, with different callbacks +picking out different variables useful to themselves. + +A config callback function takes three parameters: + +- the name of the parsed variable. This is in canonical "flat" form: the + section, subsection, and variable segments will be separated by dots, + and the section and variable segments will be all lowercase. E.g., + `core.ignorecase`, `diff.SomeType.textconv`. + +- the value of the found variable, as a string. If the variable had no + value specified, the value will be NULL (typically this means it + should be interpreted as boolean true). + +- a void pointer passed in by the caller of the config API; this can + contain callback-specific data + +A config callback should return 0 for success, or -1 if the variable +could not be parsed properly. + +Basic Config Querying +--------------------- + +Most programs will simply want to look up variables in all config files +that git knows about, using the normal precedence rules. To do this, +call `git_config` with a callback function and void data pointer. + +`git_config` will read all config sources in order of increasing +priority. Thus a callback should typically overwrite previously-seen +entries with new ones (e.g., if both the user-wide `~/.gitconfig` and +repo-specific `.git/config` contain `color.ui`, the config machinery +will first feed the user-wide one to the callback, and then the +repo-specific one; by overwriting, the higher-priority repo-specific +value is left at the end). + +The `git_config_with_options` function lets the caller examine config +while adjusting some of the default behavior of `git_config`. It should +almost never be used by "regular" git code that is looking up +configuration variables. It is intended for advanced callers like +`git-config`, which are intentionally tweaking the normal config-lookup +process. It takes two extra parameters: + +`filename`:: +If this parameter is non-NULL, it specifies the name of a file to +parse for configuration, rather than looking in the usual files. Regular +`git_config` defaults to `NULL`. + +`respect_includes`:: +Specify whether include directives should be followed in parsed files. +Regular `git_config` defaults to `1`. + +There is a special version of `git_config` called `git_config_early`. +This version takes an additional parameter to specify the repository +config, instead of having it looked up via `git_path`. This is useful +early in a git program before the repository has been found. Unless +you're working with early setup code, you probably don't want to use +this. + +Reading Specific Files +---------------------- + +To read a specific file in git-config format, use +`git_config_from_file`. This takes the same callback and data parameters +as `git_config`. + +Value Parsing Helpers +--------------------- + +To aid in parsing string values, the config API provides callbacks with +a number of helper functions, including: + +`git_config_int`:: +Parse the string to an integer, including unit factors. Dies on error; +otherwise, returns the parsed result. + +`git_config_ulong`:: +Identical to `git_config_int`, but for unsigned longs. + +`git_config_bool`:: +Parse a string into a boolean value, respecting keywords like "true" and +"false". Integer values are converted into true/false values (when they +are non-zero or zero, respectively). Other values cause a die(). If +parsing is successful, the return value is the result. + +`git_config_bool_or_int`:: +Same as `git_config_bool`, except that integers are returned as-is, and +an `is_bool` flag is unset. + +`git_config_maybe_bool`:: +Same as `git_config_bool`, except that it returns -1 on error rather +than dying. + +`git_config_string`:: +Allocates and copies the value string into the `dest` parameter; if no +string is given, prints an error message and returns -1. + +`git_config_pathname`:: +Similar to `git_config_string`, but expands `~` or `~user` into the +user's home directory when found at the beginning of the path. + +Include Directives +------------------ + +By default, the config parser does not respect include directives. +However, a caller can use the special `git_config_include` wrapper +callback to support them. To do so, you simply wrap your "real" callback +function and data pointer in a `struct config_include_data`, and pass +the wrapper to the regular config-reading functions. For example: + +------------------------------------------- +int read_file_with_include(const char *file, config_fn_t fn, void *data) +{ + struct config_include_data inc = CONFIG_INCLUDE_INIT; + inc.fn = fn; + inc.data = data; + return git_config_from_file(git_config_include, file, &inc); +} +------------------------------------------- + +`git_config` respects includes automatically. The lower-level +`git_config_from_file` does not. + +Writing Config Files +-------------------- + +TODO diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt new file mode 100644 index 0000000000..21ca6a2553 --- /dev/null +++ b/Documentation/technical/api-credentials.txt @@ -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). diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index f6a4a361bd..2527b7e8d7 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -39,7 +39,8 @@ The parse-options API allows: * Short options may be bundled, e.g. `-a -b` can be specified as `-ab`. * Boolean long options can be 'negated' (or 'unset') by prepending - `no-`, e.g. `\--no-abbrev` instead of `\--abbrev`. + `no-`, e.g. `\--no-abbrev` instead of `\--abbrev`. Conversely, + options that begin with `no-` can be 'negated' by removing it. * Options and non-option arguments can clearly be separated using the `\--` option, e.g. `-a -b \--option \-- \--this-is-a-file` indicates that @@ -135,9 +136,14 @@ There are some macros to easily define options: describes the group or an empty string. Start the description with an upper-case letter. -`OPT_BOOLEAN(short, long, &int_var, description)`:: - Introduce a boolean option. - `int_var` is incremented on each use. +`OPT_BOOL(short, long, &int_var, description)`:: + Introduce a boolean option. `int_var` is set to one with + `--option` and set to zero with `--no-option`. + +`OPT_COUNTUP(short, long, &int_var, description)`:: + Introduce a count-up option. + `int_var` is incremented on each use of `--option`, and + reset to zero with `--no-option`. `OPT_BIT(short, long, &int_var, description, mask)`:: Introduce a boolean option. @@ -148,8 +154,9 @@ There are some macros to easily define options: If used, `int_var` is bitwise-anded with the inverted `mask`. `OPT_SET_INT(short, long, &int_var, description, integer)`:: - Introduce a boolean option. - If used, set `int_var` to `integer`. + Introduce an integer option. + `int_var` is set to `integer` with `--option`, and + reset to zero with `--no-option`. `OPT_SET_PTR(short, long, &ptr_var, description, ptr)`:: Introduce a boolean option. @@ -198,6 +205,11 @@ There are some macros to easily define options: "auto", set `int_var` to 1 if stdout is a tty or a pager, 0 otherwise. +`OPT_NOOP_NOARG(short, long)`:: + Introduce an option that has no effect and takes no arguments. + Use it to hide deprecated options that are still to be recognized + and ignored silently. + The last element of the array must be `OPT_END()`. diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt index afe2759951..95a8bf3846 100644 --- a/Documentation/technical/api-strbuf.txt +++ b/Documentation/technical/api-strbuf.txt @@ -255,8 +255,24 @@ same behaviour as well. `strbuf_getline`:: - Read a line from a FILE* pointer. The second argument specifies the line + Read a line from a FILE *, overwriting the existing contents + of the strbuf. The second argument specifies the line terminator character, typically `'\n'`. + Reading stops after the terminator or at EOF. The terminator + is removed from the buffer before returning. Returns 0 unless + there was nothing left before EOF, in which case it returns `EOF`. + +`strbuf_getwholeline`:: + + Like `strbuf_getline`, but keeps the trailing terminator (if + any) in the buffer. + +`strbuf_getwholeline_fd`:: + + Like `strbuf_getwholeline`, but operates on a file descriptor. + It reads one character at a time, so it is very slow. Do not + use it unless you need the correct position in the file + descriptor. `stripspace`:: diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt index ce24eb96f5..5a0c14fceb 100644 --- a/Documentation/technical/api-string-list.txt +++ b/Documentation/technical/api-string-list.txt @@ -83,7 +83,9 @@ Functions Insert a new element to the string_list. The returned pointer can be handy if you want to write something to the `util` pointer of the - string_list_item containing the just added string. + string_list_item containing the just added string. If the given + string already exists the insertion will be skipped and the + pointer to the existing item returned. + Since this function uses xrealloc() (which die()s if it fails) if the list needs to grow, it is safe not to check the pointer. I.e. you may diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt index a7004c63e7..546980c0a4 100644 --- a/Documentation/technical/pack-protocol.txt +++ b/Documentation/technical/pack-protocol.txt @@ -60,6 +60,13 @@ process on the server side over the Git protocol is this: "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" | nc -v example.com 9418 +If the server refuses the request for some reasons, it could abort +gracefully with an error message. + +---- + error-line = PKT-LINE("ERR" SP explanation-text) +---- + SSH Transport ------------- |