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

Re: [PATCH/RFC/BUG] unpack-trees.c: do not use "the_index"

From
Elijah Newren <newren@gmail.com>
Date
Jun 3, 2018, 04:58 UTC
Message-ID
<CABPp-BEMUUrYd_=a1sPYV941rMCdWh_x-4j5uUiCEUFA0Fwoww@mail.gmail.com>
In-Reply-To
<CACsJy8Ai5befewi9OxKzUxTOOOON9wgWpqcNy3AuK1YBk7MbxQ@mail.gmail.com>
On Fri, Jun 1, 2018 at 10:03 PM, Duy Nguyen <pclouds@gmail.com> wrote:
Show 7 quoted lines
> On Fri, Jun 1, 2018 at 8:34 PM, Elijah Newren <newren@gmail.com> wrote:
>> On Fri, Jun 1, 2018 at 9:11 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>>> This is more of a bug report than an actual fix because I'm not sure
>>> if "o->src_index" is always the correct answer instead of "the_index"
>>> here. But this is very similar to 7db118303a (unpack_trees: fix
>>> breakage when o->src_index != o->dst_index - 2018-04-23) and could
>>> potentially break things again...

I'm pretty sure your patch is correct. Adding Brandon Williams to the cc for comment since his patches came up in the analysis below...

Show 11 quoted lines
>> Actually, I don't think the patch will break anything in the current
>> code.  Currently, all callers of unpack_trees() (even merge recursive
>> which uses different src_index and dst_index now) set src_index =
>> &the_index.  So, these changes should continue to work as before (with
>> a minor possible exception of merge-recursive calling into other
>> functions from unpack-trees.c after unpack_trees() has finished..).
>> That's not to say that your patch is bug free, just that I think any
>> bugs shouldn't be triggerable from the current codebase.
>
> Ah.. I thought merge-recursive would do fancier things and used some
> temporary index. Good to know.

Well, it does does use a temporary index, but for dst_index rather than src_index. It then does some fancier things, but not until the call to unpack_trees() is over. In particular, at that point, it swaps the_index and tmp_index, reversing their roles so that now tmp_index is the original index and the_index becomes the result after unpack_trees() is run. That's done because I later want to use the original index for calling verify_uptodate(). verify_uptodate() is then used for was_tracked_and_matches() and was_tracked().

Anyway, the whole upshot of this is:
  * merge-recursive uses src_index == &the_index for the unpack_trees() call.
  * merge-recursive uses src_index == o->orig_index for subsequent
calls to verify_uptodate(), but verify_uptodate() doesn't call into
any of the sites you have modified.
Further:
  * Every other existing caller of unpack-trees in the code sets
src_index == &the_index, so this won't break any of them.
  * There are only two callers in the codebase that set dst_index to
something other than &the_index -- diff-lib.c (which sets it to NULL)
and merge-recursive (which does the stuff described above).

So, having done that analysis, I am now pretty convinced your patch won't break anything. That's one half...

Show 8 quoted lines
>> Also, if any of the changes you made are wrong, what was there before
>> was also clearly wrong.  So I think we're at least no worse off.
>>
>> But, I agree, it's not easy to verify what the correct thing should be
>> in all cases.  I'll try to take a closer look in the next couple days.
>
> Thanks. I will also stare at this code some more in the next couple
> days trying to remember what these functions do.
Your patch has two divisible parts:
1) Your modifications to
  * clear_ce_flags_1()
  * clear_ce_flags_dir()
  * clear_ce_flags()
  * mark_new_skip_worktree()
The clear_ce_flags*() functions are only called by each other and by
mark_new_skip_worktree(), which in turn is only called from
unpack_trees().  Also, in all of these, your change ends up only
modifying what index_state is passed to is_excluded_from_list().
2) Your modifications to
  * verify_clean_subdirectory()
  * check_ok_to_remove()
In this case, the former is only called by the latter, and the latter
ends up only being called (via verify_absent_1()) from verify_absent()
and verify_absent_sparse().
I'll address each, in reverse order.
2) The stuff that affects verify_absent()

While verify_absent() is not called from merge-recursive right now, it was something I wanted to use in the future for very similar reasons that verify_uptodate() started being called directly from merge-recursive. In particular, if the rewrite of merge-recursive[A] I want to do sets index_only when calling unpack_trees(), then does the whole merge without touching the worktree, then at the end goes to update the working tree, it will need to do extra checks. verify_absent() will come in handy as one of those extra checks. For that case, using the_index (the new index just created with lots of changes) would be wrong in all the same ways that using the_index caused massive problems for was_tracked() in merge-recursive (e.g. the blow up of when Junio merged the original directory rename detection series into master and subsequently reverted it); we'd instead want src_index (which was the index that existed when merge was called) instead. So, with this patch you've fixed some important bugs that I would have hit later.

[A] sidenote: see https://public-inbox.org/git/xmqqk1ydkbx0.fsf@gitster.mtv.corp.google.com/ for more details

1) mark_new_skip_worktree() ... is_excluded_from_list().
Sadly, I'm not very familiar with the skip_worktree and sparse
checkout stuff.  However, the fact that mark_new_skip_worktree()
explicitly takes an index_state (and a different one is passed to it
the two different times it is called), and that it is the only caller
of the clear_ce_flags*() family of functions, and that those function
use the cache entries from the index passed to them in all cases other
than the calls to is_excluded_from_list() makes those two look like
oversights.  In fact, a little more digging turns up commit
   fba92be8f7 ("dir: convert is_excluded_from_list to take an index",
2017-05-05)
and before then, those functions didn't use the_index directly.  But
they did use it indirectly, because they called a function in dir.c
that had it hardcoded.  So it looks like Brandon fixed part of the bug
for us, but moved the incorrect hardcoding from dir.c to
unpack-trees.c.  Your patch is just fixing it up.  In fact, a little
more digging turns up:

2c1eb10454 ("dir: convert read_directory to take an index", 2017-05-05) a0bba65b10 ("dir: convert is_excluded to take an index", 2017-05-05)

which appear to be the culprits behind the other two uses of the_index called from verify_absent(). It looks like before these commits that unpack_trees() was carefully using the appropriate index, except that functions in dir.c had use of the_index hardcoded. Brandon fix the functions in dir.c for us, but ended up still hardcoding the_index in unpack-trees.c. Basically, he did most of the necessary lifting, and your patch just finally changes them over to use the correct index.

Brandon: Does anything look off in my analysis above?
Previous: Duy NguyenNext: Brandon Williams
Message 6 of 92 in “unpack-trees.c: do not use "the_index"”
  1. unpack-trees.c: do not use "the_index"Nguyễn Thái Ngọc Duy, Jun 1, 2018
  2. Elijah NewrenJun 1, 2018
  3. Stefan BellerJun 1, 2018
  4. Duy NguyenJun 2, 2018
  5. Duy NguyenJun 2, 2018
  6. Elijah NewrenJun 3, 2018
  7. Brandon WilliamsJun 4, 2018
  8. 0/6 Fix "the_index" usage in unpack-trees.cNguyễn Thái Ngọc Duy, Jun 5, 2018
  9. 1/6 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 5, 2018
  10. 3/6 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 5, 2018
  11. Ramsay JonesJun 5, 2018
  12. 4/6 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 5, 2018
  13. Ramsay JonesJun 5, 2018
  14. 5/6 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 5, 2018
  15. 6/6 Forbid "the_index" in dir.c and unpack-trees.cNguyễn Thái Ngọc Duy, Jun 5, 2018
  16. Brandon WilliamsJun 5, 2018
  17. Duy NguyenJun 6, 2018
  18. 2/6 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 5, 2018
  19. 0/5 Fix "the_index" usage in unpack-trees.cNguyễn Thái Ngọc Duy, Jun 6, 2018
  20. 1/5 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  21. 4/5 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  22. 3/5 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  23. 2/5 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 6, 2018
  24. 5/5 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  25. 00/20 Fix incorrect use of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  26. 02/20 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 6, 2018
  27. 01/20 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  28. 04/20 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  29. 05/20 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  30. 03/20 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  31. 11/20 ls-files: correct index argument to get_convert_attr_ascii()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  32. 10/20 dir.c: remove an implicit dependency on the_index in pathspec codeNguyễn Thái Ngọc Duy, Jun 6, 2018
  33. 14/20 entry.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  34. 09/20 convert.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  35. 19/20 grep: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  36. 17/20 cache.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  37. Brandon WilliamsJun 6, 2018
  38. 18/20 resolve-undo.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  39. 20/20 cache.h: make the_index part of "compatibility macros"Nguyễn Thái Ngọc Duy, Jun 6, 2018
  40. 16/20 preload-index.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  41. 12/20 pathspec.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  42. 15/20 attr: remove index from git_attr_set_direction()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  43. Brandon WilliamsJun 6, 2018
  44. 08/20 convert.h: drop 'extern' from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  45. 13/20 submodule.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  46. 06/20 attr.h: drop extern from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  47. 07/20 attr: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  48. Ramsay JonesJun 6, 2018
  49. Brandon WilliamsJun 6, 2018
  50. Duy NguyenJun 6, 2018
  51. Brandon WilliamsJun 6, 2018
  52. 00/23 Fix incorrect use of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  53. 01/23 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  54. 02/23 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 6, 2018
  55. 04/23 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  56. Elijah NewrenJun 7, 2018
  57. Duy NguyenJun 7, 2018
  58. Duy NguyenJun 8, 2018
  59. 03/23 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  60. 05/23 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  61. 06/23 attr.h: drop extern from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  62. 08/23 convert.h: drop 'extern' from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  63. 09/23 convert.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  64. 11/23 ls-files: correct index argument to get_convert_attr_ascii()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  65. 10/23 dir.c: remove an implicit dependency on the_index in pathspec codeNguyễn Thái Ngọc Duy, Jun 6, 2018
  66. 14/23 entry.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  67. 13/23 submodule.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  68. 16/23 preload-index.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  69. 20/23 checkout: avoid the_index when possibleNguyễn Thái Ngọc Duy, Jun 6, 2018
  70. 23/23 cache.h: make the_index part of "compatibility macros"Nguyễn Thái Ngọc Duy, Jun 6, 2018
  71. 22/23 grep: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  72. 19/23 difftool: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  73. 21/23 resolve-undo.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  74. 18/23 apply.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  75. 15/23 attr: remove index from git_attr_set_direction()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  76. Elijah NewrenJun 9, 2018
  77. 17/23 read-cache.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  78. Elijah NewrenJun 9, 2018
  79. Duy NguyenJun 9, 2018
  80. Elijah NewrenJun 9, 2018
  81. 12/23 pathspec.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  82. 07/23 attr: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  83. Elijah NewrenJun 7, 2018
  84. Elijah NewrenJun 9, 2018
  85. Duy NguyenJun 11, 2018
  86. Elijah NewrenJun 11, 2018
  87. Duy NguyenJun 11, 2018
  88. Elijah NewrenJun 11, 2018
  89. Duy NguyenJun 11, 2018
  90. Duy NguyenJun 14, 2018
  91. Elijah NewrenJun 14, 2018
  92. Duy NguyenJun 11, 2018

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.