From: "Michał Kiedrowicz" <michal.kiedrowicz@gmail.com>
To: Git Mailing List <git@vger.kernel.org>
Cc: "Michał Kiedrowicz" <michal.kiedrowicz@gmail.com>
Subject: [PATCH] builtin-apply: keep information about files to be deleted
Date: Sat, 11 Apr 2009 21:31:00 +0200 [thread overview]
Message-ID: <1239478260-7420-1-git-send-email-michal.kiedrowicz@gmail.com> (raw)
Example correct diff generated by `diff -M -B' might look like this:
diff --git a/file1 b/file2
similarity index 100%
rename from file1
rename to file2
diff --git a/file2 b/file1
similarity index 100%
rename from file2
rename to file1
Information about removing `file2' comes after information about creation
of new `file2' (renamed from `file1'). Existing implementation isn't able to
apply such patch, because it has to know in advance which files will be
removed.
This patch populates fn_table with information about removal of files
before calling check_patch() for each patch to be applied.
Signed-off-by: Michał Kiedrowicz <michal.kiedrowicz@gmail.com>
---
builtin-apply.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 1926cd8..6f6bf85 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2271,6 +2271,16 @@ static struct patch *in_fn_table(const char *name)
return NULL;
}
+static int to_be_deleted(struct patch *patch)
+{
+ return patch == (struct patch *) -2;
+}
+
+static int was_deleted(struct patch *patch)
+{
+ return patch == (struct patch *) -1;
+}
+
static void add_to_fn_table(struct patch *patch)
{
struct string_list_item *item;
@@ -2295,6 +2305,24 @@ static void add_to_fn_table(struct patch *patch)
}
}
+static void prepare_fn_table(struct patch *patch)
+{
+ /*
+ * store information about incoming file deletion
+ */
+
+ while (patch) {
+
+ if ((patch->new_name == NULL) || (patch->is_rename)) {
+ struct string_list_item *item =
+ string_list_insert(patch->old_name, &fn_table);
+ item->util = (struct patch *) -2;
+ }
+
+ patch = patch->next;
+ }
+}
+
static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
{
struct strbuf buf = STRBUF_INIT;
@@ -2304,8 +2332,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
struct patch *tpatch;
if (!(patch->is_copy || patch->is_rename) &&
- ((tpatch = in_fn_table(patch->old_name)) != NULL)) {
- if (tpatch == (struct patch *) -1) {
+ (tpatch = in_fn_table(patch->old_name)) != NULL && !to_be_deleted(tpatch)) {
+ if (was_deleted(tpatch)) {
return error("patch %s has been renamed/deleted",
patch->old_name);
}
@@ -2399,8 +2427,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
assert(patch->is_new <= 0);
if (!(patch->is_copy || patch->is_rename) &&
- (tpatch = in_fn_table(old_name)) != NULL) {
- if (tpatch == (struct patch *) -1) {
+ (tpatch = in_fn_table(old_name)) != NULL && !to_be_deleted(tpatch)) {
+ if (was_deleted(tpatch)) {
return error("%s: has been deleted/renamed", old_name);
}
st_mode = tpatch->new_mode;
@@ -2410,6 +2438,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
return error("%s: %s", old_name, strerror(errno));
}
+ if(to_be_deleted(tpatch)) tpatch = NULL;
+
if (check_index && !tpatch) {
int pos = cache_name_pos(old_name, strlen(old_name));
if (pos < 0) {
@@ -2471,6 +2501,7 @@ static int check_patch(struct patch *patch)
const char *new_name = patch->new_name;
const char *name = old_name ? old_name : new_name;
struct cache_entry *ce = NULL;
+ struct patch *tpatch;
int ok_if_exists;
int status;
@@ -2481,7 +2512,8 @@ static int check_patch(struct patch *patch)
return status;
old_name = patch->old_name;
- if (in_fn_table(new_name) == (struct patch *) -1)
+ if ((tpatch = in_fn_table(new_name)) &&
+ (was_deleted(tpatch) || to_be_deleted(tpatch)))
/*
* A type-change diff is always split into a patch to
* delete old, immediately followed by a patch to
@@ -2533,6 +2565,8 @@ static int check_patch_list(struct patch *patch)
{
int err = 0;
+ prepare_fn_table(patch);
+
while (patch) {
if (apply_verbosely)
say_patch_name(stderr,
--
1.6.0.6
next reply other threads:[~2009-04-11 19:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-11 19:31 Michał Kiedrowicz [this message]
2009-04-13 13:51 ` [PATCH] builtin-apply: keep information about files to be deleted Michał Kiedrowicz
2009-04-13 18:51 ` Junio C Hamano
2009-04-13 21:03 ` Michał Kiedrowicz
2009-04-13 21:30 ` Junio C Hamano
2009-04-17 17:23 ` Michał Kiedrowicz
2009-04-18 4:59 ` Junio C Hamano
2009-04-18 11:27 ` Andreas Ericsson
2009-04-18 19:56 ` Junio C Hamano
2009-04-18 20:58 ` Michał Kiedrowicz
2009-04-18 21:03 ` [PATCH] tests: make test-apply-criss-cross-rename more robust Michał Kiedrowicz
2009-04-18 22:05 ` [PATCH] builtin-apply: keep information about files to be deleted Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1239478260-7420-1-git-send-email-michal.kiedrowicz@gmail.com \
--to=michal.kiedrowicz@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).