diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-07-12 12:50:23 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-08-12 04:09:38 +0200 |
commit | 5340d63d3815ddbd1a7e1b5b9628fce10089e8a0 (patch) | |
tree | 6a57d0912531b4dc6dc13b2f9d8aec4ebbc98c9b /src | |
parent | 36f784b538c4b27f7b52427d2cfce06c535abba0 (diff) | |
download | libgit2-5340d63d3815ddbd1a7e1b5b9628fce10089e8a0.tar.gz |
config: perform unlocking via git_transactioncmn/config-tx
This makes the API for commiting or discarding changes the same as for
references.
Diffstat (limited to 'src')
-rw-r--r-- | src/config.c | 8 | ||||
-rw-r--r-- | src/config.h | 15 | ||||
-rw-r--r-- | src/transaction.c | 42 | ||||
-rw-r--r-- | src/transaction.h | 14 |
4 files changed, 77 insertions, 2 deletions
diff --git a/src/config.c b/src/config.c index 937d00dcb..2df1fc80e 100644 --- a/src/config.c +++ b/src/config.c @@ -1144,8 +1144,9 @@ int git_config_open_default(git_config **out) return error; } -int git_config_lock(git_config *cfg) +int git_config_lock(git_transaction **out, git_config *cfg) { + int error; git_config_backend *file; file_internal *internal; @@ -1156,7 +1157,10 @@ int git_config_lock(git_config *cfg) } file = internal->file; - return file->lock(file); + if ((error = file->lock(file)) < 0) + return error; + + return git_transaction_config_new(out, cfg); } int git_config_unlock(git_config *cfg, int commit) diff --git a/src/config.h b/src/config.h index f257cc90f..ba745331a 100644 --- a/src/config.h +++ b/src/config.h @@ -88,4 +88,19 @@ extern int git_config__cvar( */ int git_config_lookup_map_enum(git_cvar_t *type_out, const char **str_out, const git_cvar_map *maps, size_t map_n, int enum_val); + +/** + * Unlock the backend with the highest priority + * + * Unlocking will allow other writers to updat the configuration + * file. Optionally, any changes performed since the lock will be + * applied to the configuration. + * + * @param cfg the configuration + * @param commit boolean which indicates whether to commit any changes + * done since locking + * @return 0 or an error code + */ +GIT_EXTERN(int) git_config_unlock(git_config *cfg, int commit); + #endif diff --git a/src/transaction.c b/src/transaction.c index e8331891c..e9639bf97 100644 --- a/src/transaction.c +++ b/src/transaction.c @@ -12,6 +12,7 @@ #include "pool.h" #include "reflog.h" #include "signature.h" +#include "config.h" #include "git2/transaction.h" #include "git2/signature.h" @@ -20,6 +21,12 @@ GIT__USE_STRMAP +typedef enum { + TRANSACTION_NONE, + TRANSACTION_REFS, + TRANSACTION_CONFIG, +} transaction_t; + typedef struct { const char *name; void *payload; @@ -39,13 +46,29 @@ typedef struct { } transaction_node; struct git_transaction { + transaction_t type; git_repository *repo; git_refdb *db; + git_config *cfg; git_strmap *locks; git_pool pool; }; +int git_transaction_config_new(git_transaction **out, git_config *cfg) +{ + git_transaction *tx; + assert(out && cfg); + + tx = git__calloc(1, sizeof(git_transaction)); + GITERR_CHECK_ALLOC(tx); + + tx->type = TRANSACTION_CONFIG; + tx->cfg = cfg; + *out = tx; + return 0; +} + int git_transaction_new(git_transaction **out, git_repository *repo) { int error; @@ -71,6 +94,7 @@ int git_transaction_new(git_transaction **out, git_repository *repo) if ((error = git_repository_refdb(&tx->db, repo)) < 0) goto on_error; + tx->type = TRANSACTION_REFS; memcpy(&tx->pool, &pool, sizeof(git_pool)); tx->repo = repo; *out = tx; @@ -305,6 +329,14 @@ int git_transaction_commit(git_transaction *tx) assert(tx); + if (tx->type == TRANSACTION_CONFIG) { + error = git_config_unlock(tx->cfg, true); + git_config_free(tx->cfg); + tx->cfg = NULL; + + return error; + } + for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) { if (!git_strmap_has_data(tx->locks, pos)) continue; @@ -332,6 +364,16 @@ void git_transaction_free(git_transaction *tx) assert(tx); + if (tx->type == TRANSACTION_CONFIG) { + if (tx->cfg) { + git_config_unlock(tx->cfg, false); + git_config_free(tx->cfg); + } + + git__free(tx); + return; + } + /* start by unlocking the ones we've left hanging, if any */ for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) { if (!git_strmap_has_data(tx->locks, pos)) diff --git a/src/transaction.h b/src/transaction.h new file mode 100644 index 000000000..780c06830 --- /dev/null +++ b/src/transaction.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_transaction_h__ +#define INCLUDE_transaction_h__ + +#include "common.h" + +int git_transaction_config_new(git_transaction **out, git_config *cfg); + +#endif |