aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>2006-12-16 15:14:14 +0100
committerJunio C Hamano <junkio@cox.net>2006-12-16 13:28:20 -0800
commit0667fcfb6271e9e1ea032a0e3a7d74c9d6a5fa8a (patch)
tree56b2353219b7d37819c93714618caaa344635904
parentb1bfcae438adb485bb66e2f59396373809e346e6 (diff)
downloadgit-0667fcfb6271e9e1ea032a0e3a7d74c9d6a5fa8a.tar.gz
git-0667fcfb6271e9e1ea032a0e3a7d74c9d6a5fa8a.tar.xz
add a function to rename sections in the config
Given a config like this: # A config [very.interesting.section] not The command $ git repo-config --rename-section very.interesting.section bla.1 will lead to this config: # A config [bla "1"] not Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--builtin-repo-config.c14
-rw-r--r--cache.h1
-rw-r--r--config.c64
-rwxr-xr-xt/t1300-repo-config.sh48
4 files changed, 126 insertions, 1 deletions
diff --git a/builtin-repo-config.c b/builtin-repo-config.c
index 64fbdb7b2..a38099a63 100644
--- a/builtin-repo-config.c
+++ b/builtin-repo-config.c
@@ -3,7 +3,7 @@
#include <regex.h>
static const char git_config_set_usage[] =
-"git-repo-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --list";
+"git-repo-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";
static char *key;
static regex_t *key_regexp;
@@ -148,6 +148,18 @@ int cmd_repo_config(int argc, const char **argv, const char *prefix)
} else {
die("$HOME not set");
}
+ } else if (!strcmp(argv[1], "--rename-section")) {
+ int ret;
+ if (argc != 4)
+ usage(git_config_set_usage);
+ ret = git_config_rename_section(argv[2], argv[3]);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ fprintf(stderr, "No such section!\n");
+ return 1;
+ }
+ return 0;
} else
break;
argc--;
diff --git a/cache.h b/cache.h
index 2d3df98dc..bfab4f975 100644
--- a/cache.h
+++ b/cache.h
@@ -404,6 +404,7 @@ 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 *, int);
+extern int git_config_rename_section(const char *, const char *);
extern int check_repository_format_version(const char *var, const char *value);
#define MAX_GITNAME (1000)
diff --git a/config.c b/config.c
index 1bdef44a3..663993fef 100644
--- a/config.c
+++ b/config.c
@@ -746,4 +746,68 @@ out_free:
return ret;
}
+int git_config_rename_section(const char *old_name, const char *new_name)
+{
+ int ret = 0;
+ const char *config_filename;
+ struct lock_file *lock = xcalloc(sizeof(struct lock_file), 1);
+ int out_fd;
+ char buf[1024];
+
+ config_filename = getenv("GIT_CONFIG");
+ if (!config_filename) {
+ config_filename = getenv("GIT_CONFIG_LOCAL");
+ if (!config_filename)
+ config_filename = git_path("config");
+ }
+ config_filename = xstrdup(config_filename);
+ out_fd = hold_lock_file_for_update(lock, config_filename, 0);
+ if (out_fd < 0)
+ return error("Could not lock config file!");
+
+ if (!(config_file = fopen(config_filename, "rb")))
+ return error("Could not open config file!");
+
+ while (fgets(buf, sizeof(buf), config_file)) {
+ int i;
+ for (i = 0; buf[i] && isspace(buf[i]); i++)
+ ; /* 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;
+ 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 matches */
+ ret++;
+ store.baselen = strlen(new_name);
+ store_write_section(out_fd, new_name);
+ continue;
+ }
+ }
+ write(out_fd, buf, strlen(buf));
+ }
+ if (close(out_fd) || commit_lock_file(lock) < 0)
+ return error("Cannot commit config file!");
+ return ret;
+}
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 16cd64261..e48a4ecdc 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -343,5 +343,53 @@ EOF
test_expect_success '--set in alternative GIT_CONFIG' 'cmp other-config expect'
+cat > .git/config << EOF
+# Hallo
+ #Bello
+[branch "eins"]
+ x = 1
+[branch.eins]
+ y = 1
+ [branch "1 234 blabl/a"]
+weird
+EOF
+
+test_expect_success "rename section" \
+ "git-repo-config --rename-section branch.eins branch.zwei"
+
+cat > expect << EOF
+# Hallo
+ #Bello
+[branch "zwei"]
+ x = 1
+[branch "zwei"]
+ y = 1
+ [branch "1 234 blabl/a"]
+weird
+EOF
+
+test_expect_success "rename succeeded" "diff -u expect .git/config"
+
+test_expect_failure "rename non-existing section" \
+ 'git-repo-config --rename-section branch."world domination" branch.drei'
+
+test_expect_success "rename succeeded" "diff -u expect .git/config"
+
+test_expect_success "rename another section" \
+ 'git-repo-config --rename-section branch."1 234 blabl/a" branch.drei'
+
+cat > expect << EOF
+# Hallo
+ #Bello
+[branch "zwei"]
+ x = 1
+[branch "zwei"]
+ y = 1
+[branch "drei"]
+weird
+EOF
+
+test_expect_success "rename succeeded" "diff -u expect .git/config"
+
test_done