apply: use an indexwriter Place the entire `git_apply` operation inside an indexwriter, so that we lock the index before we begin performing patch application. This ensures that there are no other processes modifying things in the working directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
diff --git a/src/apply.c b/src/apply.c
index df1d0d8..d098f96 100644
--- a/src/apply.c
+++ b/src/apply.c
@@ -22,6 +22,7 @@
#include "delta.h"
#include "zstream.h"
#include "reader.h"
+#include "index.h"
#define apply_err(...) \
( giterr_set(GITERR_PATCH, __VA_ARGS__), GIT_EAPPLYFAIL )
@@ -556,6 +557,7 @@ static int git_apply__to_workdir(
checkout_opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
checkout_opts.checkout_strategy |= GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
+ checkout_opts.checkout_strategy |= GIT_CHECKOUT_DONT_WRITE_INDEX;
if (opts->location == GIT_APPLY_LOCATION_WORKDIR)
checkout_opts.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
@@ -610,8 +612,6 @@ static int git_apply__to_index(
goto done;
}
- error = git_index_write(index);
-
done:
git_index_free(index);
return error;
@@ -638,7 +638,8 @@ int git_apply(
git_diff *diff,
git_apply_options *given_opts)
{
- git_index *preimage = NULL, *postimage = NULL;
+ git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
+ git_index *index = NULL, *preimage = NULL, *postimage = NULL;
git_reader *pre_reader = NULL;
git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
size_t i;
@@ -685,6 +686,10 @@ int git_apply(
(error = git_index_new(&postimage)) < 0)
goto done;
+ if ((error = git_repository_index(&index, repo)) < 0 ||
+ (error = git_indexwriter_init(&indexwriter, index)) < 0)
+ goto done;
+
for (i = 0; i < git_diff_num_deltas(diff); i++) {
if ((error = apply_one(repo, pre_reader, preimage, postimage, diff, i)) < 0)
goto done;
@@ -707,9 +712,16 @@ int git_apply(
if (error < 0)
goto done;
+ if (error < 0)
+ goto done;
+
+ error = git_indexwriter_commit(&indexwriter);
+
done:
+ git_indexwriter_cleanup(&indexwriter);
git_index_free(postimage);
git_index_free(preimage);
+ git_index_free(index);
git_reader_free(pre_reader);
return error;