mirror of
https://github.com/git/git
synced 2024-11-05 04:53:18 +00:00
Merge branch 'ps/config-subcommands'
The operation mode options (like "--get") the "git config" command uses have been deprecated and replaced with subcommands (like "git config get"). * ps/config-subcommands: builtin/config: display subcommand help builtin/config: introduce "edit" subcommand builtin/config: introduce "remove-section" subcommand builtin/config: introduce "rename-section" subcommand builtin/config: introduce "unset" subcommand builtin/config: introduce "set" subcommand builtin/config: introduce "get" subcommand builtin/config: introduce "list" subcommand builtin/config: pull out function to handle `--null` builtin/config: pull out function to handle config location builtin/config: use `OPT_CMDMODE()` to specify modes builtin/config: move "fixed-value" option to correct group builtin/config: move option array around config: clarify memory ownership when preparing comment strings
This commit is contained in:
commit
fe3ccc7aab
6 changed files with 812 additions and 370 deletions
|
@ -9,21 +9,14 @@ git-config - Get and set repository or global options
|
|||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] <name> [<value> [<value-pattern>]]
|
||||
'git config' [<file-option>] [--type=<type>] [--comment=<message>] --add <name> <value>
|
||||
'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] --replace-all <name> <value> [<value-pattern>]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get <name> [<value-pattern>]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get-all <name> [<value-pattern>]
|
||||
'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] [--name-only] --get-regexp <name-regex> [<value-pattern>]
|
||||
'git config' [<file-option>] [--type=<type>] [-z|--null] --get-urlmatch <name> <URL>
|
||||
'git config' [<file-option>] [--fixed-value] --unset <name> [<value-pattern>]
|
||||
'git config' [<file-option>] [--fixed-value] --unset-all <name> [<value-pattern>]
|
||||
'git config' [<file-option>] --rename-section <old-name> <new-name>
|
||||
'git config' [<file-option>] --remove-section <name>
|
||||
'git config' [<file-option>] [--show-origin] [--show-scope] [-z|--null] [--name-only] -l | --list
|
||||
'git config' [<file-option>] --get-color <name> [<default>]
|
||||
'git config list' [<file-option>] [<display-option>] [--includes]
|
||||
'git config get' [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>
|
||||
'git config set' [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>
|
||||
'git config unset' [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>
|
||||
'git config rename-section' [<file-option>] <old-name> <new-name>
|
||||
'git config remove-section' [<file-option>] <name>
|
||||
'git config edit' [<file-option>]
|
||||
'git config' [<file-option>] --get-colorbool <name> [<stdout-is-tty>]
|
||||
'git config' [<file-option>] -e | --edit
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -31,7 +24,7 @@ You can query/set/replace/unset options with this command. The name is
|
|||
actually the section and the key separated by a dot, and the value will be
|
||||
escaped.
|
||||
|
||||
Multiple lines can be added to an option by using the `--add` option.
|
||||
Multiple lines can be added to an option by using the `--append` option.
|
||||
If you want to update or unset an option which can occur on multiple
|
||||
lines, a `value-pattern` (which is an extended regular expression,
|
||||
unless the `--fixed-value` option is given) needs to be given. Only the
|
||||
|
@ -74,6 +67,42 @@ On success, the command returns the exit code 0.
|
|||
A list of all available configuration variables can be obtained using the
|
||||
`git help --config` command.
|
||||
|
||||
COMMANDS
|
||||
--------
|
||||
|
||||
list::
|
||||
List all variables set in config file, along with their values.
|
||||
|
||||
get::
|
||||
Emits the value of the specified key. If key is present multiple times
|
||||
in the configuration, emits the last value. If `--all` is specified,
|
||||
emits all values associated with key. Returns error code 1 if key is
|
||||
not present.
|
||||
|
||||
set::
|
||||
Set value for one or more config options. By default, this command
|
||||
refuses to write multi-valued config options. Passing `--all` will
|
||||
replace all multi-valued config options with the new value, whereas
|
||||
`--value=` will replace all config options whose values match the given
|
||||
pattern.
|
||||
|
||||
unset::
|
||||
Unset value for one or more config options. By default, this command
|
||||
refuses to unset multi-valued keys. Passing `--all` will unset all
|
||||
multi-valued config options, whereas `--value` will unset all config
|
||||
options whose values match the given pattern.
|
||||
|
||||
rename-section::
|
||||
Rename the given section to a new name.
|
||||
|
||||
remove-section::
|
||||
Remove the given section from the configuration file.
|
||||
|
||||
edit::
|
||||
Opens an editor to modify the specified config file; either
|
||||
`--system`, `--global`, `--local` (default), `--worktree`, or
|
||||
`--file <config-file>`.
|
||||
|
||||
[[OPTIONS]]
|
||||
OPTIONS
|
||||
-------
|
||||
|
@ -82,10 +111,9 @@ OPTIONS
|
|||
Default behavior is to replace at most one line. This replaces
|
||||
all lines matching the key (and optionally the `value-pattern`).
|
||||
|
||||
--add::
|
||||
--append::
|
||||
Adds a new line to the option without altering any existing
|
||||
values. This is the same as providing '^$' as the `value-pattern`
|
||||
in `--replace-all`.
|
||||
values. This is the same as providing '--value=^$' in `set`.
|
||||
|
||||
--comment <message>::
|
||||
Append a comment at the end of new or modified lines.
|
||||
|
@ -99,22 +127,16 @@ OPTIONS
|
|||
not contain linefeed characters (no multi-line comments are
|
||||
permitted).
|
||||
|
||||
--get::
|
||||
Get the value for a given key (optionally filtered by a regex
|
||||
matching the value). Returns error code 1 if the key was not
|
||||
found and the last value if multiple key values were found.
|
||||
--all::
|
||||
With `get`, return all values for a multi-valued key.
|
||||
|
||||
--get-all::
|
||||
Like get, but returns all values for a multi-valued key.
|
||||
---regexp::
|
||||
With `get`, interpret the name as a regular expression. Regular
|
||||
expression matching is currently case-sensitive and done against a
|
||||
canonicalized version of the key in which section and variable names
|
||||
are lowercased, but subsection names are not.
|
||||
|
||||
--get-regexp::
|
||||
Like --get-all, but interprets the name as a regular expression and
|
||||
writes out the key names. Regular expression matching is currently
|
||||
case-sensitive and done against a canonicalized version of the key
|
||||
in which section and variable names are lowercased, but subsection
|
||||
names are not.
|
||||
|
||||
--get-urlmatch <name> <URL>::
|
||||
--url=<URL>::
|
||||
When given a two-part <name> as <section>.<key>, the value for
|
||||
<section>.<URL>.<key> whose <URL> part matches the best to the
|
||||
given URL is returned (if no such key exists, the value for
|
||||
|
@ -178,22 +200,6 @@ See also <<FILES>>.
|
|||
section in linkgit:gitrevisions[7] for a more complete list of
|
||||
ways to spell blob names.
|
||||
|
||||
--remove-section::
|
||||
Remove the given section from the configuration file.
|
||||
|
||||
--rename-section::
|
||||
Rename the given section to a new name.
|
||||
|
||||
--unset::
|
||||
Remove the line matching the key from config file.
|
||||
|
||||
--unset-all::
|
||||
Remove all lines matching the key from config file.
|
||||
|
||||
-l::
|
||||
--list::
|
||||
List all variables set in config file, along with their values.
|
||||
|
||||
--fixed-value::
|
||||
When used with the `value-pattern` argument, treat `value-pattern` as
|
||||
an exact string instead of a regular expression. This will restrict
|
||||
|
@ -248,8 +254,8 @@ Valid `<type>`'s include:
|
|||
contain line breaks.
|
||||
|
||||
--name-only::
|
||||
Output only the names of config variables for `--list` or
|
||||
`--get-regexp`.
|
||||
Output only the names of config variables for `list` or
|
||||
`get`.
|
||||
|
||||
--show-origin::
|
||||
Augment the output of all queried config options with the
|
||||
|
@ -273,23 +279,6 @@ Valid `<type>`'s include:
|
|||
When the color setting for `name` is undefined, the command uses
|
||||
`color.ui` as fallback.
|
||||
|
||||
--get-color <name> [<default>]::
|
||||
|
||||
Find the color configured for `name` (e.g. `color.diff.new`) and
|
||||
output it as the ANSI color escape sequence to the standard
|
||||
output. The optional `default` parameter is used instead, if
|
||||
there is no color configured for `name`.
|
||||
+
|
||||
`--type=color [--default=<default>]` is preferred over `--get-color`
|
||||
(but note that `--get-color` will omit the trailing newline printed by
|
||||
`--type=color`).
|
||||
|
||||
-e::
|
||||
--edit::
|
||||
Opens an editor to modify the specified config file; either
|
||||
`--system`, `--global`, `--local` (default), `--worktree`, or
|
||||
`--file <config-file>`.
|
||||
|
||||
--[no-]includes::
|
||||
Respect `include.*` directives in config files when looking up
|
||||
values. Defaults to `off` when a specific file is given (e.g.,
|
||||
|
@ -297,14 +286,64 @@ Valid `<type>`'s include:
|
|||
config files.
|
||||
|
||||
--default <value>::
|
||||
When using `--get`, and the requested variable is not found, behave as if
|
||||
When using `get`, and the requested variable is not found, behave as if
|
||||
<value> were the value assigned to that variable.
|
||||
|
||||
DEPRECATED MODES
|
||||
----------------
|
||||
|
||||
The following modes have been deprecated in favor of subcommands. It is
|
||||
recommended to migrate to the new syntax.
|
||||
|
||||
'git config <name>'::
|
||||
Replaced by `git config get <name>`.
|
||||
|
||||
'git config <name> <value> [<value-pattern>]'::
|
||||
Replaced by `git config set [--value=<pattern>] <name> <value>`.
|
||||
|
||||
-l::
|
||||
--list::
|
||||
Replaced by `git config list`.
|
||||
|
||||
--get <name> [<value-pattern>]::
|
||||
Replaced by `git config get [--value=<pattern>] <name>`.
|
||||
|
||||
--get-all <name> [<value-pattern>]::
|
||||
Replaced by `git config get [--value=<pattern>] --all --show-names <name>`.
|
||||
|
||||
--get-regexp <name-regexp>::
|
||||
Replaced by `git config get --all --show-names --regexp <name-regexp>`.
|
||||
|
||||
--get-urlmatch <name> <URL>::
|
||||
Replaced by `git config get --all --show-names --url=<URL> <name>`.
|
||||
|
||||
--get-color <name> [<default>]::
|
||||
Replaced by `git config get --type=color [--default=<default>] <name>`.
|
||||
|
||||
--add <name> <value>::
|
||||
Replaced by `git config set --append <name> <value>`.
|
||||
|
||||
--unset <name> [<value-pattern>]::
|
||||
Replaced by `git config unset [--value=<pattern>] <name>`.
|
||||
|
||||
--unset-all <name> [<value-pattern>]::
|
||||
Replaced by `git config unset [--value=<pattern>] --all <name>`.
|
||||
|
||||
--rename-section <old-name> <new-name>::
|
||||
Replaced by `git config rename-section <old-name> <new-name>`.
|
||||
|
||||
--remove-section <name>::
|
||||
Replaced by `git config remove-section <name>`.
|
||||
|
||||
-e::
|
||||
--edit::
|
||||
Replaced by `git config edit`.
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
`pager.config` is only respected when listing configuration, i.e., when
|
||||
using `--list` or any of the `--get-*` which may return multiple results.
|
||||
The default is to use a pager.
|
||||
using `list` or `get` which may return multiple results. The default is to use
|
||||
a pager.
|
||||
|
||||
[[FILES]]
|
||||
FILES
|
||||
|
@ -346,8 +385,8 @@ precedence over values read earlier. When multiple values are taken then all
|
|||
values of a key from all files will be used.
|
||||
|
||||
By default, options are only written to the repository specific
|
||||
configuration file. Note that this also affects options like `--replace-all`
|
||||
and `--unset`. *'git config' will only ever change one file at a time*.
|
||||
configuration file. Note that this also affects options like `set`
|
||||
and `unset`. *'git config' will only ever change one file at a time*.
|
||||
|
||||
You can limit which configuration sources are read from or written to by
|
||||
specifying the path of a file with the `--file` option, or by specifying a
|
||||
|
@ -482,7 +521,7 @@ Given a .git/config like this:
|
|||
you can set the filemode to true with
|
||||
|
||||
------------
|
||||
% git config core.filemode true
|
||||
% git config set core.filemode true
|
||||
------------
|
||||
|
||||
The hypothetical proxy command entries actually have a postfix to discern
|
||||
|
@ -490,7 +529,7 @@ what URL they apply to. Here is how to change the entry for kernel.org
|
|||
to "ssh".
|
||||
|
||||
------------
|
||||
% git config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$'
|
||||
% git config set --value='for kernel.org$' core.gitproxy '"ssh" for kernel.org'
|
||||
------------
|
||||
|
||||
This makes sure that only the key/value pair for kernel.org is replaced.
|
||||
|
@ -498,7 +537,7 @@ This makes sure that only the key/value pair for kernel.org is replaced.
|
|||
To delete the entry for renames, do
|
||||
|
||||
------------
|
||||
% git config --unset diff.renames
|
||||
% git config unset diff.renames
|
||||
------------
|
||||
|
||||
If you want to delete an entry for a multivar (like core.gitproxy above),
|
||||
|
@ -507,51 +546,45 @@ you have to provide a regex matching the value of exactly one line.
|
|||
To query the value for a given key, do
|
||||
|
||||
------------
|
||||
% git config --get core.filemode
|
||||
------------
|
||||
|
||||
or
|
||||
|
||||
------------
|
||||
% git config core.filemode
|
||||
% git config get core.filemode
|
||||
------------
|
||||
|
||||
or, to query a multivar:
|
||||
|
||||
------------
|
||||
% git config --get core.gitproxy "for kernel.org$"
|
||||
% git config get --value="for kernel.org$" core.gitproxy
|
||||
------------
|
||||
|
||||
If you want to know all the values for a multivar, do:
|
||||
|
||||
------------
|
||||
% git config --get-all core.gitproxy
|
||||
% git config get --all --show-names core.gitproxy
|
||||
------------
|
||||
|
||||
If you like to live dangerously, you can replace *all* core.gitproxy by a
|
||||
new one with
|
||||
|
||||
------------
|
||||
% git config --replace-all core.gitproxy ssh
|
||||
% git config set --all core.gitproxy ssh
|
||||
------------
|
||||
|
||||
However, if you really only want to replace the line for the default proxy,
|
||||
i.e. the one without a "for ..." postfix, do something like this:
|
||||
|
||||
------------
|
||||
% git config core.gitproxy ssh '! for '
|
||||
% git config set --value='! for ' core.gitproxy ssh
|
||||
------------
|
||||
|
||||
To actually match only values with an exclamation mark, you have to
|
||||
|
||||
------------
|
||||
% git config section.key value '[!]'
|
||||
% git config set --value='[!]' section.key value
|
||||
------------
|
||||
|
||||
To add a new proxy, without altering any of the existing ones, use
|
||||
|
||||
------------
|
||||
% git config --add core.gitproxy '"proxy-command" for example.com'
|
||||
% git config set --append core.gitproxy '"proxy-command" for example.com'
|
||||
------------
|
||||
|
||||
An example to use customized color from the configuration in your
|
||||
|
@ -559,8 +592,8 @@ script:
|
|||
|
||||
------------
|
||||
#!/bin/sh
|
||||
WS=$(git config --get-color color.diff.whitespace "blue reverse")
|
||||
RESET=$(git config --get-color "" "reset")
|
||||
WS=$(git config get --type=color --default="blue reverse" color.diff.whitespace)
|
||||
RESET=$(git config get --type=color --default="reset" "")
|
||||
echo "${WS}your whitespace color or blue reverse${RESET}"
|
||||
------------
|
||||
|
||||
|
@ -568,11 +601,11 @@ For URLs in `https://weak.example.com`, `http.sslVerify` is set to
|
|||
false, while it is set to `true` for all others:
|
||||
|
||||
------------
|
||||
% git config --type=bool --get-urlmatch http.sslverify https://good.example.com
|
||||
% git config get --type=bool --url=https://good.example.com http.sslverify
|
||||
true
|
||||
% git config --type=bool --get-urlmatch http.sslverify https://weak.example.com
|
||||
% git config get --type=bool --url=https://weak.example.com http.sslverify
|
||||
false
|
||||
% git config --get-urlmatch http https://weak.example.com
|
||||
% git config get --url=https://weak.example.com http
|
||||
http.cookieFile /tmp/cookie.txt
|
||||
http.sslverify false
|
||||
------------
|
||||
|
|
512
builtin/config.c
512
builtin/config.c
|
@ -16,7 +16,49 @@
|
|||
#include "worktree.h"
|
||||
|
||||
static const char *const builtin_config_usage[] = {
|
||||
N_("git config [<options>]"),
|
||||
N_("git config list [<file-option>] [<display-option>] [--includes]"),
|
||||
N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>"),
|
||||
N_("git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
|
||||
N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
|
||||
N_("git config rename-section [<file-option>] <old-name> <new-name>"),
|
||||
N_("git config remove-section [<file-option>] <name>"),
|
||||
N_("git config edit [<file-option>]"),
|
||||
N_("git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const builtin_config_list_usage[] = {
|
||||
N_("git config list [<file-option>] [<display-option>] [--includes]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const builtin_config_get_usage[] = {
|
||||
N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] <name>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const builtin_config_set_usage[] = {
|
||||
N_("git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const builtin_config_unset_usage[] = {
|
||||
N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const builtin_config_rename_section_usage[] = {
|
||||
N_("git config rename-section [<file-option>] <old-name> <new-name>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const builtin_config_remove_section_usage[] = {
|
||||
N_("git config remove-section [<file-option>] <name>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const builtin_config_edit_usage[] = {
|
||||
N_("git config edit [<file-option>]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -33,6 +75,7 @@ static char delim = '=';
|
|||
static char key_delim = ' ';
|
||||
static char term = '\n';
|
||||
|
||||
static parse_opt_subcommand_fn *subcommand;
|
||||
static int use_global_config, use_system_config, use_local_config;
|
||||
static int use_worktree_config;
|
||||
static struct git_config_source given_config_source;
|
||||
|
@ -44,7 +87,7 @@ static struct config_options config_options;
|
|||
static int show_origin;
|
||||
static int show_scope;
|
||||
static int fixed_value;
|
||||
static const char *comment;
|
||||
static const char *comment_arg;
|
||||
|
||||
#define ACTION_GET (1<<0)
|
||||
#define ACTION_GET_ALL (1<<1)
|
||||
|
@ -135,54 +178,6 @@ static int option_parse_type(const struct option *opt, const char *arg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct option builtin_config_options[] = {
|
||||
OPT_GROUP(N_("Config file location")),
|
||||
OPT_BOOL(0, "global", &use_global_config, N_("use global config file")),
|
||||
OPT_BOOL(0, "system", &use_system_config, N_("use system config file")),
|
||||
OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")),
|
||||
OPT_BOOL(0, "worktree", &use_worktree_config, N_("use per-worktree config file")),
|
||||
OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")),
|
||||
OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object")),
|
||||
OPT_GROUP(N_("Action")),
|
||||
OPT_BIT(0, "get", &actions, N_("get value: name [value-pattern]"), ACTION_GET),
|
||||
OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-pattern]"), ACTION_GET_ALL),
|
||||
OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-pattern]"), ACTION_GET_REGEXP),
|
||||
OPT_BIT(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH),
|
||||
OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value-pattern]"), ACTION_REPLACE_ALL),
|
||||
OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
|
||||
OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-pattern]"), ACTION_UNSET),
|
||||
OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-pattern]"), ACTION_UNSET_ALL),
|
||||
OPT_BIT(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION),
|
||||
OPT_BIT(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION),
|
||||
OPT_BIT('l', "list", &actions, N_("list all"), ACTION_LIST),
|
||||
OPT_BOOL(0, "fixed-value", &fixed_value, N_("use string equality when comparing values to 'value-pattern'")),
|
||||
OPT_BIT('e', "edit", &actions, N_("open an editor"), ACTION_EDIT),
|
||||
OPT_BIT(0, "get-color", &actions, N_("find the color configured: slot [default]"), ACTION_GET_COLOR),
|
||||
OPT_BIT(0, "get-colorbool", &actions, N_("find the color setting: slot [stdout-is-tty]"), ACTION_GET_COLORBOOL),
|
||||
OPT_GROUP(N_("Type")),
|
||||
OPT_CALLBACK('t', "type", &type, N_("type"), N_("value is given this type"), option_parse_type),
|
||||
OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
|
||||
OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
|
||||
OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
|
||||
OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR),
|
||||
OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
|
||||
OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")),
|
||||
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
|
||||
OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
|
||||
OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
|
||||
OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)")),
|
||||
OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
|
||||
OPT_STRING(0, "comment", &comment, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
static NORETURN void usage_builtin_config(void)
|
||||
{
|
||||
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||
}
|
||||
|
||||
static void check_argc(int argc, int min, int max)
|
||||
{
|
||||
if (argc >= min && argc <= max)
|
||||
|
@ -671,20 +666,8 @@ static char *default_user_config(void)
|
|||
return strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
static void handle_config_location(const char *prefix)
|
||||
{
|
||||
int nongit = !startup_info->have_repository;
|
||||
char *value = NULL;
|
||||
int flags = 0;
|
||||
int ret = 0;
|
||||
struct key_value_info default_kvi = KVI_INIT;
|
||||
|
||||
given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
|
||||
|
||||
argc = parse_options(argc, argv, prefix, builtin_config_options,
|
||||
builtin_config_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
||||
if (use_global_config + use_system_config + use_local_config +
|
||||
use_worktree_config +
|
||||
!!given_config_source.file + !!given_config_source.blob > 1) {
|
||||
|
@ -692,14 +675,13 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
usage_builtin_config();
|
||||
}
|
||||
|
||||
if (nongit) {
|
||||
if (!startup_info->have_repository) {
|
||||
if (use_local_config)
|
||||
die(_("--local can only be used inside a git repository"));
|
||||
if (given_config_source.blob)
|
||||
die(_("--blob can only be used inside a git repository"));
|
||||
if (use_worktree_config)
|
||||
die(_("--worktree can only be used inside a git repository"));
|
||||
|
||||
}
|
||||
|
||||
if (given_config_source.file &&
|
||||
|
@ -753,26 +735,384 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
config_options.respect_includes = !given_config_source.file;
|
||||
else
|
||||
config_options.respect_includes = respect_includes_opt;
|
||||
if (!nongit) {
|
||||
if (startup_info->have_repository) {
|
||||
config_options.commondir = get_git_common_dir();
|
||||
config_options.git_dir = get_git_dir();
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_nul(void) {
|
||||
if (end_nul) {
|
||||
term = '\0';
|
||||
delim = '\n';
|
||||
key_delim = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
#define CONFIG_LOCATION_OPTIONS \
|
||||
OPT_GROUP(N_("Config file location")), \
|
||||
OPT_BOOL(0, "global", &use_global_config, N_("use global config file")), \
|
||||
OPT_BOOL(0, "system", &use_system_config, N_("use system config file")), \
|
||||
OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")), \
|
||||
OPT_BOOL(0, "worktree", &use_worktree_config, N_("use per-worktree config file")), \
|
||||
OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")), \
|
||||
OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object"))
|
||||
|
||||
#define CONFIG_TYPE_OPTIONS \
|
||||
OPT_GROUP(N_("Type")), \
|
||||
OPT_CALLBACK('t', "type", &type, N_("type"), N_("value is given this type"), option_parse_type), \
|
||||
OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL), \
|
||||
OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT), \
|
||||
OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT), \
|
||||
OPT_CALLBACK_VALUE(0, "bool-or-str", &type, N_("value is --bool or string"), TYPE_BOOL_OR_STR), \
|
||||
OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH), \
|
||||
OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE)
|
||||
|
||||
#define CONFIG_DISPLAY_OPTIONS \
|
||||
OPT_GROUP(N_("Display options")), \
|
||||
OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")), \
|
||||
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")), \
|
||||
OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")), \
|
||||
OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)"))
|
||||
|
||||
static struct option builtin_config_options[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
OPT_GROUP(N_("Action")),
|
||||
OPT_CMDMODE(0, "get", &actions, N_("get value: name [<value-pattern>]"), ACTION_GET),
|
||||
OPT_CMDMODE(0, "get-all", &actions, N_("get all values: key [<value-pattern>]"), ACTION_GET_ALL),
|
||||
OPT_CMDMODE(0, "get-regexp", &actions, N_("get values for regexp: name-regex [<value-pattern>]"), ACTION_GET_REGEXP),
|
||||
OPT_CMDMODE(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH),
|
||||
OPT_CMDMODE(0, "replace-all", &actions, N_("replace all matching variables: name value [<value-pattern>]"), ACTION_REPLACE_ALL),
|
||||
OPT_CMDMODE(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
|
||||
OPT_CMDMODE(0, "unset", &actions, N_("remove a variable: name [<value-pattern>]"), ACTION_UNSET),
|
||||
OPT_CMDMODE(0, "unset-all", &actions, N_("remove all matches: name [<value-pattern>]"), ACTION_UNSET_ALL),
|
||||
OPT_CMDMODE(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION),
|
||||
OPT_CMDMODE(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION),
|
||||
OPT_CMDMODE('l', "list", &actions, N_("list all"), ACTION_LIST),
|
||||
OPT_CMDMODE('e', "edit", &actions, N_("open an editor"), ACTION_EDIT),
|
||||
OPT_CMDMODE(0, "get-color", &actions, N_("find the color configured: slot [<default>]"), ACTION_GET_COLOR),
|
||||
OPT_CMDMODE(0, "get-colorbool", &actions, N_("find the color setting: slot [<stdout-is-tty>]"), ACTION_GET_COLORBOOL),
|
||||
CONFIG_TYPE_OPTIONS,
|
||||
CONFIG_DISPLAY_OPTIONS,
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
|
||||
OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
|
||||
OPT_BOOL(0, "fixed-value", &fixed_value, N_("use string equality when comparing values to 'value-pattern'")),
|
||||
OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
static NORETURN void usage_builtin_config(void)
|
||||
{
|
||||
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||
}
|
||||
|
||||
static int cmd_config_list(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct option opts[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
CONFIG_DISPLAY_OPTIONS,
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
argc = parse_options(argc, argv, prefix, opts, builtin_config_list_usage, 0);
|
||||
check_argc(argc, 0, 0);
|
||||
|
||||
handle_config_location(prefix);
|
||||
handle_nul();
|
||||
|
||||
setup_auto_pager("config", 1);
|
||||
|
||||
if (config_with_options(show_all_config, NULL,
|
||||
&given_config_source, the_repository,
|
||||
&config_options) < 0) {
|
||||
if (given_config_source.file)
|
||||
die_errno(_("unable to read config file '%s'"),
|
||||
given_config_source.file);
|
||||
else
|
||||
die(_("error processing config file(s)"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_config_get(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
const char *value_pattern = NULL, *url = NULL;
|
||||
int flags = 0;
|
||||
struct option opts[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
CONFIG_TYPE_OPTIONS,
|
||||
OPT_GROUP(N_("Filter options")),
|
||||
OPT_BOOL(0, "all", &do_all, N_("return all values for multi-valued config options")),
|
||||
OPT_BOOL(0, "regexp", &use_key_regexp, N_("interpret the name as a regular expression")),
|
||||
OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
|
||||
OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
|
||||
OPT_STRING(0, "url", &url, N_("URL"), N_("show config matching the given URL")),
|
||||
CONFIG_DISPLAY_OPTIONS,
|
||||
OPT_BOOL(0, "show-names", &show_keys, N_("show config keys in addition to their values")),
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
|
||||
OPT_STRING(0, "default", &default_value, N_("value"), N_("use default value when missing entry")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
argc = parse_options(argc, argv, prefix, opts, builtin_config_get_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
check_argc(argc, 1, 1);
|
||||
|
||||
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
|
||||
die(_("--fixed-value only applies with 'value-pattern'"));
|
||||
if (default_value && (do_all || url))
|
||||
die(_("--default= cannot be used with --all or --url="));
|
||||
if (url && (do_all || use_key_regexp || value_pattern))
|
||||
die(_("--url= cannot be used with --all, --regexp or --value"));
|
||||
|
||||
handle_config_location(prefix);
|
||||
handle_nul();
|
||||
|
||||
setup_auto_pager("config", 1);
|
||||
|
||||
if (url)
|
||||
return get_urlmatch(argv[0], url);
|
||||
return get_value(argv[0], value_pattern, flags);
|
||||
}
|
||||
|
||||
static int cmd_config_set(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
const char *value_pattern = NULL, *comment_arg = NULL;
|
||||
char *comment = NULL;
|
||||
int flags = 0, append = 0;
|
||||
struct option opts[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
CONFIG_TYPE_OPTIONS,
|
||||
OPT_GROUP(N_("Filter")),
|
||||
OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE),
|
||||
OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
|
||||
OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
|
||||
OPT_BOOL(0, "append", &append, N_("add a new line without altering any existing values")),
|
||||
OPT_END(),
|
||||
};
|
||||
struct key_value_info default_kvi = KVI_INIT;
|
||||
char *value;
|
||||
int ret;
|
||||
|
||||
argc = parse_options(argc, argv, prefix, opts, builtin_config_set_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
check_write();
|
||||
check_argc(argc, 2, 2);
|
||||
|
||||
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
|
||||
die(_("--fixed-value only applies with --value=<pattern>"));
|
||||
if (append && value_pattern)
|
||||
die(_("--append cannot be used with --value=<pattern>"));
|
||||
if (append)
|
||||
value_pattern = CONFIG_REGEX_NONE;
|
||||
|
||||
comment = git_config_prepare_comment_string(comment_arg);
|
||||
|
||||
handle_config_location(prefix);
|
||||
|
||||
value = normalize_value(argv[0], argv[1], &default_kvi);
|
||||
|
||||
if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) {
|
||||
ret = git_config_set_multivar_in_file_gently(given_config_source.file,
|
||||
argv[0], value, value_pattern,
|
||||
comment, flags);
|
||||
} else {
|
||||
ret = git_config_set_in_file_gently(given_config_source.file,
|
||||
argv[0], comment, value);
|
||||
if (ret == CONFIG_NOTHING_SET)
|
||||
error(_("cannot overwrite multiple values with a single value\n"
|
||||
" Use a regexp, --add or --replace-all to change %s."), argv[0]);
|
||||
}
|
||||
|
||||
free(comment);
|
||||
free(value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cmd_config_unset(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
const char *value_pattern = NULL;
|
||||
int flags = 0;
|
||||
struct option opts[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
OPT_GROUP(N_("Filter")),
|
||||
OPT_BIT(0, "all", &flags, N_("replace multi-valued config option with new value"), CONFIG_FLAGS_MULTI_REPLACE),
|
||||
OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
|
||||
OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
argc = parse_options(argc, argv, prefix, opts, builtin_config_unset_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
check_write();
|
||||
check_argc(argc, 1, 1);
|
||||
|
||||
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
|
||||
die(_("--fixed-value only applies with 'value-pattern'"));
|
||||
|
||||
handle_config_location(prefix);
|
||||
|
||||
if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern)
|
||||
return git_config_set_multivar_in_file_gently(given_config_source.file,
|
||||
argv[0], NULL, value_pattern,
|
||||
NULL, flags);
|
||||
else
|
||||
return git_config_set_in_file_gently(given_config_source.file, argv[0],
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static int cmd_config_rename_section(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct option opts[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
OPT_END(),
|
||||
};
|
||||
int ret;
|
||||
|
||||
argc = parse_options(argc, argv, prefix, opts, builtin_config_rename_section_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
check_write();
|
||||
check_argc(argc, 2, 2);
|
||||
|
||||
handle_config_location(prefix);
|
||||
|
||||
ret = git_config_rename_section_in_file(given_config_source.file,
|
||||
argv[0], argv[1]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (!ret)
|
||||
die(_("no such section: %s"), argv[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_config_remove_section(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct option opts[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
OPT_END(),
|
||||
};
|
||||
int ret;
|
||||
|
||||
argc = parse_options(argc, argv, prefix, opts, builtin_config_remove_section_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
check_write();
|
||||
check_argc(argc, 1, 1);
|
||||
|
||||
handle_config_location(prefix);
|
||||
|
||||
ret = git_config_rename_section_in_file(given_config_source.file,
|
||||
argv[0], NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (!ret)
|
||||
die(_("no such section: %s"), argv[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_editor(void)
|
||||
{
|
||||
char *config_file;
|
||||
|
||||
if (!given_config_source.file && !startup_info->have_repository)
|
||||
die(_("not in a git directory"));
|
||||
if (given_config_source.use_stdin)
|
||||
die(_("editing stdin is not supported"));
|
||||
if (given_config_source.blob)
|
||||
die(_("editing blobs is not supported"));
|
||||
git_config(git_default_config, NULL);
|
||||
config_file = given_config_source.file ?
|
||||
xstrdup(given_config_source.file) :
|
||||
git_pathdup("config");
|
||||
if (use_global_config) {
|
||||
int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
|
||||
if (fd >= 0) {
|
||||
char *content = default_user_config();
|
||||
write_str_in_full(fd, content);
|
||||
free(content);
|
||||
close(fd);
|
||||
}
|
||||
else if (errno != EEXIST)
|
||||
die_errno(_("cannot create configuration file %s"), config_file);
|
||||
}
|
||||
launch_editor(config_file, NULL, NULL);
|
||||
free(config_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_config_edit(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct option opts[] = {
|
||||
CONFIG_LOCATION_OPTIONS,
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
argc = parse_options(argc, argv, prefix, opts, builtin_config_edit_usage, 0);
|
||||
check_write();
|
||||
check_argc(argc, 0, 0);
|
||||
|
||||
handle_config_location(prefix);
|
||||
|
||||
return show_editor();
|
||||
}
|
||||
|
||||
static struct option builtin_subcommand_options[] = {
|
||||
OPT_SUBCOMMAND("list", &subcommand, cmd_config_list),
|
||||
OPT_SUBCOMMAND("get", &subcommand, cmd_config_get),
|
||||
OPT_SUBCOMMAND("set", &subcommand, cmd_config_set),
|
||||
OPT_SUBCOMMAND("unset", &subcommand, cmd_config_unset),
|
||||
OPT_SUBCOMMAND("rename-section", &subcommand, cmd_config_rename_section),
|
||||
OPT_SUBCOMMAND("remove-section", &subcommand, cmd_config_remove_section),
|
||||
OPT_SUBCOMMAND("edit", &subcommand, cmd_config_edit),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
char *value = NULL, *comment = NULL;
|
||||
int flags = 0;
|
||||
int ret = 0;
|
||||
struct key_value_info default_kvi = KVI_INIT;
|
||||
|
||||
given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
|
||||
|
||||
/*
|
||||
* This is somewhat hacky: we first parse the command line while
|
||||
* keeping all args intact in order to determine whether a subcommand
|
||||
* has been specified. If so, we re-parse it a second time, but this
|
||||
* time we drop KEEP_ARGV0. This is so that we don't munge the command
|
||||
* line in case no subcommand was given, which would otherwise confuse
|
||||
* us when parsing the legacy-style modes that don't use subcommands.
|
||||
*/
|
||||
argc = parse_options(argc, argv, prefix, builtin_subcommand_options, builtin_config_usage,
|
||||
PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_ARGV0|PARSE_OPT_KEEP_UNKNOWN_OPT);
|
||||
if (subcommand) {
|
||||
argc = parse_options(argc, argv, prefix, builtin_subcommand_options, builtin_config_usage,
|
||||
PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_UNKNOWN_OPT);
|
||||
return subcommand(argc, argv, prefix);
|
||||
}
|
||||
|
||||
argc = parse_options(argc, argv, prefix, builtin_config_options,
|
||||
builtin_config_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
||||
handle_config_location(prefix);
|
||||
handle_nul();
|
||||
|
||||
if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && type) {
|
||||
error(_("--get-color and variable type are incoherent"));
|
||||
usage_builtin_config();
|
||||
}
|
||||
|
||||
if (HAS_MULTI_BITS(actions)) {
|
||||
error(_("only one action at a time"));
|
||||
usage_builtin_config();
|
||||
}
|
||||
if (actions == 0)
|
||||
switch (argc) {
|
||||
case 1: actions = ACTION_GET; break;
|
||||
|
@ -799,7 +1139,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
usage_builtin_config();
|
||||
}
|
||||
|
||||
if (comment &&
|
||||
if (comment_arg &&
|
||||
!(actions & (ACTION_ADD|ACTION_SET|ACTION_SET_ALL|ACTION_REPLACE_ALL))) {
|
||||
error(_("--comment is only applicable to add/set/replace operations"));
|
||||
usage_builtin_config();
|
||||
|
@ -841,7 +1181,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
flags |= CONFIG_FLAGS_FIXED_VALUE;
|
||||
}
|
||||
|
||||
comment = git_config_prepare_comment_string(comment);
|
||||
comment = git_config_prepare_comment_string(comment_arg);
|
||||
|
||||
if (actions & PAGING_ACTIONS)
|
||||
setup_auto_pager("config", 1);
|
||||
|
@ -859,32 +1199,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
}
|
||||
else if (actions == ACTION_EDIT) {
|
||||
char *config_file;
|
||||
|
||||
check_argc(argc, 0, 0);
|
||||
if (!given_config_source.file && nongit)
|
||||
die(_("not in a git directory"));
|
||||
if (given_config_source.use_stdin)
|
||||
die(_("editing stdin is not supported"));
|
||||
if (given_config_source.blob)
|
||||
die(_("editing blobs is not supported"));
|
||||
git_config(git_default_config, NULL);
|
||||
config_file = given_config_source.file ?
|
||||
xstrdup(given_config_source.file) :
|
||||
git_pathdup("config");
|
||||
if (use_global_config) {
|
||||
int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
|
||||
if (fd >= 0) {
|
||||
char *content = default_user_config();
|
||||
write_str_in_full(fd, content);
|
||||
free(content);
|
||||
close(fd);
|
||||
}
|
||||
else if (errno != EEXIST)
|
||||
die_errno(_("cannot create configuration file %s"), config_file);
|
||||
}
|
||||
launch_editor(config_file, NULL, NULL);
|
||||
free(config_file);
|
||||
ret = show_editor();
|
||||
}
|
||||
else if (actions == ACTION_SET) {
|
||||
check_write();
|
||||
|
@ -993,6 +1308,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
return get_colorbool(argv[0], argc == 2);
|
||||
}
|
||||
|
||||
free(comment);
|
||||
free(value);
|
||||
return ret;
|
||||
}
|
||||
|
|
16
config.c
16
config.c
|
@ -3193,14 +3193,10 @@ void git_config_set(const char *key, const char *value)
|
|||
trace2_cmd_set_config(key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* The ownership rule is that the caller will own the string
|
||||
* if it receives a piece of memory different from what it passed
|
||||
* as the parameter.
|
||||
*/
|
||||
const char *git_config_prepare_comment_string(const char *comment)
|
||||
char *git_config_prepare_comment_string(const char *comment)
|
||||
{
|
||||
size_t leading_blanks;
|
||||
char *prepared;
|
||||
|
||||
if (!comment)
|
||||
return NULL;
|
||||
|
@ -3221,13 +3217,13 @@ const char *git_config_prepare_comment_string(const char *comment)
|
|||
|
||||
leading_blanks = strspn(comment, " \t");
|
||||
if (leading_blanks && comment[leading_blanks] == '#')
|
||||
; /* use it as-is */
|
||||
prepared = xstrdup(comment); /* use it as-is */
|
||||
else if (comment[0] == '#')
|
||||
comment = xstrfmt(" %s", comment);
|
||||
prepared = xstrfmt(" %s", comment);
|
||||
else
|
||||
comment = xstrfmt(" # %s", comment);
|
||||
prepared = xstrfmt(" # %s", comment);
|
||||
|
||||
return comment;
|
||||
return prepared;
|
||||
}
|
||||
|
||||
static void validate_comment_string(const char *comment)
|
||||
|
|
2
config.h
2
config.h
|
@ -338,7 +338,7 @@ void git_config_set_multivar(const char *, const char *, const char *, unsigned)
|
|||
int repo_config_set_multivar_gently(struct repository *, const char *, const char *, const char *, unsigned);
|
||||
int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, const char *, unsigned);
|
||||
|
||||
const char *git_config_prepare_comment_string(const char *);
|
||||
char *git_config_prepare_comment_string(const char *);
|
||||
|
||||
/**
|
||||
* takes four parameters:
|
||||
|
|
|
@ -10,7 +10,6 @@ checkout
|
|||
checkout-index
|
||||
clone
|
||||
column
|
||||
config
|
||||
credential
|
||||
credential-cache
|
||||
credential-store
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue