git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/8] fixup! combine_diff: simplify intersect_paths() further

From
Kirill Smelkov <kirr@mns.spb.ru>
Date
Feb 3, 2014, 12:47 UTC
Message-ID
<60ec61bdd2ef3cba7537e29c42f9c8a810da245d.1391430523.git.kirr@mns.spb.ru>
In-Reply-To
<cover.1391430523.git.kirr@mns.spb.ru>

That cleanup patch is good, but I've found a bug in it. In the item removal code

Show 7 quoted lines
> +                      /* p->path not in q->queue[]; drop it */
> +                      struct combine_diff_path *next = p->next;
> +
> +                      if ((*tail = next) != NULL)
> +                              tail = &next->next;
> +                      free(p);
>                        continue;
        *tail = next
is right, but
        tail = &next->next

is wrong, because it will lead to skipping the element after removed one. Proof:

    tail        p
      |         |
      |         |
      v         v
     +-+       +------+-+       +------+-+       +------+-+
     | |       |      | |       |      | |       |      | |
     |o------->|      |o------->|      |o------->|      |o------->
     |0|       |     1| |       |     2| |       |     3| |
     +-+       +------+-+       +------+-+       +------+-+
suppose, we are removing element 1. p->next points to 2, after
    *tail = next
0 points to 2, which != NULL. After
    tail = &next->next
tail points to &2->next.
On the next cycle iteration, after
    p = *tail
we'll have
    p = *2->next = 3
so 2 was skipped, oops.

I've actually hit the bug - when generating combine-diff, for merges with should-be empty `log -c` output, every second path was present in the diff. That, by the way, means we need to extend combine-diff tests somewhat.

Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru>
---
 combine-diff.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/combine-diff.c b/combine-diff.c
index 0809e79..a03147c 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -58,8 +58,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
 			/* p->path not in q->queue[]; drop it */
 			struct combine_diff_path *next = p->next;
 
-			if ((*tail = next) != NULL)
-				tail = &next->next;
+			*tail = next;
 			free(p);
 			continue;
 		}
-- 
1.9.rc1.181.g641f458
Previous: Kirill SmelkovNext: Junio C Hamano
Message 2 of 26 in “`log -c` speedup (part 2)”
  1. 0/8 `log -c` speedup (part 2)Kirill Smelkov, Feb 3, 2014
  2. 1/8 fixup! combine_diff: simplify intersect_paths() furtherKirill Smelkov, Feb 3, 2014
  3. Junio C HamanoFeb 3, 2014
  4. 2/8 tests: add checking that combine-diff emits only correct pathsKirill Smelkov, Feb 3, 2014
  5. Junio C HamanoFeb 3, 2014
  6. Kirill SmelkovFeb 5, 2014
  7. 3/8 tree-diff: no need to manually verify that there is no mode change for a pathKirill Smelkov, Feb 3, 2014
  8. Junio C HamanoFeb 3, 2014
  9. 4/8 tree-diff: no need to pass match to skip_uninteresting()Kirill Smelkov, Feb 3, 2014
  10. 5/8 combine-diff: move show_log_first logic/action out of paths scanningKirill Smelkov, Feb 3, 2014
  11. Junio C HamanoFeb 3, 2014
  12. 6/8 combine-diff: Move changed-paths scanning logic into its own functionKirill Smelkov, Feb 3, 2014
  13. 7/8 combine-diff: Fast changed-to-all-parents paths scanningKirill Smelkov, Feb 3, 2014
  14. Junio C HamanoFeb 3, 2014
  15. Junio C HamanoFeb 3, 2014
  16. Kirill SmelkovFeb 4, 2014
  17. Junio C HamanoFeb 4, 2014
  18. Kirill SmelkovFeb 5, 2014
  19. Junio C HamanoFeb 5, 2014
  20. Kirill SmelkovFeb 5, 2014
  21. Junio C HamanoFeb 5, 2014
  22. Kirill SmelkovFeb 5, 2014
  23. Junio C HamanoFeb 5, 2014
  24. Kirill SmelkovFeb 6, 2014
  25. Junio C HamanoFeb 4, 2014
  26. 8/8 combine-diff: bail out early, if num_paths=0Kirill Smelkov, Feb 3, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.