From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?utf-8?q?Micha=C5=82=20Kiedrowicz?= Subject: [PATCH] builtin-apply: keep information about files to be deleted Date: Sat, 11 Apr 2009 21:31:00 +0200 Message-ID: <1239478260-7420-1-git-send-email-michal.kiedrowicz@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: =?utf-8?q?Micha=C5=82=20Kiedrowicz?= To: Git Mailing List X-From: git-owner@vger.kernel.org Sat Apr 11 21:32:46 2009 Return-path: Envelope-to: gcvg-git-2@gmane.org Received: from vger.kernel.org ([209.132.176.167]) by lo.gmane.org with esmtp (Exim 4.50) id 1LsiwS-0006zn-E7 for gcvg-git-2@gmane.org; Sat, 11 Apr 2009 21:32:40 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754741AbZDKTbI convert rfc822-to-quoted-printable (ORCPT ); Sat, 11 Apr 2009 15:31:08 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754609AbZDKTbG (ORCPT ); Sat, 11 Apr 2009 15:31:06 -0400 Received: from mail-bw0-f169.google.com ([209.85.218.169]:60425 "EHLO mail-bw0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753975AbZDKTbD (ORCPT ); Sat, 11 Apr 2009 15:31:03 -0400 Received: by bwz17 with SMTP id 17so1552937bwz.37 for ; Sat, 11 Apr 2009 12:31:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:mime-version:content-type :content-transfer-encoding; bh=MZlUAYh18zBlnQDqTh0CE9ZuCN4VX4s9pHrjmF3xIB8=; b=TwJ18z4H+BO0B/9nO8Kof738T+/6Vbc8p6yYiW3H4J/rwdRe/boust+HZWv7DdzmHY bE4Wrf81fpUFZmFbO4zNvEfRTrYHfwI5eRpE9Sd8z+BllVgL1mJW2D0cxOvbVI7Gjyl9 RwQ00YoUCd27w4lVePG2jNfp+D15gp7LI4eaM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:mime-version :content-type:content-transfer-encoding; b=HZCYrX6+wf2DS0Lv+A06zfBWvWOxGi791wKUDxUKAzvrTzm4CmRDy3WavWhitxTzxJ rb9wxdYusTOD9A0ztN1vE0VzwO9ODdc6qg5tmN/3NYXH2O910o2NJZDfKtzCiVtyXrhi X/pMLL/Om1lxmp/AVFmw1cWVggH4EDP1yfD7c= Received: by 10.204.31.230 with SMTP id z38mr4415769bkc.85.1239478261870; Sat, 11 Apr 2009 12:31:01 -0700 (PDT) Received: from localhost (77-254-83-61.adsl.inetia.pl [77.254.83.61]) by mx.google.com with ESMTPS id 22sm3150211fkr.17.2009.04.11.12.31.01 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 11 Apr 2009 12:31:01 -0700 (PDT) X-Mailer: git-send-email 1.6.0.6 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: 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 creati= on of new `file2' (renamed from `file1'). Existing implementation isn't ab= le 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=C5=82 Kiedrowicz --- 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 *nam= e) return NULL; } =20 +static int to_be_deleted(struct patch *patch) +{ + return patch =3D=3D (struct patch *) -2; +} + +static int was_deleted(struct patch *patch) +{ + return patch =3D=3D (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) } } =20 +static void prepare_fn_table(struct patch *patch) +{ + /* + * store information about incoming file deletion + */ + + while (patch) { + + if ((patch->new_name =3D=3D NULL) || (patch->is_rename)) { + struct string_list_item *item =3D + string_list_insert(patch->old_name, &fn_table); + item->util =3D (struct patch *) -2; + } + + patch =3D patch->next; + } +} + static int apply_data(struct patch *patch, struct stat *st, struct cac= he_entry *ce) { struct strbuf buf =3D STRBUF_INIT; @@ -2304,8 +2332,8 @@ static int apply_data(struct patch *patch, struct= stat *st, struct cache_entry * struct patch *tpatch; =20 if (!(patch->is_copy || patch->is_rename) && - ((tpatch =3D in_fn_table(patch->old_name)) !=3D NULL)) { - if (tpatch =3D=3D (struct patch *) -1) { + (tpatch =3D in_fn_table(patch->old_name)) !=3D NULL && !to_be_del= eted(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, st= ruct cache_entry **ce, struct s assert(patch->is_new <=3D 0); =20 if (!(patch->is_copy || patch->is_rename) && - (tpatch =3D in_fn_table(old_name)) !=3D NULL) { - if (tpatch =3D=3D (struct patch *) -1) { + (tpatch =3D in_fn_table(old_name)) !=3D NULL && !to_be_deleted(tp= atch)) { + if (was_deleted(tpatch)) { return error("%s: has been deleted/renamed", old_name); } st_mode =3D tpatch->new_mode; @@ -2410,6 +2438,8 @@ static int check_preimage(struct patch *patch, st= ruct cache_entry **ce, struct s return error("%s: %s", old_name, strerror(errno)); } =20 + if(to_be_deleted(tpatch)) tpatch =3D NULL; + if (check_index && !tpatch) { int pos =3D 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 =3D patch->new_name; const char *name =3D old_name ? old_name : new_name; struct cache_entry *ce =3D NULL; + struct patch *tpatch; int ok_if_exists; int status; =20 @@ -2481,7 +2512,8 @@ static int check_patch(struct patch *patch) return status; old_name =3D patch->old_name; =20 - if (in_fn_table(new_name) =3D=3D (struct patch *) -1) + if ((tpatch =3D 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 =3D 0; =20 + prepare_fn_table(patch); + while (patch) { if (apply_verbosely) say_patch_name(stderr, --=20 1.6.0.6