diff options
author | Edward Thomson <ethomson@microsoft.com> | 2015-01-17 20:49:04 -0600 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2015-02-14 09:25:35 -0500 |
commit | 55798fd1536f055fc23a760c41d679fc60cd2ead (patch) | |
tree | f1633dbbdb53bab4e55fdcd024beceef855b9dde /src | |
parent | 42f98a26a5da450b3ef8600b85711112dd9860f4 (diff) | |
download | libgit2-55798fd1536f055fc23a760c41d679fc60cd2ead.tar.gz |
git_indexwriter: lock then write the index
Introduce `git_indexwriter`, to allow us to lock the index while
performing additional operations, then complete the write (or abort,
unlocking the index).
Diffstat (limited to 'src')
-rw-r--r-- | src/index.c | 90 | ||||
-rw-r--r-- | src/index.h | 18 |
2 files changed, 79 insertions, 29 deletions
diff --git a/src/index.c b/src/index.c index cbace3606..58575fec3 100644 --- a/src/index.c +++ b/src/index.c @@ -656,39 +656,15 @@ int git_index__changed_relative_to( int git_index_write(git_index *index) { - git_filebuf file = GIT_FILEBUF_INIT; + git_indexwriter writer = GIT_INDEXWRITER_INIT; int error; - if (!index->index_file_path) - return create_index_error(-1, - "Failed to read index: The index is in-memory only"); - - if (index_sort_if_needed(index, true) < 0) - return -1; - git_vector_sort(&index->reuc); - - if ((error = git_filebuf_open( - &file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_INDEX_FILE_MODE)) < 0) { - if (error == GIT_ELOCKED) - giterr_set(GITERR_INDEX, "The index is locked. This might be due to a concurrent or crashed process"); - - return error; - } + if ((error = git_indexwriter_init(&writer, index)) == 0) + error = git_indexwriter_commit(&writer); - if ((error = write_index(index, &file)) < 0) { - git_filebuf_cleanup(&file); - return error; - } + git_indexwriter_cleanup(&writer); - if ((error = git_filebuf_commit(&file)) < 0) - return error; - - if (git_futils_filestamp_check(&index->stamp, index->index_file_path) < 0) - /* index could not be read from disk! */; - else - index->on_disk = 1; - - return 0; + return error; } const char * git_index_path(const git_index *index) @@ -2686,3 +2662,59 @@ int git_index_snapshot_find( { return index_find_in_entries(out, entries, entry_srch, path, path_len, stage); } + +int git_indexwriter_init( + git_indexwriter *writer, + git_index *index) +{ + int error; + + writer->index = index; + + if (!index->index_file_path) + return create_index_error(-1, + "Failed to write index: The index is in-memory only"); + + if ((error = git_filebuf_open( + &writer->file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_INDEX_FILE_MODE)) < 0) { + if (error == GIT_ELOCKED) + giterr_set(GITERR_INDEX, "The index is locked. This might be due to a concurrent or crashed process"); + + return error; + } + + return 0; +} + +int git_indexwriter_commit(git_indexwriter *writer) +{ + int error; + + if (index_sort_if_needed(writer->index, true) < 0) + return -1; + + git_vector_sort(&writer->index->reuc); + + if ((error = write_index(writer->index, &writer->file)) < 0) { + git_indexwriter_cleanup(writer); + return error; + } + + if ((error = git_filebuf_commit(&writer->file)) < 0) + return error; + + if ((error = git_futils_filestamp_check( + &writer->index->stamp, writer->index->index_file_path)) < 0) { + giterr_set(GITERR_OS, "Could not read index timestamp"); + return -1; + } + + writer->index->on_disk = 1; + + return 0; +} + +void git_indexwriter_cleanup(git_indexwriter *writer) +{ + git_filebuf_cleanup(&writer->file); +} diff --git a/src/index.h b/src/index.h index 2eb93fb17..d151f6614 100644 --- a/src/index.h +++ b/src/index.h @@ -94,4 +94,22 @@ extern int git_index_snapshot_find( const char *path, size_t path_len, int stage); +typedef struct { + git_index *index; + git_filebuf file; +} git_indexwriter; + +#define GIT_INDEXWRITER_INIT { NULL, GIT_FILEBUF_INIT } + +/* Lock the index for eventual writing. */ +extern int git_indexwriter_init(git_indexwriter *writer, git_index *index); + +/* Write the index and unlock it. */ +extern int git_indexwriter_commit(git_indexwriter *writer); + +/* Cleanup an index writing session, unlocking the file (if it is still + * locked and freeing any data structures. + */ +extern void git_indexwriter_cleanup(git_indexwriter *writer); + #endif |