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

Re: [PATCH 8/8] dir: avoid removing the current working directory

From
Elijah Newren <newren@gmail.com>
Date
Nov 24, 2021, 04:35 UTC
Message-ID
<CABPp-BGZPheDqWD1pXbePOYe2BcT1-TqX-zGVqnNLGtFuXab1g@mail.gmail.com>
In-Reply-To
<211124.86ee76e4fl.gmgdl@evledraar.gmail.com>

On Tue, Nov 23, 2021 at 5:19 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:

Show 34 quoted lines
>
> On Tue, Nov 23 2021, Elijah Newren wrote:
>
> > On Tue, Nov 23, 2021 at 10:19 AM Glen Choo <chooglen@google.com> wrote:
> >>
> >> Elijah Newren <newren@gmail.com> writes:
> >> [...]
> >> I'm not going to say that we'll *definitely* need remove_path()
> >> in its current form, but mixing concerns like this is an invitation to
> >> unexpected behavior. An (imperfect) example that demonstrates this
> >> principle is https://lore.kernel.org/git/24bffdab139435173712101aaf72f7277298c99d.1632497954.git.gitgitgadget@gmail.com/,
> >> where we made a change to a generic path matching function in order to
> >> speed up unpack_trees(), but accidentally ended up breaking gitignore.
> >
> > There's no mixture of concerns; my patch is correcting this library
> > function to more fully match its documented intent; from dir.h:
> >
> >     /* tries to remove the path with empty directories along it,
> > ignores ENOENT */
> >     int remove_path(const char *path);
> >
> > Since the parent process's current working directory is still likely
> > parked in that directory, there is a good reason to treat it as
> > non-empty.  Thus the cwd should not be one of those directories
> > removed along with the specified path.  No need to die, just stop
> > removing the leading directories once it hits the cwd (much like it'd
> > stop once it hit a directory that had files left in it).
>
> I can buy that we'd pick this new behavior as a worthwhile trade-off,
> but not that anyone intended for this to be the behavior all along.
>
> I don't think "a process is sitting in it" has ever been anyone's idea
> of a "non-empty directory". Rather it's what rmdir() returning EEXIST or
> ENOTEMPTY maps to.

Yeah, Junio commented on my reasoning in that same paragraph of mine. Bad reasoning on my part, and you were both right to call it out.

But that reasoning wasn't the underlying motivation for Peff to suggest the behavior behind this series[1] and this patch, nor the rationale Junio used to say that the overall behavioral change behind this series "makes sense".[2]

[1] https://lore.kernel.org/git/YS8eEtwQvF7TaLCb@coredump.intra.peff.net/ [2] https://lore.kernel.org/git/xmqqo86elyht.fsf@gitster.g/

> Doesn't this series also change the behavior of e.g.:
>
>     cd contrib/subtree
>     git rm -r ../subtree
Yes, of course!
Before:
    $ cd contrib/subtree
    $ git rm -r -q ../subtree/
    $ ls -ld ../subtree/
    ls: cannot access '../subtree/': No such file or directory
    $ git status --porcelain
    fatal: Unable to read current working directory: No such file or directory
    $ git checkout HEAD ../subtree/
    fatal: Unable to read current working directory: No such file or directory
After:
    $ cd contrib/subtree
    $ git rm -r -q ../subtree/
    $ ls -ld ../subtree/
    drwxrwxr-x. 1 newren newren 0 Nov 23 19:18 ../subtree/
    $ git status --porcelain
    D  contrib/subtree/.gitignore
    D  contrib/subtree/COPYING
    D  contrib/subtree/INSTALL
    D  contrib/subtree/Makefile
    D  contrib/subtree/README
    D  contrib/subtree/git-subtree.sh
    D  contrib/subtree/git-subtree.txt
    D  contrib/subtree/t/Makefile
    D  contrib/subtree/t/t7900-subtree.sh
    D  contrib/subtree/todo
    $ git checkout HEAD ../subtree/
    Updated 10 paths from c557be478e
Very nice fix, don't you think?
> If so then re the "spidey sense" comment I had earlier: There's no rm
> codepaths or tests changed by this series,

That's not correct; I explicitly added a new rm test in the first patch in my series. Further, that same test was modified to mark it as passing by this particular patch you are commenting on.

> so the implementation of
> doing it at this lower level might be casting too wide a net.

I'm getting the vibe that you are assuming I'm changing these two functions without realizing what places might be calling them; basically, that I'm just flippantly changing them. Ignoring the ramifications of such an assumption, if this vibe is correct, then let me inform you that I've read over each and every caller (as well as searched for other callers of unlink() and rmdir() throughout the tree to see if they needed similar changes). In my opinion, *each* *and* *every* *single* *one* of the calls to remove_path() and remove_dir_recursively() should take the behavioral change suggested in this patch.

It's also not clear to me that you understand the point of the change behind the series. Clearly, I'm not doing well explaining it, but have you read Peff's or Junio's comments on why they thought protecting the_original_cwd makes sense? Again, see the links [1] and [2] above. I think it'd help me understand how to respond to you better if you could clarify to me whether you disagree with them, or whether you agree with them but think I've gone wrong in the implementation of their high level explanation somehow in this particular patch.

> e.g. changing callers that use "remove_dir_recursively()" to use a
> "remove_dir_recursively_not_cwd()" (or whatever) be a gentler way of
> introducing this, and make sure that each step of the way we grok what's
> being changed, that there's test coverage etc.

I'll ask you the same two questions I asked Glen when he suggested basically the same thing; if you can provide an answer to either one of my questions that is compelling to me, I'd be totally onboard with your suggested change:

(1) Can you point to any concrete example caller anywhere in the code tree (or even provide a future hypothetical caller) that would in fact be harmed by the change in this patch?

...and no, I'm not asking you to do my work for me; I've done that same work -- in fact looking at all callsites -- and came up empty-handed. Since this and your previous email are essentially claiming that I've probably missed things, I think it's a fair question.

(2) What benefit would there be to introducing these new functions?

In particular, if I were to introduce these new functions, it would look like this:

  * add new remove_path_not_cwd() and remove_dir_recursively_not_cwd()
function in one patch
  * convert all relevant callsites to use these new functions in the
subsequent patch(es)
  * delete the existing remove_path() and remove_dir_recursively()
functions for two reasons: (1) they are now unused, and (2) future
potential callers of these old functions would more than likely
reintroduce the bugs this series is trying to fix if they were to use
them and should be discouraged from doing so
  * rename {remove_path,remove_dir_recursively}_not_cwd() to remove
the "_not_cwd" suffix in order to have more memorable and less ugly
names

Once finished, the end result would be identical to this patch. Well, identical other than taking more patches to get to the same end result and using up more reviewer time. If there's some benefit to taking this circuitous route, though, I'm more than willing to do so.

Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 35 of 163 in “Avoid removing the current working directory, even if it becomes empty”
  1. 0/8 Avoid removing the current working directory, even if it becomes emptyElijah Newren via GitGitGadget, Nov 21, 2021
  2. 2/8 repository, setup: introduce the_cwdElijah Newren via GitGitGadget, Nov 21, 2021
  3. Junio C HamanoNov 21, 2021
  4. Elijah NewrenNov 22, 2021
  5. René ScharfeNov 21, 2021
  6. Elijah NewrenNov 22, 2021
  7. 1/8 t2501: add various tests for removing the current working directoryElijah Newren via GitGitGadget, Nov 21, 2021
  8. Ævar Arnfjörð BjarmasonNov 21, 2021
  9. Elijah NewrenNov 23, 2021
  10. Ævar Arnfjörð BjarmasonNov 23, 2021
  11. Elijah NewrenNov 23, 2021
  12. Ævar Arnfjörð BjarmasonNov 25, 2021
  13. 4/8 unpack-trees: add special cwd handlingElijah Newren via GitGitGadget, Nov 21, 2021
  14. 3/8 unpack-trees: refuse to remove the current working directoryElijah Newren via GitGitGadget, Nov 21, 2021
  15. 7/8 stash: do not attempt to remove current working directoryElijah Newren via GitGitGadget, Nov 21, 2021
  16. 6/8 clean: do not attempt to remove current working directoryElijah Newren via GitGitGadget, Nov 21, 2021
  17. Ævar Arnfjörð BjarmasonNov 21, 2021
  18. Elijah NewrenNov 23, 2021
  19. 5/8 symlinks: do not include current working directory in dir removalElijah Newren via GitGitGadget, Nov 21, 2021
  20. René ScharfeNov 21, 2021
  21. Elijah NewrenNov 23, 2021
  22. 8/8 dir: avoid removing the current working directoryElijah Newren via GitGitGadget, Nov 21, 2021
  23. Glen ChooNov 23, 2021
  24. Elijah NewrenNov 23, 2021
  25. Glen ChooNov 23, 2021
  26. Elijah NewrenNov 23, 2021
  27. Glen ChooNov 23, 2021
  28. Junio C HamanoNov 23, 2021
  29. Elijah NewrenNov 23, 2021
  30. Junio C HamanoNov 24, 2021
  31. Elijah NewrenNov 23, 2021
  32. Glen ChooNov 24, 2021
  33. Junio C HamanoNov 24, 2021
  34. Ævar Arnfjörð BjarmasonNov 24, 2021
  35. Elijah NewrenNov 24, 2021
  36. Ævar Arnfjörð BjarmasonNov 24, 2021
  37. Philip OakleyNov 24, 2021
  38. Junio C HamanoNov 24, 2021
  39. Philip OakleyNov 25, 2021
  40. Ævar Arnfjörð BjarmasonNov 25, 2021
  41. Ævar Arnfjörð BjarmasonNov 24, 2021
  42. Elijah NewrenNov 25, 2021
  43. Ævar Arnfjörð BjarmasonNov 25, 2021
  44. The overhead of bin-wrappers/ (was: [PATCH 8/8] dir: avoid removing the current working directory)Ævar Arnfjörð Bjarmason, Nov 26, 2021
  45. Elijah NewrenNov 25, 2021
  46. Junio C HamanoNov 24, 2021
  47. Junio C HamanoNov 21, 2021
  48. 0/9 Avoid removing the current working directory, even if it becomes emptyElijah Newren via GitGitGadget, Nov 25, 2021
  49. 1/9 t2501: add various tests for removing the current working directoryElijah Newren via GitGitGadget, Nov 25, 2021
  50. Ævar Arnfjörð BjarmasonNov 25, 2021
  51. 2/9 setup: introduce startup_info->original_cwdElijah Newren via GitGitGadget, Nov 25, 2021
  52. Ævar Arnfjörð BjarmasonNov 25, 2021
  53. Elijah NewrenNov 26, 2021
  54. Junio C HamanoNov 26, 2021
  55. Elijah NewrenNov 26, 2021
  56. Derrick StoleeNov 29, 2021
  57. Junio C HamanoNov 29, 2021
  58. Elijah NewrenNov 29, 2021
  59. Derrick StoleeNov 29, 2021
  60. 3/9 unpack-trees: refuse to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 25, 2021
  61. Ævar Arnfjörð BjarmasonNov 25, 2021
  62. Elijah NewrenNov 26, 2021
  63. Derrick StoleeNov 29, 2021
  64. Elijah NewrenNov 29, 2021
  65. 4/9 unpack-trees: add special cwd handlingElijah Newren via GitGitGadget, Nov 25, 2021
  66. Derrick StoleeNov 29, 2021
  67. Elijah NewrenNov 29, 2021
  68. 5/9 symlinks: do not include startup_info->original_cwd in dir removalElijah Newren via GitGitGadget, Nov 25, 2021
  69. 7/9 stash: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 25, 2021
  70. Ævar Arnfjörð BjarmasonNov 25, 2021
  71. Elijah NewrenNov 26, 2021
  72. 6/9 clean: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 25, 2021
  73. 8/9 dir: avoid incidentally removing the original_cwd in remove_path()Elijah Newren via GitGitGadget, Nov 25, 2021
  74. 9/9 dir: new flag to remove_dir_recurse() to spare the original_cwdElijah Newren via GitGitGadget, Nov 25, 2021
  75. 00/11 Avoid removing the current working directory, even if it becomes emptyElijah Newren via GitGitGadget, Nov 26, 2021
  76. 01/11 t2501: add various tests for removing the current working directoryElijah Newren via GitGitGadget, Nov 26, 2021
  77. Ævar Arnfjörð BjarmasonNov 27, 2021
  78. Elijah NewrenNov 27, 2021
  79. 02/11 setup: introduce startup_info->original_cwdElijah Newren via GitGitGadget, Nov 26, 2021
  80. Ævar Arnfjörð BjarmasonNov 27, 2021
  81. Elijah NewrenNov 27, 2021
  82. Ævar Arnfjörð BjarmasonNov 27, 2021
  83. Elijah NewrenNov 27, 2021
  84. Ævar Arnfjörð BjarmasonNov 28, 2021
  85. Elijah NewrenNov 29, 2021
  86. 03/11 unpack-trees: refuse to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 26, 2021
  87. 04/11 unpack-trees: add special cwd handlingElijah Newren via GitGitGadget, Nov 26, 2021
  88. 05/11 symlinks: do not include startup_info->original_cwd in dir removalElijah Newren via GitGitGadget, Nov 26, 2021
  89. 06/11 clean: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 26, 2021
  90. 10/11 dir: new flag to remove_dir_recurse() to spare the original_cwdElijah Newren via GitGitGadget, Nov 26, 2021
  91. 07/11 rebase: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 26, 2021
  92. Derrick StoleeNov 29, 2021
  93. Elijah NewrenNov 29, 2021
  94. Derrick StoleeNov 29, 2021
  95. 09/11 dir: avoid incidentally removing the original_cwd in remove_path()Elijah Newren via GitGitGadget, Nov 26, 2021
  96. 08/11 stash: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 26, 2021
  97. 11/11 t2501: simplify the tests since we can now assume desired behaviorElijah Newren via GitGitGadget, Nov 26, 2021
  98. Derrick StoleeNov 29, 2021
  99. 00/11 Avoid removing the current working directory, even if it becomes emptyElijah Newren via GitGitGadget, Nov 29, 2021
  100. 06/11 clean: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 29, 2021
  101. 04/11 unpack-trees: add special cwd handlingElijah Newren via GitGitGadget, Nov 29, 2021
  102. 10/11 dir: new flag to remove_dir_recurse() to spare the original_cwdElijah Newren via GitGitGadget, Nov 29, 2021
  103. 05/11 symlinks: do not include startup_info->original_cwd in dir removalElijah Newren via GitGitGadget, Nov 29, 2021
  104. 08/11 stash: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 29, 2021
  105. 03/11 unpack-trees: refuse to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 29, 2021
  106. 07/11 rebase: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Nov 29, 2021
  107. 09/11 dir: avoid incidentally removing the original_cwd in remove_path()Elijah Newren via GitGitGadget, Nov 29, 2021
  108. 01/11 t2501: add various tests for removing the current working directoryElijah Newren via GitGitGadget, Nov 29, 2021
  109. Junio C HamanoNov 30, 2021
  110. Elijah NewrenNov 30, 2021
  111. 11/11 t2501: simplify the tests since we can now assume desired behaviorElijah Newren via GitGitGadget, Nov 29, 2021
  112. 02/11 setup: introduce startup_info->original_cwdElijah Newren via GitGitGadget, Nov 29, 2021
  113. Eric SunshineNov 29, 2021
  114. Elijah NewrenNov 30, 2021
  115. 00/11 Avoid removing the current working directory, even if it becomes emptyElijah Newren via GitGitGadget, Dec 1, 2021
  116. 01/11 t2501: add various tests for removing the current working directoryElijah Newren via GitGitGadget, Dec 1, 2021
  117. 02/11 setup: introduce startup_info->original_cwdElijah Newren via GitGitGadget, Dec 1, 2021
  118. 03/11 unpack-trees: refuse to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 1, 2021
  119. 04/11 unpack-trees: add special cwd handlingElijah Newren via GitGitGadget, Dec 1, 2021
  120. 05/11 symlinks: do not include startup_info->original_cwd in dir removalElijah Newren via GitGitGadget, Dec 1, 2021
  121. 06/11 clean: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 1, 2021
  122. 07/11 rebase: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 1, 2021
  123. [Bug] Rebase from worktree subdir is broken (was Re: [PATCH v5 07/11] rebase: do not attempt to remove startup_info->original_cwd)Glen Choo, Jan 25, 2022
  124. Elijah NewrenJan 25, 2022
  125. Glen ChooJan 26, 2022
  126. Elijah NewrenJan 26, 2022
  127. Eric SunshineJan 26, 2022
  128. Eric SunshineJan 26, 2022
  129. Elijah NewrenJan 26, 2022
  130. Glen ChooJan 26, 2022
  131. Elijah NewrenJan 26, 2022
  132. Phillip WoodJan 26, 2022
  133. Eric SunshineJan 26, 2022
  134. Phillip WoodJan 27, 2022
  135. Elijah NewrenJan 27, 2022
  136. Eric SunshineFeb 5, 2022
  137. Eric SunshineFeb 5, 2022
  138. Elijah NewrenFeb 5, 2022
  139. 08/11 stash: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 1, 2021
  140. 09/11 dir: avoid incidentally removing the original_cwd in remove_path()Elijah Newren via GitGitGadget, Dec 1, 2021
  141. 10/11 dir: new flag to remove_dir_recurse() to spare the original_cwdElijah Newren via GitGitGadget, Dec 1, 2021
  142. 11/11 t2501: simplify the tests since we can now assume desired behaviorElijah Newren via GitGitGadget, Dec 1, 2021
  143. Derrick StoleeDec 7, 2021
  144. Ævar Arnfjörð BjarmasonDec 7, 2021
  145. Derrick StoleeDec 7, 2021
  146. Ævar Arnfjörð BjarmasonDec 8, 2021
  147. Elijah NewrenDec 7, 2021
  148. Derrick StoleeDec 7, 2021
  149. 00/11 Avoid removing the current working directory, even if it becomes emptyElijah Newren via GitGitGadget, Dec 9, 2021
  150. 01/11 t2501: add various tests for removing the current working directoryElijah Newren via GitGitGadget, Dec 9, 2021
  151. Ævar Arnfjörð BjarmasonMar 11, 2022
  152. 02/11 setup: introduce startup_info->original_cwdElijah Newren via GitGitGadget, Dec 9, 2021
  153. 03/11 unpack-trees: refuse to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 9, 2021
  154. 04/11 unpack-trees: add special cwd handlingElijah Newren via GitGitGadget, Dec 9, 2021
  155. 06/11 clean: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 9, 2021
  156. 05/11 symlinks: do not include startup_info->original_cwd in dir removalElijah Newren via GitGitGadget, Dec 9, 2021
  157. 07/11 rebase: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 9, 2021
  158. 08/11 stash: do not attempt to remove startup_info->original_cwdElijah Newren via GitGitGadget, Dec 9, 2021
  159. 09/11 dir: avoid incidentally removing the original_cwd in remove_path()Elijah Newren via GitGitGadget, Dec 9, 2021
  160. 10/11 dir: new flag to remove_dir_recurse() to spare the original_cwdElijah Newren via GitGitGadget, Dec 9, 2021
  161. 11/11 t2501: simplify the tests since we can now assume desired behaviorElijah Newren via GitGitGadget, Dec 9, 2021
  162. Phillip WoodNov 30, 2021
  163. Elijah NewrenDec 1, 2021

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.