* priority levels as well.
*/
typedef enum {
+ /** System-wide on Windows, for compatibility with portable git */
+ GIT_CONFIG_LEVEL_PROGRAMDATA = 1,
+
/** System-wide configuration file; /etc/gitconfig on Linux systems */
- GIT_CONFIG_LEVEL_SYSTEM = 1,
+ GIT_CONFIG_LEVEL_SYSTEM = 2,
/** XDG compatible configuration file; typically ~/.config/git/config */
- GIT_CONFIG_LEVEL_XDG = 2,
+ GIT_CONFIG_LEVEL_XDG = 3,
/** User-specific configuration file (also called Global configuration
* file); typically ~/.gitconfig
*/
- GIT_CONFIG_LEVEL_GLOBAL = 3,
+ GIT_CONFIG_LEVEL_GLOBAL = 4,
/** Repository specific configuration file; $WORK_DIR/.git/config on
* non-bare repos
*/
- GIT_CONFIG_LEVEL_LOCAL = 4,
+ GIT_CONFIG_LEVEL_LOCAL = 5,
/** Application specific configuration file; freely defined by applications
*/
- GIT_CONFIG_LEVEL_APP = 5,
+ GIT_CONFIG_LEVEL_APP = 6,
/** Represents the highest level available config file (i.e. the most
* specific config file available that actually is loaded)
/**
* An entry in a configuration file
*/
-typedef struct {
+typedef struct git_config_entry {
const char *name; /**< Name of the entry (normalised) */
const char *value; /**< String value of the entry */
+ unsigned int include_depth; /**< Depth of includes where this variable was found */
git_config_level_t level; /**< Which config file this was found in */
+ void GIT_CALLBACK(free)(struct git_config_entry *entry); /**< Free function for this entry */
+ void *payload; /**< Opaque value for the free function. Do not read or write */
} git_config_entry;
-typedef int (*git_config_foreach_cb)(const git_config_entry *, void *);
+/**
+ * Free a config entry
+ */
+GIT_EXTERN(void) git_config_entry_free(git_config_entry *);
+
+/**
+ * A config enumeration callback
+ *
+ * @param entry the entry currently being enumerated
+ * @param payload a user-specified pointer
+ */
+typedef int GIT_CALLBACK(git_config_foreach_cb)(const git_config_entry *entry, void *payload);
+
+/**
+ * An opaque structure for a configuration iterator
+ */
typedef struct git_config_iterator git_config_iterator;
/**
* Config var type
*/
typedef enum {
- GIT_CVAR_FALSE = 0,
- GIT_CVAR_TRUE = 1,
- GIT_CVAR_INT32,
- GIT_CVAR_STRING
-} git_cvar_t;
+ GIT_CONFIGMAP_FALSE = 0,
+ GIT_CONFIGMAP_TRUE = 1,
+ GIT_CONFIGMAP_INT32,
+ GIT_CONFIGMAP_STRING
+} git_configmap_t;
/**
* Mapping from config variables to values.
*/
typedef struct {
- git_cvar_t cvar_type;
+ git_configmap_t type;
const char *str_match;
int map_value;
-} git_cvar_map;
+} git_configmap;
/**
* Locate the path to the global configuration file
*/
GIT_EXTERN(int) git_config_find_system(git_buf *out);
+/**
+ * Locate the path to the configuration file in ProgramData
+ *
+ * Look for the file in %PROGRAMDATA%\Git\config used by portable git.
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a ProgramData configuration file has been
+ * found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_programdata(git_buf *out);
+
/**
* Open the global, XDG and system configuration files
*
* parsed; it's expected to be a native Git config file following
* the default Git config syntax (see man git-config).
*
+ * If the file does not exist, the file will still be added and it
+ * will be created the first time we write to it.
+ *
* Note that the configuration object will free the file
* automatically.
*
* @param path path to the configuration file to add
* @param level the priority level of the backend
* @param force replace config file at the given priority level
+ * @param repo optional repository to allow parsing of
+ * conditional includes
* @return 0 on success, GIT_EEXISTS when adding more than one file
* for a given priority level (and force_replace set to 0),
* GIT_ENOTFOUND when the file doesn't exist or error code
git_config *cfg,
const char *path,
git_config_level_t level,
+ const git_repository *repo,
int force);
/**
*
* @param out The configuration instance to create
* @param path Path to the on-disk file to open
- * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist
- * or an error code
+ * @return 0 on success, or an error code
*/
GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path);
* Open the global/XDG configuration file according to git's rules
*
* Git allows you to store your global configuration at
- * `$HOME/.config` or `$XDG_CONFIG_HOME/git/config`. For backwards
- * compatability, the XDG file shouldn't be used unless the use has
+ * `$HOME/.gitconfig` or `$XDG_CONFIG_HOME/git/config`. For backwards
+ * compatibility, the XDG file shouldn't be used unless the use has
* created it explicitly. With this function you'll open the correct
* one to write to.
*
/**
* Get the git_config_entry of a config variable.
*
- * The git_config_entry is owned by the config and should not be freed by the
- * user.
-
+ * Free the git_config_entry after use with `git_config_entry_free()`.
+ *
* @param out pointer to the variable git_config_entry
* @param cfg where to look for the variable
* @param name the variable's name
* @return 0 or an error code
*/
GIT_EXTERN(int) git_config_get_entry(
- const git_config_entry **out,
+ git_config_entry **out,
const git_config *cfg,
const char *name);
/**
* Get the value of a string config variable.
*
- * The string is owned by the variable and should not be freed by the
- * user. The pointer will be valid until the next operation on this
- * config object.
+ * This function can only be used on snapshot config objects. The
+ * string is owned by the config and should not be freed by the
+ * user. The pointer will be valid until the config is freed.
*
* All config files will be looked into, in the order of their
* defined level. A higher level means a higher priority. The
* first occurrence of the variable will be returned here.
*
- * @param out pointer to the variable's value
+ * @param out pointer to the string
* @param cfg where to look for the variable
* @param name the variable's name
* @return 0 or an error code
*/
GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name);
+/**
+ * Get the value of a string config variable.
+ *
+ * The value of the config will be copied into the buffer.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out buffer in which to store the string
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_string_buf(git_buf *out, const git_config *cfg, const char *name);
+
/**
* Get each value of a multivar in a foreach callback
*
* The callback will be called on each variable found
*
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
* @param cfg where to look for the variable
* @param name the variable's name
* @param regexp regular expression to filter which variables we're
/**
* Get each value of a multivar
*
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
* @param out pointer to store the iterator
* @param cfg where to look for the variable
* @param name the variable's name
/**
* Set a multivar in the local config file.
*
+ * The regular expression is applied case-sensitively on the value.
+ *
* @param cfg where to look for the variable
* @param name the variable's name
* @param regexp a regular expression to indicate which values to replace
/**
* Deletes one or several entries from a multivar in the local config file.
*
+ * The regular expression is applied case-sensitively on the value.
+ *
* @param cfg where to look for the variables
* @param name the variable's name
* @param regexp a regular expression to indicate which values to delete
* Use `git_config_next` to advance the iteration and
* `git_config_iterator_free` when done.
*
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
* @param out pointer to store the iterator
* @param cfg where to ge the variables from
* @param regexp regular expression to match the names
/**
* Perform an operation on each config variable matching a regular expression.
*
- * This behaviors like `git_config_foreach` with an additional filter of a
+ * This behaves like `git_config_foreach` with an additional filter of a
* regular expression that filters which config keys are passed to the
* callback.
*
- * The pointers passed to the callback are only valid as long as the
- * iteration is ongoing.
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the case-insensitive parts are lower-case.
*
* @param cfg where to get the variables from
* @param regexp regular expression to match against config names
*
* A mapping array looks as follows:
*
- * git_cvar_map autocrlf_mapping[] = {
+ * git_configmap autocrlf_mapping[] = {
* {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
* {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
* {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT},
* @param out place to store the result of the mapping
* @param cfg config file to get the variables from
* @param name name of the config variable to lookup
- * @param maps array of `git_cvar_map` objects specifying the possible mappings
+ * @param maps array of `git_configmap` objects specifying the possible mappings
* @param map_n number of mapping objects in `maps`
* @return 0 on success, error code otherwise
*/
int *out,
const git_config *cfg,
const char *name,
- const git_cvar_map *maps,
+ const git_configmap *maps,
size_t map_n);
/**
* Maps a string value to an integer constant
*
* @param out place to store the result of the parsing
- * @param maps array of `git_cvar_map` objects specifying the possible mappings
+ * @param maps array of `git_configmap` objects specifying the possible mappings
* @param map_n number of mapping objects in `maps`
* @param value value to parse
*/
GIT_EXTERN(int) git_config_lookup_map_value(
int *out,
- const git_cvar_map *maps,
+ const git_configmap *maps,
size_t map_n,
const char *value);
GIT_EXTERN(int) git_config_parse_path(git_buf *out, const char *value);
/**
- * Perform an operation on each config variable in given config backend
+ * Perform an operation on each config variable in a given config backend,
* matching a regular expression.
*
- * This behaviors like `git_config_foreach_match` except instead of all config
- * entries it just enumerates through the given backend entry.
+ * This behaves like `git_config_foreach_match` except that only config
+ * entries from the given backend entry are enumerated.
+ *
+ * The regular expression is applied case-sensitively on the normalized form of
+ * the variable name: the section and variable parts are lower-cased. The
+ * subsection is left unchanged.
*
* @param backend where to get the variables from
* @param regexp regular expression to match against config names (can be NULL)
void *payload);
+/**
+ * Lock the backend with the highest priority
+ *
+ * Locking disallows anybody else from writing to that backend. Any
+ * updates made after locking will not be visible to a reader until
+ * the file is unlocked.
+ *
+ * You can apply the changes by calling `git_transaction_commit()`
+ * before freeing the transaction. Either of these actions will unlock
+ * the config.
+ *
+ * @param tx the resulting transaction, use this to commit or undo the
+ * changes
+ * @param cfg the configuration in which to lock
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_lock(git_transaction **tx, git_config *cfg);
+
/** @} */
GIT_END_DECL
#endif