Merge branch 'hw/doc-in-header'
* hw/doc-in-header: trace2: move doc to trace2.h submodule-config: move doc to submodule-config.h tree-walk: move doc to tree-walk.h trace: move doc to trace.h run-command: move doc to run-command.h parse-options: add link to doc file in parse-options.h credential: move doc to credential.h argv-array: move doc to argv-array.h cache: move doc to cache.h sigchain: move doc to sigchain.h pathspec: move doc to pathspec.h revision: move doc to revision.h attr: move doc to attr.h refs: move doc to refs.h remote: move doc to remote.h and refspec.h sha1-array: move doc to sha1-array.h merge: move doc to ll-merge.h graph: move doc to graph.h and graph.c dir: move doc to dir.h diff: move doc to diff.h and diffcore.h
This commit is contained in:
@ -17,7 +17,7 @@ revision walk is used for operations like `git log`.
|
||||
|
||||
- `Documentation/user-manual.txt` under "Hacking Git" contains some coverage of
|
||||
the revision walker in its various incarnations.
|
||||
- `Documentation/technical/api-revision-walking.txt`
|
||||
- `revision.h`
|
||||
- https://eagain.net/articles/git-for-computer-scientists/[Git for Computer Scientists]
|
||||
gives a good overview of the types of objects in Git and what your object
|
||||
walk is really describing.
|
||||
@ -119,9 +119,8 @@ parameters provided by the user over the CLI.
|
||||
|
||||
`nr` represents the number of `rev_cmdline_entry` present in the array.
|
||||
|
||||
`alloc` is used by the `ALLOC_GROW` macro. Check
|
||||
`Documentation/technical/api-allocation-growing.txt` - this variable is used to
|
||||
track the allocated size of the list.
|
||||
`alloc` is used by the `ALLOC_GROW` macro. Check `cache.h` - this variable is
|
||||
used to track the allocated size of the list.
|
||||
|
||||
Per entry, we find:
|
||||
|
||||
|
@ -19,8 +19,7 @@ from system-specific helpers, as well as prompting the user for
|
||||
usernames and passwords. The git-credential command exposes this
|
||||
interface to scripts which may want to retrieve, store, or prompt for
|
||||
credentials in the same manner as Git. The design of this scriptable
|
||||
interface models the internal C API; see
|
||||
link:technical/api-credentials.html[the Git credential API] for more
|
||||
interface models the internal C API; see credential.h for more
|
||||
background on the concepts.
|
||||
|
||||
git-credential takes an "action" option on the command-line (one of
|
||||
|
@ -186,8 +186,7 @@ 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.
|
||||
which you keep credentials. See credential.h for details.
|
||||
|
||||
GIT
|
||||
---
|
||||
|
@ -1,39 +0,0 @@
|
||||
allocation growing API
|
||||
======================
|
||||
|
||||
Dynamically growing an array using realloc() is error prone and boring.
|
||||
|
||||
Define your array with:
|
||||
|
||||
* a pointer (`item`) that points at the array, initialized to `NULL`
|
||||
(although please name the variable based on its contents, not on its
|
||||
type);
|
||||
|
||||
* an integer variable (`alloc`) that keeps track of how big the current
|
||||
allocation is, initialized to `0`;
|
||||
|
||||
* another integer variable (`nr`) to keep track of how many elements the
|
||||
array currently has, initialized to `0`.
|
||||
|
||||
Then before adding `n`th element to the item, call `ALLOC_GROW(item, n,
|
||||
alloc)`. This ensures that the array can hold at least `n` elements by
|
||||
calling `realloc(3)` and adjusting `alloc` variable.
|
||||
|
||||
------------
|
||||
sometype *item;
|
||||
size_t nr;
|
||||
size_t alloc
|
||||
|
||||
for (i = 0; i < nr; i++)
|
||||
if (we like item[i] already)
|
||||
return;
|
||||
|
||||
/* we did not like any existing one, so add one */
|
||||
ALLOC_GROW(item, nr + 1, alloc);
|
||||
item[nr++] = value you like;
|
||||
------------
|
||||
|
||||
You are responsible for updating the `nr` variable.
|
||||
|
||||
If you need to specify the number of elements to allocate explicitly
|
||||
then use the macro `REALLOC_ARRAY(item, alloc)` instead of `ALLOC_GROW`.
|
@ -1,65 +0,0 @@
|
||||
argv-array API
|
||||
==============
|
||||
|
||||
The argv-array API allows one to dynamically build and store
|
||||
NULL-terminated lists. An argv-array maintains the invariant that the
|
||||
`argv` member always points to a non-NULL array, and that the array is
|
||||
always NULL-terminated at the element pointed to by `argv[argc]`. This
|
||||
makes the result suitable for passing to functions expecting to receive
|
||||
argv from main(), or the link:api-run-command.html[run-command API].
|
||||
|
||||
The string-list API (documented in string-list.h) is similar, but cannot be
|
||||
used for these purposes; instead of storing a straight string pointer,
|
||||
it contains an item structure with a `util` field that is not compatible
|
||||
with the traditional argv interface.
|
||||
|
||||
Each `argv_array` manages its own memory. Any strings pushed into the
|
||||
array are duplicated, and all memory is freed by argv_array_clear().
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct argv_array`::
|
||||
|
||||
A single array. This should be initialized by assignment from
|
||||
`ARGV_ARRAY_INIT`, or by calling `argv_array_init`. The `argv`
|
||||
member contains the actual array; the `argc` member contains the
|
||||
number of elements in the array, not including the terminating
|
||||
NULL.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`argv_array_init`::
|
||||
Initialize an array. This is no different than assigning from
|
||||
`ARGV_ARRAY_INIT`.
|
||||
|
||||
`argv_array_push`::
|
||||
Push a copy of a string onto the end of the array.
|
||||
|
||||
`argv_array_pushl`::
|
||||
Push a list of strings onto the end of the array. The arguments
|
||||
should be a list of `const char *` strings, terminated by a NULL
|
||||
argument.
|
||||
|
||||
`argv_array_pushf`::
|
||||
Format a string and push it onto the end of the array. This is a
|
||||
convenience wrapper combining `strbuf_addf` and `argv_array_push`.
|
||||
|
||||
`argv_array_pushv`::
|
||||
Push a null-terminated array of strings onto the end of the array.
|
||||
|
||||
`argv_array_pop`::
|
||||
Remove the final element from the array. If there are no
|
||||
elements in the array, do nothing.
|
||||
|
||||
`argv_array_clear`::
|
||||
Free all memory associated with the array and return it to the
|
||||
initial, empty state.
|
||||
|
||||
`argv_array_detach`::
|
||||
Disconnect the `argv` member from the `argv_array` struct and
|
||||
return it. The caller is responsible for freeing the memory used
|
||||
by the array, and by the strings it references. After detaching,
|
||||
the `argv_array` is in a reinitialized state and can be pushed
|
||||
into again.
|
@ -1,271 +0,0 @@
|
||||
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).
|
||||
|
||||
This document describes two interfaces: the C API that the credential
|
||||
subsystem provides to the rest of Git, and the protocol that Git uses to
|
||||
communicate with system-specific "credential helpers". If you are
|
||||
writing Git code that wants to look up or prompt for credentials, see
|
||||
the section "C API" below. If you want to write your own helper, see
|
||||
the section on "Credential Helpers" below.
|
||||
|
||||
Typical setup
|
||||
-------------
|
||||
|
||||
------------
|
||||
+-----------------------+
|
||||
| Git code (C) |--- to server requiring --->
|
||||
| | authentication
|
||||
|.......................|
|
||||
| C credential API |--- prompt ---> User
|
||||
+-----------------------+
|
||||
^ |
|
||||
| pipe |
|
||||
| v
|
||||
+-----------------------+
|
||||
| Git credential helper |
|
||||
+-----------------------+
|
||||
------------
|
||||
|
||||
The Git code (typically a remote-helper) will call the C API to obtain
|
||||
credential data like a login/password pair (credential_fill). The
|
||||
API will itself call a remote helper (e.g. "git credential-cache" or
|
||||
"git credential-store") that may retrieve credential data from a
|
||||
store. If the credential helper cannot find the information, the C API
|
||||
will prompt the user. Then, the caller of the API takes care of
|
||||
contacting the server, and does the actual authentication.
|
||||
|
||||
C API
|
||||
-----
|
||||
|
||||
The credential C API is meant to be called by Git code which needs to
|
||||
acquire or store a credential. It is centered around an object
|
||||
representing a single credential and provides three basic operations:
|
||||
fill (acquire credentials by calling helpers and/or prompting the user),
|
||||
approve (mark a credential as successfully used so that it can be stored
|
||||
for later use), and reject (mark a credential as unsuccessful so that it
|
||||
can be erased from any persistent storage).
|
||||
|
||||
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 list is filled-in by the API functions
|
||||
according to the corresponding configuration variables before
|
||||
consulting helpers, so there usually is no need for a caller to
|
||||
modify the helpers field at all.
|
||||
+
|
||||
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 occurred. 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 in the configuration
|
||||
variable `credential.helper` (and others, see linkgit:git-config[1]).
|
||||
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 exact format is the same as the input/output format of the
|
||||
`git credential` plumbing command (see the section `INPUT/OUTPUT
|
||||
FORMAT` in linkgit:git-credential[1] for a detailed specification).
|
||||
|
||||
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. If a helper
|
||||
outputs a `quit` attribute with a value of `true` or `1`, no further
|
||||
helpers will be consulted, nor will the user be prompted (if no
|
||||
credential has been provided, the operation will then fail).
|
||||
|
||||
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).
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
linkgit:gitcredentials[7]
|
||||
|
||||
linkgit:git-config[1] (See configuration variables `credential.*`)
|
@ -1,174 +0,0 @@
|
||||
diff API
|
||||
========
|
||||
|
||||
The diff API is for programs that compare two sets of files (e.g. two
|
||||
trees, one tree and the index) and present the found difference in
|
||||
various ways. The calling program is responsible for feeding the API
|
||||
pairs of files, one from the "old" set and the corresponding one from
|
||||
"new" set, that are different. The library called through this API is
|
||||
called diffcore, and is responsible for two things.
|
||||
|
||||
* finding total rewrites (`-B`), renames (`-M`) and copies (`-C`), and
|
||||
changes that touch a string (`-S`), as specified by the caller.
|
||||
|
||||
* outputting the differences in various formats, as specified by the
|
||||
caller.
|
||||
|
||||
Calling sequence
|
||||
----------------
|
||||
|
||||
* Prepare `struct diff_options` to record the set of diff options, and
|
||||
then call `repo_diff_setup()` to initialize this structure. This
|
||||
sets up the vanilla default.
|
||||
|
||||
* Fill in the options structure to specify desired output format, rename
|
||||
detection, etc. `diff_opt_parse()` can be used to parse options given
|
||||
from the command line in a way consistent with existing git-diff
|
||||
family of programs.
|
||||
|
||||
* Call `diff_setup_done()`; this inspects the options set up so far for
|
||||
internal consistency and make necessary tweaking to it (e.g. if
|
||||
textual patch output was asked, recursive behaviour is turned on);
|
||||
the callback set_default in diff_options can be used to tweak this more.
|
||||
|
||||
* As you find different pairs of files, call `diff_change()` to feed
|
||||
modified files, `diff_addremove()` to feed created or deleted files,
|
||||
or `diff_unmerge()` to feed a file whose state is 'unmerged' to the
|
||||
API. These are thin wrappers to a lower-level `diff_queue()` function
|
||||
that is flexible enough to record any of these kinds of changes.
|
||||
|
||||
* Once you finish feeding the pairs of files, call `diffcore_std()`.
|
||||
This will tell the diffcore library to go ahead and do its work.
|
||||
|
||||
* Calling `diff_flush()` will produce the output.
|
||||
|
||||
|
||||
Data structures
|
||||
---------------
|
||||
|
||||
* `struct diff_filespec`
|
||||
|
||||
This is the internal representation for a single file (blob). It
|
||||
records the blob object name (if known -- for a work tree file it
|
||||
typically is a NUL SHA-1), filemode and pathname. This is what the
|
||||
`diff_addremove()`, `diff_change()` and `diff_unmerge()` synthesize and
|
||||
feed `diff_queue()` function with.
|
||||
|
||||
* `struct diff_filepair`
|
||||
|
||||
This records a pair of `struct diff_filespec`; the filespec for a file
|
||||
in the "old" set (i.e. preimage) is called `one`, and the filespec for a
|
||||
file in the "new" set (i.e. postimage) is called `two`. A change that
|
||||
represents file creation has NULL in `one`, and file deletion has NULL
|
||||
in `two`.
|
||||
|
||||
A `filepair` starts pointing at `one` and `two` that are from the same
|
||||
filename, but `diffcore_std()` can break pairs and match component
|
||||
filespecs with other filespecs from a different filepair to form new
|
||||
filepair. This is called 'rename detection'.
|
||||
|
||||
* `struct diff_queue`
|
||||
|
||||
This is a collection of filepairs. Notable members are:
|
||||
|
||||
`queue`::
|
||||
|
||||
An array of pointers to `struct diff_filepair`. This
|
||||
dynamically grows as you add filepairs;
|
||||
|
||||
`alloc`::
|
||||
|
||||
The allocated size of the `queue` array;
|
||||
|
||||
`nr`::
|
||||
|
||||
The number of elements in the `queue` array.
|
||||
|
||||
|
||||
* `struct diff_options`
|
||||
|
||||
This describes the set of options the calling program wants to affect
|
||||
the operation of diffcore library with.
|
||||
|
||||
Notable members are:
|
||||
|
||||
`output_format`::
|
||||
The output format used when `diff_flush()` is run.
|
||||
|
||||
`context`::
|
||||
Number of context lines to generate in patch output.
|
||||
|
||||
`break_opt`, `detect_rename`, `rename-score`, `rename_limit`::
|
||||
Affects the way detection logic for complete rewrites, renames
|
||||
and copies.
|
||||
|
||||
`abbrev`::
|
||||
Number of hexdigits to abbreviate raw format output to.
|
||||
|
||||
`pickaxe`::
|
||||
A constant string (can and typically does contain newlines to
|
||||
look for a block of text, not just a single line) to filter out
|
||||
the filepairs that do not change the number of strings contained
|
||||
in its preimage and postimage of the diff_queue.
|
||||
|
||||
`flags`::
|
||||
This is mostly a collection of boolean options that affects the
|
||||
operation, but some do not have anything to do with the diffcore
|
||||
library.
|
||||
|
||||
`touched_flags`::
|
||||
Records whether a flag has been changed due to user request
|
||||
(rather than just set/unset by default).
|
||||
|
||||
`set_default`::
|
||||
Callback which allows tweaking the options in diff_setup_done().
|
||||
|
||||
BINARY, TEXT;;
|
||||
Affects the way how a file that is seemingly binary is treated.
|
||||
|
||||
FULL_INDEX;;
|
||||
Tells the patch output format not to use abbreviated object
|
||||
names on the "index" lines.
|
||||
|
||||
FIND_COPIES_HARDER;;
|
||||
Tells the diffcore library that the caller is feeding unchanged
|
||||
filepairs to allow copies from unmodified files be detected.
|
||||
|
||||
COLOR_DIFF;;
|
||||
Output should be colored.
|
||||
|
||||
COLOR_DIFF_WORDS;;
|
||||
Output is a colored word-diff.
|
||||
|
||||
NO_INDEX;;
|
||||
Tells diff-files that the input is not tracked files but files
|
||||
in random locations on the filesystem.
|
||||
|
||||
ALLOW_EXTERNAL;;
|
||||
Tells output routine that it is Ok to call user specified patch
|
||||
output routine. Plumbing disables this to ensure stable output.
|
||||
|
||||
QUIET;;
|
||||
Do not show any output.
|
||||
|
||||
REVERSE_DIFF;;
|
||||
Tells the library that the calling program is feeding the
|
||||
filepairs reversed; `one` is two, and `two` is one.
|
||||
|
||||
EXIT_WITH_STATUS;;
|
||||
For communication between the calling program and the options
|
||||
parser; tell the calling program to signal the presence of
|
||||
difference using program exit code.
|
||||
|
||||
HAS_CHANGES;;
|
||||
Internal; used for optimization to see if there is any change.
|
||||
|
||||
SILENT_ON_REMOVE;;
|
||||
Affects if diff-files shows removed files.
|
||||
|
||||
RECURSIVE, TREE_IN_RECURSIVE;;
|
||||
Tells if tree traversal done by tree-diff should recursively
|
||||
descend into a tree object pair that are different in preimage
|
||||
and postimage set.
|
||||
|
||||
(JC)
|
@ -1,130 +0,0 @@
|
||||
directory listing API
|
||||
=====================
|
||||
|
||||
The directory listing API is used to enumerate paths in the work tree,
|
||||
optionally taking `.git/info/exclude` and `.gitignore` files per
|
||||
directory into account.
|
||||
|
||||
Data structure
|
||||
--------------
|
||||
|
||||
`struct dir_struct` structure is used to pass directory traversal
|
||||
options to the library and to record the paths discovered. A single
|
||||
`struct dir_struct` is used regardless of whether or not the traversal
|
||||
recursively descends into subdirectories.
|
||||
|
||||
The notable options are:
|
||||
|
||||
`exclude_per_dir`::
|
||||
|
||||
The name of the file to be read in each directory for excluded
|
||||
files (typically `.gitignore`).
|
||||
|
||||
`flags`::
|
||||
|
||||
A bit-field of options:
|
||||
|
||||
`DIR_SHOW_IGNORED`:::
|
||||
|
||||
Return just ignored files in `entries[]`, not untracked
|
||||
files. This flag is mutually exclusive with
|
||||
`DIR_SHOW_IGNORED_TOO`.
|
||||
|
||||
`DIR_SHOW_IGNORED_TOO`:::
|
||||
|
||||
Similar to `DIR_SHOW_IGNORED`, but return ignored files in
|
||||
`ignored[]` in addition to untracked files in
|
||||
`entries[]`. This flag is mutually exclusive with
|
||||
`DIR_SHOW_IGNORED`.
|
||||
|
||||
`DIR_KEEP_UNTRACKED_CONTENTS`:::
|
||||
|
||||
Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is set, the
|
||||
untracked contents of untracked directories are also returned in
|
||||
`entries[]`.
|
||||
|
||||
`DIR_SHOW_IGNORED_TOO_MODE_MATCHING`:::
|
||||
|
||||
Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if
|
||||
this is set, returns ignored files and directories that match
|
||||
an exclude pattern. If a directory matches an exclude pattern,
|
||||
then the directory is returned and the contained paths are
|
||||
not. A directory that does not match an exclude pattern will
|
||||
not be returned even if all of its contents are ignored. In
|
||||
this case, the contents are returned as individual entries.
|
||||
+
|
||||
If this is set, files and directories that explicitly match an ignore
|
||||
pattern are reported. Implicitly ignored directories (directories that
|
||||
do not match an ignore pattern, but whose contents are all ignored)
|
||||
are not reported, instead all of the contents are reported.
|
||||
|
||||
`DIR_COLLECT_IGNORED`:::
|
||||
|
||||
Special mode for git-add. Return ignored files in `ignored[]` and
|
||||
untracked files in `entries[]`. Only returns ignored files that match
|
||||
pathspec exactly (no wildcards). Does not recurse into ignored
|
||||
directories.
|
||||
|
||||
`DIR_SHOW_OTHER_DIRECTORIES`:::
|
||||
|
||||
Include a directory that is not tracked.
|
||||
|
||||
`DIR_HIDE_EMPTY_DIRECTORIES`:::
|
||||
|
||||
Do not include a directory that is not tracked and is empty.
|
||||
|
||||
`DIR_NO_GITLINKS`:::
|
||||
|
||||
If set, recurse into a directory that looks like a Git
|
||||
directory. Otherwise it is shown as a directory.
|
||||
|
||||
The result of the enumeration is left in these fields:
|
||||
|
||||
`entries[]`::
|
||||
|
||||
An array of `struct dir_entry`, each element of which describes
|
||||
a path.
|
||||
|
||||
`nr`::
|
||||
|
||||
The number of members in `entries[]` array.
|
||||
|
||||
`alloc`::
|
||||
|
||||
Internal use; keeps track of allocation of `entries[]` array.
|
||||
|
||||
`ignored[]`::
|
||||
|
||||
An array of `struct dir_entry`, used for ignored paths with the
|
||||
`DIR_SHOW_IGNORED_TOO` and `DIR_COLLECT_IGNORED` flags.
|
||||
|
||||
`ignored_nr`::
|
||||
|
||||
The number of members in `ignored[]` array.
|
||||
|
||||
Calling sequence
|
||||
----------------
|
||||
|
||||
Note: index may be looked at for .gitignore files that are CE_SKIP_WORKTREE
|
||||
marked. If you to exclude files, make sure you have loaded index first.
|
||||
|
||||
* Prepare `struct dir_struct dir` and clear it with `memset(&dir, 0,
|
||||
sizeof(dir))`.
|
||||
|
||||
* To add single exclude pattern, call `add_pattern_list()` and then
|
||||
`add_pattern()`.
|
||||
|
||||
* To add patterns from a file (e.g. `.git/info/exclude`), call
|
||||
`add_patterns_from_file()` , and/or set `dir.exclude_per_dir`. A
|
||||
short-hand function `setup_standard_excludes()` can be used to set
|
||||
up the standard set of exclude settings.
|
||||
|
||||
* Set options described in the Data Structure section above.
|
||||
|
||||
* Call `read_directory()`.
|
||||
|
||||
* Use `dir.entries[]`.
|
||||
|
||||
* Call `clear_directory()` when none of the contained elements are no longer in use.
|
||||
|
||||
(JC)
|
@ -1,154 +0,0 @@
|
||||
gitattributes API
|
||||
=================
|
||||
|
||||
gitattributes mechanism gives a uniform way to associate various
|
||||
attributes to set of paths.
|
||||
|
||||
|
||||
Data Structure
|
||||
--------------
|
||||
|
||||
`struct git_attr`::
|
||||
|
||||
An attribute is an opaque object that is identified by its name.
|
||||
Pass the name to `git_attr()` function to obtain the object of
|
||||
this type. The internal representation of this structure is
|
||||
of no interest to the calling programs. The name of the
|
||||
attribute can be retrieved by calling `git_attr_name()`.
|
||||
|
||||
`struct attr_check_item`::
|
||||
|
||||
This structure represents one attribute and its value.
|
||||
|
||||
`struct attr_check`::
|
||||
|
||||
This structure represents a collection of `attr_check_item`.
|
||||
It is passed to `git_check_attr()` function, specifying the
|
||||
attributes to check, and receives their values.
|
||||
|
||||
|
||||
Attribute Values
|
||||
----------------
|
||||
|
||||
An attribute for a path can be in one of four states: Set, Unset,
|
||||
Unspecified or set to a string, and `.value` member of `struct
|
||||
attr_check_item` records it. There are three macros to check these:
|
||||
|
||||
`ATTR_TRUE()`::
|
||||
|
||||
Returns true if the attribute is Set for the path.
|
||||
|
||||
`ATTR_FALSE()`::
|
||||
|
||||
Returns true if the attribute is Unset for the path.
|
||||
|
||||
`ATTR_UNSET()`::
|
||||
|
||||
Returns true if the attribute is Unspecified for the path.
|
||||
|
||||
If none of the above returns true, `.value` member points at a string
|
||||
value of the attribute for the path.
|
||||
|
||||
|
||||
Querying Specific Attributes
|
||||
----------------------------
|
||||
|
||||
* Prepare `struct attr_check` using attr_check_initl()
|
||||
function, enumerating the names of attributes whose values you are
|
||||
interested in, terminated with a NULL pointer. Alternatively, an
|
||||
empty `struct attr_check` can be prepared by calling
|
||||
`attr_check_alloc()` function and then attributes you want to
|
||||
ask about can be added to it with `attr_check_append()`
|
||||
function.
|
||||
|
||||
* Call `git_check_attr()` to check the attributes for the path.
|
||||
|
||||
* Inspect `attr_check` structure to see how each of the
|
||||
attribute in the array is defined for the path.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
To see how attributes "crlf" and "ident" are set for different paths.
|
||||
|
||||
. Prepare a `struct attr_check` with two elements (because
|
||||
we are checking two attributes):
|
||||
|
||||
------------
|
||||
static struct attr_check *check;
|
||||
static void setup_check(void)
|
||||
{
|
||||
if (check)
|
||||
return; /* already done */
|
||||
check = attr_check_initl("crlf", "ident", NULL);
|
||||
}
|
||||
------------
|
||||
|
||||
. Call `git_check_attr()` with the prepared `struct attr_check`:
|
||||
|
||||
------------
|
||||
const char *path;
|
||||
|
||||
setup_check();
|
||||
git_check_attr(path, check);
|
||||
------------
|
||||
|
||||
. Act on `.value` member of the result, left in `check->items[]`:
|
||||
|
||||
------------
|
||||
const char *value = check->items[0].value;
|
||||
|
||||
if (ATTR_TRUE(value)) {
|
||||
The attribute is Set, by listing only the name of the
|
||||
attribute in the gitattributes file for the path.
|
||||
} else if (ATTR_FALSE(value)) {
|
||||
The attribute is Unset, by listing the name of the
|
||||
attribute prefixed with a dash - for the path.
|
||||
} else if (ATTR_UNSET(value)) {
|
||||
The attribute is neither set nor unset for the path.
|
||||
} else if (!strcmp(value, "input")) {
|
||||
If none of ATTR_TRUE(), ATTR_FALSE(), or ATTR_UNSET() is
|
||||
true, the value is a string set in the gitattributes
|
||||
file for the path by saying "attr=value".
|
||||
} else if (... other check using value as string ...) {
|
||||
...
|
||||
}
|
||||
------------
|
||||
|
||||
To see how attributes in argv[] are set for different paths, only
|
||||
the first step in the above would be different.
|
||||
|
||||
------------
|
||||
static struct attr_check *check;
|
||||
static void setup_check(const char **argv)
|
||||
{
|
||||
check = attr_check_alloc();
|
||||
while (*argv) {
|
||||
struct git_attr *attr = git_attr(*argv);
|
||||
attr_check_append(check, attr);
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
------------
|
||||
|
||||
|
||||
Querying All Attributes
|
||||
-----------------------
|
||||
|
||||
To get the values of all attributes associated with a file:
|
||||
|
||||
* Prepare an empty `attr_check` structure by calling
|
||||
`attr_check_alloc()`.
|
||||
|
||||
* Call `git_all_attrs()`, which populates the `attr_check`
|
||||
with the attributes attached to the path.
|
||||
|
||||
* Iterate over the `attr_check.items[]` array to examine
|
||||
the attribute names and values. The name of the attribute
|
||||
described by an `attr_check.items[]` object can be retrieved via
|
||||
`git_attr_name(check->items[i].attr)`. (Please note that no items
|
||||
will be returned for unset attributes, so `ATTR_UNSET()` will return
|
||||
false for all returned `attr_check.items[]` objects.)
|
||||
|
||||
* Free the `attr_check` struct by calling `attr_check_free()`.
|
@ -1,173 +0,0 @@
|
||||
history graph API
|
||||
=================
|
||||
|
||||
The graph API is used to draw a text-based representation of the commit
|
||||
history. The API generates the graph in a line-by-line fashion.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
Core functions:
|
||||
|
||||
* `graph_init()` creates a new `struct git_graph`
|
||||
|
||||
* `graph_update()` moves the graph to a new commit.
|
||||
|
||||
* `graph_next_line()` outputs the next line of the graph into a strbuf. It
|
||||
does not add a terminating newline.
|
||||
|
||||
* `graph_padding_line()` outputs a line of vertical padding in the graph. It
|
||||
is similar to `graph_next_line()`, but is guaranteed to never print the line
|
||||
containing the current commit. Where `graph_next_line()` would print the
|
||||
commit line next, `graph_padding_line()` prints a line that simply extends
|
||||
all branch lines downwards one row, leaving their positions unchanged.
|
||||
|
||||
* `graph_is_commit_finished()` determines if the graph has output all lines
|
||||
necessary for the current commit. If `graph_update()` is called before all
|
||||
lines for the current commit have been printed, the next call to
|
||||
`graph_next_line()` will output an ellipsis, to indicate that a portion of
|
||||
the graph was omitted.
|
||||
|
||||
The following utility functions are wrappers around `graph_next_line()` and
|
||||
`graph_is_commit_finished()`. They always print the output to stdout.
|
||||
They can all be called with a NULL graph argument, in which case no graph
|
||||
output will be printed.
|
||||
|
||||
* `graph_show_commit()` calls `graph_next_line()` and
|
||||
`graph_is_commit_finished()` until one of them return non-zero. This prints
|
||||
all graph lines up to, and including, the line containing this commit.
|
||||
Output is printed to stdout. The last line printed does not contain a
|
||||
terminating newline.
|
||||
|
||||
* `graph_show_oneline()` calls `graph_next_line()` and prints the result to
|
||||
stdout. The line printed does not contain a terminating newline.
|
||||
|
||||
* `graph_show_padding()` calls `graph_padding_line()` and prints the result to
|
||||
stdout. The line printed does not contain a terminating newline.
|
||||
|
||||
* `graph_show_remainder()` calls `graph_next_line()` until
|
||||
`graph_is_commit_finished()` returns non-zero. Output is printed to stdout.
|
||||
The last line printed does not contain a terminating newline. Returns 1 if
|
||||
output was printed, and 0 if no output was necessary.
|
||||
|
||||
* `graph_show_strbuf()` prints the specified strbuf to stdout, prefixing all
|
||||
lines but the first with a graph line. The caller is responsible for
|
||||
ensuring graph output for the first line has already been printed to stdout.
|
||||
(This can be done with `graph_show_commit()` or `graph_show_oneline()`.) If
|
||||
a NULL graph is supplied, the strbuf is printed as-is.
|
||||
|
||||
* `graph_show_commit_msg()` is similar to `graph_show_strbuf()`, but it also
|
||||
prints the remainder of the graph, if more lines are needed after the strbuf
|
||||
ends. It is better than directly calling `graph_show_strbuf()` followed by
|
||||
`graph_show_remainder()` since it properly handles buffers that do not end in
|
||||
a terminating newline. The output printed by `graph_show_commit_msg()` will
|
||||
end in a newline if and only if the strbuf ends in a newline.
|
||||
|
||||
Data structure
|
||||
--------------
|
||||
`struct git_graph` is an opaque data type used to store the current graph
|
||||
state.
|
||||
|
||||
Calling sequence
|
||||
----------------
|
||||
|
||||
* Create a `struct git_graph` by calling `graph_init()`. When using the
|
||||
revision walking API, this is done automatically by `setup_revisions()` if
|
||||
the '--graph' option is supplied.
|
||||
|
||||
* Use the revision walking API to walk through a group of contiguous commits.
|
||||
The `get_revision()` function automatically calls `graph_update()` each time
|
||||
it is invoked.
|
||||
|
||||
* For each commit, call `graph_next_line()` repeatedly, until
|
||||
`graph_is_commit_finished()` returns non-zero. Each call to
|
||||
`graph_next_line()` will output a single line of the graph. The resulting
|
||||
lines will not contain any newlines. `graph_next_line()` returns 1 if the
|
||||
resulting line contains the current commit, or 0 if this is merely a line
|
||||
needed to adjust the graph before or after the current commit. This return
|
||||
value can be used to determine where to print the commit summary information
|
||||
alongside the graph output.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
* `graph_update()` must be called with commits in topological order. It should
|
||||
not be called on a commit if it has already been invoked with an ancestor of
|
||||
that commit, or the graph output will be incorrect.
|
||||
|
||||
* `graph_update()` must be called on a contiguous group of commits. If
|
||||
`graph_update()` is called on a particular commit, it should later be called
|
||||
on all parents of that commit. Parents must not be skipped, or the graph
|
||||
output will appear incorrect.
|
||||
+
|
||||
`graph_update()` may be used on a pruned set of commits only if the parent list
|
||||
has been rewritten so as to include only ancestors from the pruned set.
|
||||
|
||||
* The graph API does not currently support reverse commit ordering. In
|
||||
order to implement reverse ordering, the graphing API needs an
|
||||
(efficient) mechanism to find the children of a commit.
|
||||
|
||||
Sample usage
|
||||
------------
|
||||
|
||||
------------
|
||||
struct commit *commit;
|
||||
struct git_graph *graph = graph_init(opts);
|
||||
|
||||
while ((commit = get_revision(opts)) != NULL) {
|
||||
while (!graph_is_commit_finished(graph))
|
||||
{
|
||||
struct strbuf sb;
|
||||
int is_commit_line;
|
||||
|
||||
strbuf_init(&sb, 0);
|
||||
is_commit_line = graph_next_line(graph, &sb);
|
||||
fputs(sb.buf, stdout);
|
||||
|
||||
if (is_commit_line)
|
||||
log_tree_commit(opts, commit);
|
||||
else
|
||||
putchar(opts->diffopt.line_termination);
|
||||
}
|
||||
}
|
||||
------------
|
||||
|
||||
Sample output
|
||||
-------------
|
||||
|
||||
The following is an example of the output from the graph API. This output does
|
||||
not include any commit summary information--callers are responsible for
|
||||
outputting that information, if desired.
|
||||
|
||||
------------
|
||||
*
|
||||
*
|
||||
*
|
||||
|\
|
||||
* |
|
||||
| | *
|
||||
| \ \
|
||||
| \ \
|
||||
*-. \ \
|
||||
|\ \ \ \
|
||||
| | * | |
|
||||
| | | | | *
|
||||
| | | | | *
|
||||
| | | | | *
|
||||
| | | | | |\
|
||||
| | | | | | *
|
||||
| * | | | | |
|
||||
| | | | | * \
|
||||
| | | | | |\ |
|
||||
| | | | * | | |
|
||||
| | | | * | | |
|
||||
* | | | | | | |
|
||||
| |/ / / / / /
|
||||
|/| / / / / /
|
||||
* | | | | | |
|
||||
|/ / / / / /
|
||||
* | | | | |
|
||||
| | | | | *
|
||||
| | | | |/
|
||||
| | | | *
|
||||
------------
|
@ -28,77 +28,9 @@ and `diff.c` for examples.
|
||||
|
||||
* `struct ll_merge_options`
|
||||
|
||||
This describes the set of options the calling program wants to affect
|
||||
the operation of a low-level (single file) merge. Some options:
|
||||
|
||||
`virtual_ancestor`::
|
||||
Behave as though this were part of a merge between common
|
||||
ancestors in a recursive merge.
|
||||
If a helper program is specified by the
|
||||
`[merge "<driver>"] recursive` configuration, it will
|
||||
be used (see linkgit:gitattributes[5]).
|
||||
|
||||
`variant`::
|
||||
Resolve local conflicts automatically in favor
|
||||
of one side or the other (as in 'git merge-file'
|
||||
`--ours`/`--theirs`/`--union`). Can be `0`,
|
||||
`XDL_MERGE_FAVOR_OURS`, `XDL_MERGE_FAVOR_THEIRS`, or
|
||||
`XDL_MERGE_FAVOR_UNION`.
|
||||
|
||||
`renormalize`::
|
||||
Resmudge and clean the "base", "theirs" and "ours" files
|
||||
before merging. Use this when the merge is likely to have
|
||||
overlapped with a change in smudge/clean or end-of-line
|
||||
normalization rules.
|
||||
Check ll-merge.h for details.
|
||||
|
||||
Low-level (single file) merge
|
||||
-----------------------------
|
||||
|
||||
`ll_merge`::
|
||||
|
||||
Perform a three-way single-file merge in core. This is
|
||||
a thin wrapper around `xdl_merge` that takes the path and
|
||||
any merge backend specified in `.gitattributes` or
|
||||
`.git/info/attributes` into account. Returns 0 for a
|
||||
clean merge.
|
||||
|
||||
Calling sequence:
|
||||
|
||||
* Prepare a `struct ll_merge_options` to record options.
|
||||
If you have no special requests, skip this and pass `NULL`
|
||||
as the `opts` parameter to use the default options.
|
||||
|
||||
* Allocate an mmbuffer_t variable for the result.
|
||||
|
||||
* Allocate and fill variables with the file's original content
|
||||
and two modified versions (using `read_mmfile`, for example).
|
||||
|
||||
* Call `ll_merge()`.
|
||||
|
||||
* Read the merged content from `result_buf.ptr` and `result_buf.size`.
|
||||
|
||||
* Release buffers when finished. A simple
|
||||
`free(ancestor.ptr); free(ours.ptr); free(theirs.ptr);
|
||||
free(result_buf.ptr);` will do.
|
||||
|
||||
If the modifications do not merge cleanly, `ll_merge` will return a
|
||||
nonzero value and `result_buf` will generally include a description of
|
||||
the conflict bracketed by markers such as the traditional `<<<<<<<`
|
||||
and `>>>>>>>`.
|
||||
|
||||
The `ancestor_label`, `our_label`, and `their_label` parameters are
|
||||
used to label the different sides of a conflict if the merge driver
|
||||
supports this.
|
||||
|
||||
Everything else
|
||||
---------------
|
||||
|
||||
Talk about <merge-recursive.h> and merge_file():
|
||||
|
||||
- merge_trees() to merge with rename detection
|
||||
- merge_recursive() for ancestor consolidation
|
||||
- try_merge_command() for other strategies
|
||||
- conflict format
|
||||
- merge options
|
||||
|
||||
(Daniel, Miklos, Stephan, JC)
|
||||
Check ll-merge.h for details.
|
||||
|
@ -1,90 +0,0 @@
|
||||
oid-array API
|
||||
==============
|
||||
|
||||
The oid-array API provides storage and manipulation of sets of object
|
||||
identifiers. The emphasis is on storage and processing efficiency,
|
||||
making them suitable for large lists. Note that the ordering of items is
|
||||
not preserved over some operations.
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct oid_array`::
|
||||
|
||||
A single array of object IDs. This should be initialized by
|
||||
assignment from `OID_ARRAY_INIT`. The `oid` member contains
|
||||
the actual data. The `nr` member contains the number of items in
|
||||
the set. The `alloc` and `sorted` members are used internally,
|
||||
and should not be needed by API callers.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`oid_array_append`::
|
||||
Add an item to the set. The object ID will be placed at the end of
|
||||
the array (but note that some operations below may lose this
|
||||
ordering).
|
||||
|
||||
`oid_array_lookup`::
|
||||
Perform a binary search of the array for a specific object ID.
|
||||
If found, returns the offset (in number of elements) of the
|
||||
object ID. If not found, returns a negative integer. If the array
|
||||
is not sorted, this function has the side effect of sorting it.
|
||||
|
||||
`oid_array_clear`::
|
||||
Free all memory associated with the array and return it to the
|
||||
initial, empty state.
|
||||
|
||||
`oid_array_for_each`::
|
||||
Iterate over each element of the list, executing the callback
|
||||
function for each one. Does not sort the list, so any custom
|
||||
hash order is retained. If the callback returns a non-zero
|
||||
value, the iteration ends immediately and the callback's
|
||||
return is propagated; otherwise, 0 is returned.
|
||||
|
||||
`oid_array_for_each_unique`::
|
||||
Iterate over each unique element of the list in sorted order,
|
||||
but otherwise behave like `oid_array_for_each`. If the array
|
||||
is not sorted, this function has the side effect of sorting
|
||||
it.
|
||||
|
||||
`oid_array_filter`::
|
||||
Apply the callback function `want` to each entry in the array,
|
||||
retaining only the entries for which the function returns true.
|
||||
Preserve the order of the entries that are retained.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
-----------------------------------------
|
||||
int print_callback(const struct object_id *oid,
|
||||
void *data)
|
||||
{
|
||||
printf("%s\n", oid_to_hex(oid));
|
||||
return 0; /* always continue */
|
||||
}
|
||||
|
||||
void some_func(void)
|
||||
{
|
||||
struct sha1_array hashes = OID_ARRAY_INIT;
|
||||
struct object_id oid;
|
||||
|
||||
/* Read objects into our set */
|
||||
while (read_object_from_stdin(oid.hash))
|
||||
oid_array_append(&hashes, &oid);
|
||||
|
||||
/* Check if some objects are in our set */
|
||||
while (read_object_from_stdin(oid.hash)) {
|
||||
if (oid_array_lookup(&hashes, &oid) >= 0)
|
||||
printf("it's in there!\n");
|
||||
|
||||
/*
|
||||
* Print the unique set of objects. We could also have
|
||||
* avoided adding duplicate objects in the first place,
|
||||
* but we would end up re-sorting the array repeatedly.
|
||||
* Instead, this will sort once and then skip duplicates
|
||||
* in linear time.
|
||||
*/
|
||||
oid_array_for_each_unique(&hashes, print_callback, NULL);
|
||||
}
|
||||
-----------------------------------------
|
@ -1,78 +0,0 @@
|
||||
ref iteration API
|
||||
=================
|
||||
|
||||
|
||||
Iteration of refs is done by using an iterate function which will call a
|
||||
callback function for every ref. The callback function has this
|
||||
signature:
|
||||
|
||||
int handle_one_ref(const char *refname, const struct object_id *oid,
|
||||
int flags, void *cb_data);
|
||||
|
||||
There are different kinds of iterate functions which all take a
|
||||
callback of this type. The callback is then called for each found ref
|
||||
until the callback returns nonzero. The returned value is then also
|
||||
returned by the iterate function.
|
||||
|
||||
Iteration functions
|
||||
-------------------
|
||||
|
||||
* `head_ref()` just iterates the head ref.
|
||||
|
||||
* `for_each_ref()` iterates all refs.
|
||||
|
||||
* `for_each_ref_in()` iterates all refs which have a defined prefix and
|
||||
strips that prefix from the passed variable refname.
|
||||
|
||||
* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`,
|
||||
`for_each_replace_ref()` iterate refs from the respective area.
|
||||
|
||||
* `for_each_glob_ref()` iterates all refs that match the specified glob
|
||||
pattern.
|
||||
|
||||
* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined.
|
||||
|
||||
* Use `refs_` API for accessing submodules. The submodule ref store could
|
||||
be obtained with `get_submodule_ref_store()`.
|
||||
|
||||
* `for_each_rawref()` can be used to learn about broken ref and symref.
|
||||
|
||||
* `for_each_reflog()` iterates each reflog file.
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
If you want to iterate the refs of a submodule you first need to add the
|
||||
submodules object database. You can do this by a code-snippet like
|
||||
this:
|
||||
|
||||
const char *path = "path/to/submodule"
|
||||
if (add_submodule_odb(path))
|
||||
die("Error submodule '%s' not populated.", path);
|
||||
|
||||
`add_submodule_odb()` will return zero on success. If you
|
||||
do not do this you will get an error for each ref that it does not point
|
||||
to a valid object.
|
||||
|
||||
Note: As a side-effect of this you cannot safely assume that all
|
||||
objects you lookup are available in superproject. All submodule objects
|
||||
will be available the same way as the superprojects objects.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
----
|
||||
static int handle_remote_ref(const char *refname,
|
||||
const unsigned char *sha1, int flags, void *cb_data)
|
||||
{
|
||||
struct strbuf *output = cb_data;
|
||||
strbuf_addf(output, "%s\n", refname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
struct strbuf output = STRBUF_INIT;
|
||||
for_each_remote_ref(handle_remote_ref, &output);
|
||||
printf("%s", output.buf);
|
||||
----
|
@ -1,127 +0,0 @@
|
||||
Remotes configuration API
|
||||
=========================
|
||||
|
||||
The API in remote.h gives access to the configuration related to
|
||||
remotes. It handles all three configuration mechanisms historically
|
||||
and currently used by Git, and presents the information in a uniform
|
||||
fashion. Note that the code also handles plain URLs without any
|
||||
configuration, giving them just the default information.
|
||||
|
||||
struct remote
|
||||
-------------
|
||||
|
||||
`name`::
|
||||
|
||||
The user's nickname for the remote
|
||||
|
||||
`url`::
|
||||
|
||||
An array of all of the url_nr URLs configured for the remote
|
||||
|
||||
`pushurl`::
|
||||
|
||||
An array of all of the pushurl_nr push URLs configured for the remote
|
||||
|
||||
`push`::
|
||||
|
||||
An array of refspecs configured for pushing, with
|
||||
push_refspec being the literal strings, and push_refspec_nr
|
||||
being the quantity.
|
||||
|
||||
`fetch`::
|
||||
|
||||
An array of refspecs configured for fetching, with
|
||||
fetch_refspec being the literal strings, and fetch_refspec_nr
|
||||
being the quantity.
|
||||
|
||||
`fetch_tags`::
|
||||
|
||||
The setting for whether to fetch tags (as a separate rule from
|
||||
the configured refspecs); -1 means never to fetch tags, 0
|
||||
means to auto-follow tags based on the default heuristic, 1
|
||||
means to always auto-follow tags, and 2 means to fetch all
|
||||
tags.
|
||||
|
||||
`receivepack`, `uploadpack`::
|
||||
|
||||
The configured helper programs to run on the remote side, for
|
||||
Git-native protocols.
|
||||
|
||||
`http_proxy`::
|
||||
|
||||
The proxy to use for curl (http, https, ftp, etc.) URLs.
|
||||
|
||||
`http_proxy_authmethod`::
|
||||
|
||||
The method used for authenticating against `http_proxy`.
|
||||
|
||||
struct remotes can be found by name with remote_get(), and iterated
|
||||
through with for_each_remote(). remote_get(NULL) will return the
|
||||
default remote, given the current branch and configuration.
|
||||
|
||||
struct refspec
|
||||
--------------
|
||||
|
||||
A struct refspec holds the parsed interpretation of a refspec. If it
|
||||
will force updates (starts with a '+'), force is true. If it is a
|
||||
pattern (sides end with '*') pattern is true. src and dest are the
|
||||
two sides (including '*' characters if present); if there is only one
|
||||
side, it is src, and dst is NULL; if sides exist but are empty (i.e.,
|
||||
the refspec either starts or ends with ':'), the corresponding side is
|
||||
"".
|
||||
|
||||
An array of strings can be parsed into an array of struct refspecs
|
||||
using parse_fetch_refspec() or parse_push_refspec().
|
||||
|
||||
remote_find_tracking(), given a remote and a struct refspec with
|
||||
either src or dst filled out, will fill out the other such that the
|
||||
result is in the "fetch" specification for the remote (note that this
|
||||
evaluates patterns and returns a single result).
|
||||
|
||||
struct branch
|
||||
-------------
|
||||
|
||||
Note that this may end up moving to branch.h
|
||||
|
||||
struct branch holds the configuration for a branch. It can be looked
|
||||
up with branch_get(name) for "refs/heads/{name}", or with
|
||||
branch_get(NULL) for HEAD.
|
||||
|
||||
It contains:
|
||||
|
||||
`name`::
|
||||
|
||||
The short name of the branch.
|
||||
|
||||
`refname`::
|
||||
|
||||
The full path for the branch ref.
|
||||
|
||||
`remote_name`::
|
||||
|
||||
The name of the remote listed in the configuration.
|
||||
|
||||
`merge_name`::
|
||||
|
||||
An array of the "merge" lines in the configuration.
|
||||
|
||||
`merge`::
|
||||
|
||||
An array of the struct refspecs used for the merge lines. That
|
||||
is, merge[i]->dst is a local tracking ref which should be
|
||||
merged into this branch by default.
|
||||
|
||||
`merge_nr`::
|
||||
|
||||
The number of merge configurations
|
||||
|
||||
branch_has_merge_config() returns true if the given branch has merge
|
||||
configuration given.
|
||||
|
||||
Other stuff
|
||||
-----------
|
||||
|
||||
There is other stuff in remote.h that is related, in general, to the
|
||||
process of interacting with remotes.
|
||||
|
||||
(Daniel Barkalow)
|
@ -1,72 +0,0 @@
|
||||
revision walking API
|
||||
====================
|
||||
|
||||
The revision walking API offers functions to build a list of revisions
|
||||
and then iterate over that list.
|
||||
|
||||
Calling sequence
|
||||
----------------
|
||||
|
||||
The walking API has a given calling sequence: first you need to
|
||||
initialize a rev_info structure, then add revisions to control what kind
|
||||
of revision list do you want to get, finally you can iterate over the
|
||||
revision list.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`repo_init_revisions`::
|
||||
|
||||
Initialize a rev_info structure with default values. The third
|
||||
parameter may be NULL or can be prefix path, and then the `.prefix`
|
||||
variable will be set to it. This is typically the first function you
|
||||
want to call when you want to deal with a revision list. After calling
|
||||
this function, you are free to customize options, like set
|
||||
`.ignore_merges` to 0 if you don't want to ignore merges, and so on. See
|
||||
`revision.h` for a complete list of available options.
|
||||
|
||||
`add_pending_object`::
|
||||
|
||||
This function can be used if you want to add commit objects as revision
|
||||
information. You can use the `UNINTERESTING` object flag to indicate if
|
||||
you want to include or exclude the given commit (and commits reachable
|
||||
from the given commit) from the revision list.
|
||||
+
|
||||
NOTE: If you have the commits as a string list then you probably want to
|
||||
use setup_revisions(), instead of parsing each string and using this
|
||||
function.
|
||||
|
||||
`setup_revisions`::
|
||||
|
||||
Parse revision information, filling in the `rev_info` structure, and
|
||||
removing the used arguments from the argument list. Returns the number
|
||||
of arguments left that weren't recognized, which are also moved to the
|
||||
head of the argument list. The last parameter is used in case no
|
||||
parameter given by the first two arguments.
|
||||
|
||||
`prepare_revision_walk`::
|
||||
|
||||
Prepares the rev_info structure for a walk. You should check if it
|
||||
returns any error (non-zero return code) and if it does not, you can
|
||||
start using get_revision() to do the iteration.
|
||||
|
||||
`get_revision`::
|
||||
|
||||
Takes a pointer to a `rev_info` structure and iterates over it,
|
||||
returning a `struct commit *` each time you call it. The end of the
|
||||
revision list is indicated by returning a NULL pointer.
|
||||
|
||||
`reset_revision_walk`::
|
||||
|
||||
Reset the flags used by the revision walking api. You can use
|
||||
this to do multiple sequential revision walks.
|
||||
|
||||
Data structures
|
||||
---------------
|
||||
|
||||
Talk about <revision.h>, things like:
|
||||
|
||||
* two diff_options, one for path limiting, another for output;
|
||||
* remaining functions;
|
||||
|
||||
(Linus, JC, Dscho)
|
@ -1,264 +0,0 @@
|
||||
run-command API
|
||||
===============
|
||||
|
||||
The run-command API offers a versatile tool to run sub-processes with
|
||||
redirected input and output as well as with a modified environment
|
||||
and an alternate current directory.
|
||||
|
||||
A similar API offers the capability to run a function asynchronously,
|
||||
which is primarily used to capture the output that the function
|
||||
produces in the caller in order to process it.
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`child_process_init`::
|
||||
|
||||
Initialize a struct child_process variable.
|
||||
|
||||
`start_command`::
|
||||
|
||||
Start a sub-process. Takes a pointer to a `struct child_process`
|
||||
that specifies the details and returns pipe FDs (if requested).
|
||||
See below for details.
|
||||
|
||||
`finish_command`::
|
||||
|
||||
Wait for the completion of a sub-process that was started with
|
||||
start_command().
|
||||
|
||||
`run_command`::
|
||||
|
||||
A convenience function that encapsulates a sequence of
|
||||
start_command() followed by finish_command(). Takes a pointer
|
||||
to a `struct child_process` that specifies the details.
|
||||
|
||||
`run_command_v_opt`, `run_command_v_opt_cd_env`::
|
||||
|
||||
Convenience functions that encapsulate a sequence of
|
||||
start_command() followed by finish_command(). The argument argv
|
||||
specifies the program and its arguments. The argument opt is zero
|
||||
or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`,
|
||||
`RUN_COMMAND_STDOUT_TO_STDERR`, or `RUN_SILENT_EXEC_FAILURE`
|
||||
that correspond to the members .no_stdin, .git_cmd,
|
||||
.stdout_to_stderr, .silent_exec_failure of `struct child_process`.
|
||||
The argument dir corresponds the member .dir. The argument env
|
||||
corresponds to the member .env.
|
||||
|
||||
`child_process_clear`::
|
||||
|
||||
Release the memory associated with the struct child_process.
|
||||
Most users of the run-command API don't need to call this
|
||||
function explicitly because `start_command` invokes it on
|
||||
failure and `finish_command` calls it automatically already.
|
||||
|
||||
The functions above do the following:
|
||||
|
||||
. If a system call failed, errno is set and -1 is returned. A diagnostic
|
||||
is printed.
|
||||
|
||||
. If the program was not found, then -1 is returned and errno is set to
|
||||
ENOENT; a diagnostic is printed only if .silent_exec_failure is 0.
|
||||
|
||||
. Otherwise, the program is run. If it terminates regularly, its exit
|
||||
code is returned. No diagnostic is printed, even if the exit code is
|
||||
non-zero.
|
||||
|
||||
. If the program terminated due to a signal, then the return value is the
|
||||
signal number + 128, ie. the same value that a POSIX shell's $? would
|
||||
report. A diagnostic is printed.
|
||||
|
||||
|
||||
`start_async`::
|
||||
|
||||
Run a function asynchronously. Takes a pointer to a `struct
|
||||
async` that specifies the details and returns a set of pipe FDs
|
||||
for communication with the function. See below for details.
|
||||
|
||||
`finish_async`::
|
||||
|
||||
Wait for the completion of an asynchronous function that was
|
||||
started with start_async().
|
||||
|
||||
`run_hook`::
|
||||
|
||||
Run a hook.
|
||||
The first argument is a pathname to an index file, or NULL
|
||||
if the hook uses the default index file or no index is needed.
|
||||
The second argument is the name of the hook.
|
||||
The further arguments correspond to the hook arguments.
|
||||
The last argument has to be NULL to terminate the arguments list.
|
||||
If the hook does not exist or is not executable, the return
|
||||
value will be zero.
|
||||
If it is executable, the hook will be executed and the exit
|
||||
status of the hook is returned.
|
||||
On execution, .stdout_to_stderr and .no_stdin will be set.
|
||||
(See below.)
|
||||
|
||||
|
||||
Data structures
|
||||
---------------
|
||||
|
||||
* `struct child_process`
|
||||
|
||||
This describes the arguments, redirections, and environment of a
|
||||
command to run in a sub-process.
|
||||
|
||||
The caller:
|
||||
|
||||
1. allocates and clears (using child_process_init() or
|
||||
CHILD_PROCESS_INIT) a struct child_process variable;
|
||||
2. initializes the members;
|
||||
3. calls start_command();
|
||||
4. processes the data;
|
||||
5. closes file descriptors (if necessary; see below);
|
||||
6. calls finish_command().
|
||||
|
||||
The .argv member is set up as an array of string pointers (NULL
|
||||
terminated), of which .argv[0] is the program name to run (usually
|
||||
without a path). If the command to run is a git command, set argv[0] to
|
||||
the command name without the 'git-' prefix and set .git_cmd = 1.
|
||||
|
||||
Note that the ownership of the memory pointed to by .argv stays with the
|
||||
caller, but it should survive until `finish_command` completes. If the
|
||||
.argv member is NULL, `start_command` will point it at the .args
|
||||
`argv_array` (so you may use one or the other, but you must use exactly
|
||||
one). The memory in .args will be cleaned up automatically during
|
||||
`finish_command` (or during `start_command` when it is unsuccessful).
|
||||
|
||||
The members .in, .out, .err are used to redirect stdin, stdout,
|
||||
stderr as follows:
|
||||
|
||||
. Specify 0 to request no special redirection. No new file descriptor
|
||||
is allocated. The child process simply inherits the channel from the
|
||||
parent.
|
||||
|
||||
. Specify -1 to have a pipe allocated; start_command() replaces -1
|
||||
by the pipe FD in the following way:
|
||||
|
||||
.in: Returns the writable pipe end into which the caller writes;
|
||||
the readable end of the pipe becomes the child's stdin.
|
||||
|
||||
.out, .err: Returns the readable pipe end from which the caller
|
||||
reads; the writable end of the pipe end becomes child's
|
||||
stdout/stderr.
|
||||
|
||||
The caller of start_command() must close the so returned FDs
|
||||
after it has completed reading from/writing to it!
|
||||
|
||||
. Specify a file descriptor > 0 to be used by the child:
|
||||
|
||||
.in: The FD must be readable; it becomes child's stdin.
|
||||
.out: The FD must be writable; it becomes child's stdout.
|
||||
.err: The FD must be writable; it becomes child's stderr.
|
||||
|
||||
The specified FD is closed by start_command(), even if it fails to
|
||||
run the sub-process!
|
||||
|
||||
. Special forms of redirection are available by setting these members
|
||||
to 1:
|
||||
|
||||
.no_stdin, .no_stdout, .no_stderr: The respective channel is
|
||||
redirected to /dev/null.
|
||||
|
||||
.stdout_to_stderr: stdout of the child is redirected to its
|
||||
stderr. This happens after stderr is itself redirected.
|
||||
So stdout will follow stderr to wherever it is
|
||||
redirected.
|
||||
|
||||
To modify the environment of the sub-process, specify an array of
|
||||
string pointers (NULL terminated) in .env:
|
||||
|
||||
. If the string is of the form "VAR=value", i.e. it contains '='
|
||||
the variable is added to the child process's environment.
|
||||
|
||||
. If the string does not contain '=', it names an environment
|
||||
variable that will be removed from the child process's environment.
|
||||
|
||||
If the .env member is NULL, `start_command` will point it at the
|
||||
.env_array `argv_array` (so you may use one or the other, but not both).
|
||||
The memory in .env_array will be cleaned up automatically during
|
||||
`finish_command` (or during `start_command` when it is unsuccessful).
|
||||
|
||||
To specify a new initial working directory for the sub-process,
|
||||
specify it in the .dir member.
|
||||
|
||||
If the program cannot be found, the functions return -1 and set
|
||||
errno to ENOENT. Normally, an error message is printed, but if
|
||||
.silent_exec_failure is set to 1, no message is printed for this
|
||||
special error condition.
|
||||
|
||||
|
||||
* `struct async`
|
||||
|
||||
This describes a function to run asynchronously, whose purpose is
|
||||
to produce output that the caller reads.
|
||||
|
||||
The caller:
|
||||
|
||||
1. allocates and clears (memset(&asy, 0, sizeof(asy));) a
|
||||
struct async variable;
|
||||
2. initializes .proc and .data;
|
||||
3. calls start_async();
|
||||
4. processes communicates with proc through .in and .out;
|
||||
5. closes .in and .out;
|
||||
6. calls finish_async().
|
||||
|
||||
The members .in, .out are used to provide a set of fd's for
|
||||
communication between the caller and the callee as follows:
|
||||
|
||||
. Specify 0 to have no file descriptor passed. The callee will
|
||||
receive -1 in the corresponding argument.
|
||||
|
||||
. Specify < 0 to have a pipe allocated; start_async() replaces
|
||||
with the pipe FD in the following way:
|
||||
|
||||
.in: Returns the writable pipe end into which the caller
|
||||
writes; the readable end of the pipe becomes the function's
|
||||
in argument.
|
||||
|
||||
.out: Returns the readable pipe end from which the caller
|
||||
reads; the writable end of the pipe becomes the function's
|
||||
out argument.
|
||||
|
||||
The caller of start_async() must close the returned FDs after it
|
||||
has completed reading from/writing from them.
|
||||
|
||||
. Specify a file descriptor > 0 to be used by the function:
|
||||
|
||||
.in: The FD must be readable; it becomes the function's in.
|
||||
.out: The FD must be writable; it becomes the function's out.
|
||||
|
||||
The specified FD is closed by start_async(), even if it fails to
|
||||
run the function.
|
||||
|
||||
The function pointer in .proc has the following signature:
|
||||
|
||||
int proc(int in, int out, void *data);
|
||||
|
||||
. in, out specifies a set of file descriptors to which the function
|
||||
must read/write the data that it needs/produces. The function
|
||||
*must* close these descriptors before it returns. A descriptor
|
||||
may be -1 if the caller did not configure a descriptor for that
|
||||
direction.
|
||||
|
||||
. data is the value that the caller has specified in the .data member
|
||||
of struct async.
|
||||
|
||||
. The return value of the function is 0 on success and non-zero
|
||||
on failure. If the function indicates failure, finish_async() will
|
||||
report failure as well.
|
||||
|
||||
|
||||
There are serious restrictions on what the asynchronous function can do
|
||||
because this facility is implemented by a thread in the same address
|
||||
space on most platforms (when pthreads is available), but by a pipe to
|
||||
a forked process otherwise:
|
||||
|
||||
. It cannot change the program's state (global variables, environment,
|
||||
etc.) in a way that the caller notices; in other words, .in and .out
|
||||
are the only communication channels to the caller.
|
||||
|
||||
. It must not change the program's state that the caller of the
|
||||
facility also uses.
|
@ -1,47 +0,0 @@
|
||||
setup API
|
||||
=========
|
||||
|
||||
Talk about
|
||||
|
||||
* setup_git_directory()
|
||||
* setup_git_directory_gently()
|
||||
* is_inside_git_dir()
|
||||
* is_inside_work_tree()
|
||||
* setup_work_tree()
|
||||
|
||||
(Dscho)
|
||||
|
||||
Pathspec
|
||||
--------
|
||||
|
||||
See glossary-context.txt for the syntax of pathspec. In memory, a
|
||||
pathspec set is represented by "struct pathspec" and is prepared by
|
||||
parse_pathspec(). This function takes several arguments:
|
||||
|
||||
- magic_mask specifies what features that are NOT supported by the
|
||||
following code. If a user attempts to use such a feature,
|
||||
parse_pathspec() can reject it early.
|
||||
|
||||
- flags specifies other things that the caller wants parse_pathspec to
|
||||
perform.
|
||||
|
||||
- prefix and args come from cmd_* functions
|
||||
|
||||
parse_pathspec() helps catch unsupported features and reject them
|
||||
politely. At a lower level, different pathspec-related functions may
|
||||
not support the same set of features. Such pathspec-sensitive
|
||||
functions are guarded with GUARD_PATHSPEC(), which will die in an
|
||||
unfriendly way when an unsupported feature is requested.
|
||||
|
||||
The command designers are supposed to make sure that GUARD_PATHSPEC()
|
||||
never dies. They have to make sure all unsupported features are caught
|
||||
by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC()
|
||||
should give the designers all pathspec-sensitive codepaths and what
|
||||
features they support.
|
||||
|
||||
A similar process is applied when a new pathspec magic is added. The
|
||||
designer lifts the GUARD_PATHSPEC restriction in the functions that
|
||||
support the new magic. At the same time (s)he has to make sure this
|
||||
new feature will be caught at parse_pathspec() in commands that cannot
|
||||
handle the new magic in some cases. grepping parse_pathspec() should
|
||||
help.
|
@ -1,41 +0,0 @@
|
||||
sigchain API
|
||||
============
|
||||
|
||||
Code often wants to set a signal handler to clean up temporary files or
|
||||
other work-in-progress when we die unexpectedly. For multiple pieces of
|
||||
code to do this without conflicting, each piece of code must remember
|
||||
the old value of the handler and restore it either when:
|
||||
|
||||
1. The work-in-progress is finished, and the handler is no longer
|
||||
necessary. The handler should revert to the original behavior
|
||||
(either another handler, SIG_DFL, or SIG_IGN).
|
||||
|
||||
2. The signal is received. We should then do our cleanup, then chain
|
||||
to the next handler (or die if it is SIG_DFL).
|
||||
|
||||
Sigchain is a tiny library for keeping a stack of handlers. Your handler
|
||||
and installation code should look something like:
|
||||
|
||||
------------------------------------------
|
||||
void clean_foo_on_signal(int sig)
|
||||
{
|
||||
clean_foo();
|
||||
sigchain_pop(sig);
|
||||
raise(sig);
|
||||
}
|
||||
|
||||
void other_func()
|
||||
{
|
||||
sigchain_push_common(clean_foo_on_signal);
|
||||
mess_up_foo();
|
||||
clean_foo();
|
||||
}
|
||||
------------------------------------------
|
||||
|
||||
Handlers are given the typedef of sigchain_fun. This is the same type
|
||||
that is given to signal() or sigaction(). It is perfectly reasonable to
|
||||
push SIG_DFL or SIG_IGN onto the stack.
|
||||
|
||||
You can sigchain_push and sigchain_pop individual signals. For
|
||||
convenience, sigchain_push_common will push the handler onto the stack
|
||||
for many common signals.
|
@ -1,66 +0,0 @@
|
||||
submodule config cache API
|
||||
==========================
|
||||
|
||||
The submodule config cache API allows to read submodule
|
||||
configurations/information from specified revisions. Internally
|
||||
information is lazily read into a cache that is used to avoid
|
||||
unnecessary parsing of the same .gitmodules files. Lookups can be done by
|
||||
submodule path or name.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To initialize the cache with configurations from the worktree the caller
|
||||
typically first calls `gitmodules_config()` to read values from the
|
||||
worktree .gitmodules and then to overlay the local git config values
|
||||
`parse_submodule_config_option()` from the config parsing
|
||||
infrastructure.
|
||||
|
||||
The caller can look up information about submodules by using the
|
||||
`submodule_from_path()` or `submodule_from_name()` functions. They return
|
||||
a `struct submodule` which contains the values. The API automatically
|
||||
initializes and allocates the needed infrastructure on-demand. If the
|
||||
caller does only want to lookup values from revisions the initialization
|
||||
can be skipped.
|
||||
|
||||
If the internal cache might grow too big or when the caller is done with
|
||||
the API, all internally cached values can be freed with submodule_free().
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct submodule`::
|
||||
|
||||
This structure is used to return the information about one
|
||||
submodule for a certain revision. It is returned by the lookup
|
||||
functions.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`void submodule_free(struct repository *r)`::
|
||||
|
||||
Use these to free the internally cached values.
|
||||
|
||||
`int parse_submodule_config_option(const char *var, const char *value)`::
|
||||
|
||||
Can be passed to the config parsing infrastructure to parse
|
||||
local (worktree) submodule configurations.
|
||||
|
||||
`const struct submodule *submodule_from_path(const unsigned char *treeish_name, const char *path)`::
|
||||
|
||||
Given a tree-ish in the superproject and a path, return the
|
||||
submodule that is bound at the path in the named tree.
|
||||
|
||||
`const struct submodule *submodule_from_name(const unsigned char *treeish_name, const char *name)`::
|
||||
|
||||
The same as above but lookup by name.
|
||||
|
||||
Whenever a submodule configuration is parsed in `parse_submodule_config_option`
|
||||
via e.g. `gitmodules_config()`, it will overwrite the null_sha1 entry.
|
||||
So in the normal case, when HEAD:.gitmodules is parsed first and then overlaid
|
||||
with the repository configuration, the null_sha1 entry contains the local
|
||||
configuration of a submodule (e.g. consolidated values from local git
|
||||
configuration and the .gitmodules file in the worktree).
|
||||
|
||||
For an example usage see test-submodule-config.c.
|
@ -1,140 +0,0 @@
|
||||
trace API
|
||||
=========
|
||||
|
||||
The trace API can be used to print debug messages to stderr or a file. Trace
|
||||
code is inactive unless explicitly enabled by setting `GIT_TRACE*` environment
|
||||
variables.
|
||||
|
||||
The trace implementation automatically adds `timestamp file:line ... \n` to
|
||||
all trace messages. E.g.:
|
||||
|
||||
------------
|
||||
23:59:59.123456 git.c:312 trace: built-in: git 'foo'
|
||||
00:00:00.000001 builtin/foo.c:99 foo: some message
|
||||
------------
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct trace_key`::
|
||||
|
||||
Defines a trace key (or category). The default (for API functions that
|
||||
don't take a key) is `GIT_TRACE`.
|
||||
+
|
||||
E.g. to define a trace key controlled by environment variable `GIT_TRACE_FOO`:
|
||||
+
|
||||
------------
|
||||
static struct trace_key trace_foo = TRACE_KEY_INIT(FOO);
|
||||
|
||||
static void trace_print_foo(const char *message)
|
||||
{
|
||||
trace_printf_key(&trace_foo, "%s", message);
|
||||
}
|
||||
------------
|
||||
+
|
||||
Note: don't use `const` as the trace implementation stores internal state in
|
||||
the `trace_key` structure.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`int trace_want(struct trace_key *key)`::
|
||||
|
||||
Checks whether the trace key is enabled. Used to prevent expensive
|
||||
string formatting before calling one of the printing APIs.
|
||||
|
||||
`void trace_disable(struct trace_key *key)`::
|
||||
|
||||
Disables tracing for the specified key, even if the environment
|
||||
variable was set.
|
||||
|
||||
`void trace_printf(const char *format, ...)`::
|
||||
`void trace_printf_key(struct trace_key *key, const char *format, ...)`::
|
||||
|
||||
Prints a formatted message, similar to printf.
|
||||
|
||||
`void trace_argv_printf(const char **argv, const char *format, ...)``::
|
||||
|
||||
Prints a formatted message, followed by a quoted list of arguments.
|
||||
|
||||
`void trace_strbuf(struct trace_key *key, const struct strbuf *data)`::
|
||||
|
||||
Prints the strbuf, without additional formatting (i.e. doesn't
|
||||
choke on `%` or even `\0`).
|
||||
|
||||
`uint64_t getnanotime(void)`::
|
||||
|
||||
Returns nanoseconds since the epoch (01/01/1970), typically used
|
||||
for performance measurements.
|
||||
+
|
||||
Currently there are high precision timer implementations for Linux (using
|
||||
`clock_gettime(CLOCK_MONOTONIC)`) and Windows (`QueryPerformanceCounter`).
|
||||
Other platforms use `gettimeofday` as time source.
|
||||
|
||||
`void trace_performance(uint64_t nanos, const char *format, ...)`::
|
||||
`void trace_performance_since(uint64_t start, const char *format, ...)`::
|
||||
|
||||
Prints the elapsed time (in nanoseconds), or elapsed time since
|
||||
`start`, followed by a formatted message. Enabled via environment
|
||||
variable `GIT_TRACE_PERFORMANCE`. Used for manual profiling, e.g.:
|
||||
+
|
||||
------------
|
||||
uint64_t start = getnanotime();
|
||||
/* code section to measure */
|
||||
trace_performance_since(start, "foobar");
|
||||
------------
|
||||
+
|
||||
------------
|
||||
uint64_t t = 0;
|
||||
for (;;) {
|
||||
/* ignore */
|
||||
t -= getnanotime();
|
||||
/* code section to measure */
|
||||
t += getnanotime();
|
||||
/* ignore */
|
||||
}
|
||||
trace_performance(t, "frotz");
|
||||
------------
|
||||
|
||||
Bugs & Caveats
|
||||
--------------
|
||||
|
||||
GIT_TRACE_* environment variables can be used to tell Git to show
|
||||
trace output to its standard error stream. Git can often spawn a pager
|
||||
internally to run its subcommand and send its standard output and
|
||||
standard error to it.
|
||||
|
||||
Because GIT_TRACE_PERFORMANCE trace is generated only at the very end
|
||||
of the program with atexit(), which happens after the pager exits, it
|
||||
would not work well if you send its log to the standard error output
|
||||
and let Git spawn the pager at the same time.
|
||||
|
||||
As a work around, you can for example use '--no-pager', or set
|
||||
GIT_TRACE_PERFORMANCE to another file descriptor which is redirected
|
||||
to stderr, or set GIT_TRACE_PERFORMANCE to a file specified by its
|
||||
absolute path.
|
||||
|
||||
For example instead of the following command which by default may not
|
||||
print any performance information:
|
||||
|
||||
------------
|
||||
GIT_TRACE_PERFORMANCE=2 git log -1
|
||||
------------
|
||||
|
||||
you may want to use:
|
||||
|
||||
------------
|
||||
GIT_TRACE_PERFORMANCE=2 git --no-pager log -1
|
||||
------------
|
||||
|
||||
or:
|
||||
|
||||
------------
|
||||
GIT_TRACE_PERFORMANCE=3 3>&2 git log -1
|
||||
------------
|
||||
|
||||
or:
|
||||
|
||||
------------
|
||||
GIT_TRACE_PERFORMANCE=/path/to/log/file git log -1
|
||||
------------
|
@ -188,261 +188,36 @@ purposes.
|
||||
=== Basic Command Messages
|
||||
|
||||
These are concerned with the lifetime of the overall git process.
|
||||
|
||||
`void trace2_initialize_clock()`::
|
||||
|
||||
Initialize the Trace2 start clock and nothing else. This should
|
||||
be called at the very top of main() to capture the process start
|
||||
time and reduce startup order dependencies.
|
||||
|
||||
`void trace2_initialize()`::
|
||||
|
||||
Determines if any Trace2 Targets should be enabled and
|
||||
initializes the Trace2 facility. This includes setting up the
|
||||
Trace2 thread local storage (TLS).
|
||||
+
|
||||
This function emits a "version" message containing the version of git
|
||||
and the Trace2 protocol.
|
||||
+
|
||||
This function should be called from `main()` as early as possible in
|
||||
the life of the process after essential process initialization.
|
||||
|
||||
`int trace2_is_enabled()`::
|
||||
|
||||
Returns 1 if Trace2 is enabled (at least one target is
|
||||
active).
|
||||
|
||||
`void trace2_cmd_start(int argc, const char **argv)`::
|
||||
|
||||
Emits a "start" message containing the process command line
|
||||
arguments.
|
||||
|
||||
`int trace2_cmd_exit(int exit_code)`::
|
||||
|
||||
Emits an "exit" message containing the process exit-code and
|
||||
elapsed time.
|
||||
+
|
||||
Returns the exit-code.
|
||||
|
||||
`void trace2_cmd_error(const char *fmt, va_list ap)`::
|
||||
|
||||
Emits an "error" message containing a formatted error message.
|
||||
|
||||
`void trace2_cmd_path(const char *pathname)`::
|
||||
|
||||
Emits a "cmd_path" message with the full pathname of the
|
||||
current process.
|
||||
e.g: `void trace2_initialize_clock()`, `void trace2_initialize()`,
|
||||
`int trace2_is_enabled()`, `void trace2_cmd_start(int argc, const char **argv)`.
|
||||
|
||||
=== Command Detail Messages
|
||||
|
||||
These are concerned with describing the specific Git command
|
||||
after the command line, config, and environment are inspected.
|
||||
|
||||
`void trace2_cmd_name(const char *name)`::
|
||||
|
||||
Emits a "cmd_name" message with the canonical name of the
|
||||
command, for example "status" or "checkout".
|
||||
|
||||
`void trace2_cmd_mode(const char *mode)`::
|
||||
|
||||
Emits a "cmd_mode" message with a qualifier name to further
|
||||
describe the current git command.
|
||||
+
|
||||
This message is intended to be used with git commands having multiple
|
||||
major modes. For example, a "checkout" command can checkout a new
|
||||
branch or it can checkout a single file, so the checkout code could
|
||||
emit a cmd_mode message of "branch" or "file".
|
||||
|
||||
`void trace2_cmd_alias(const char *alias, const char **argv_expansion)`::
|
||||
|
||||
Emits an "alias" message containing the alias used and the
|
||||
argument expansion.
|
||||
|
||||
`void trace2_def_param(const char *parameter, const char *value)`::
|
||||
|
||||
Emits a "def_param" message containing a key/value pair.
|
||||
+
|
||||
This message is intended to report some global aspect of the current
|
||||
command, such as a configuration setting or command line switch that
|
||||
significantly affects program performance or behavior, such as
|
||||
`core.abbrev`, `status.showUntrackedFiles`, or `--no-ahead-behind`.
|
||||
|
||||
`void trace2_cmd_list_config()`::
|
||||
|
||||
Emits a "def_param" messages for "important" configuration
|
||||
settings.
|
||||
+
|
||||
The environment variable `GIT_TRACE2_CONFIG_PARAMS` or the `trace2.configParams`
|
||||
config value can be set to a
|
||||
list of patterns of important configuration settings, for example:
|
||||
`core.*,remote.*.url`. This function will iterate over all config
|
||||
settings and emit a "def_param" message for each match.
|
||||
|
||||
`void trace2_cmd_set_config(const char *key, const char *value)`::
|
||||
|
||||
Emits a "def_param" message for a new or updated key/value
|
||||
pair IF `key` is considered important.
|
||||
+
|
||||
This is used to hook into `git_config_set()` and catch any
|
||||
configuration changes and update a value previously reported by
|
||||
`trace2_cmd_list_config()`.
|
||||
|
||||
`void trace2_def_repo(struct repository *repo)`::
|
||||
|
||||
Registers a repository with the Trace2 layer. Assigns a
|
||||
unique "repo-id" to `repo->trace2_repo_id`.
|
||||
+
|
||||
Emits a "worktree" messages containing the repo-id and the worktree
|
||||
pathname.
|
||||
+
|
||||
Region and data messages (described later) may refer to this repo-id.
|
||||
+
|
||||
The main/top-level repository will have repo-id value 1 (aka "r1").
|
||||
+
|
||||
The repo-id field is in anticipation of future in-proc submodule
|
||||
repositories.
|
||||
e.g: `void trace2_cmd_name(const char *name)`,
|
||||
`void trace2_cmd_mode(const char *mode)`.
|
||||
|
||||
=== Child Process Messages
|
||||
|
||||
These are concerned with the various spawned child processes,
|
||||
including shell scripts, git commands, editors, pagers, and hooks.
|
||||
|
||||
`void trace2_child_start(struct child_process *cmd)`::
|
||||
|
||||
Emits a "child_start" message containing the "child-id",
|
||||
"child-argv", and "child-classification".
|
||||
+
|
||||
Before calling this, set `cmd->trace2_child_class` to a name
|
||||
describing the type of child process, for example "editor".
|
||||
+
|
||||
This function assigns a unique "child-id" to `cmd->trace2_child_id`.
|
||||
This field is used later during the "child_exit" message to associate
|
||||
it with the "child_start" message.
|
||||
+
|
||||
This function should be called before spawning the child process.
|
||||
|
||||
`void trace2_child_exit(struct child_proess *cmd, int child_exit_code)`::
|
||||
|
||||
Emits a "child_exit" message containing the "child-id",
|
||||
the child's elapsed time and exit-code.
|
||||
+
|
||||
The reported elapsed time includes the process creation overhead and
|
||||
time spend waiting for it to exit, so it may be slightly longer than
|
||||
the time reported by the child itself.
|
||||
+
|
||||
This function should be called after reaping the child process.
|
||||
|
||||
`int trace2_exec(const char *exe, const char **argv)`::
|
||||
|
||||
Emits a "exec" message containing the "exec-id" and the
|
||||
argv of the new process.
|
||||
+
|
||||
This function should be called before calling one of the `exec()`
|
||||
variants, such as `execvp()`.
|
||||
+
|
||||
This function returns a unique "exec-id". This value is used later
|
||||
if the exec() fails and a "exec-result" message is necessary.
|
||||
|
||||
`void trace2_exec_result(int exec_id, int error_code)`::
|
||||
|
||||
Emits a "exec_result" message containing the "exec-id"
|
||||
and the error code.
|
||||
+
|
||||
On Unix-based systems, `exec()` does not return if successful.
|
||||
This message is used to indicate that the `exec()` failed and
|
||||
that the current program is continuing.
|
||||
e.g: `void trace2_child_start(struct child_process *cmd)`.
|
||||
|
||||
=== Git Thread Messages
|
||||
|
||||
These messages are concerned with Git thread usage.
|
||||
|
||||
`void trace2_thread_start(const char *thread_name)`::
|
||||
|
||||
Emits a "thread_start" message.
|
||||
+
|
||||
The `thread_name` field should be a descriptive name, such as the
|
||||
unique name of the thread-proc. A unique "thread-id" will be added
|
||||
to the name to uniquely identify thread instances.
|
||||
+
|
||||
Region and data messages (described later) may refer to this thread
|
||||
name.
|
||||
+
|
||||
This function must be called by the thread-proc of the new thread
|
||||
(so that TLS data is properly initialized) and not by the caller
|
||||
of `pthread_create()`.
|
||||
|
||||
`void trace2_thread_exit()`::
|
||||
|
||||
Emits a "thread_exit" message containing the thread name
|
||||
and the thread elapsed time.
|
||||
+
|
||||
This function must be called by the thread-proc before it returns
|
||||
(so that the correct TLS data is used and cleaned up). It should
|
||||
not be called by the caller of `pthread_join()`.
|
||||
e.g: `void trace2_thread_start(const char *thread_name)`.
|
||||
|
||||
=== Region and Data Messages
|
||||
|
||||
These are concerned with recording performance data
|
||||
over regions or spans of code.
|
||||
over regions or spans of code. e.g:
|
||||
`void trace2_region_enter(const char *category, const char *label, const struct repository *repo)`.
|
||||
|
||||
`void trace2_region_enter(const char *category, const char *label, const struct repository *repo)`::
|
||||
|
||||
`void trace2_region_enter_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`::
|
||||
|
||||
`void trace2_region_enter_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`::
|
||||
|
||||
Emits a thread-relative "region_enter" message with optional
|
||||
printf string.
|
||||
+
|
||||
This function pushes a new region nesting stack level on the current
|
||||
thread and starts a clock for the new stack frame.
|
||||
+
|
||||
The `category` field is an arbitrary category name used to classify
|
||||
regions by feature area, such as "status" or "index". At this time
|
||||
it is only just printed along with the rest of the message. It may
|
||||
be used in the future to filter messages.
|
||||
+
|
||||
The `label` field is an arbitrary label used to describe the activity
|
||||
being started, such as "read_recursive" or "do_read_index".
|
||||
+
|
||||
The `repo` field, if set, will be used to get the "repo-id", so that
|
||||
recursive operations can be attributed to the correct repository.
|
||||
|
||||
`void trace2_region_leave(const char *category, const char *label, const struct repository *repo)`::
|
||||
|
||||
`void trace2_region_leave_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`::
|
||||
|
||||
`void trace2_region_leave_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`::
|
||||
|
||||
Emits a thread-relative "region_leave" message with optional
|
||||
printf string.
|
||||
+
|
||||
This function pops the region nesting stack on the current thread
|
||||
and reports the elapsed time of the stack frame.
|
||||
+
|
||||
The `category`, `label`, and `repo` fields are the same as above.
|
||||
The `category` and `label` do not need to match the corresponding
|
||||
"region_enter" message, but it makes the data stream easier to
|
||||
understand.
|
||||
|
||||
`void trace2_data_string(const char *category, const struct repository *repo, const char *key, const char * value)`::
|
||||
|
||||
`void trace2_data_intmax(const char *category, const struct repository *repo, const char *key, intmax value)`::
|
||||
|
||||
`void trace2_data_json(const char *category, const struct repository *repo, const char *key, const struct json_writer *jw)`::
|
||||
|
||||
Emits a region- and thread-relative "data" or "data_json" message.
|
||||
+
|
||||
This is a key/value pair message containing information about the
|
||||
current thread, region stack, and repository. This could be used
|
||||
to print the number of files in a directory during a multi-threaded
|
||||
recursive tree walk.
|
||||
|
||||
`void trace2_printf(const char *fmt, ...)`::
|
||||
|
||||
`void trace2_printf_va(const char *fmt, va_list ap)`::
|
||||
|
||||
Emits a region- and thread-relative "printf" message.
|
||||
Refer to trace2.h for details about all trace2 functions.
|
||||
|
||||
== Trace2 Target Formats
|
||||
|
||||
|
@ -1,149 +0,0 @@
|
||||
tree walking API
|
||||
================
|
||||
|
||||
The tree walking API is used to traverse and inspect trees.
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct name_entry`::
|
||||
|
||||
An entry in a tree. Each entry has a sha1 identifier, pathname, and
|
||||
mode.
|
||||
|
||||
`struct tree_desc`::
|
||||
|
||||
A semi-opaque data structure used to maintain the current state of the
|
||||
walk.
|
||||
+
|
||||
* `buffer` is a pointer into the memory representation of the tree. It always
|
||||
points at the current entry being visited.
|
||||
|
||||
* `size` counts the number of bytes left in the `buffer`.
|
||||
|
||||
* `entry` points to the current entry being visited.
|
||||
|
||||
`struct traverse_info`::
|
||||
|
||||
A structure used to maintain the state of a traversal.
|
||||
+
|
||||
* `prev` points to the traverse_info which was used to descend into the
|
||||
current tree. If this is the top-level tree `prev` will point to
|
||||
a dummy traverse_info.
|
||||
|
||||
* `name` is the entry for the current tree (if the tree is a subtree).
|
||||
|
||||
* `pathlen` is the length of the full path for the current tree.
|
||||
|
||||
* `conflicts` can be used by callbacks to maintain directory-file conflicts.
|
||||
|
||||
* `fn` is a callback called for each entry in the tree. See Traversing for more
|
||||
information.
|
||||
|
||||
* `data` can be anything the `fn` callback would want to use.
|
||||
|
||||
* `show_all_errors` tells whether to stop at the first error or not.
|
||||
|
||||
Initializing
|
||||
------------
|
||||
|
||||
`init_tree_desc`::
|
||||
|
||||
Initialize a `tree_desc` and decode its first entry. The buffer and
|
||||
size parameters are assumed to be the same as the buffer and size
|
||||
members of `struct tree`.
|
||||
|
||||
`fill_tree_descriptor`::
|
||||
|
||||
Initialize a `tree_desc` and decode its first entry given the
|
||||
object ID of a tree. Returns the `buffer` member if the latter
|
||||
is a valid tree identifier and NULL otherwise.
|
||||
|
||||
`setup_traverse_info`::
|
||||
|
||||
Initialize a `traverse_info` given the pathname of the tree to start
|
||||
traversing from.
|
||||
|
||||
Walking
|
||||
-------
|
||||
|
||||
`tree_entry`::
|
||||
|
||||
Visit the next entry in a tree. Returns 1 when there are more entries
|
||||
left to visit and 0 when all entries have been visited. This is
|
||||
commonly used in the test of a while loop.
|
||||
|
||||
`tree_entry_len`::
|
||||
|
||||
Calculate the length of a tree entry's pathname. This utilizes the
|
||||
memory structure of a tree entry to avoid the overhead of using a
|
||||
generic strlen().
|
||||
|
||||
`update_tree_entry`::
|
||||
|
||||
Walk to the next entry in a tree. This is commonly used in conjunction
|
||||
with `tree_entry_extract` to inspect the current entry.
|
||||
|
||||
`tree_entry_extract`::
|
||||
|
||||
Decode the entry currently being visited (the one pointed to by
|
||||
`tree_desc's` `entry` member) and return the sha1 of the entry. The
|
||||
`pathp` and `modep` arguments are set to the entry's pathname and mode
|
||||
respectively.
|
||||
|
||||
`get_tree_entry`::
|
||||
|
||||
Find an entry in a tree given a pathname and the sha1 of a tree to
|
||||
search. Returns 0 if the entry is found and -1 otherwise. The third
|
||||
and fourth parameters are set to the entry's sha1 and mode
|
||||
respectively.
|
||||
|
||||
Traversing
|
||||
----------
|
||||
|
||||
`traverse_trees`::
|
||||
|
||||
Traverse `n` number of trees in parallel. The `fn` callback member of
|
||||
`traverse_info` is called once for each tree entry.
|
||||
|
||||
`traverse_callback_t`::
|
||||
The arguments passed to the traverse callback are as follows:
|
||||
+
|
||||
* `n` counts the number of trees being traversed.
|
||||
|
||||
* `mask` has its nth bit set if something exists in the nth entry.
|
||||
|
||||
* `dirmask` has its nth bit set if the nth tree's entry is a directory.
|
||||
|
||||
* `entry` is an array of size `n` where the nth entry is from the nth tree.
|
||||
|
||||
* `info` maintains the state of the traversal.
|
||||
|
||||
+
|
||||
Returning a negative value will terminate the traversal. Otherwise the
|
||||
return value is treated as an update mask. If the nth bit is set the nth tree
|
||||
will be updated and if the bit is not set the nth tree entry will be the
|
||||
same in the next callback invocation.
|
||||
|
||||
`make_traverse_path`::
|
||||
|
||||
Generate the full pathname of a tree entry based from the root of the
|
||||
traversal. For example, if the traversal has recursed into another
|
||||
tree named "bar" the pathname of an entry "baz" in the "bar"
|
||||
tree would be "bar/baz".
|
||||
|
||||
`traverse_path_len`::
|
||||
|
||||
Calculate the length of a pathname returned by `make_traverse_path`.
|
||||
This utilizes the memory structure of a tree entry to avoid the
|
||||
overhead of using a generic strlen().
|
||||
|
||||
`strbuf_make_traverse_path`::
|
||||
|
||||
Convenience wrapper to `make_traverse_path` into a strbuf.
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
Written by Junio C Hamano <gitster@pobox.com> and Linus Torvalds
|
||||
<torvalds@linux-foundation.org>
|
Reference in New Issue
Block a user