From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: Junio C Hamano <junkio@cox.net>
Cc: git@vger.kernel.org
Subject: [PATCH] git-config-set: support selecting values by non-matching regex
Date: Sun, 20 Nov 2005 13:24:18 +0100 (CET) [thread overview]
Message-ID: <Pine.LNX.4.63.0511201320340.4838@wbgn013.biozentrum.uni-wuerzburg.de> (raw)
In-Reply-To: <7vr79b3i7e.fsf@assigned-by-dhcp.cox.net>
Extend the regex syntax of value_regex so that prepending an exclamation
mark means non-match:
[core]
quetzal = "Dodo" for Brainf*ck
quetzal = "T. Rex" for Malbolge
quetzal = "cat"
You can match the third line with
git-config-set --get quetzal '! for '
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
On Sat, 19 Nov 2005, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > The only thing I am concerned about now is how to deal with
> > anti value_regex's, i.e.
> >...
> > Note: we could adjust the pattern syntax so that a prefix "!"
> > means "no match", and "\!" means "match literal !", but this
> > is ugly.
>
> I do not think it is so bad, except that I would not even bother
> doing the quoting of prefix '!'; the user can always say '[!]'
> to mean a positive match that begins with an exclamation point.
The patch is a little bit bigger, because I included also the
documentation update and test cases proving that it works.
Also, the matching part got minimally refactored in config.c.
Documentation/git-config-set.txt | 18 +++++++++++++++++-
config-set.c | 9 ++++++++-
config.c | 23 +++++++++++++++++------
t/t1300-config-set.sh | 28 ++++++++++++++++++++++++++++
4 files changed, 70 insertions(+), 8 deletions(-)
applies-to: 648bd602281a789b2dbcecedeae32321bb09ccbf
e2e9f798d6aa02ca54193f0c84d916d0e1a1d29b
diff --git a/Documentation/git-config-set.txt b/Documentation/git-config-set.txt
index c707fbc..bfbd421 100644
--- a/Documentation/git-config-set.txt
+++ b/Documentation/git-config-set.txt
@@ -22,7 +22,9 @@ actually the section and the key separat
escaped.
If you want to set/unset an option which can occor on multiple lines, you
-should provide a POSIX regex for the value.
+should provide a POSIX regex for the value. If you want to handle the lines
+*not* matching the regex, just prepend a single exlamation mark in front
+(see EXAMPLES).
This command will fail if
@@ -82,6 +84,7 @@ Given a .git/config like this:
command="ssh" for "ssh://kernel.org/"
command="proxy-command" for kernel.org
command="myprotocol-command" for "my://"
+ command=default-proxy ; for all the rest
you can set the filemode to true with
@@ -139,6 +142,19 @@ new one with
% git config-set --replace-all proxy.command 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-set proxy.command ssh '! for '
+------------
+
+To actually match only values with an exclamation mark, you have to
+
+------------
+% git config-set section.key value '[!]'
+------------
+
Author
------
diff --git a/config-set.c b/config-set.c
index 90a28b3..5f654f7 100644
--- a/config-set.c
+++ b/config-set.c
@@ -8,13 +8,15 @@ static char* key = NULL;
static char* value = NULL;
static regex_t* regex = NULL;
static int do_all = 0;
+static int do_not_match = 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))) {
+ (do_not_match ^
+ !regexec(regex, value_, 0, NULL, 0)))) {
if (do_all) {
printf("%s\n", value_);
return 0;
@@ -38,6 +40,11 @@ static int get_value(const char* key_, c
key[i] = tolower(key_[i]);
if (regex_) {
+ if (regex_[0] == '!') {
+ do_not_match = 1;
+ regex_++;
+ }
+
regex = (regex_t*)malloc(sizeof(regex_t));
if (regcomp(regex, regex_, REG_EXTENDED)) {
fprintf(stderr, "Invalid pattern: %s\n", regex_);
diff --git a/config.c b/config.c
index 697d79f..5d237c8 100644
--- a/config.c
+++ b/config.c
@@ -269,6 +269,7 @@ int git_config(config_fn_t fn)
static struct {
int baselen;
char* key;
+ int do_not_match;
regex_t* value_regex;
int multi_replace;
off_t offset[MAX_MATCHES];
@@ -276,13 +277,19 @@ static struct {
int seen;
} store;
+static int matches(const char* key, const char* value)
+{
+ return !strcmp(key, store.key) &&
+ (store.value_regex == NULL ||
+ (store.do_not_match ^
+ !regexec(store.value_regex, value, 0, NULL, 0)));
+}
+
static int store_aux(const char* key, const char* value)
{
switch (store.state) {
case KEY_SEEN:
- if (!strcmp(key, store.key) &&
- (store.value_regex == NULL ||
- !regexec(store.value_regex, value, 0, NULL, 0))) {
+ if (matches(key, value)) {
if (store.seen == 1 && store.multi_replace == 0) {
fprintf(stderr,
"Warning: %s has multiple values\n",
@@ -306,9 +313,7 @@ static int store_aux(const char* key, co
/* fallthru */
case SECTION_END_SEEN:
case START:
- if (!strcmp(key, store.key) &&
- (store.value_regex == NULL ||
- !regexec(store.value_regex, value, 0, NULL, 0))) {
+ if (matches(key, value)) {
store.offset[store.seen] = ftell(config_file);
store.state = KEY_SEEN;
store.seen++;
@@ -471,6 +476,12 @@ int git_config_set_multivar(const char*
if (value_regex == NULL)
store.value_regex = NULL;
else {
+ if (value_regex[0] == '!') {
+ store.do_not_match = 1;
+ value_regex++;
+ } else
+ store.do_not_match = 0;
+
store.value_regex = (regex_t*)malloc(sizeof(regex_t));
if (regcomp(store.value_regex, value_regex,
REG_EXTENDED)) {
diff --git a/t/t1300-config-set.sh b/t/t1300-config-set.sh
index 717bf4d..59b6c4c 100644
--- a/t/t1300-config-set.sh
+++ b/t/t1300-config-set.sh
@@ -69,6 +69,28 @@ EOF
test_expect_success 'similar section' 'cmp .git/config expect'
+test_expect_success 'replace with non-match' \
+ 'git-config-set core.penguin kingpin !blue'
+
+test_expect_success 'replace with non-match (actually matching)' \
+ 'git-config-set core.penguin "very blue" !kingpin'
+
+cat > expect << EOF
+#
+# This is the config file
+#
+
+[core]
+ penguin = very blue
+ Movie = BadPhysics
+ UPPERCASE = true
+ penguin = kingpin
+[Cores]
+ WhatEver = Second
+EOF
+
+test_expect_success 'non-match result' 'cmp .git/config expect'
+
cat > .git/config << EOF
[beta] ; silly comment # another comment
noIndent= sillyValue ; 'nother silly comment
@@ -173,6 +195,12 @@ EOF
test_expect_success 'multivar' 'cmp .git/config expect'
+test_expect_success 'non-match' \
+ 'git-config-set --get nextsection.nonewline !for'
+
+test_expect_success 'non-match value' \
+ 'test wow = $(git-config-set --get nextsection.nonewline !for)'
+
test_expect_failure 'ambiguous get' \
'git-config-set --get nextsection.nonewline'
---
0.99.9.GIT
prev parent reply other threads:[~2005-11-20 12:24 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-20 5:52 [PATCH] git-config-set: add more options Johannes Schindelin
2005-11-20 7:13 ` Junio C Hamano
2005-11-20 12:24 ` Johannes Schindelin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.63.0511201320340.4838@wbgn013.biozentrum.uni-wuerzburg.de \
--to=johannes.schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).