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.hmaint
						commit
						26c816a67d
					
				|  | @ -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> | ||||
							
								
								
									
										62
									
								
								argv-array.h
								
								
								
								
							
							
						
						
									
										62
									
								
								argv-array.h
								
								
								
								
							|  | @ -1,8 +1,32 @@ | |||
| #ifndef ARGV_ARRAY_H | ||||
| #define ARGV_ARRAY_H | ||||
|  | ||||
| /** | ||||
|  * 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(). | ||||
|  * | ||||
|  * 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(). | ||||
|  */ | ||||
|  | ||||
| extern const char *empty_argv[]; | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| struct argv_array { | ||||
| 	const char **argv; | ||||
| 	int argc; | ||||
|  | @ -11,17 +35,55 @@ struct argv_array { | |||
|  | ||||
| #define ARGV_ARRAY_INIT { empty_argv, 0, 0 } | ||||
|  | ||||
| /** | ||||
|  * Initialize an array. This is no different than assigning from | ||||
|  * `ARGV_ARRAY_INIT`. | ||||
|  */ | ||||
| void argv_array_init(struct argv_array *); | ||||
|  | ||||
| /* Push a copy of a string onto the end of the array. */ | ||||
| const char *argv_array_push(struct argv_array *, const char *); | ||||
|  | ||||
| /** | ||||
|  * Format a string and push it onto the end of the array. This is a | ||||
|  * convenience wrapper combining `strbuf_addf` and `argv_array_push`. | ||||
|  */ | ||||
| __attribute__((format (printf,2,3))) | ||||
| const char *argv_array_pushf(struct argv_array *, const char *fmt, ...); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| LAST_ARG_MUST_BE_NULL | ||||
| void argv_array_pushl(struct argv_array *, ...); | ||||
|  | ||||
| /* Push a null-terminated array of strings onto the end of the array. */ | ||||
| void argv_array_pushv(struct argv_array *, const char **); | ||||
|  | ||||
| /** | ||||
|  * Remove the final element from the array. If there are no | ||||
|  * elements in the array, do nothing. | ||||
|  */ | ||||
| void argv_array_pop(struct argv_array *); | ||||
|  | ||||
| /* Splits by whitespace; does not handle quoted arguments! */ | ||||
| void argv_array_split(struct argv_array *, const char *); | ||||
|  | ||||
| /** | ||||
|  * Free all memory associated with the array and return it to the | ||||
|  * initial, empty state. | ||||
|  */ | ||||
| void argv_array_clear(struct argv_array *); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| const char **argv_array_detach(struct argv_array *); | ||||
|  | ||||
| #endif /* ARGV_ARRAY_H */ | ||||
|  |  | |||
							
								
								
									
										3
									
								
								attr.c
								
								
								
								
							
							
						
						
									
										3
									
								
								attr.c
								
								
								
								
							|  | @ -1,7 +1,6 @@ | |||
| /* | ||||
|  * Handle git attributes.  See gitattributes(5) for a description of | ||||
|  * the file syntax, and Documentation/technical/api-gitattributes.txt | ||||
|  * for a description of the API. | ||||
|  * the file syntax, and attr.h for a description of the API. | ||||
|  * | ||||
|  * One basic design decision here is that we are not going to support | ||||
|  * an insanely large number of attributes. | ||||
|  |  | |||
							
								
								
									
										141
									
								
								attr.h
								
								
								
								
							
							
						
						
									
										141
									
								
								attr.h
								
								
								
								
							|  | @ -1,9 +1,121 @@ | |||
| #ifndef ATTR_H | ||||
| #define ATTR_H | ||||
|  | ||||
| /** | ||||
|  * gitattributes mechanism gives a uniform way to associate various attributes | ||||
|  * to set of paths. | ||||
|  * | ||||
|  * | ||||
|  * 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()`. | ||||
|  */ | ||||
|  | ||||
| struct index_state; | ||||
|  | ||||
| /* An attribute is a pointer to this opaque structure */ | ||||
| /** | ||||
|  * 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 git_attr; | ||||
|  | ||||
| /* opaque structures used internally for attribute collection */ | ||||
|  | @ -21,21 +133,36 @@ const struct git_attr *git_attr(const char *); | |||
| extern const char git_attr__true[]; | ||||
| extern const char git_attr__false[]; | ||||
|  | ||||
| /* For public to check git_attr_check results */ | ||||
| /** | ||||
|  * 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. The three macros check these, if none of them returns true, `.value` | ||||
|  * member points at a string value of the attribute for the path. | ||||
|  */ | ||||
|  | ||||
| /* Returns true if the attribute is Set for the path. */ | ||||
| #define ATTR_TRUE(v) ((v) == git_attr__true) | ||||
|  | ||||
| /* Returns true if the attribute is Unset for the path. */ | ||||
| #define ATTR_FALSE(v) ((v) == git_attr__false) | ||||
|  | ||||
| /* Returns true if the attribute is Unspecified for the path. */ | ||||
| #define ATTR_UNSET(v) ((v) == NULL) | ||||
|  | ||||
| /* | ||||
|  * Send one or more git_attr_check to git_check_attrs(), and | ||||
|  * each 'value' member tells what its value is. | ||||
|  * Unset one is returned as NULL. | ||||
|  */ | ||||
| /* This structure represents one attribute and its value. */ | ||||
| struct attr_check_item { | ||||
| 	const struct git_attr *attr; | ||||
| 	const char *value; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| struct attr_check { | ||||
| 	int nr; | ||||
| 	int alloc; | ||||
|  |  | |||
							
								
								
									
										41
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										41
									
								
								cache.h
								
								
								
								
							|  | @ -632,10 +632,43 @@ int daemonize(void); | |||
|  | ||||
| #define alloc_nr(x) (((x)+16)*3/2) | ||||
|  | ||||
| /* | ||||
|  * Realloc the buffer pointed at by variable 'x' so that it can hold | ||||
|  * at least 'nr' entries; the number of entries currently allocated | ||||
|  * is 'alloc', using the standard growing factor alloc_nr() macro. | ||||
| /** | ||||
|  * 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`. | ||||
|  * | ||||
|  * Consider using ALLOC_GROW_BY instead of ALLOC_GROW as it has some | ||||
|  * added niceties. | ||||
|  |  | |||
							
								
								
									
										236
									
								
								credential.h
								
								
								
								
							
							
						
						
									
										236
									
								
								credential.h
								
								
								
								
							|  | @ -3,8 +3,208 @@ | |||
|  | ||||
| #include "string-list.h" | ||||
|  | ||||
| /** | ||||
|  * The credentials API provides an abstracted way of gathering username and | ||||
|  * password credentials from the user. | ||||
|  * | ||||
|  * 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). | ||||
|  * | ||||
|  * 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 Documentation/git-config.txt). | ||||
|  * 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 Documentation/git-credential.txt 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). | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  * | ||||
|  * This struct should always be initialized with `CREDENTIAL_INIT` or | ||||
|  * `credential_init`. | ||||
|  */ | ||||
| struct credential { | ||||
|  | ||||
| 	/** | ||||
| 	 * A `string_list` of helpers. Each string specifies an external | ||||
| 	 * helper which will be run, in order, to either acquire or store | ||||
| 	 * credentials. 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. | ||||
| 	 */ | ||||
| 	struct string_list helpers; | ||||
|  | ||||
| 	unsigned approved:1, | ||||
| 		 configured:1, | ||||
| 		 quit:1, | ||||
|  | @ -19,16 +219,52 @@ struct credential { | |||
|  | ||||
| #define CREDENTIAL_INIT { STRING_LIST_INIT_DUP } | ||||
|  | ||||
| /* Initialize a credential structure, setting all fields to empty. */ | ||||
| void credential_init(struct credential *); | ||||
|  | ||||
| /** | ||||
|  * Free any resources associated with the credential structure, returning | ||||
|  * it to a pristine initialized state. | ||||
|  */ | ||||
| void credential_clear(struct credential *); | ||||
|  | ||||
| /** | ||||
|  * 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(). | ||||
|  */ | ||||
| void credential_fill(struct credential *); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void credential_approve(struct credential *); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void credential_reject(struct credential *); | ||||
|  | ||||
| int credential_read(struct credential *, FILE *); | ||||
| void credential_write(const struct credential *, FILE *); | ||||
|  | ||||
| /* Parse a URL into broken-down credential fields. */ | ||||
| void credential_from_url(struct credential *, const char *url); | ||||
|  | ||||
| int credential_match(const struct credential *have, | ||||
| 		     const struct credential *want); | ||||
|  | ||||
|  |  | |||
							
								
								
									
										126
									
								
								diff.h
								
								
								
								
							
							
						
						
									
										126
									
								
								diff.h
								
								
								
								
							|  | @ -9,6 +9,49 @@ | |||
| #include "object.h" | ||||
| #include "oidset.h" | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| struct combine_diff_path; | ||||
| struct commit; | ||||
| struct diff_filespec; | ||||
|  | @ -65,21 +108,66 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data) | |||
|  | ||||
| #define DIFF_FLAGS_INIT { 0 } | ||||
| struct diff_flags { | ||||
|  | ||||
| 	/** | ||||
| 	 * Tells if tree traversal done by tree-diff should recursively descend | ||||
| 	 * into a tree object pair that are different in preimage and postimage set. | ||||
| 	 */ | ||||
| 	unsigned recursive; | ||||
| 	unsigned tree_in_recursive; | ||||
|  | ||||
| 	/* Affects the way how a file that is seemingly binary is treated. */ | ||||
| 	unsigned binary; | ||||
| 	unsigned text; | ||||
|  | ||||
| 	/** | ||||
| 	 * Tells the patch output format not to use abbreviated object names on the | ||||
| 	 * "index" lines. | ||||
| 	 */ | ||||
| 	unsigned full_index; | ||||
|  | ||||
| 	/* Affects if diff-files shows removed files. */ | ||||
| 	unsigned silent_on_remove; | ||||
|  | ||||
| 	/** | ||||
| 	 * Tells the diffcore library that the caller is feeding unchanged | ||||
| 	 * filepairs to allow copies from unmodified files be detected. | ||||
| 	 */ | ||||
| 	unsigned find_copies_harder; | ||||
|  | ||||
| 	unsigned follow_renames; | ||||
| 	unsigned rename_empty; | ||||
|  | ||||
| 	/* Internal; used for optimization to see if there is any change. */ | ||||
| 	unsigned has_changes; | ||||
|  | ||||
| 	unsigned quick; | ||||
|  | ||||
| 	/** | ||||
| 	 * Tells diff-files that the input is not tracked files but files in random | ||||
| 	 * locations on the filesystem. | ||||
| 	 */ | ||||
| 	unsigned no_index; | ||||
|  | ||||
| 	/** | ||||
| 	 * Tells output routine that it is Ok to call user specified patch output | ||||
| 	 * routine.  Plumbing disables this to ensure stable output. | ||||
| 	 */ | ||||
| 	unsigned allow_external; | ||||
|  | ||||
| 	/** | ||||
| 	 * For communication between the calling program and the options parser; | ||||
| 	 * tell the calling program to signal the presence of difference using | ||||
| 	 * program exit code. | ||||
| 	 */ | ||||
| 	unsigned exit_with_status; | ||||
|  | ||||
| 	/** | ||||
| 	 * Tells the library that the calling program is feeding the filepairs | ||||
| 	 * reversed; `one` is two, and `two` is one. | ||||
| 	 */ | ||||
| 	unsigned reverse_diff; | ||||
|  | ||||
| 	unsigned check_failed; | ||||
| 	unsigned relative_name; | ||||
| 	unsigned ignore_submodules; | ||||
|  | @ -131,36 +219,72 @@ enum diff_submodule_format { | |||
| 	DIFF_SUBMODULE_INLINE_DIFF | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * the set of options the calling program wants to affect the operation of | ||||
|  * diffcore library with. | ||||
|  */ | ||||
| struct diff_options { | ||||
| 	const char *orderfile; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 */ | ||||
| 	const char *pickaxe; | ||||
|  | ||||
| 	const char *single_follow; | ||||
| 	const char *a_prefix, *b_prefix; | ||||
| 	const char *line_prefix; | ||||
| 	size_t line_prefix_length; | ||||
|  | ||||
| 	/** | ||||
| 	 * collection of boolean options that affects the operation, but some do | ||||
| 	 * not have anything to do with the diffcore library. | ||||
| 	 */ | ||||
| 	struct diff_flags flags; | ||||
|  | ||||
| 	/* diff-filter bits */ | ||||
| 	unsigned int filter; | ||||
|  | ||||
| 	int use_color; | ||||
|  | ||||
| 	/* Number of context lines to generate in patch output. */ | ||||
| 	int context; | ||||
|  | ||||
| 	int interhunkcontext; | ||||
|  | ||||
| 	/* Affects the way detection logic for complete rewrites, renames and | ||||
| 	 * copies. | ||||
| 	 */ | ||||
| 	int break_opt; | ||||
| 	int detect_rename; | ||||
|  | ||||
| 	int irreversible_delete; | ||||
| 	int skip_stat_unmatch; | ||||
| 	int line_termination; | ||||
|  | ||||
| 	/* The output format used when `diff_flush()` is run. */ | ||||
| 	int output_format; | ||||
|  | ||||
| 	unsigned pickaxe_opts; | ||||
|  | ||||
| 	/* Affects the way detection logic for complete rewrites, renames and | ||||
| 	 * copies. | ||||
| 	 */ | ||||
| 	int rename_score; | ||||
| 	int rename_limit; | ||||
|  | ||||
| 	int needed_rename_limit; | ||||
| 	int degraded_cc_to_c; | ||||
| 	int show_rename_progress; | ||||
| 	int dirstat_permille; | ||||
| 	int setup; | ||||
|  | ||||
| 	/* Number of hexdigits to abbreviate raw format output to. */ | ||||
| 	int abbrev; | ||||
|  | ||||
| 	int ita_invisible_in_index; | ||||
| /* white-space error highlighting */ | ||||
| #define WSEH_NEW (1<<12) | ||||
|  | @ -192,6 +316,7 @@ struct diff_options { | |||
| 	/* to support internal diff recursion by --follow hack*/ | ||||
| 	int found_follow; | ||||
|  | ||||
| 	/* Callback which allows tweaking the options in diff_setup_done(). */ | ||||
| 	void (*set_default)(struct diff_options *); | ||||
|  | ||||
| 	FILE *file; | ||||
|  | @ -286,6 +411,7 @@ enum color_diff { | |||
| 	DIFF_FILE_OLD_BOLD = 21, | ||||
| 	DIFF_FILE_NEW_BOLD = 22, | ||||
| }; | ||||
|  | ||||
| const char *diff_get_color(int diff_use_color, enum color_diff ix); | ||||
| #define diff_get_color_opt(o, ix) \ | ||||
| 	diff_get_color((o)->use_color, ix) | ||||
|  |  | |||
							
								
								
									
										32
									
								
								diffcore.h
								
								
								
								
							
							
						
						
									
										32
									
								
								diffcore.h
								
								
								
								
							|  | @ -28,6 +28,12 @@ struct userdiff_driver; | |||
|  | ||||
| #define MINIMUM_BREAK_SIZE     400 /* do not break a file smaller than this */ | ||||
|  | ||||
| /** | ||||
|  * 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_filespec { | ||||
| 	struct object_id oid; | ||||
| 	char *path; | ||||
|  | @ -66,6 +72,17 @@ void diff_free_filespec_data(struct diff_filespec *); | |||
| void diff_free_filespec_blob(struct diff_filespec *); | ||||
| int diff_filespec_is_binary(struct repository *, struct diff_filespec *); | ||||
|  | ||||
| /** | ||||
|  * 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_filepair { | ||||
| 	struct diff_filespec *one; | ||||
| 	struct diff_filespec *two; | ||||
|  | @ -77,6 +94,7 @@ struct diff_filepair { | |||
| 	unsigned done_skip_stat_unmatch : 1; | ||||
| 	unsigned skip_stat_unmatch_result : 1; | ||||
| }; | ||||
|  | ||||
| #define DIFF_PAIR_UNMERGED(p) ((p)->is_unmerged) | ||||
|  | ||||
| #define DIFF_PAIR_RENAME(p) ((p)->renamed_pair) | ||||
|  | @ -94,11 +112,25 @@ void diff_free_filepair(struct diff_filepair *); | |||
|  | ||||
| int diff_unmodified_pair(struct diff_filepair *); | ||||
|  | ||||
| /** | ||||
|  * 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_queue_struct { | ||||
| 	struct diff_filepair **queue; | ||||
| 	int alloc; | ||||
| 	int nr; | ||||
| }; | ||||
|  | ||||
| #define DIFF_QUEUE_CLEAR(q) \ | ||||
| 	do { \ | ||||
| 		(q)->queue = NULL; \ | ||||
|  |  | |||
							
								
								
									
										2
									
								
								dir.c
								
								
								
								
							
							
						
						
									
										2
									
								
								dir.c
								
								
								
								
							|  | @ -2,8 +2,6 @@ | |||
|  * This handles recursive filename detection with exclude | ||||
|  * files, index knowledge etc.. | ||||
|  * | ||||
|  * See Documentation/technical/api-directory-listing.txt | ||||
|  * | ||||
|  * Copyright (C) Linus Torvalds, 2005-2006 | ||||
|  *		 Junio Hamano, 2005-2006 | ||||
|  */ | ||||
|  |  | |||
							
								
								
									
										119
									
								
								dir.h
								
								
								
								
							
							
						
						
									
										119
									
								
								dir.h
								
								
								
								
							|  | @ -1,11 +1,44 @@ | |||
| #ifndef DIR_H | ||||
| #define DIR_H | ||||
|  | ||||
| /* See Documentation/technical/api-directory-listing.txt */ | ||||
|  | ||||
| #include "cache.h" | ||||
| #include "strbuf.h" | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Calling sequence | ||||
|  * ---------------- | ||||
|  * | ||||
|  * Note: The index may be checked for .gitignore files that are | ||||
|  * CE_SKIP_WORKTREE marked. If you want to exclude files, make sure you have | ||||
|  * loaded the 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. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| struct dir_entry { | ||||
| 	unsigned int len; | ||||
| 	char name[FLEX_ARRAY]; /* more */ | ||||
|  | @ -144,25 +177,101 @@ struct untracked_cache { | |||
| 	unsigned int use_fsmonitor : 1; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| struct dir_struct { | ||||
| 	int nr, alloc; | ||||
| 	int ignored_nr, ignored_alloc; | ||||
|  | ||||
| 	/* The number of members in `entries[]` array. */ | ||||
| 	int nr; | ||||
|  | ||||
| 	/* Internal use; keeps track of allocation of `entries[]` array.*/ | ||||
| 	int alloc; | ||||
|  | ||||
| 	/* The number of members in `ignored[]` array. */ | ||||
| 	int ignored_nr; | ||||
|  | ||||
| 	int ignored_alloc; | ||||
|  | ||||
| 	/* bit-field of options */ | ||||
| 	enum { | ||||
|  | ||||
| 		/** | ||||
| 		 * Return just ignored files in `entries[]`, not untracked files. | ||||
| 		 * This flag is mutually exclusive with `DIR_SHOW_IGNORED_TOO`. | ||||
| 		 */ | ||||
| 		DIR_SHOW_IGNORED = 1<<0, | ||||
|  | ||||
| 		/* Include a directory that is not tracked. */ | ||||
| 		DIR_SHOW_OTHER_DIRECTORIES = 1<<1, | ||||
|  | ||||
| 		/* Do not include a directory that is not tracked and is empty. */ | ||||
| 		DIR_HIDE_EMPTY_DIRECTORIES = 1<<2, | ||||
|  | ||||
| 		/** | ||||
| 		 * If set, recurse into a directory that looks like a Git directory. | ||||
| 		 * Otherwise it is shown as a directory. | ||||
| 		 */ | ||||
| 		DIR_NO_GITLINKS = 1<<3, | ||||
|  | ||||
| 		/** | ||||
| 		 * 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_COLLECT_IGNORED = 1<<4, | ||||
|  | ||||
| 		/** | ||||
| 		 * 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_SHOW_IGNORED_TOO = 1<<5, | ||||
|  | ||||
| 		DIR_COLLECT_KILLED_ONLY = 1<<6, | ||||
|  | ||||
| 		/** | ||||
| 		 * 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_KEEP_UNTRACKED_CONTENTS = 1<<7, | ||||
|  | ||||
| 		/** | ||||
| 		 * 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_SHOW_IGNORED_TOO_MODE_MATCHING = 1<<8, | ||||
|  | ||||
| 		DIR_SKIP_NESTED_GIT = 1<<9 | ||||
| 	} flags; | ||||
|  | ||||
| 	/* An array of `struct dir_entry`, each element of which describes a path. */ | ||||
| 	struct dir_entry **entries; | ||||
|  | ||||
| 	/** | ||||
| 	 * used for ignored paths with the `DIR_SHOW_IGNORED_TOO` and | ||||
| 	 * `DIR_COLLECT_IGNORED` flags. | ||||
| 	 */ | ||||
| 	struct dir_entry **ignored; | ||||
|  | ||||
| 	/* Exclude info */ | ||||
| 	/** | ||||
| 	 * The name of the file to be read in each directory for excluded files | ||||
| 	 * (typically `.gitignore`). | ||||
| 	 */ | ||||
| 	const char *exclude_per_dir; | ||||
|  | ||||
| 	/* | ||||
|  |  | |||
							
								
								
									
										1
									
								
								graph.c
								
								
								
								
							
							
						
						
									
										1
									
								
								graph.c
								
								
								
								
							|  | @ -34,6 +34,7 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb); | |||
|  * handle directly. It is assumed that this is the same file handle as the | ||||
|  * file specified by the graph diff options. This is necessary so that | ||||
|  * graph_show_strbuf can be called even with a NULL graph. | ||||
|  * If a NULL graph is supplied, the strbuf is printed as-is. | ||||
|  */ | ||||
| static void graph_show_strbuf(struct git_graph *graph, | ||||
| 			      FILE *file, | ||||
|  |  | |||
							
								
								
									
										121
									
								
								graph.h
								
								
								
								
							
							
						
						
									
										121
									
								
								graph.h
								
								
								
								
							|  | @ -2,6 +2,103 @@ | |||
| #define GRAPH_H | ||||
| #include "diff.h" | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  * | ||||
|  * 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 | ||||
|  * ----------- | ||||
|  * - Check the graph_update() function for its limitations. | ||||
|  * | ||||
|  * - 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. | ||||
|  * ------------ | ||||
|  * * | ||||
|  * * | ||||
|  * * | ||||
|  * |\ | ||||
|  * * | | ||||
|  * | | * | ||||
|  * | \ \ | ||||
|  * |  \ \ | ||||
|  * *-. \ \ | ||||
|  * |\ \ \ \ | ||||
|  * | | * | | | ||||
|  * | | | | | * | ||||
|  * | | | | | * | ||||
|  * | | | | | * | ||||
|  * | | | | | |\ | ||||
|  * | | | | | | * | ||||
|  * | * | | | | | | ||||
|  * | | | | | *  \ | ||||
|  * | | | | | |\  | | ||||
|  * | | | | * | | | | ||||
|  * | | | | * | | | | ||||
|  * * | | | | | | | | ||||
|  * | |/ / / / / / | ||||
|  * |/| / / / / / | ||||
|  * * | | | | | | | ||||
|  * |/ / / / / / | ||||
|  * * | | | | | | ||||
|  * | | | | | * | ||||
|  * | | | | |/ | ||||
|  * | | | | * | ||||
|  * ------------ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* A graph is a pointer to this opaque structure */ | ||||
| struct git_graph; | ||||
|  | ||||
|  | @ -50,6 +147,21 @@ struct git_graph *graph_init(struct rev_info *opt); | |||
|  * If graph_update() is called before graph_is_commit_finished() returns 1, | ||||
|  * the next call to graph_next_line() will output an ellipsis ("...") | ||||
|  * to indicate that a portion of the graph is missing. | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
| void graph_update(struct git_graph *graph, struct commit *commit); | ||||
|  | ||||
|  | @ -62,6 +174,10 @@ void graph_update(struct git_graph *graph, struct commit *commit); | |||
|  * for this commit.  If 0 is returned, graph_next_line() may still be | ||||
|  * called without calling graph_update(), and it will merely output | ||||
|  * appropriate "vertical padding" in the graph. | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
| int graph_is_commit_finished(struct git_graph const *graph); | ||||
|  | ||||
|  | @ -112,6 +228,7 @@ void graph_show_padding(struct git_graph *graph); | |||
| /* | ||||
|  * If the graph is non-NULL, print the rest of the history graph for this | ||||
|  * commit to stdout.  Does not print a terminating newline on the last line. | ||||
|  * Returns 1 if output was printed, and 0 if no output was necessary. | ||||
|  */ | ||||
| int graph_show_remainder(struct git_graph *graph); | ||||
|  | ||||
|  | @ -121,6 +238,10 @@ int graph_show_remainder(struct git_graph *graph); | |||
|  * This is similar to graph_show_strbuf(), but it always prints the | ||||
|  * remainder of the graph. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * If the strbuf ends with a newline, the output printed by | ||||
|  * graph_show_commit_msg() will end with a newline.  If the strbuf is | ||||
|  * missing a terminating newline (including if it is empty), the output | ||||
|  |  | |||
							
								
								
									
										73
									
								
								ll-merge.h
								
								
								
								
							
							
						
						
									
										73
									
								
								ll-merge.h
								
								
								
								
							|  | @ -7,16 +7,87 @@ | |||
|  | ||||
| #include "xdiff/xdiff.h" | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| struct index_state; | ||||
|  | ||||
| /** | ||||
|  * This describes the set of options the calling program wants to affect | ||||
|  * the operation of a low-level (single file) merge. | ||||
|  */ | ||||
| struct ll_merge_options { | ||||
|  | ||||
| 	/** | ||||
| 	 * Behave as though this were part of a merge between common ancestors in | ||||
| 	 * a recursive merge (merges of binary files may need to be handled | ||||
| 	 * differently in such cases, for example). If a helper program is | ||||
| 	 * specified by the `[merge "<driver>"] recursive` configuration, it will | ||||
| 	 * be used. | ||||
| 	 */ | ||||
| 	unsigned virtual_ancestor : 1; | ||||
| 	unsigned variant : 2;	/* favor ours, favor theirs, or union merge */ | ||||
|  | ||||
| 	/** | ||||
| 	 * 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`. | ||||
| 	 */ | ||||
| 	unsigned variant : 2; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 */ | ||||
| 	unsigned renormalize : 1; | ||||
|  | ||||
| 	/** | ||||
| 	 * Increase the length of conflict markers so that nested conflicts | ||||
| 	 * can be differentiated. | ||||
| 	 */ | ||||
| 	unsigned extra_marker_size; | ||||
|  | ||||
| 	/* Extra xpparam_t flags as defined in xdiff/xdiff.h. */ | ||||
| 	long xdl_opts; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int ll_merge(mmbuffer_t *result_buf, | ||||
| 	     const char *path, | ||||
| 	     mmfile_t *ancestor, const char *ancestor_label, | ||||
|  |  | |||
|  | @ -1,6 +1,10 @@ | |||
| #ifndef PARSE_OPTIONS_H | ||||
| #define PARSE_OPTIONS_H | ||||
|  | ||||
| /** | ||||
|  * Refer to Documentation/technical/api-parse-options.txt for the API doc. | ||||
|  */ | ||||
|  | ||||
| enum parse_opt_type { | ||||
| 	/* special types */ | ||||
| 	OPTION_END, | ||||
|  |  | |||
							
								
								
									
										35
									
								
								pathspec.h
								
								
								
								
							
							
						
						
									
										35
									
								
								pathspec.h
								
								
								
								
							|  | @ -22,6 +22,11 @@ struct index_state; | |||
|  | ||||
| #define PATHSPEC_ONESTAR 1	/* the pathspec pattern satisfies GFNM_ONESTAR */ | ||||
|  | ||||
| /** | ||||
|  * 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(). | ||||
|  */ | ||||
| struct pathspec { | ||||
| 	int nr; | ||||
| 	unsigned int has_wildcard:1; | ||||
|  | @ -73,12 +78,39 @@ struct pathspec { | |||
|  */ | ||||
| #define PATHSPEC_LITERAL_PATH (1<<6) | ||||
|  | ||||
| /* | ||||
| /** | ||||
|  * Given command line arguments and a prefix, convert the input to | ||||
|  * pathspec. die() if any magic in magic_mask is used. | ||||
|  * | ||||
|  * Any arguments used are copied. It is safe for the caller to modify | ||||
|  * or free 'prefix' and 'args' after calling this function. | ||||
|  * | ||||
|  * - 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. | ||||
|  */ | ||||
| void parse_pathspec(struct pathspec *pathspec, | ||||
| 		    unsigned magic_mask, | ||||
|  | @ -95,6 +127,7 @@ void parse_pathspec_file(struct pathspec *pathspec, | |||
| 			 const char *prefix, | ||||
| 			 const char *file, | ||||
| 			 int nul_term_line); | ||||
|  | ||||
| void copy_pathspec(struct pathspec *dst, const struct pathspec *src); | ||||
| void clear_pathspec(struct pathspec *); | ||||
|  | ||||
|  |  | |||
							
								
								
									
										51
									
								
								refs.h
								
								
								
								
							
							
						
						
									
										51
									
								
								refs.h
								
								
								
								
							|  | @ -310,19 +310,35 @@ int refs_for_each_branch_ref(struct ref_store *refs, | |||
| int refs_for_each_remote_ref(struct ref_store *refs, | ||||
| 			     each_ref_fn fn, void *cb_data); | ||||
|  | ||||
| /* just iterates the head ref. */ | ||||
| int head_ref(each_ref_fn fn, void *cb_data); | ||||
|  | ||||
| /* iterates all refs. */ | ||||
| int for_each_ref(each_ref_fn fn, void *cb_data); | ||||
|  | ||||
| /** | ||||
|  * iterates all refs which have a defined prefix and strips that prefix from | ||||
|  * the passed variable refname. | ||||
|  */ | ||||
| int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data); | ||||
|  | ||||
| int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix, | ||||
| 			     each_ref_fn fn, void *cb_data, | ||||
| 			     unsigned int broken); | ||||
| int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, | ||||
| 			unsigned int broken); | ||||
|  | ||||
| /** | ||||
|  * iterate refs from the respective area. | ||||
|  */ | ||||
| int for_each_tag_ref(each_ref_fn fn, void *cb_data); | ||||
| int for_each_branch_ref(each_ref_fn fn, void *cb_data); | ||||
| int for_each_remote_ref(each_ref_fn fn, void *cb_data); | ||||
| int for_each_replace_ref(struct repository *r, each_repo_ref_fn fn, void *cb_data); | ||||
|  | ||||
| /* iterates all refs that match the specified glob pattern. */ | ||||
| int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data); | ||||
|  | ||||
| int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, | ||||
| 			 const char *prefix, void *cb_data); | ||||
|  | ||||
|  | @ -791,6 +807,41 @@ int reflog_expire(const char *refname, const struct object_id *oid, | |||
| int ref_storage_backend_exists(const char *name); | ||||
|  | ||||
| struct ref_store *get_main_ref_store(struct repository *r); | ||||
|  | ||||
| /** | ||||
|  * 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; | ||||
|  * } | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Return the ref_store instance for the specified submodule. For the | ||||
|  * main repository, use submodule==NULL; such a call cannot fail. For | ||||
|  |  | |||
							
								
								
									
										16
									
								
								refspec.h
								
								
								
								
							
							
						
						
									
										16
									
								
								refspec.h
								
								
								
								
							|  | @ -20,6 +20,22 @@ struct refspec_item { | |||
| #define REFSPEC_INIT_FETCH { .fetch = REFSPEC_FETCH } | ||||
| #define REFSPEC_INIT_PUSH { .fetch = REFSPEC_PUSH } | ||||
|  | ||||
| /** | ||||
|  * 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 refspec { | ||||
| 	struct refspec_item *items; | ||||
| 	int alloc; | ||||
|  |  | |||
							
								
								
									
										57
									
								
								remote.h
								
								
								
								
							
							
						
						
									
										57
									
								
								remote.h
								
								
								
								
							|  | @ -6,6 +6,14 @@ | |||
| #include "hashmap.h" | ||||
| #include "refspec.h" | ||||
|  | ||||
| /** | ||||
|  * The API 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. | ||||
|  */ | ||||
|  | ||||
| enum { | ||||
| 	REMOTE_UNCONFIGURED = 0, | ||||
| 	REMOTE_CONFIG, | ||||
|  | @ -16,16 +24,22 @@ enum { | |||
| struct remote { | ||||
| 	struct hashmap_entry ent; | ||||
|  | ||||
| 	/* The user's nickname for the remote */ | ||||
| 	const char *name; | ||||
|  | ||||
| 	int origin, configured_in_repo; | ||||
|  | ||||
| 	const char *foreign_vcs; | ||||
|  | ||||
| 	/* An array of all of the url_nr URLs configured for the remote */ | ||||
| 	const char **url; | ||||
|  | ||||
| 	int url_nr; | ||||
| 	int url_alloc; | ||||
|  | ||||
| 	/* An array of all of the pushurl_nr push URLs configured for the remote */ | ||||
| 	const char **pushurl; | ||||
|  | ||||
| 	int pushurl_nr; | ||||
| 	int pushurl_alloc; | ||||
|  | ||||
|  | @ -34,32 +48,47 @@ struct remote { | |||
| 	struct refspec fetch; | ||||
|  | ||||
| 	/* | ||||
| 	 * The setting for whether to fetch tags (as a separate rule from the | ||||
| 	 * configured refspecs); | ||||
| 	 * -1 to never fetch tags | ||||
| 	 * 0 to auto-follow tags on heuristic (default) | ||||
| 	 * 1 to always auto-follow tags | ||||
| 	 * 2 to always fetch tags | ||||
| 	 */ | ||||
| 	int fetch_tags; | ||||
|  | ||||
| 	int skip_default_update; | ||||
| 	int mirror; | ||||
| 	int prune; | ||||
| 	int prune_tags; | ||||
|  | ||||
| 	/** | ||||
| 	 * The configured helper programs to run on the remote side, for | ||||
| 	 * Git-native protocols. | ||||
| 	 */ | ||||
| 	const char *receivepack; | ||||
| 	const char *uploadpack; | ||||
|  | ||||
| 	/* | ||||
| 	 * for curl remotes only | ||||
| 	 */ | ||||
| 	/* The proxy to use for curl (http, https, ftp, etc.) URLs. */ | ||||
| 	char *http_proxy; | ||||
|  | ||||
| 	/* The method used for authenticating against `http_proxy`. */ | ||||
| 	char *http_proxy_authmethod; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct remotes can be found by name with remote_get(). | ||||
|  * remote_get(NULL) will return the default remote, given the current branch | ||||
|  * and configuration. | ||||
|  */ | ||||
| struct remote *remote_get(const char *name); | ||||
|  | ||||
| struct remote *pushremote_get(const char *name); | ||||
| int remote_is_configured(struct remote *remote, int in_repo); | ||||
|  | ||||
| typedef int each_remote_fn(struct remote *remote, void *priv); | ||||
|  | ||||
| /* iterate through struct remotes */ | ||||
| int for_each_remote(each_remote_fn fn, void *priv); | ||||
|  | ||||
| int remote_has_url(struct remote *remote, const char *url); | ||||
|  | @ -194,16 +223,36 @@ struct ref *get_remote_ref(const struct ref *remote_refs, const char *name); | |||
|  */ | ||||
| int remote_find_tracking(struct remote *remote, struct refspec_item *refspec); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| struct branch { | ||||
|  | ||||
| 	/* The short name of the branch. */ | ||||
| 	const char *name; | ||||
|  | ||||
| 	/* The full path for the branch ref. */ | ||||
| 	const char *refname; | ||||
|  | ||||
| 	/* The name of the remote listed in the configuration. */ | ||||
| 	const char *remote_name; | ||||
|  | ||||
| 	const char *pushremote_name; | ||||
|  | ||||
| 	/* An array of the "merge" lines in the configuration. */ | ||||
| 	const char **merge_name; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 */ | ||||
| 	struct refspec_item **merge; | ||||
|  | ||||
| 	/* The number of merge configurations */ | ||||
| 	int merge_nr; | ||||
|  | ||||
| 	int merge_alloc; | ||||
|  | ||||
| 	const char *push_tracking_ref; | ||||
|  | @ -215,7 +264,9 @@ const char *pushremote_for_branch(struct branch *branch, int *explicit); | |||
| const char *remote_ref_for_branch(struct branch *branch, int for_push, | ||||
| 				  int *explicit); | ||||
|  | ||||
| /* returns true if the given branch has merge configuration given. */ | ||||
| int branch_has_merge_config(struct branch *branch); | ||||
|  | ||||
| int branch_merge_matches(struct branch *, int n, const char *); | ||||
|  | ||||
| /** | ||||
|  |  | |||
							
								
								
									
										59
									
								
								revision.h
								
								
								
								
							
							
						
						
									
										59
									
								
								revision.h
								
								
								
								
							|  | @ -9,6 +9,19 @@ | |||
| #include "diff.h" | ||||
| #include "commit-slab-decl.h" | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* Remember to update object flag allocation in object.h */ | ||||
| #define SEEN		(1u<<0) | ||||
| #define UNINTERESTING   (1u<<1) | ||||
|  | @ -306,11 +319,29 @@ struct setup_revision_opt { | |||
| #ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS | ||||
| #define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix) | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void repo_init_revisions(struct repository *r, | ||||
| 			 struct rev_info *revs, | ||||
| 			 const char *prefix); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int setup_revisions(int argc, const char **argv, struct rev_info *revs, | ||||
| 		    struct setup_revision_opt *); | ||||
|  | ||||
| void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, | ||||
| 			const struct option *options, | ||||
| 			const char * const usagestr[]); | ||||
|  | @ -319,9 +350,26 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, | |||
| int handle_revision_arg(const char *arg, struct rev_info *revs, | ||||
| 			int flags, unsigned revarg_opt); | ||||
|  | ||||
| /** | ||||
|  * Reset the flags used by the revision walking api. You can use this to do | ||||
|  * multiple sequential revision walks. | ||||
|  */ | ||||
| void reset_revision_walk(void); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int prepare_revision_walk(struct rev_info *revs); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| struct commit *get_revision(struct rev_info *revs); | ||||
|  | ||||
| const char *get_revision_mark(const struct rev_info *revs, | ||||
| 			      const struct commit *commit); | ||||
| void put_revision_mark(const struct rev_info *revs, | ||||
|  | @ -333,8 +381,19 @@ void mark_trees_uninteresting_sparse(struct repository *r, struct oidset *trees) | |||
|  | ||||
| void show_object_with_name(FILE *, struct object *, const char *); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void add_pending_object(struct rev_info *revs, | ||||
| 			struct object *obj, const char *name); | ||||
|  | ||||
| void add_pending_oid(struct rev_info *revs, | ||||
| 		     const char *name, const struct object_id *oid, | ||||
| 		     unsigned int flags); | ||||
|  |  | |||
							
								
								
									
										252
									
								
								run-command.h
								
								
								
								
							
							
						
						
									
										252
									
								
								run-command.h
								
								
								
								
							|  | @ -5,8 +5,60 @@ | |||
|  | ||||
| #include "argv-array.h" | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * 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(). | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
| struct child_process { | ||||
|  | ||||
| 	/** | ||||
| 	 * 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). | ||||
| 	 * | ||||
| 	 */ | ||||
| 	const char **argv; | ||||
|  | ||||
| 	struct argv_array args; | ||||
| 	struct argv_array env_array; | ||||
| 	pid_t pid; | ||||
|  | @ -18,8 +70,8 @@ struct child_process { | |||
|  | ||||
| 	/* | ||||
| 	 * Using .in, .out, .err: | ||||
| 	 * - Specify 0 for no redirections (child inherits stdin, stdout, | ||||
| 	 *   stderr from parent). | ||||
| 	 * - Specify 0 for no redirections. No new file descriptor is allocated. | ||||
| 	 * (child inherits stdin, stdout, stderr from parent). | ||||
| 	 * - Specify -1 to have a pipe allocated as follows: | ||||
| 	 *     .in: returns the writable pipe end; parent writes to it, | ||||
| 	 *          the readable pipe end becomes child's stdin | ||||
|  | @ -37,13 +89,43 @@ struct child_process { | |||
| 	int in; | ||||
| 	int out; | ||||
| 	int err; | ||||
|  | ||||
| 	/** | ||||
| 	 * To specify a new initial working directory for the sub-process, | ||||
| 	 * specify it in the .dir member. | ||||
| 	 */ | ||||
| 	const char *dir; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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). | ||||
| 	 */ | ||||
| 	const char *const *env; | ||||
|  | ||||
| 	unsigned no_stdin:1; | ||||
| 	unsigned no_stdout:1; | ||||
| 	unsigned no_stderr:1; | ||||
| 	unsigned git_cmd:1; /* if this is to be git sub-command */ | ||||
|     unsigned git_cmd:1; /* if this is to be git sub-command */ | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 */ | ||||
| 	unsigned silent_exec_failure:1; | ||||
|  | ||||
| 	unsigned stdout_to_stderr:1; | ||||
| 	unsigned use_shell:1; | ||||
| 	unsigned clean_on_exit:1; | ||||
|  | @ -53,13 +135,63 @@ struct child_process { | |||
| }; | ||||
|  | ||||
| #define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT, ARGV_ARRAY_INIT } | ||||
|  | ||||
| /** | ||||
|  * The functions: child_process_init, start_command, finish_command, | ||||
|  * run_command, run_command_v_opt, run_command_v_opt_cd_env, child_process_clear | ||||
|  * 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. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Initialize a struct child_process variable. | ||||
|  */ | ||||
| void child_process_init(struct child_process *); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void child_process_clear(struct child_process *); | ||||
|  | ||||
| int is_executable(const char *name); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int start_command(struct child_process *); | ||||
|  | ||||
| /** | ||||
|  * Wait for the completion of a sub-process that was started with | ||||
|  * start_command(). | ||||
|  */ | ||||
| int finish_command(struct child_process *); | ||||
|  | ||||
| int finish_command_in_signal(struct child_process *); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int run_command(struct child_process *); | ||||
|  | ||||
| /* | ||||
|  | @ -68,6 +200,20 @@ int run_command(struct child_process *); | |||
|  * overwritten by further calls to find_hook and run_hook_*. | ||||
|  */ | ||||
| const char *find_hook(const char *name); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| LAST_ARG_MUST_BE_NULL | ||||
| int run_hook_le(const char *const *env, const char *name, ...); | ||||
| int run_hook_ve(const char *const *env, const char *name, va_list args); | ||||
|  | @ -78,6 +224,18 @@ int run_hook_ve(const char *const *env, const char *name, va_list args); | |||
| #define RUN_SILENT_EXEC_FAILURE 8 | ||||
| #define RUN_USING_SHELL 16 | ||||
| #define RUN_CLEAN_ON_EXIT 32 | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int run_command_v_opt(const char **argv, int opt); | ||||
| int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class); | ||||
| /* | ||||
|  | @ -125,15 +283,84 @@ static inline int capture_command(struct child_process *cmd, | |||
|  * It is expected that no synchronization and mutual exclusion between | ||||
|  * the caller and the feed function is necessary so that the function | ||||
|  * can run in a thread without interfering with the caller. | ||||
|  * | ||||
|  * 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(). | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  */ | ||||
| struct async { | ||||
| 	/* | ||||
| 	 * proc reads from in; closes it before return | ||||
| 	 * proc writes to out; closes it before return | ||||
| 	 * returns 0 on success, non-zero on failure | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 * | ||||
| 	 */ | ||||
| 	int (*proc)(int in, int out, void *data); | ||||
|  | ||||
| 	void *data; | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 */ | ||||
| 	int in;		/* caller writes here and closes it */ | ||||
| 	int out;	/* caller reads from here and closes it */ | ||||
| #ifdef NO_PTHREADS | ||||
|  | @ -146,8 +373,19 @@ struct async { | |||
| 	int isolate_sigpipe; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int start_async(struct async *async); | ||||
|  | ||||
| /** | ||||
|  * Wait for the completion of an asynchronous function that was | ||||
|  * started with start_async(). | ||||
|  */ | ||||
| int finish_async(struct async *async); | ||||
|  | ||||
| int in_async(void); | ||||
| int async_with_fork(void); | ||||
| void check_pipe(int err); | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ int oid_array_for_each(struct oid_array *array, | |||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	/* No oid_array_sort() here! See the api-oid-array.txt docs! */ | ||||
| 	/* No oid_array_sort() here! See sha1-array.h */ | ||||
|  | ||||
| 	for (i = 0; i < array->nr; i++) { | ||||
| 		int ret = fn(array->oid + i, data); | ||||
|  |  | |||
							
								
								
									
										80
									
								
								sha1-array.h
								
								
								
								
							
							
						
						
									
										80
									
								
								sha1-array.h
								
								
								
								
							|  | @ -1,6 +1,52 @@ | |||
| #ifndef SHA1_ARRAY_H | ||||
| #define SHA1_ARRAY_H | ||||
|  | ||||
| /** | ||||
|  * The 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. | ||||
|  * | ||||
|  * 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); | ||||
|  *     } | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| struct oid_array { | ||||
| 	struct object_id *oid; | ||||
| 	int nr; | ||||
|  | @ -10,18 +56,52 @@ struct oid_array { | |||
|  | ||||
| #define OID_ARRAY_INIT { NULL, 0, 0, 0 } | ||||
|  | ||||
| /** | ||||
|  * 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). | ||||
|  */ | ||||
| void oid_array_append(struct oid_array *array, const struct object_id *oid); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int oid_array_lookup(struct oid_array *array, const struct object_id *oid); | ||||
|  | ||||
| /** | ||||
|  * Free all memory associated with the array and return it to the initial, | ||||
|  * empty state. | ||||
|  */ | ||||
| void oid_array_clear(struct oid_array *array); | ||||
|  | ||||
| typedef int (*for_each_oid_fn)(const struct object_id *oid, | ||||
| 			       void *data); | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int oid_array_for_each(struct oid_array *array, | ||||
| 		       for_each_oid_fn fn, | ||||
| 		       void *data); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int oid_array_for_each_unique(struct oid_array *array, | ||||
| 			      for_each_oid_fn fn, | ||||
| 			      void *data); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void oid_array_filter(struct oid_array *array, | ||||
| 		      for_each_oid_fn want, | ||||
| 		      void *cbdata); | ||||
|  |  | |||
							
								
								
									
										45
									
								
								sigchain.h
								
								
								
								
							
							
						
						
									
										45
									
								
								sigchain.h
								
								
								
								
							|  | @ -1,12 +1,57 @@ | |||
| #ifndef SIGCHAIN_H | ||||
| #define SIGCHAIN_H | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| typedef void (*sigchain_fun)(int); | ||||
|  | ||||
| /* You can sigchain_push and sigchain_pop individual signals. */ | ||||
| int sigchain_push(int sig, sigchain_fun f); | ||||
| int sigchain_pop(int sig); | ||||
|  | ||||
| /** | ||||
|  * push the handler onto the stack for the common signals: | ||||
|  * SIGINT, SIGHUP, SIGTERM, SIGQUIT and SIGPIPE. | ||||
|  */ | ||||
| void sigchain_push_common(sigchain_fun f); | ||||
|  | ||||
| void sigchain_pop_common(void); | ||||
|  | ||||
| #endif /* SIGCHAIN_H */ | ||||
|  |  | |||
|  | @ -7,9 +7,31 @@ | |||
| #include "submodule.h" | ||||
| #include "strbuf.h" | ||||
|  | ||||
| /** | ||||
|  * 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 | ||||
|  * ----- | ||||
|  * | ||||
|  * 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(). | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Submodule entry containing the information about a certain submodule | ||||
|  * in a certain revision. | ||||
|  * in a certain revision. It is returned by the lookup functions. | ||||
|  */ | ||||
| struct submodule { | ||||
| 	const char *path; | ||||
|  | @ -41,13 +63,27 @@ int parse_update_recurse_submodules_arg(const char *opt, const char *arg); | |||
| int parse_push_recurse_submodules_arg(const char *opt, const char *arg); | ||||
| void repo_read_gitmodules(struct repository *repo); | ||||
| void gitmodules_config_oid(const struct object_id *commit_oid); | ||||
|  | ||||
| /** | ||||
|  * Same as submodule_from_path but lookup by name. | ||||
|  */ | ||||
| const struct submodule *submodule_from_name(struct repository *r, | ||||
| 					    const struct object_id *commit_or_tree, | ||||
| 					    const char *name); | ||||
|  | ||||
| /** | ||||
|  * 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_path(struct repository *r, | ||||
| 					    const struct object_id *commit_or_tree, | ||||
| 					    const char *path); | ||||
|  | ||||
| /** | ||||
|  * Use these to free the internally cached values. | ||||
|  */ | ||||
| void submodule_free(struct repository *r); | ||||
|  | ||||
| int print_config_from_gitmodules(struct repository *repo, const char *key); | ||||
| int config_set_in_gitmodules_file_gently(const char *key, const char *value); | ||||
|  | ||||
|  |  | |||
							
								
								
									
										133
									
								
								trace.h
								
								
								
								
							
							
						
						
									
										133
									
								
								trace.h
								
								
								
								
							|  | @ -4,6 +4,82 @@ | |||
| #include "git-compat-util.h" | ||||
| #include "strbuf.h" | ||||
|  | ||||
| /** | ||||
|  * 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 | ||||
|  * ------------ | ||||
|  * | ||||
|  * 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 | ||||
|  * ------------ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| struct trace_key { | ||||
| 	const char * const key; | ||||
| 	int fd; | ||||
|  | @ -18,31 +94,84 @@ extern struct trace_key trace_perf_key; | |||
| extern struct trace_key trace_setup_key; | ||||
|  | ||||
| void trace_repo_setup(const char *prefix); | ||||
|  | ||||
| /** | ||||
|  * Checks whether the trace key is enabled. Used to prevent expensive | ||||
|  * string formatting before calling one of the printing APIs. | ||||
|  */ | ||||
| int trace_want(struct trace_key *key); | ||||
|  | ||||
| /** | ||||
|  * Disables tracing for the specified key, even if the environment variable | ||||
|  * was set. | ||||
|  */ | ||||
| void trace_disable(struct trace_key *key); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| uint64_t getnanotime(void); | ||||
|  | ||||
| void trace_command_performance(const char **argv); | ||||
| void trace_verbatim(struct trace_key *key, const void *buf, unsigned len); | ||||
| uint64_t trace_performance_enter(void); | ||||
|  | ||||
| #ifndef HAVE_VARIADIC_MACROS | ||||
|  | ||||
| /** | ||||
|  * Prints a formatted message, similar to printf. | ||||
|  */ | ||||
| __attribute__((format (printf, 1, 2))) | ||||
| void trace_printf(const char *format, ...); | ||||
|  | ||||
| __attribute__((format (printf, 2, 3))) | ||||
| void trace_printf_key(struct trace_key *key, const char *format, ...); | ||||
|  | ||||
| /** | ||||
|  * Prints a formatted message, followed by a quoted list of arguments. | ||||
|  */ | ||||
| __attribute__((format (printf, 2, 3))) | ||||
| void trace_argv_printf(const char **argv, const char *format, ...); | ||||
|  | ||||
| /** | ||||
|  * Prints the strbuf, without additional formatting (i.e. doesn't | ||||
|  * choke on `%` or even `\0`). | ||||
|  */ | ||||
| void trace_strbuf(struct trace_key *key, const struct strbuf *data); | ||||
|  | ||||
| /* Prints elapsed time (in nanoseconds) if GIT_TRACE_PERFORMANCE is enabled. */ | ||||
| /** | ||||
|  * Prints elapsed time (in nanoseconds) if GIT_TRACE_PERFORMANCE is enabled. | ||||
|  * | ||||
|  * Example: | ||||
|  * ------------ | ||||
|  * uint64_t t = 0; | ||||
|  * for (;;) { | ||||
|  * 	// ignore | ||||
|  * t -= getnanotime(); | ||||
|  * // code section to measure | ||||
|  * t += getnanotime(); | ||||
|  * // ignore | ||||
|  * } | ||||
|  * trace_performance(t, "frotz"); | ||||
|  * ------------ | ||||
|  */ | ||||
| __attribute__((format (printf, 2, 3))) | ||||
| void trace_performance(uint64_t nanos, const char *format, ...); | ||||
|  | ||||
| /* Prints elapsed time since 'start' if GIT_TRACE_PERFORMANCE is enabled. */ | ||||
| /** | ||||
|  * Prints elapsed time since 'start' if GIT_TRACE_PERFORMANCE is enabled. | ||||
|  * | ||||
|  * Example: | ||||
|  * ------------ | ||||
|  * uint64_t start = getnanotime(); | ||||
|  * // code section to measure | ||||
|  * trace_performance_since(start, "foobar"); | ||||
|  * ------------ | ||||
|  */ | ||||
| __attribute__((format (printf, 2, 3))) | ||||
| void trace_performance_since(uint64_t start, const char *format, ...); | ||||
|  | ||||
|  |  | |||
							
								
								
									
										124
									
								
								trace2.h
								
								
								
								
							
							
						
						
									
										124
									
								
								trace2.h
								
								
								
								
							|  | @ -1,6 +1,40 @@ | |||
| #ifndef TRACE2_H | ||||
| #define TRACE2_H | ||||
|  | ||||
| /** | ||||
|  * The Trace2 API can be used to print debug, performance, and telemetry | ||||
|  * information to stderr or a file.  The Trace2 feature is inactive unless | ||||
|  * explicitly enabled by enabling one or more Trace2 Targets. | ||||
|  * | ||||
|  * The Trace2 API is intended to replace the existing (Trace1) | ||||
|  * printf-style tracing provided by the existing `GIT_TRACE` and | ||||
|  * `GIT_TRACE_PERFORMANCE` facilities.  During initial implementation, | ||||
|  * Trace2 and Trace1 may operate in parallel. | ||||
|  * | ||||
|  * The Trace2 API defines a set of high-level messages with known fields, | ||||
|  * such as (`start`: `argv`) and (`exit`: {`exit-code`, `elapsed-time`}). | ||||
|  * | ||||
|  * Trace2 instrumentation throughout the Git code base sends Trace2 | ||||
|  * messages to the enabled Trace2 Targets.  Targets transform these | ||||
|  * messages content into purpose-specific formats and write events to | ||||
|  * their data streams.  In this manner, the Trace2 API can drive | ||||
|  * many different types of analysis. | ||||
|  * | ||||
|  * Targets are defined using a VTable allowing easy extension to other | ||||
|  * formats in the future.  This might be used to define a binary format, | ||||
|  * for example. | ||||
|  * | ||||
|  * Trace2 is controlled using `trace2.*` config values in the system and | ||||
|  * global config files and `GIT_TRACE2*` environment variables.  Trace2 does | ||||
|  * not read from repo local or worktree config files or respect `-c` | ||||
|  * command line config settings. | ||||
|  * | ||||
|  * For more info about: trace2 targets, conventions for public functions and | ||||
|  * macros, trace2 target formats and examples on trace2 API usage refer to | ||||
|  * Documentation/technical/api-trace2.txt | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| struct child_process; | ||||
| struct repository; | ||||
| struct json_writer; | ||||
|  | @ -39,7 +73,12 @@ void trace2_initialize_clock(void); | |||
| /* | ||||
|  * Initialize TRACE2 tracing facility if any of the builtin TRACE2 | ||||
|  * targets are enabled in the system config or the environment. | ||||
|  * Emits a 'version' event. | ||||
|  * This includes setting up the Trace2 thread local storage (TLS). | ||||
|  * 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. | ||||
|  * | ||||
|  * Cleanup/Termination is handled automatically by a registered | ||||
|  * atexit() routine. | ||||
|  | @ -49,7 +88,7 @@ void trace2_initialize_fl(const char *file, int line); | |||
| #define trace2_initialize() trace2_initialize_fl(__FILE__, __LINE__) | ||||
|  | ||||
| /* | ||||
|  * Return true if trace2 is enabled. | ||||
|  * Return 1 if trace2 is enabled (at least one target is active). | ||||
|  */ | ||||
| int trace2_is_enabled(void); | ||||
|  | ||||
|  | @ -114,7 +153,8 @@ void trace2_cmd_mode_fl(const char *file, int line, const char *mode); | |||
| #define trace2_cmd_mode(sv) trace2_cmd_mode_fl(__FILE__, __LINE__, (sv)) | ||||
|  | ||||
| /* | ||||
|  * Emit an 'alias' expansion event. | ||||
|  * Emits an "alias" message containing the alias used and the argument | ||||
|  * expansion. | ||||
|  */ | ||||
| void trace2_cmd_alias_fl(const char *file, int line, const char *alias, | ||||
| 			 const char **argv); | ||||
|  | @ -123,7 +163,7 @@ void trace2_cmd_alias_fl(const char *file, int line, const char *alias, | |||
| 	trace2_cmd_alias_fl(__FILE__, __LINE__, (alias), (argv)) | ||||
|  | ||||
| /* | ||||
|  * Emit one or more 'def_param' events for "interesting" configuration | ||||
|  * Emit one or more 'def_param' events for "important" configuration | ||||
|  * settings. | ||||
|  * | ||||
|  * Use the TR2_SYSENV_CFG_PARAM setting to register a comma-separated | ||||
|  | @ -144,7 +184,7 @@ void trace2_cmd_list_config_fl(const char *file, int line); | |||
|  | ||||
| /* | ||||
|  * Emit a "def_param" event for the given config key/value pair IF | ||||
|  * we consider the key to be "interesting". | ||||
|  * we consider the key to be "important". | ||||
|  * | ||||
|  * Use this for new/updated config settings created/updated after | ||||
|  * trace2_cmd_list_config() is called. | ||||
|  | @ -155,20 +195,34 @@ void trace2_cmd_set_config_fl(const char *file, int line, const char *key, | |||
| #define trace2_cmd_set_config(k, v) \ | ||||
| 	trace2_cmd_set_config_fl(__FILE__, __LINE__, (k), (v)) | ||||
|  | ||||
| /* | ||||
|  * Emit a 'child_start' event prior to spawning a child process. | ||||
| /** | ||||
|  * Emits a "child_start" message containing the "child-id", | ||||
|  * "child-argv", and "child-classification". | ||||
|  * | ||||
|  * Before calling optionally set "cmd->trace2_child_class" to a string | ||||
|  * describing the type of the child process.  For example, "editor" or | ||||
|  * "pager". | ||||
|  * | ||||
|  * 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_start_fl(const char *file, int line, | ||||
| 			   struct child_process *cmd); | ||||
|  | ||||
| #define trace2_child_start(cmd) trace2_child_start_fl(__FILE__, __LINE__, (cmd)) | ||||
|  | ||||
| /* | ||||
|  * Emit a 'child_exit' event after the child process completes. | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void trace2_child_exit_fl(const char *file, int line, struct child_process *cmd, | ||||
| 			  int child_exit_code); | ||||
|  | @ -176,21 +230,22 @@ void trace2_child_exit_fl(const char *file, int line, struct child_process *cmd, | |||
| #define trace2_child_exit(cmd, code) \ | ||||
| 	trace2_child_exit_fl(__FILE__, __LINE__, (cmd), (code)) | ||||
|  | ||||
| /* | ||||
| /** | ||||
|  * Emit an 'exec' event prior to calling one of exec(), execv(), | ||||
|  * execvp(), and etc.  On Unix-derived systems, this will be the | ||||
|  * last event emitted for the current process, unless the exec | ||||
|  * fails.  On Windows, exec() behaves like 'child_start' and a | ||||
|  * waitpid(), so additional events may be emitted. | ||||
|  * | ||||
|  * Returns the "exec_id". | ||||
|  * Returns a unique "exec-id".  This value is used later | ||||
|  * if the exec() fails and a "exec-result" message is necessary. | ||||
|  */ | ||||
| int trace2_exec_fl(const char *file, int line, const char *exe, | ||||
| 		   const char **argv); | ||||
|  | ||||
| #define trace2_exec(exe, argv) trace2_exec_fl(__FILE__, __LINE__, (exe), (argv)) | ||||
|  | ||||
| /* | ||||
| /** | ||||
|  * Emit an 'exec_result' when possible.  On Unix-derived systems, | ||||
|  * this should be called after exec() returns (which only happens | ||||
|  * when there is an error starting the new process).  On Windows, | ||||
|  | @ -226,11 +281,12 @@ void trace2_thread_exit_fl(const char *file, int line); | |||
| #define trace2_thread_exit() trace2_thread_exit_fl(__FILE__, __LINE__) | ||||
|  | ||||
| /* | ||||
|  * Emit a 'param' event. | ||||
|  * Emits a "def_param" message containing a key/value pair. | ||||
|  * | ||||
|  * Write a "<param> = <value>" pair describing some aspect of the | ||||
|  * run such as an important configuration setting or command line | ||||
|  * option that significantly changes command behavior. | ||||
|  * 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_def_param_fl(const char *file, int line, const char *param, | ||||
| 			 const char *value); | ||||
|  | @ -243,18 +299,35 @@ void trace2_def_param_fl(const char *file, int line, const char *param, | |||
|  * a trace2-repo-id to be used in subsequent activity events. | ||||
|  * | ||||
|  * Emits a 'worktree' event for this repo instance. | ||||
|  * | ||||
|  * Region and data messages 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. | ||||
|  */ | ||||
| void trace2_def_repo_fl(const char *file, int line, struct repository *repo); | ||||
|  | ||||
| #define trace2_def_repo(repo) trace2_def_repo_fl(__FILE__, __LINE__, repo) | ||||
|  | ||||
| /* | ||||
| /** | ||||
|  * Emit a 'region_enter' event for <category>.<label> with optional | ||||
|  * repo-id and printf message. | ||||
|  * | ||||
|  * Enter a new nesting level on the current thread and remember the | ||||
|  * current time.  This controls the indenting of all subsequent events | ||||
|  * on this thread. | ||||
|  * 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 oerations can be attributed to the correct repository. | ||||
|  */ | ||||
| void trace2_region_enter_fl(const char *file, int line, const char *category, | ||||
| 			    const char *label, const struct repository *repo, ...); | ||||
|  | @ -289,12 +362,17 @@ void trace2_region_enter_printf(const char *category, const char *label, | |||
| /* clang-format on */ | ||||
| #endif | ||||
|  | ||||
| /* | ||||
| /** | ||||
|  * Emit a 'region_leave' event for <category>.<label> with optional | ||||
|  * repo-id and printf message. | ||||
|  * | ||||
|  * Leave current nesting level and report the elapsed time spent | ||||
|  * in this nesting level. | ||||
|  * | ||||
|  * The `category`, `label`, and `repo` fields are the same as | ||||
|  * trace2_region_enter_fl. 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_region_leave_fl(const char *file, int line, const char *category, | ||||
| 			    const char *label, const struct repository *repo, ...); | ||||
|  | @ -329,10 +407,12 @@ void trace2_region_leave_printf(const char *category, const char *label, | |||
| /* clang-format on */ | ||||
| #endif | ||||
|  | ||||
| /* | ||||
| /** | ||||
|  * Emit a key-value pair 'data' event of the form <category>.<key> = <value>. | ||||
|  * This event implicitly contains information about thread, nesting region, | ||||
|  * and optional repo-id. | ||||
|  * This could be used to print the number of files in a directory during | ||||
|  * a multi-threaded recursive tree walk. | ||||
|  * | ||||
|  * On event-based TRACE2 targets, this generates a 'data' event suitable | ||||
|  * for post-processing.  On printf-based TRACE2 targets, this is converted | ||||
|  |  | |||
							
								
								
									
										122
									
								
								tree-walk.h
								
								
								
								
							
							
						
						
									
										122
									
								
								tree-walk.h
								
								
								
								
							|  | @ -3,6 +3,13 @@ | |||
|  | ||||
| #include "cache.h" | ||||
|  | ||||
| /** | ||||
|  * The tree walking API is used to traverse and inspect trees. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * An entry in a tree. Each entry has a sha1 identifier, pathname, and mode. | ||||
|  */ | ||||
| struct name_entry { | ||||
| 	struct object_id oid; | ||||
| 	const char *path; | ||||
|  | @ -10,12 +17,29 @@ struct name_entry { | |||
| 	unsigned int mode; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * A semi-opaque data structure used to maintain the current state of the walk. | ||||
|  */ | ||||
| struct tree_desc { | ||||
| 	/* | ||||
| 	 * pointer into the memory representation of the tree. It always | ||||
| 	 * points at the current entry being visited. | ||||
| 	 */ | ||||
| 	const void *buffer; | ||||
|  | ||||
| 	/* points to the current entry being visited. */ | ||||
| 	struct name_entry entry; | ||||
|  | ||||
| 	/* counts the number of bytes left in the `buffer`. */ | ||||
| 	unsigned int size; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| static inline const struct object_id *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned short *modep) | ||||
| { | ||||
| 	*pathp = desc->entry.path; | ||||
|  | @ -23,6 +47,11 @@ static inline const struct object_id *tree_entry_extract(struct tree_desc *desc, | |||
| 	return &desc->entry.oid; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 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(). | ||||
|  */ | ||||
| static inline int tree_entry_len(const struct name_entry *ne) | ||||
| { | ||||
| 	return ne->pathlen; | ||||
|  | @ -33,52 +62,141 @@ static inline int tree_entry_len(const struct name_entry *ne) | |||
|  * corrupt tree entry rather than dying, | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Walk to the next entry in a tree. This is commonly used in conjunction | ||||
|  * with `tree_entry_extract` to inspect the current entry. | ||||
|  */ | ||||
| void update_tree_entry(struct tree_desc *); | ||||
|  | ||||
| int update_tree_entry_gently(struct 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`. | ||||
|  */ | ||||
| void init_tree_desc(struct tree_desc *desc, const void *buf, unsigned long size); | ||||
|  | ||||
| int init_tree_desc_gently(struct tree_desc *desc, const void *buf, unsigned long size); | ||||
|  | ||||
| /* | ||||
|  * Helper function that does both tree_entry_extract() and update_tree_entry() | ||||
|  * and returns true for success | ||||
|  * 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. | ||||
|  */ | ||||
| int tree_entry(struct tree_desc *, struct name_entry *); | ||||
|  | ||||
| int tree_entry_gently(struct tree_desc *, struct name_entry *); | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| void *fill_tree_descriptor(struct repository *r, | ||||
| 			   struct tree_desc *desc, | ||||
| 			   const struct object_id *oid); | ||||
|  | ||||
| struct traverse_info; | ||||
| typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *); | ||||
|  | ||||
| /** | ||||
|  * Traverse `n` number of trees in parallel. The `fn` callback member of | ||||
|  * `traverse_info` is called once for each tree entry. | ||||
|  */ | ||||
| int traverse_trees(struct index_state *istate, int n, struct tree_desc *t, struct traverse_info *info); | ||||
|  | ||||
| enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r, struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned short *mode); | ||||
|  | ||||
| /** | ||||
|  * A structure used to maintain the state of a traversal. | ||||
|  */ | ||||
| struct traverse_info { | ||||
| 	const char *traverse_path; | ||||
|  | ||||
| 	/* | ||||
| 	 * 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. | ||||
| 	 */ | ||||
| 	struct traverse_info *prev; | ||||
|  | ||||
| 	/* is the entry for the current tree (if the tree is a subtree). */ | ||||
| 	const char *name; | ||||
|  | ||||
| 	size_t namelen; | ||||
| 	unsigned mode; | ||||
|  | ||||
| 	/* is the length of the full path for the current tree. */ | ||||
| 	size_t pathlen; | ||||
|  | ||||
| 	struct pathspec *pathspec; | ||||
|  | ||||
| 	/* can be used by callbacks to maintain directory-file conflicts. */ | ||||
| 	unsigned long df_conflicts; | ||||
|  | ||||
| 	/* a callback called for each entry in the tree. | ||||
| 	 * | ||||
| 	 * 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. | ||||
| 	 */ | ||||
| 	traverse_callback_t fn; | ||||
|  | ||||
| 	/* can be anything the `fn` callback would want to use. */ | ||||
| 	void *data; | ||||
|  | ||||
| 	/* tells whether to stop at the first error or not. */ | ||||
| 	int show_all_errors; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|  */ | ||||
| int get_tree_entry(struct repository *, const struct object_id *, const char *, struct object_id *, unsigned short *); | ||||
|  | ||||
| /** | ||||
|  * 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". | ||||
|  */ | ||||
| char *make_traverse_path(char *path, size_t pathlen, const struct traverse_info *info, | ||||
| 			 const char *name, size_t namelen); | ||||
|  | ||||
| /** | ||||
|  * Convenience wrapper to `make_traverse_path` into a strbuf. | ||||
|  */ | ||||
| void strbuf_make_traverse_path(struct strbuf *out, | ||||
| 			       const struct traverse_info *info, | ||||
| 			       const char *name, size_t namelen); | ||||
|  | ||||
| /** | ||||
|  * Initialize a `traverse_info` given the pathname of the tree to start | ||||
|  * traversing from. | ||||
|  */ | ||||
| void setup_traverse_info(struct traverse_info *info, const char *base); | ||||
|  | ||||
| /** | ||||
|  * 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(). | ||||
|  */ | ||||
| static inline size_t traverse_path_len(const struct traverse_info *info, | ||||
| 				       size_t namelen) | ||||
| { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano