aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-07-16 23:52:09 -0700
committerJunio C Hamano <junkio@cox.net>2006-07-16 23:52:09 -0700
commiteed46644ca48ad08e1fd71e14afbe801399e8a67 (patch)
tree0c0de6b7e698f87684ab1025236f698230035d9f
parentc28c571c143a5145665f4bf334671ac3a7d0980c (diff)
downloadgit-eed46644ca48ad08e1fd71e14afbe801399e8a67.tar.gz
git-eed46644ca48ad08e1fd71e14afbe801399e8a67.tar.xz
apply: split out removal and creation into different phases.
This reworks write_out_result() loop so we first remove the paths that are to go away and then create them after finishing all the removal. This is necessary when a patch creates a file "foo" and removes a file "foo/bar". Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--builtin-apply.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/builtin-apply.c b/builtin-apply.c
index 97274425d..37404e2e6 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2059,32 +2059,42 @@ static void create_file(struct patch *patch)
cache_tree_invalidate_path(active_cache_tree, path);
}
-static void write_out_one_result(struct patch *patch)
+/* phase zero is to remove, phase one is to create */
+static void write_out_one_result(struct patch *patch, int phase)
{
if (patch->is_delete > 0) {
- remove_file(patch);
+ if (phase == 0)
+ remove_file(patch);
return;
}
if (patch->is_new > 0 || patch->is_copy) {
- create_file(patch);
+ if (phase == 1)
+ create_file(patch);
return;
}
/*
* Rename or modification boils down to the same
* thing: remove the old, write the new
*/
- remove_file(patch);
+ if (phase == 0)
+ remove_file(patch);
+ if (phase == 1)
create_file(patch);
}
static void write_out_results(struct patch *list, int skipped_patch)
{
+ int phase;
+
if (!list && !skipped_patch)
die("No changes");
- while (list) {
- write_out_one_result(list);
- list = list->next;
+ for (phase = 0; phase < 2; phase++) {
+ struct patch *l = list;
+ while (l) {
+ write_out_one_result(l, phase);
+ l = l->next;
+ }
}
}