From: Junio C Hamano <junkio@cox.net>
Date: Mon, 30 May 2005 07:08:07 +0000 (-0700)
Subject: [PATCH] diff: fix the culling of unneeded delete record.
X-Git-Tag: v0.99~413
X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=2cd68882ee8629f9782be017007fff4c78e45e45;p=git.git

[PATCH] diff: fix the culling of unneeded delete record.

The commit 15d061b435a7e3b6bead39df3889f4af78c4b00a

    [PATCH] Fix the way diffcore-rename records unremoved source.

still leaves unneeded delete records in its output stream by
mistake, which was covered up by having an extra check to turn
such a delete into a no-op downstream.  Fix the check in the
diffcore-rename to simplify the output routine.

Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

diff --git a/diff.c b/diff.c
index 919280d2d..a080d94c3 100644
--- a/diff.c
+++ b/diff.c
@@ -792,27 +792,8 @@ static void diff_resolve_rename_copy(void)
 			p->status = 'U';
 		else if (!DIFF_FILE_VALID(p->one))
 			p->status = 'N';
-		else if (!DIFF_FILE_VALID(p->two)) {
-			/* Deleted entry may have been picked up by
-			 * another rename-copy entry.  So we scan the
-			 * queue and if we find one that uses us as the
-			 * source we do not say delete for this entry.
-			 */
-			for (j = 0; j < q->nr; j++) {
-				pp = q->queue[j];
-				if (!strcmp(p->one->path, pp->one->path) &&
-				    DIFF_PAIR_RENAME(pp)) {
-					/* rename/copy are always valid
-					 * so we do not say DIFF_FILE_VALID()
-					 * on pp->one and pp->two.
-					 */
-					p->status = 'X';
-					break;
-				}
-			}
-			if (!p->status)
-				p->status = 'D';
-		}
+		else if (!DIFF_FILE_VALID(p->two))
+			p->status = 'D';
 		else if (DIFF_PAIR_TYPE_CHANGED(p))
 			p->status = 'T';
 
diff --git a/diffcore-rename.c b/diffcore-rename.c
index cf3fe0932..6ed8cf5ae 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -328,26 +328,48 @@ void diffcore_rename(int detect_rename, int minimum_score)
 	outq.nr = outq.alloc = 0;
 	for (i = 0; i < q->nr; i++) {
 		struct diff_filepair *p = q->queue[i];
-		struct diff_rename_dst *dst = locate_rename_dst(p->two, 0);
 		struct diff_filepair *pair_to_free = NULL;
 
-		if (dst) {
-			/* creation */
-			if (dst->pair) {
-				/* renq has rename/copy to produce
-				 * this file already, so we do not
-				 * emit the creation record in the
-				 * output.
-				 */
+		if (!DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
+			/*
+			 * Creation
+			 *
+			 * We would output this create record if it has
+			 * not been turned into a rename/copy already.
+			 */
+			struct diff_rename_dst *dst =
+				locate_rename_dst(p->two, 0);
+			if (dst && dst->pair) {
 				diff_q(&outq, dst->pair);
 				pair_to_free = p;
 			}
 			else
-				/* no matching rename/copy source, so record
-				 * this as a creation.
+				/* no matching rename/copy source, so
+				 * record this as a creation.
 				 */
 				diff_q(&outq, p);
 		}
+		else if (DIFF_FILE_VALID(p->one) && !DIFF_FILE_VALID(p->two)) {
+			/*
+			 * Deletion
+			 *
+			 * We would output this delete record if renq
+			 * does not have a rename/copy to move
+			 * p->one->path out.
+			 */
+			for (j = 0; j < renq.nr; j++)
+				if (!strcmp(renq.queue[j]->one->path,
+					    p->one->path))
+					break;
+			if (j < renq.nr)
+				/* this path remains */
+				pair_to_free = p;
+
+			if (pair_to_free)
+				;
+			else
+				diff_q(&outq, p);
+		}
 		else if (!diff_unmodified_pair(p))
 			/* all the usual ones need to be kept */
 			diff_q(&outq, p);