From aba70781771061e8f6df78f2af3f9ac395dd5f57 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Tue, 11 Sep 2012 18:11:26 +0200 Subject: [PATCH] config: introduce git_config_rename_section() --- src/branch.c | 117 +++++++++++++-------------------------------------- src/config.c | 78 ++++++++++++++++++++++++++++++++++ src/config.h | 5 +++ 3 files changed, 113 insertions(+), 87 deletions(-) diff --git a/src/branch.c b/src/branch.c index 9562805fb..43bebd9ef 100644 --- a/src/branch.c +++ b/src/branch.c @@ -89,86 +89,11 @@ cleanup: return error; } -typedef struct rename_data -{ - git_config *config; - const char *old_name; - const char *new_name; -} rename_data; - -static int rename_config_entries_cb( - const char *var_name, - const char *value, - void *payload) -{ - rename_data *data = (rename_data *)payload; - - GIT_UNUSED(value); - - if (data->new_name != NULL) { - git_buf name = GIT_BUF_INIT; - int error; - - if (git_buf_printf( - &name, - "branch.%s.%s", - data->new_name, - var_name + strlen("branch") + strlen(data->old_name) + 2) < 0) - return -1; - - error = git_config_set_string( - data->config, - git_buf_cstr(&name), - value); - - git_buf_free(&name); - - if (error) - return error; - } - - return git_config_delete(data->config, var_name); -} - -static int rename_branch_config_entries( - git_repository *repo, - const char *old_branch_name, - const char *new_branch_name) -{ - git_config *config; - git_buf pattern = GIT_BUF_INIT; - int error = -1; - rename_data data; - - git_buf_sets(&pattern, "branch\\."); - git_buf_puts_escape_regex(&pattern, old_branch_name); - git_buf_puts(&pattern, "\\..+"); - if (git_buf_oom(&pattern)) - goto cleanup; - - if (git_repository_config__weakptr(&config, repo) < 0) - goto cleanup; - - data.config = config; - data.old_name = old_branch_name; - data.new_name = new_branch_name; - - if ((error = git_config_foreach_match( - config, - git_buf_cstr(&pattern), - rename_config_entries_cb, &data)) < 0) - goto cleanup; - - error = 0; - -cleanup: - git_buf_free(&pattern); - return error; -} - int git_branch_delete(git_reference *branch) { int is_head; + git_buf config_section = GIT_BUF_INIT; + int error = -1; assert(branch); @@ -187,13 +112,23 @@ int git_branch_delete(git_reference *branch) return -1; } - if (rename_branch_config_entries( + if (git_buf_printf(&config_section, "branch.%s", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0) + goto on_error; + + if (git_config_rename_section( git_reference_owner(branch), - git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR), + git_buf_cstr(&config_section), NULL) < 0) goto on_error; - return git_reference_delete(branch); + if (git_reference_delete(branch) < 0) + goto on_error; + + error = 0; + +on_error: + git_buf_free(&config_section); + return error; } typedef struct { @@ -245,7 +180,8 @@ int git_branch_move( int force) { git_buf new_reference_name = GIT_BUF_INIT, - old_branch_name = GIT_BUF_INIT; + old_config_section = GIT_BUF_INIT, + new_config_section = GIT_BUF_INIT; int error; assert(branch && new_branch_name); @@ -256,21 +192,28 @@ int git_branch_move( if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0) goto cleanup; - if ((error = git_buf_puts(&old_branch_name, git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR))) < 0) - goto cleanup; + if (git_buf_printf( + &old_config_section, + "branch.%s", + git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0) + goto cleanup; if ((error = git_reference_rename(branch, git_buf_cstr(&new_reference_name), force)) < 0) goto cleanup; - if ((error = rename_branch_config_entries( + if (git_buf_printf(&new_config_section, "branch.%s", new_branch_name) < 0) + goto cleanup; + + if ((error = git_config_rename_section( git_reference_owner(branch), - git_buf_cstr(&old_branch_name), - new_branch_name)) < 0) + git_buf_cstr(&old_config_section), + git_buf_cstr(&new_config_section))) < 0) goto cleanup; cleanup: git_buf_free(&new_reference_name); - git_buf_free(&old_branch_name); + git_buf_free(&old_config_section); + git_buf_free(&new_config_section); return error; } diff --git a/src/config.c b/src/config.c index f9bd205af..377bbaf87 100644 --- a/src/config.c +++ b/src/config.c @@ -720,3 +720,81 @@ fail_parse: giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a 32-bit integer", value); return -1; } + +struct rename_data +{ + git_config *config; + const char *old_name; + const char *new_name; +}; + +static int rename_config_entries_cb( + const git_config_entry *entry, + void *payload) +{ + struct rename_data *data = (struct rename_data *)payload; + + if (data->new_name != NULL) { + git_buf name = GIT_BUF_INIT; + int error; + + if (git_buf_printf( + &name, + "%s.%s", + data->new_name, + entry->name + strlen(data->old_name) + 1) < 0) + return -1; + + error = git_config_set_string( + data->config, + git_buf_cstr(&name), + entry->value); + + git_buf_free(&name); + + if (error) + return error; + } + + return git_config_delete(data->config, entry->name); +} + +int git_config_rename_section( + git_repository *repo, + const char *old_section_name, + const char *new_section_name) +{ + git_config *config; + git_buf pattern = GIT_BUF_INIT; + int error = -1; + struct rename_data data; + + git_buf_puts_escape_regex(&pattern, old_section_name); + git_buf_puts(&pattern, "\\..+"); + if (git_buf_oom(&pattern)) + goto cleanup; + + if (git_repository_config__weakptr(&config, repo) < 0) + goto cleanup; + + data.config = config; + data.old_name = old_section_name; + data.new_name = new_section_name; + + if ((error = git_config_foreach_match( + config, + git_buf_cstr(&pattern), + rename_config_entries_cb, &data)) < 0) { + giterr_set(GITERR_CONFIG, + "Cannot rename config section '%s' to '%s'", + old_section_name, + new_section_name); + goto cleanup; + } + + error = 0; + +cleanup: + git_buf_free(&pattern); + return error; +} diff --git a/src/config.h b/src/config.h index 16b8413b7..a0569ec93 100644 --- a/src/config.h +++ b/src/config.h @@ -27,4 +27,9 @@ extern int git_config_find_global_r(git_buf *global_config_path); extern int git_config_find_xdg_r(git_buf *system_config_path); extern int git_config_find_system_r(git_buf *system_config_path); +extern int git_config_rename_section( + git_repository *repo, + const char *old_section_name, /* eg "branch.dummy" */ + const char *new_section_name); /* NULL to drop the old section */ + #endif