diff options
-rw-r--r-- | include/git2/common.h | 11 | ||||
-rw-r--r-- | src/index.c | 4 | ||||
-rw-r--r-- | src/index.h | 2 | ||||
-rw-r--r-- | src/settings.c | 5 | ||||
-rw-r--r-- | tests/index/tests.c | 16 |
5 files changed, 35 insertions, 3 deletions
diff --git a/include/git2/common.h b/include/git2/common.h index fc820cae7..8c9347413 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -194,7 +194,8 @@ typedef enum { GIT_OPT_GET_WINDOWS_SHAREMODE, GIT_OPT_SET_WINDOWS_SHAREMODE, GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, - GIT_OPT_SET_ALLOCATOR + GIT_OPT_SET_ALLOCATOR, + GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY } git_libgit2_opt_t; /** @@ -363,6 +364,14 @@ typedef enum { * > allocator will then be used to make all memory allocations for * > libgit2 operations. * + * opts(GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY, int enabled) + * + * > Ensure that there are no unsaved changes in the index before + * > beginning any operation that reloads the index from disk (eg, + * > checkout). If there are unsaved changes, the instruction will + * > fail. (Using the FORCE flag to checkout will still overwrite + * > these changes.) + * * @param option Option key * @param ... value to set the option * @return 0 on success, <0 on failure diff --git a/src/index.c b/src/index.c index b8aa5160b..4907c81e1 100644 --- a/src/index.c +++ b/src/index.c @@ -135,6 +135,8 @@ struct reuc_entry_internal { char path[GIT_FLEX_ARRAY]; }; +bool git_index__enforce_unsaved_safety = false; + /* local declarations */ static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size); static int read_header(struct index_header *dest, const void *buffer); @@ -682,7 +684,7 @@ int git_index_read(git_index *index, int force) int git_index_read_safely(git_index *index) { - if (index->dirty) { + if (git_index__enforce_unsaved_safety && index->dirty) { giterr_set(GITERR_INDEX, "the index has unsaved changes that would be overwritten by this operation"); return GIT_EINDEXDIRTY; diff --git a/src/index.h b/src/index.h index a5182743a..aa54215dd 100644 --- a/src/index.h +++ b/src/index.h @@ -20,6 +20,8 @@ #define GIT_INDEX_FILE "index" #define GIT_INDEX_FILE_MODE 0666 +extern bool git_index__enforce_unsaved_safety; + struct git_index { git_refcount rc; diff --git a/src/settings.c b/src/settings.c index 14280f8c0..ba2f7158c 100644 --- a/src/settings.c +++ b/src/settings.c @@ -23,6 +23,7 @@ #include "object.h" #include "odb.h" #include "refs.h" +#include "index.h" #include "transports/smart.h" #include "streams/openssl.h" #include "streams/mbedtls.h" @@ -265,6 +266,10 @@ int git_libgit2_opts(int key, ...) error = git_allocator_setup(va_arg(ap, git_allocator *)); break; + case GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY: + git_index__enforce_unsaved_safety = (va_arg(ap, int) != 0); + break; + default: giterr_set(GITERR_INVALID, "invalid option key"); error = -1; diff --git a/tests/index/tests.c b/tests/index/tests.c index d7a1cc50b..3605ac9c3 100644 --- a/tests/index/tests.c +++ b/tests/index/tests.c @@ -72,6 +72,11 @@ void test_index_tests__initialize(void) { } +void test_index_tests__cleanup(void) +{ + cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY, 0)); +} + void test_index_tests__empty_index(void) { git_index *index; @@ -384,7 +389,7 @@ void test_index_tests__dirty_and_clean(void) git_repository_free(repo); } -void test_index_tests__dirty_fails_with_error(void) +void test_index_tests__dirty_fails_optionally(void) { git_repository *repo; git_index *index; @@ -400,6 +405,15 @@ void test_index_tests__dirty_fails_with_error(void) cl_git_pass(git_index_add_frombuffer(index, &entry, "Hi.\n", 4)); cl_assert(git_index_is_dirty(index)); + cl_git_pass(git_checkout_head(repo, NULL)); + + /* Index is dirty (again) after adding an entry */ + entry.mode = GIT_FILEMODE_BLOB; + entry.path = "test.txt"; + cl_git_pass(git_index_add_frombuffer(index, &entry, "Hi.\n", 4)); + cl_assert(git_index_is_dirty(index)); + + cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY, 1)); cl_git_fail_with(GIT_EINDEXDIRTY, git_checkout_head(repo, NULL)); git_index_free(index); |