Skip to content

Commit

Permalink
git-config-set: add more options
Browse files Browse the repository at this point in the history
... namely

--replace-all, to replace any amount of matching lines, not just 0 or 1,
--get, to get the value of one key,
--get-all, the multivar version of --get, and
--unset-all, which deletes all matching lines from .git/config

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Johannes Schindelin authored and Junio C Hamano committed Nov 20, 2005
1 parent 7b5d895 commit 4ddba79
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 61 deletions.
62 changes: 54 additions & 8 deletions Documentation/git-config-set.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ git-config-set - Set options in .git/config.

SYNOPSIS
--------
'git-config-set' ( name [value [value_regex]] | --unset name [value_regex] )
'git-config-set' name [value [value_regex]]
'git-config-set' --replace-all name [value [value_regex]]
'git-config-set' --get name [value_regex]
'git-config-set' --get-all name [value_regex]
'git-config-set' --unset name [value_regex]
'git-config-set' --unset-all name [value_regex]

DESCRIPTION
-----------
You can 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.
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.

If you want to set/unset an option which can occor on multiple lines, you
should provide a POSIX regex for the value.
Expand All @@ -31,8 +37,23 @@ This command will fail if
OPTIONS
-------

--replace-all::
Default behaviour is to replace at most one line. This replaces
all lines matching the key (and optionally the value_regex)

--get::
Get the value for a given key (optionally filtered by a regex
matching the value).

--get-all::
Like get, but does not fail if the number of values for the key
is not exactly one.

--unset::
Remove the given option from .git/config
Remove the line matching the key from .git/config.

--unset-all::
Remove all matching lines from .git/config.


EXAMPLE
Expand Down Expand Up @@ -84,14 +105,39 @@ To delete the entry for renames, do
% git config-set --unset diff.renames
------------

or just
If you want to delete an entry for a multivar (like proxy.command above),
you have to provide a regex matching the value of exactly one line.

To query the value for a given key, do

------------
% git config-set diff.renames
% git config-set --get core.filemode
------------

If you want to delete an entry for a multivar (like proxy.command above),
you have to provide a regex matching the value of exactly one line.
or

------------
% git config-set core.filemode
------------

or, to query a multivar:

------------
% git config-set --get proxy.command "for kernel.org$"
------------

If you want to know all the values for a multivar, do:

------------
% git config-set --get-all proxy.command
------------

If you like to live dangerous, you can replace *all* proxy.commands by a
new one with

------------
% git config-set --replace-all proxy.command ssh
------------


Author
Expand Down
3 changes: 1 addition & 2 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ extern int diff_rename_limit_default;

/* Return a statically allocated filename matching the sha1 signature */
extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern char *enter_repo(char *path, int strict);
extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern char *sha1_file_name(const unsigned char *sha1);
extern char *sha1_pack_name(const unsigned char *sha1);
Expand Down Expand Up @@ -388,7 +387,7 @@ extern int git_config(config_fn_t fn);
extern int git_config_int(const char *, const char *);
extern int git_config_bool(const char *, const char *);
extern int git_config_set(const char *, const char *);
extern int git_config_set_multivar(const char *, const char *, const char *);
extern int git_config_set_multivar(const char *, const char *, const char *, int);

#define MAX_GITNAME (1000)
extern char git_default_email[MAX_GITNAME];
Expand Down
92 changes: 87 additions & 5 deletions config-set.c
Original file line number Diff line number Diff line change
@@ -1,24 +1,106 @@
#include "cache.h"
#include <regex.h>

static const char git_config_set_usage[] =
"git-config-set name [value [value_regex]] | --unset name [value_regex]";
"git-config-set [--get | --get-all | --replace-all | --unset | --unset-all] name [value [value_regex]]";

static char* key = NULL;
static char* value = NULL;
static regex_t* regex = NULL;
static int do_all = 0;
static int seen = 0;

static int show_config(const char* key_, const char* value_)
{
if (!strcmp(key_, key) &&
(regex == NULL ||
!regexec(regex, value_, 0, NULL, 0))) {
if (do_all) {
printf("%s\n", value_);
return 0;
}
if (seen > 0) {
fprintf(stderr, "More than one value: %s\n", value);
free(value);
}
value = strdup(value_);
seen++;
}
return 0;
}

static int get_value(const char* key_, const char* regex_)
{
int i;

key = malloc(strlen(key_)+1);
for (i = 0; key_[i]; i++)
key[i] = tolower(key_[i]);

if (regex_) {
regex = (regex_t*)malloc(sizeof(regex_t));
if (regcomp(regex, regex_, REG_EXTENDED)) {
fprintf(stderr, "Invalid pattern: %s\n", regex_);
return -1;
}
}

i = git_config(show_config);
if (value) {
printf("%s\n", value);
free(value);
}
free(key);
if (regex) {
regfree(regex);
free(regex);
}

if (do_all)
return 0;

return seen == 1 ? 0 : 1;
}

int main(int argc, const char **argv)
{
setup_git_directory();
switch (argc) {
case 2:
return git_config_set(argv[1], NULL);
return get_value(argv[1], NULL);
case 3:
if (!strcmp(argv[1], "--unset"))
return git_config_set(argv[2], NULL);
else
else if (!strcmp(argv[1], "--unset-all"))
return git_config_set_multivar(argv[2], NULL, NULL, 1);
else if (!strcmp(argv[1], "--get"))
return get_value(argv[2], NULL);
else if (!strcmp(argv[1], "--get-all")) {
do_all = 1;
return get_value(argv[2], NULL);
} else

return git_config_set(argv[1], argv[2]);
case 4:
if (!strcmp(argv[1], "--unset"))
return git_config_set_multivar(argv[2], NULL, argv[3]);
return git_config_set_multivar(argv[2], NULL, argv[3], 0);
else if (!strcmp(argv[1], "--unset-all"))
return git_config_set_multivar(argv[2], NULL, argv[3], 1);
else if (!strcmp(argv[1], "--get"))
return get_value(argv[2], argv[3]);
else if (!strcmp(argv[1], "--get-all")) {
do_all = 1;
return get_value(argv[2], argv[3]);
} else if (!strcmp(argv[1], "--replace-all"))

return git_config_set_multivar(argv[2], argv[3], NULL, 1);
else
return git_config_set_multivar(argv[1], argv[2], argv[3]);

return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
case 5:
if (!strcmp(argv[1], "--replace-all"))
return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
case 1:
default:
usage(git_config_set_usage);
}
Expand Down
Loading

0 comments on commit 4ddba79

Please sign in to comment.