summaryrefslogtreecommitdiff
path: root/Documentation/technical
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/technical')
-rw-r--r--Documentation/technical/api-allocation-growing.txt3
-rw-r--r--Documentation/technical/api-argv-array.txt8
-rw-r--r--Documentation/technical/api-builtin.txt13
-rw-r--r--Documentation/technical/api-config.txt186
-rw-r--r--Documentation/technical/api-credentials.txt5
-rw-r--r--Documentation/technical/api-hashmap.txt54
-rw-r--r--Documentation/technical/api-lockfile.txt254
-rw-r--r--Documentation/technical/api-run-command.txt20
-rw-r--r--Documentation/technical/api-strbuf.txt32
-rw-r--r--Documentation/technical/api-string-list.txt11
-rw-r--r--Documentation/technical/api-trace.txt97
-rw-r--r--Documentation/technical/http-protocol.txt2
-rw-r--r--Documentation/technical/index-format.txt35
-rw-r--r--Documentation/technical/pack-protocol.txt51
-rw-r--r--Documentation/technical/protocol-capabilities.txt15
15 files changed, 701 insertions, 85 deletions
diff --git a/Documentation/technical/api-allocation-growing.txt b/Documentation/technical/api-allocation-growing.txt
index 542946b..5a59b54 100644
--- a/Documentation/technical/api-allocation-growing.txt
+++ b/Documentation/technical/api-allocation-growing.txt
@@ -34,3 +34,6 @@ 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`.
diff --git a/Documentation/technical/api-argv-array.txt b/Documentation/technical/api-argv-array.txt
index a6b7d83..1a79781 100644
--- a/Documentation/technical/api-argv-array.txt
+++ b/Documentation/technical/api-argv-array.txt
@@ -53,11 +53,3 @@ Functions
`argv_array_clear`::
Free all memory associated with the array and return it to the
initial, empty state.
-
-`argv_array_detach`::
- Detach the argv array from the `struct argv_array`, transferring
- ownership of the allocated array and strings.
-
-`argv_array_free_detached`::
- Free the memory allocated by a `struct argv_array` that was later
- detached and is now no longer needed.
diff --git a/Documentation/technical/api-builtin.txt b/Documentation/technical/api-builtin.txt
index e3d6e7a..22a39b9 100644
--- a/Documentation/technical/api-builtin.txt
+++ b/Documentation/technical/api-builtin.txt
@@ -22,11 +22,14 @@ Git:
where options is the bitwise-or of:
`RUN_SETUP`::
-
- Make sure there is a Git directory to work on, and if there is a
- work tree, chdir to the top of it if the command was invoked
- in a subdirectory. If there is no work tree, no chdir() is
- done.
+ If there is not a Git directory to work on, abort. If there
+ is a work tree, chdir to the top of it if the command was
+ invoked in a subdirectory. If there is no work tree, no
+ chdir() is done.
+
+`RUN_SETUP_GENTLY`::
+ If there is a Git directory, chdir as per RUN_SETUP, otherwise,
+ don't chdir anywhere.
`USE_PAGER`::
diff --git a/Documentation/technical/api-config.txt b/Documentation/technical/api-config.txt
index 230b3a0..0d8b99b 100644
--- a/Documentation/technical/api-config.txt
+++ b/Documentation/technical/api-config.txt
@@ -77,6 +77,99 @@ To read a specific file in git-config format, use
`git_config_from_file`. This takes the same callback and data parameters
as `git_config`.
+Querying For Specific Variables
+-------------------------------
+
+For programs wanting to query for specific variables in a non-callback
+manner, the config API provides two functions `git_config_get_value`
+and `git_config_get_value_multi`. They both read values from an internal
+cache generated previously from reading the config files.
+
+`int git_config_get_value(const char *key, const char **value)`::
+
+ Finds the highest-priority value for the configuration variable `key`,
+ stores the pointer to it in `value` and returns 0. When the
+ configuration variable `key` is not found, returns 1 without touching
+ `value`. The caller should not free or modify `value`, as it is owned
+ by the cache.
+
+`const struct string_list *git_config_get_value_multi(const char *key)`::
+
+ Finds and returns the value list, sorted in order of increasing priority
+ for the configuration variable `key`. When the configuration variable
+ `key` is not found, returns NULL. The caller should not free or modify
+ the returned pointer, as it is owned by the cache.
+
+`void git_config_clear(void)`::
+
+ Resets and invalidates the config cache.
+
+The config API also provides type specific API functions which do conversion
+as well as retrieval for the queried variable, including:
+
+`int git_config_get_int(const char *key, int *dest)`::
+
+ Finds and parses the value to an integer for the configuration variable
+ `key`. Dies on error; otherwise, stores the value of the parsed integer in
+ `dest` and returns 0. When the configuration variable `key` is not found,
+ returns 1 without touching `dest`.
+
+`int git_config_get_ulong(const char *key, unsigned long *dest)`::
+
+ Similar to `git_config_get_int` but for unsigned longs.
+
+`int git_config_get_bool(const char *key, int *dest)`::
+
+ Finds and parses the value into a boolean value, for the configuration
+ variable `key` respecting keywords like "true" and "false". Integer
+ values are converted into true/false values (when they are non-zero or
+ zero, respectively). Other values cause a die(). If parsing is successful,
+ stores the value of the parsed result in `dest` and returns 0. When the
+ configuration variable `key` is not found, returns 1 without touching
+ `dest`.
+
+`int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest)`::
+
+ Similar to `git_config_get_bool`, except that integers are copied as-is,
+ and `is_bool` flag is unset.
+
+`int git_config_get_maybe_bool(const char *key, int *dest)`::
+
+ Similar to `git_config_get_bool`, except that it returns -1 on error
+ rather than dying.
+
+`int git_config_get_string_const(const char *key, const char **dest)`::
+
+ Allocates and copies the retrieved string into the `dest` parameter for
+ the configuration variable `key`; if NULL string is given, prints an
+ error message and returns -1. When the configuration variable `key` is
+ not found, returns 1 without touching `dest`.
+
+`int git_config_get_string(const char *key, char **dest)`::
+
+ Similar to `git_config_get_string_const`, except that retrieved value
+ copied into the `dest` parameter is a mutable string.
+
+`int git_config_get_pathname(const char *key, const char **dest)`::
+
+ Similar to `git_config_get_string`, but expands `~` or `~user` into
+ the user's home directory when found at the beginning of the path.
+
+`git_die_config(const char *key, const char *err, ...)`::
+
+ First prints the error message specified by the caller in `err` and then
+ dies printing the line number and the file name of the highest priority
+ value for the configuration variable `key`.
+
+`void git_die_config_linenr(const char *key, const char *filename, int linenr)`::
+
+ Helper function which formats the die error message according to the
+ parameters entered. Used by `git_die_config()`. It can be used by callers
+ handling `git_config_get_value_multi()` to print the correct error message
+ for the desired value.
+
+See test-config.c for usage examples.
+
Value Parsing Helpers
---------------------
@@ -134,7 +227,98 @@ int read_file_with_include(const char *file, config_fn_t fn, void *data)
`git_config` respects includes automatically. The lower-level
`git_config_from_file` does not.
+Custom Configsets
+-----------------
+
+A `config_set` can be used to construct an in-memory cache for
+config-like files that the caller specifies (i.e., files like `.gitmodules`,
+`~/.gitconfig` etc.). For example,
+
+---------------------------------------
+struct config_set gm_config;
+git_configset_init(&gm_config);
+int b;
+/* we add config files to the config_set */
+git_configset_add_file(&gm_config, ".gitmodules");
+git_configset_add_file(&gm_config, ".gitmodules_alt");
+
+if (!git_configset_get_bool(gm_config, "submodule.frotz.ignore", &b)) {
+ /* hack hack hack */
+}
+
+/* when we are done with the configset */
+git_configset_clear(&gm_config);
+----------------------------------------
+
+Configset API provides functions for the above mentioned work flow, including:
+
+`void git_configset_init(struct config_set *cs)`::
+
+ Initializes the config_set `cs`.
+
+`int git_configset_add_file(struct config_set *cs, const char *filename)`::
+
+ Parses the file and adds the variable-value pairs to the `config_set`,
+ dies if there is an error in parsing the file. Returns 0 on success, or
+ -1 if the file does not exist or is inaccessible. The user has to decide
+ if he wants to free the incomplete configset or continue using it when
+ the function returns -1.
+
+`int git_configset_get_value(struct config_set *cs, const char *key, const char **value)`::
+
+ Finds the highest-priority value for the configuration variable `key`
+ and config set `cs`, stores the pointer to it in `value` and returns 0.
+ When the configuration variable `key` is not found, returns 1 without
+ touching `value`. The caller should not free or modify `value`, as it
+ is owned by the cache.
+
+`const struct string_list *git_configset_get_value_multi(struct config_set *cs, const char *key)`::
+
+ Finds and returns the value list, sorted in order of increasing priority
+ for the configuration variable `key` and config set `cs`. When the
+ configuration variable `key` is not found, returns NULL. The caller
+ should not free or modify the returned pointer, as it is owned by the cache.
+
+`void git_configset_clear(struct config_set *cs)`::
+
+ Clears `config_set` structure, removes all saved variable-value pairs.
+
+In addition to above functions, the `config_set` API provides type specific
+functions in the vein of `git_config_get_int` and family but with an extra
+parameter, pointer to struct `config_set`.
+They all behave similarly to the `git_config_get*()` family described in
+"Querying For Specific Variables" above.
+
Writing Config Files
--------------------
-TODO
+Git gives multiple entry points in the Config API to write config values to
+files namely `git_config_set_in_file` and `git_config_set`, which write to
+a specific config file or to `.git/config` respectively. They both take a
+key/value pair as parameter.
+In the end they both call `git_config_set_multivar_in_file` which takes four
+parameters:
+
+- the name of the file, as a string, to which key/value pairs will be written.
+
+- the name of key, as a string. This is in canonical "flat" form: the section,
+ subsection, and variable segments will be separated by dots, and the section
+ and variable segments will be all lowercase.
+ E.g., `core.ignorecase`, `diff.SomeType.textconv`.
+
+- the value of the variable, as a string. If value is equal to NULL, it will
+ remove the matching key from the config file.
+
+- the value regex, as a string. It will disregard key/value pairs where value
+ does not match.
+
+- a multi_replace value, as an int. If value is equal to zero, nothing or only
+ one matching key/value is replaced, else all matching key/values (regardless
+ how many) are removed, before the new pair is written.
+
+It returns 0 on success.
+
+Also, there are functions `git_config_rename_section` and
+`git_config_rename_section_in_file` with parameters `old_name` and `new_name`
+for renaming or removing sections in the config files. If NULL is passed
+through `new_name` parameter, the section will be removed from the config file.
diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt
index c1b42a4..e44426d 100644
--- a/Documentation/technical/api-credentials.txt
+++ b/Documentation/technical/api-credentials.txt
@@ -248,7 +248,10 @@ FORMAT` in linkgit:git-credential[7] 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.
+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
diff --git a/Documentation/technical/api-hashmap.txt b/Documentation/technical/api-hashmap.txt
index b977ae8..ad7a5bd 100644
--- a/Documentation/technical/api-hashmap.txt
+++ b/Documentation/technical/api-hashmap.txt
@@ -8,11 +8,19 @@ Data Structures
`struct hashmap`::
- The hash table structure.
+ The hash table structure. Members can be used as follows, but should
+ not be modified directly:
+
-The `size` member keeps track of the total number of entries. The `cmpfn`
-member is a function used to compare two entries for equality. The `table` and
-`tablesize` members store the hash table and its size, respectively.
+The `size` member keeps track of the total number of entries (0 means the
+hashmap is empty).
++
+`tablesize` is the allocated size of the hash table. A non-0 value indicates
+that the hashmap is initialized. It may also be useful for statistical purposes
+(i.e. `size / tablesize` is the current load factor).
++
+`cmpfn` stores the comparison function specified in `hashmap_init()`. In
+advanced scenarios, it may be useful to change this, e.g. to switch between
+case-sensitive and case-insensitive lookup.
`struct hashmap_entry`::
@@ -58,6 +66,15 @@ Functions
+
`strihash` and `memihash` are case insensitive versions.
+`unsigned int sha1hash(const unsigned char *sha1)`::
+
+ Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code
+ for use in hash tables. Cryptographic hashes are supposed to have
+ uniform distribution, so in contrast to `memhash()`, this just copies
+ the first `sizeof(int)` bytes without shuffling any bits. Note that
+ the results will be different on big-endian and little-endian
+ platforms, so they should not be stored or transferred over the net.
+
`void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, size_t initial_size)`::
Initializes a hashmap structure.
@@ -101,6 +118,20 @@ hashmap_entry) that has at least been initialized with the proper hash code
If an entry with matching hash code is found, `key` and `keydata` are passed
to `hashmap_cmp_fn` to decide whether the entry matches the key.
+`void *hashmap_get_from_hash(const struct hashmap *map, unsigned int hash, const void *keydata)`::
+
+ Returns the hashmap entry for the specified hash code and key data,
+ or NULL if not found.
++
+`map` is the hashmap structure.
++
+`hash` is the hash code of the entry to look up.
++
+If an entry with matching hash code is found, `keydata` is passed to
+`hashmap_cmp_fn` to decide whether the entry matches the key. The
+`entry_or_key` parameter points to a bogus hashmap_entry structure that
+should not be used in the comparison.
+
`void *hashmap_get_next(const struct hashmap *map, const void *entry)`::
Returns the next equal hashmap entry, or NULL if not found. This can be
@@ -162,6 +193,21 @@ more entries.
`hashmap_iter_first` is a combination of both (i.e. initializes the iterator
and returns the first entry, if any).
+`const char *strintern(const char *string)`::
+`const void *memintern(const void *data, size_t len)`::
+
+ Returns the unique, interned version of the specified string or data,
+ similar to the `String.intern` API in Java and .NET, respectively.
+ Interned strings remain valid for the entire lifetime of the process.
++
+Can be used as `[x]strdup()` or `xmemdupz` replacement, except that interned
+strings / data must not be modified or freed.
++
+Interned strings are best used for short strings with high probability of
+duplicates.
++
+Uses a hashmap to store the pool of interned strings.
+
Usage example
-------------
diff --git a/Documentation/technical/api-lockfile.txt b/Documentation/technical/api-lockfile.txt
index dd89404..93b5f23 100644
--- a/Documentation/technical/api-lockfile.txt
+++ b/Documentation/technical/api-lockfile.txt
@@ -3,20 +3,132 @@ lockfile API
The lockfile API serves two purposes:
-* Mutual exclusion. When we write out a new index file, first
- we create a new file `$GIT_DIR/index.lock`, write the new
- contents into it, and rename it to the final destination
- `$GIT_DIR/index`. We try to create the `$GIT_DIR/index.lock`
- file with O_EXCL so that we can notice and fail when somebody
- else is already trying to update the index file.
-
-* Automatic cruft removal. After we create the "lock" file, we
- may decide to `die()`, and we would want to make sure that we
- remove the file that has not been committed to its final
- destination. This is done by remembering the lockfiles we
- created in a linked list and cleaning them up from an
- `atexit(3)` handler. Outstanding lockfiles are also removed
- when the program dies on a signal.
+* Mutual exclusion and atomic file updates. When we want to change a
+ file, we create a lockfile `<filename>.lock`, write the new file
+ contents into it, and then rename the lockfile to its final
+ destination `<filename>`. We create the `<filename>.lock` file with
+ `O_CREAT|O_EXCL` so that we can notice and fail if somebody else has
+ already locked the file, then atomically rename the lockfile to its
+ final destination to commit the changes and unlock the file.
+
+* Automatic cruft removal. If the program exits after we lock a file
+ but before the changes have been committed, we want to make sure
+ that we remove the lockfile. This is done by remembering the
+ lockfiles we have created in a linked list and setting up an
+ `atexit(3)` handler and a signal handler that clean up the
+ lockfiles. This mechanism ensures that outstanding lockfiles are
+ cleaned up if the program exits (including when `die()` is called)
+ or if the program dies on a signal.
+
+Please note that lockfiles only block other writers. Readers do not
+block, but they are guaranteed to see either the old contents of the
+file or the new contents of the file (assuming that the filesystem
+implements `rename(2)` atomically).
+
+
+Calling sequence
+----------------
+
+The caller:
+
+* Allocates a `struct lock_file` either as a static variable or on the
+ heap, initialized to zeros. Once you use the structure to call the
+ `hold_lock_file_*` family of functions, it belongs to the lockfile
+ subsystem and its storage must remain valid throughout the life of
+ the program (i.e. you cannot use an on-stack variable to hold this
+ structure).
+
+* Attempts to create a lockfile by passing that variable and the path
+ of the final destination (e.g. `$GIT_DIR/index`) to
+ `hold_lock_file_for_update` or `hold_lock_file_for_append`.
+
+* Writes new content for the destination file by either:
+
+ * writing to the file descriptor returned by the `hold_lock_file_*`
+ functions (also available via `lock->fd`).
+
+ * calling `fdopen_lock_file` to get a `FILE` pointer for the open
+ file and writing to the file using stdio.
+
+When finished writing, the caller can:
+
+* Close the file descriptor and rename the lockfile to its final
+ destination by calling `commit_lock_file` or `commit_lock_file_to`.
+
+* Close the file descriptor and remove the lockfile by calling
+ `rollback_lock_file`.
+
+* Close the file descriptor without removing or renaming the lockfile
+ by calling `close_lock_file`, and later call `commit_lock_file`,
+ `commit_lock_file_to`, `rollback_lock_file`, or `reopen_lock_file`.
+
+Even after the lockfile is committed or rolled back, the `lock_file`
+object must not be freed or altered by the caller. However, it may be
+reused; just pass it to another call of `hold_lock_file_for_update` or
+`hold_lock_file_for_append`.
+
+If the program exits before you have called one of `commit_lock_file`,
+`commit_lock_file_to`, `rollback_lock_file`, or `close_lock_file`, an
+`atexit(3)` handler will close and remove the lockfile, rolling back
+any uncommitted changes.
+
+If you need to close the file descriptor you obtained from a
+`hold_lock_file_*` function yourself, do so by calling
+`close_lock_file`. You should never call `close(2)` or `fclose(3)`
+yourself! Otherwise the `struct lock_file` structure would still think
+that the file descriptor needs to be closed, and a commit or rollback
+would result in duplicate calls to `close(2)`. Worse yet, if you close
+and then later open another file descriptor for a completely different
+purpose, then a commit or rollback might close that unrelated file
+descriptor.
+
+
+Error handling
+--------------
+
+The `hold_lock_file_*` functions return a file descriptor on success
+or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see below). On
+errors, `errno` describes the reason for failure. Errors can be
+reported by passing `errno` to one of the following helper functions:
+
+unable_to_lock_message::
+
+ Append an appropriate error message to a `strbuf`.
+
+unable_to_lock_error::
+
+ Emit an appropriate error message using `error()`.
+
+unable_to_lock_die::
+
+ Emit an appropriate error message and `die()`.
+
+Similarly, `commit_lock_file`, `commit_lock_file_to`, and
+`close_lock_file` return 0 on success. On failure they set `errno`
+appropriately, do their best to roll back the lockfile, and return -1.
+
+
+Flags
+-----
+
+The following flags can be passed to `hold_lock_file_for_update` or
+`hold_lock_file_for_append`:
+
+LOCK_NO_DEREF::
+
+ Usually symbolic links in the destination path are resolved
+ and the lockfile is created by adding ".lock" to the resolved
+ path. If `LOCK_NO_DEREF` is set, then the lockfile is created
+ by adding ".lock" to the path argument itself. This option is
+ used, for example, when locking a symbolic reference, which
+ for backwards-compatibility reasons can be a symbolic link
+ containing the name of the referred-to-reference.
+
+LOCK_DIE_ON_ERROR::
+
+ If a lock is already taken for the file, `die()` with an error
+ message. If this option is not specified, trying to lock a
+ file that is already locked returns -1 to the caller.
The functions
@@ -24,51 +136,85 @@ The functions
hold_lock_file_for_update::
- Take a pointer to `struct lock_file`, the filename of
- the final destination (e.g. `$GIT_DIR/index`) and a flag
- `die_on_error`. Attempt to create a lockfile for the
- destination and return the file descriptor for writing
- to the file. If `die_on_error` flag is true, it dies if
- a lock is already taken for the file; otherwise it
- returns a negative integer to the caller on failure.
+ Take a pointer to `struct lock_file`, the path of the file to
+ be locked (e.g. `$GIT_DIR/index`) and a flags argument (see
+ above). Attempt to create a lockfile for the destination and
+ return the file descriptor for writing to the file.
+
+hold_lock_file_for_append::
+
+ Like `hold_lock_file_for_update`, but before returning copy
+ the existing contents of the file (if any) to the lockfile and
+ position its write pointer at the end of the file.
+
+fdopen_lock_file::
+
+ Associate a stdio stream with the lockfile. Return NULL
+ (*without* rolling back the lockfile) on error. The stream is
+ closed automatically when `close_lock_file` is called or when
+ the file is committed or rolled back.
+
+get_locked_file_path::
+
+ Return the path of the file that is locked by the specified
+ lock_file object. The caller must free the memory.
commit_lock_file::
- Take a pointer to the `struct lock_file` initialized
- with an earlier call to `hold_lock_file_for_update()`,
- close the file descriptor and rename the lockfile to its
- final destination. Returns 0 upon success, a negative
- value on failure to close(2) or rename(2).
+ Take a pointer to the `struct lock_file` initialized with an
+ earlier call to `hold_lock_file_for_update` or
+ `hold_lock_file_for_append`, close the file descriptor, and
+ rename the lockfile to its final destination. Return 0 upon
+ success. On failure, roll back the lock file and return -1,
+ with `errno` set to the value from the failing call to
+ `close(2)` or `rename(2)`. It is a bug to call
+ `commit_lock_file` for a `lock_file` object that is not
+ currently locked.
+
+commit_lock_file_to::
+
+ Like `commit_lock_file()`, except that it takes an explicit
+ `path` argument to which the lockfile should be renamed. The
+ `path` must be on the same filesystem as the lock file.
rollback_lock_file::
- Take a pointer to the `struct lock_file` initialized
- with an earlier call to `hold_lock_file_for_update()`,
- close the file descriptor and remove the lockfile.
+ Take a pointer to the `struct lock_file` initialized with an
+ earlier call to `hold_lock_file_for_update` or
+ `hold_lock_file_for_append`, close the file descriptor and
+ remove the lockfile. It is a NOOP to call
+ `rollback_lock_file()` for a `lock_file` object that has
+ already been committed or rolled back.
close_lock_file::
- Take a pointer to the `struct lock_file` initialized
- with an earlier call to `hold_lock_file_for_update()`,
- and close the file descriptor. Returns 0 upon success,
- a negative value on failure to close(2).
-
-Because the structure is used in an `atexit(3)` handler, its
-storage has to stay throughout the life of the program. It
-cannot be an auto variable allocated on the stack.
-
-Call `commit_lock_file()` or `rollback_lock_file()` when you are
-done writing to the file descriptor. If you do not call either
-and simply `exit(3)` from the program, an `atexit(3)` handler
-will close and remove the lockfile.
-
-If you need to close the file descriptor you obtained from
-`hold_lock_file_for_update` function yourself, do so by calling
-`close_lock_file()`. You should never call `close(2)` yourself!
-Otherwise the `struct
-lock_file` structure still remembers that the file descriptor
-needs to be closed, and a later call to `commit_lock_file()` or
-`rollback_lock_file()` will result in duplicate calls to
-`close(2)`. Worse yet, if you `close(2)`, open another file
-descriptor for completely different purpose, and then call
-`commit_lock_file()` or `rollback_lock_file()`, they may close
-that unrelated file descriptor.
+
+ Take a pointer to the `struct lock_file` initialized with an
+ earlier call to `hold_lock_file_for_update` or
+ `hold_lock_file_for_append`. Close the file descriptor (and
+ the file pointer if it has been opened using
+ `fdopen_lock_file`). Return 0 upon success. On failure to
+ `close(2)`, return a negative value and roll back the lock
+ file. Usually `commit_lock_file`, `commit_lock_file_to`, or
+ `rollback_lock_file` should eventually be called if
+ `close_lock_file` succeeds.
+
+reopen_lock_file::
+
+ Re-open a lockfile that has been closed (using
+ `close_lock_file`) but not yet committed or rolled back. This
+ can be used to implement a sequence of operations like the
+ following:
+
+ * Lock file.
+
+ * Write new contents to lockfile, then `close_lock_file` to
+ cause the contents to be written to disk.
+
+ * Pass the name of the lockfile to another program to allow it
+ (and nobody else) to inspect the contents you wrote, while
+ still holding the lock yourself.
+
+ * `reopen_lock_file` to reopen the lockfile. Make further
+ updates to the contents.
+
+ * `commit_lock_file` to make the final version permanent.
diff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt
index 5d7d7f2..a9fdb45 100644
--- a/Documentation/technical/api-run-command.txt
+++ b/Documentation/technical/api-run-command.txt
@@ -13,6 +13,10 @@ 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`
@@ -96,8 +100,8 @@ command to run in a sub-process.
The caller:
-1. allocates and clears (memset(&chld, 0, sizeof(chld));) a
- struct child_process variable;
+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;
@@ -109,6 +113,13 @@ 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:
@@ -158,6 +169,11 @@ string pointers (NULL terminated) in .env:
. 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.
diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt
index 1d00e4d..cca6543 100644
--- a/Documentation/technical/api-strbuf.txt
+++ b/Documentation/technical/api-strbuf.txt
@@ -121,10 +121,28 @@ Functions
* Related to the contents of the buffer
+`strbuf_trim`::
+
+ Strip whitespace from the beginning and end of a string.
+ Equivalent to performing `strbuf_rtrim()` followed by `strbuf_ltrim()`.
+
`strbuf_rtrim`::
Strip whitespace from the end of a string.
+`strbuf_ltrim`::
+
+ Strip whitespace from the beginning of a string.
+
+`strbuf_reencode`::
+
+ Replace the contents of the strbuf with a reencoded form. Returns -1
+ on error, 0 on success.
+
+`strbuf_tolower`::
+
+ Lowercase each character in the buffer using `tolower`.
+
`strbuf_cmp`::
Compare two buffers. Returns an integer less than, equal to, or greater
@@ -142,6 +160,10 @@ then they will free() it.
Add a single character to the buffer.
+`strbuf_addchars`::
+
+ Add a character the specified number of times to the buffer.
+
`strbuf_insert`::
Insert data to the given position of the buffer. The remaining contents
@@ -289,6 +311,16 @@ same behaviour as well.
use it unless you need the correct position in the file
descriptor.
+`strbuf_getcwd`::
+
+ Set the buffer to the path of the current working directory.
+
+`strbuf_add_absolute_path`
+
+ Add a path to a buffer, converting a relative path to an
+ absolute one in the process. Symbolic links are not
+ resolved.
+
`stripspace`::
Strip whitespace from a buffer. The second parameter controls if
diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt
index 20be348..c08402b 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -29,7 +29,7 @@ member (you need this if you add things later) and you should set the
`unsorted_string_list_has_string` and get it from the list using
`string_list_lookup` for sorted lists.
-. Can sort an unsorted list using `sort_string_list`.
+. Can sort an unsorted list using `string_list_sort`.
. Can remove duplicate items from a sorted list using
`string_list_remove_duplicates`.
@@ -68,6 +68,11 @@ Functions
* General ones (works with sorted and unsorted lists as well)
+`string_list_init`::
+
+ Initialize the members of the string_list, set `strdup_strings`
+ member according to the value of the second parameter.
+
`filter_string_list`::
Apply a function to each item in a list, retaining only the
@@ -141,7 +146,7 @@ write `string_list_insert(...)->util = ...;`.
ownership of a malloc()ed string to a `string_list` that has
`strdup_string` set.
-`sort_string_list`::
+`string_list_sort`::
Sort the list's entries by string value in `strcmp()` order.
@@ -200,3 +205,5 @@ Represents the list itself.
You should not tamper with it.
. Setting the `strdup_strings` member to 1 will strdup() the strings
before adding them, see above.
+. The `compare_strings_fn` member is used to specify a custom compare
+ function, otherwise `strcmp()` is used as the default function.
diff --git a/Documentation/technical/api-trace.txt b/Documentation/technical/api-trace.txt
new file mode 100644
index 0000000..097a651
--- /dev/null
+++ b/Documentation/technical/api-trace.txt
@@ -0,0 +1,97 @@
+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_print_key(&trace_foo, 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");
+------------
diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt
index 58c7e87..229f845 100644
--- a/Documentation/technical/http-protocol.txt
+++ b/Documentation/technical/http-protocol.txt
@@ -374,7 +374,7 @@ C: Send one `$GIT_URL/git-upload-pack` request:
C: 0000
The stream is organized into "commands", with each command
-appearing by itself in a pkt-line. Within a command line
+appearing by itself in a pkt-line. Within a command line,
the text leading up to the first space is the command name,
and the remainder of the line to the first LF is the value.
Command lines are terminated with an LF as the last byte of
diff --git a/Documentation/technical/index-format.txt b/Documentation/technical/index-format.txt
index f352a9b..35112e4 100644
--- a/Documentation/technical/index-format.txt
+++ b/Documentation/technical/index-format.txt
@@ -129,6 +129,9 @@ Git index format
(Version 4) In version 4, the padding after the pathname does not
exist.
+ Interpretation of index entries in split index mode is completely
+ different. See below for details.
+
== Extensions
=== Cached tree
@@ -198,3 +201,35 @@ Git index format
- At most three 160-bit object names of the entry in stages from 1 to 3
(nothing is written for a missing stage).
+=== Split index
+
+ In split index mode, the majority of index entries could be stored
+ in a separate file. This extension records the changes to be made on
+ top of that to produce the final index.
+
+ The signature for this extension is { 'l', 'i', 'n', 'k' }.
+
+ The extension consists of:
+
+ - 160-bit SHA-1 of the shared index file. The shared index file path
+ is $GIT_DIR/sharedindex.<SHA-1>. If all 160 bits are zero, the
+ index does not require a shared index file.
+
+ - An ewah-encoded delete bitmap, each bit represents an entry in the
+ shared index. If a bit is set, its corresponding entry in the
+ shared index will be removed from the final index. Note, because
+ a delete operation changes index entry positions, but we do need
+ original positions in replace phase, it's best to just mark
+ entries for removal, then do a mass deletion after replacement.
+
+ - An ewah-encoded replace bitmap, each bit represents an entry in
+ the shared index. If a bit is set, its corresponding entry in the
+ shared index will be replaced with an entry in this index
+ file. All replaced entries are stored in sorted order in this
+ index. The first "1" bit in the replace bitmap corresponds to the
+ first index entry, the second "1" bit to the second entry and so
+ on. Replaced entries may have empty path names to save space.
+
+ The remaining index entries after replaced ones will be added to the
+ final index. These added entries are also sorted by entry name then
+ stage.
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 18dea8d..462e206 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -212,9 +212,9 @@ out of what the server said it could do with the first 'want' line.
want-list = first-want
*additional-want
- shallow-line = PKT_LINE("shallow" SP obj-id)
+ shallow-line = PKT-LINE("shallow" SP obj-id)
- depth-request = PKT_LINE("deepen" SP depth)
+ depth-request = PKT-LINE("deepen" SP depth)
first-want = PKT-LINE("want" SP obj-id SP capability-list LF)
additional-want = PKT-LINE("want" SP obj-id LF)
@@ -465,9 +465,9 @@ contain all the objects that the server will need to complete the new
references.
----
- update-request = *shallow command-list [pack-file]
+ update-request = *shallow ( command-list | push-cert ) [pack-file]
- shallow = PKT-LINE("shallow" SP obj-id)
+ shallow = PKT-LINE("shallow" SP obj-id LF)
command-list = PKT-LINE(command NUL capability-list LF)
*PKT-LINE(command LF)
@@ -481,12 +481,27 @@ references.
old-id = obj-id
new-id = obj-id
+ push-cert = PKT-LINE("push-cert" NUL capability-list LF)
+ PKT-LINE("certificate version 0.1" LF)
+ PKT-LINE("pusher" SP ident LF)
+ PKT-LINE("pushee" SP url LF)
+ PKT-LINE("nonce" SP nonce LF)
+ PKT-LINE(LF)
+ *PKT-LINE(command LF)
+ *PKT-LINE(gpg-signature-lines LF)
+ PKT-LINE("push-cert-end" LF)
+
pack-file = "PACK" 28*(OCTET)
----
If the receiving end does not support delete-refs, the sending end MUST
NOT ask for delete command.
+If the receiving end does not support push-cert, the sending end
+MUST NOT send a push-cert command. When a push-cert command is
+sent, command-list MUST NOT be sent; the commands recorded in the
+push certificate is used instead.
+
The pack-file MUST NOT be sent if the only command used is 'delete'.
A pack-file MUST be sent if either create or update command is used,
@@ -501,6 +516,34 @@ was being processed (the obj-id is still the same as the old-id), and
it will run any update hooks to make sure that the update is acceptable.
If all of that is fine, the server will then update the references.
+Push Certificate
+----------------
+
+A push certificate begins with a set of header lines. After the
+header and an empty line, the protocol commands follow, one per
+line.
+
+Currently, the following header fields are defined:
+
+`pusher` ident::
+ Identify the GPG key in "Human Readable Name <email@address>"
+ format.
+
+`pushee` url::
+ The repository URL (anonymized, if the URL contains
+ authentication material) the user who ran `git push`
+ intended to push into.
+
+`nonce` nonce::
+ The 'nonce' string the receiving repository asked the
+ pushing user to include in the certificate, to prevent
+ replay attacks.
+
+The GPG signature lines are a detached signature for the contents
+recorded in the push certificate before the signature block begins.
+The detached signature is used to certify that the commands were
+given by the pusher, who must be the signer.
+
Report Status
-------------
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index e174343..6d5424c 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -18,8 +18,8 @@ was sent. Server MUST NOT ignore capabilities that client requested
and server advertised. As a consequence of these rules, server MUST
NOT advertise capabilities it does not understand.
-The 'report-status', 'delete-refs', and 'quiet' capabilities are sent and
-recognized by the receive-pack (push to server) process.
+The 'report-status', 'delete-refs', 'quiet', and 'push-cert' capabilities
+are sent and recognized by the receive-pack (push to server) process.
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
by both upload-pack and receive-pack protocols. The 'agent' capability
@@ -168,7 +168,7 @@ agent capability). The `X` and `Y` strings may contain any printable
ASCII characters except space (i.e., the byte range 32 < x < 127), and
are typically of the form "package/version" (e.g., "git/1.8.3.1"). The
agent strings are purely informative for statistics and debugging
-purposes, and MUST NOT be used to programatically assume the presence
+purposes, and MUST NOT be used to programmatically assume the presence
or absence of particular features.
shallow
@@ -250,3 +250,12 @@ allow-tip-sha1-in-want
If the upload-pack server advertises this capability, fetch-pack may
send "want" lines with SHA-1s that exist at the server but are not
advertised by upload-pack.
+
+push-cert=<nonce>
+-----------------
+
+The receive-pack server that advertises this capability is willing
+to accept a signed push certificate, and asks the <nonce> to be
+included in the push certificate. A send-pack client MUST NOT
+send a push-cert packet unless the receive-pack server advertises
+this capability.