[PATCH] diff: fix the culling of unneeded delete record.
authorJunio C Hamano <junkio@cox.net>
Mon, 30 May 2005 07:08:07 +0000 (00:08 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 30 May 2005 17:35:49 +0000 (10:35 -0700)
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.c
diffcore-rename.c

diff --git a/diff.c b/diff.c
index 919280d..a080d94 100644 (file)
--- 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';
 
index cf3fe09..6ed8cf5 100644 (file)
@@ -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);