Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-07-12 13:50:23 +0300
committerCarlos Martín Nieto <cmn@dwim.me>2015-08-12 05:09:38 +0300
commit5340d63d3815ddbd1a7e1b5b9628fce10089e8a0 (patch)
tree6a57d0912531b4dc6dc13b2f9d8aec4ebbc98c9b /src
parent36f784b538c4b27f7b52427d2cfce06c535abba0 (diff)
config: perform unlocking via git_transaction
This makes the API for commiting or discarding changes the same as for references.
Diffstat (limited to 'src')
-rw-r--r--src/config.c8
-rw-r--r--src/config.h15
-rw-r--r--src/transaction.c42
-rw-r--r--src/transaction.h14
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