git-config: document --rename-section, provide --remove-section
authorPaolo Bonzini <bonzini@gnu.org>
Fri, 2 Mar 2007 20:53:33 +0000 (21:53 +0100)
committerJunio C Hamano <junkio@cox.net>
Sun, 4 Mar 2007 03:59:37 +0000 (19:59 -0800)
This patch documents the previously undocumented option --rename-section
and adds a new option to zap an entire section.

Signed-off-by: Paolo Bonzini <bonzini@gnu.org>
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Documentation/git-config.txt
builtin-config.c
config.c
t/t1300-repo-config.sh
index 6624484fe1b0e50f8d32ad474da6455cf737e43a..68de5881bd36aabd1b4b13c2bce48a226c34788e 100644 (file)
@@ -16,6 +16,8 @@ SYNOPSIS
 'git-config' [--global] [type] --get-all name [value_regex]
 'git-config' [--global] [type] --unset name [value_regex]
 'git-config' [--global] [type] --unset-all name [value_regex]
+'git-config' [--global] [type] --rename-section old_name new_name
+'git-config' [--global] [type] --remove-section name
 'git-config' [--global] -l | --list
 
 DESCRIPTION
@@ -74,6 +76,12 @@ OPTIONS
 --global::
        Use global ~/.gitconfig file rather than the repository .git/config.
 
+--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.
 
index f1433a4ab6ffaa6fe29fe6be9d97f02a4c4d6e87..dfa403b94baea97c655ab707d75e80f58f318c51 100644 (file)
@@ -2,7 +2,7 @@
 #include "cache.h"
 
 static const char git_config_set_usage[] =
-"git-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --list";
+"git-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
 
 static char *key;
 static regex_t *key_regexp;
@@ -168,6 +168,19 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                        }
                        return 0;
                }
+               else if (!strcmp(argv[1], "--remove-section")) {
+                       int ret;
+                       if (argc != 3)
+                               usage(git_config_set_usage);
+                       ret = git_config_rename_section(argv[2], NULL);
+                       if (ret < 0)
+                               return ret;
+                       if (ret == 0) {
+                               fprintf(stderr, "No such section!\n");
+                               return 1;
+                       }
+                       return 0;
+               }
                else
                        break;
                argc--;
index 0ff413b804afc1ec042ed5190ae4f9055a17ea87..5611d7a6a63885b8be20f7f638185f8f92fa745f 100644 (file)
--- a/config.c
+++ b/config.c
@@ -854,9 +854,37 @@ int git_config_set_multivar(const char* key, const char* value,
 
 }
 
+static int section_name_match (const char *buf, const char *name)
+{
+       int i = 0, j = 0, dot = 0;
+       for (; buf[i] && buf[i] != ']'; i++) {
+               if (!dot && isspace(buf[i])) {
+                       dot = 1;
+                       if (name[j++] != '.')
+                               break;
+                       for (i++; isspace(buf[i]); i++)
+                               ; /* do nothing */
+                       if (buf[i] != '"')
+                               break;
+                       continue;
+               }
+               if (buf[i] == '\\' && dot)
+                       i++;
+               else if (buf[i] == '"' && dot) {
+                       for (i++; isspace(buf[i]); i++)
+                               ; /* do_nothing */
+                       break;
+               }
+               if (buf[i] != name[j++])
+                       break;
+       }
+       return (buf[i] == ']' && name[j] == 0);
+}
+
+/* if new_name == NULL, the section is removed instead */
 int git_config_rename_section(const char *old_name, const char *new_name)
 {
-       int ret = 0;
+       int ret = 0, remove = 0;
        char *config_filename;
        struct lock_file *lock = xcalloc(sizeof(struct lock_file), 1);
        int out_fd;
@@ -887,31 +915,12 @@ int git_config_rename_section(const char *old_name, const char *new_name)
                        ; /* do nothing */
                if (buf[i] == '[') {
                        /* it's a section */
-                       int j = 0, dot = 0;
-                       for (i++; buf[i] && buf[i] != ']'; i++) {
-                               if (!dot && isspace(buf[i])) {
-                                       dot = 1;
-                                       if (old_name[j++] != '.')
-                                               break;
-                                       for (i++; isspace(buf[i]); i++)
-                                               ; /* do nothing */
-                                       if (buf[i] != '"')
-                                               break;
+                       if (section_name_match (&buf[i+1], old_name)) {
+                               ret++;
+                               if (new_name == NULL) {
+                                       remove = 1;
                                        continue;
                                }
-                               if (buf[i] == '\\' && dot)
-                                       i++;
-                               else if (buf[i] == '"' && dot) {
-                                       for (i++; isspace(buf[i]); i++)
-                                               ; /* do_nothing */
-                                       break;
-                               }
-                               if (buf[i] != old_name[j++])
-                                       break;
-                       }
-                       if (buf[i] == ']' && old_name[j] == 0) {
-                               /* old_name matches */
-                               ret++;
                                store.baselen = strlen(new_name);
                                if (!store_write_section(out_fd, new_name)) {
                                        ret = write_error();
@@ -919,7 +928,10 @@ int git_config_rename_section(const char *old_name, const char *new_name)
                                }
                                continue;
                        }
+                       remove = 0;
                }
+               if (remove)
+                       continue;
                length = strlen(buf);
                if (write_in_full(out_fd, buf, length) != length) {
                        ret = write_error();
index 49b5666b33283feaf8ea2b7c09faeab8016c746d..ee386cfbf3be4d457644103b223e1fcafaa363ba 100755 (executable)
@@ -391,6 +391,22 @@ EOF
 
 test_expect_success "rename succeeded" "diff -u expect .git/config"
 
+cat >> .git/config << EOF
+  [branch "zwei"] a = 1 [branch "vier"]
+EOF
+
+test_expect_success "remove section" "git config --remove-section branch.zwei"
+
+cat > expect << EOF
+# Hallo
+       #Bello
+[branch "drei"]
+weird
+EOF
+
+test_expect_success "section was removed properly" \
+       "diff -u expect .git/config"
+
 test_expect_success numbers '
 
        git-config kilo.gram 1k &&