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

Re: [PATCH v2 2/2] mv: check for missing destination directory before renaming

From
Junio C Hamano <gitster@pobox.com>
Date
Jul 26, 2026, 14:59 UTC
Message-ID
<xmqqik61yeyn.fsf@gitster.g>
In-Reply-To
<xmqqcxwdcmln.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
Show 24 quoted lines
> Lucas Zamboni Orioli <lucaszam0@gmail.com> writes:
>
>>> lstat() can succeed and 'dir_st' may indicate something other than a
>>> directory (for example, a symbolic link or a regular file).
>>> Alternatively, it can fail with ENOTDIR when, for example, 'dst_dir'
>>> is 'a/b/c' and 'a/b' is a file rather than a directory.
>>>
>>> Both cases will cause 'git mv' into a path assumed to be a directory
>>> to fail.  Shouldn't we handle these conditions as well?
>>
>> Yes, agreed, both should be handled. For v3 I switched from lstat()
>> to stat() so that the check follows symlinks the same way rename()
>> does, and I handle the non-directory cases:
>
> Generally, a symbolic link in a Git-managed working tree should not
> be followed.  Following a symbolic link would mean that 'git mv x y'
> could move 'x' outside the working tree if 'y' is a tracked symbolic
> link pointing to a directory outside the working tree.  'git apply',
> for example, avoids being fooled by a symbolic link for the same
> reason.
>
> I doubt that using stat() instead of lstat() is the right approach.
> Doing so essentially amounts to ignoring the presence of symbolic
> links.

I actually think "outside the working tree" is an irrelevant red herring. What is relevant is the fact that Git tracks symbolic links.

If you have x (file) and y (another file), you would want to complain when the user says:

    $ git mv x y  

because the location y is "taken" and the command line tells us only about what it wants to do to x, without saying anything about what you want to do to that existing y. If y were a symbolic link instead, you should behave exactly the same way.

It actually takes even more care, and I do not know if the implementation of git-mv is done carefully enough, but think about what should happen to:

    $ git mv x a/b/c  

when 'a' is a tracked symbolic link, and it points at, say, '.'. Should it behave exactly the same as:

    $ git mv x b/c  

or should it simply error out? I think the latter, "I see a symlink in the middle, so I refuse to follow," is the right behavior.

Think carefully about cases where 'a' is a directory and 'a/b' is a symlink, or where 'a' and 'a/b' are directories and 'a/b/c' is a symlink, and so on. We do not want to craft an arbitrary rule that says we allow or refuse to operate depending on the link target.

Previous: Junio C HamanoNext: Lucas Zamboni Orioli
Message 13 of 28 in “mv: report missing destination leading directory”
  1. mv: report missing destination leading directoryLucas Zamboni Orioli via GitGitGadget, Jul 15, 2026
  2. Ben KnobleJul 15, 2026
  3. Lucas Zamboni OrioliJul 22, 2026
  4. 0/2 mv: report missing destination leading directoryLucas Zamboni Orioli via GitGitGadget, Jul 23, 2026
  5. 1/2 mv: name both source and destination when rename failsLucas Zamboni Orioli via GitGitGadget, Jul 23, 2026
  6. Junio C HamanoJul 23, 2026
  7. 2/2 mv: check for missing destination directory before renamingLucas Zamboni Orioli via GitGitGadget, Jul 23, 2026
  8. Junio C HamanoJul 23, 2026
  9. Junio C HamanoJul 23, 2026
  10. Lucas Zamboni OrioliJul 23, 2026
  11. Junio C HamanoJul 23, 2026
  12. Junio C HamanoJul 23, 2026
  13. Junio C HamanoJul 26, 2026
  14. Lucas Zamboni OrioliJul 26, 2026
  15. 0/2 mv: report missing destination leading directoryLucas Zamboni Orioli via GitGitGadget, Jul 23, 2026
  16. 1/2 mv: name both source and destination when rename failsLucas Zamboni Orioli via GitGitGadget, Jul 23, 2026
  17. 2/2 mv: check for missing destination directory before renamingLucas Zamboni Orioli via GitGitGadget, Jul 23, 2026
  18. Pablo SabaterJul 26, 2026
  19. 0/2 mv: report missing destination leading directoryLucas Zamboni Orioli via GitGitGadget, Jul 26, 2026
  20. 1/2 mv: name both source and destination when rename failsLucas Zamboni Orioli via GitGitGadget, Jul 26, 2026
  21. 2/2 mv: reject a destination whose leading path is missing or a symlinkLucas Zamboni Orioli via GitGitGadget, Jul 26, 2026
  22. Junio C HamanoJul 27, 2026
  23. Lucas Zamboni OrioliJul 30, 2026
  24. Junio C HamanoJul 26, 2026
  25. 0/2 mv: report missing destination leading directoryLucas Zamboni Orioli via GitGitGadget, Jul 30, 2026
  26. 1/2 mv: name both source and destination when rename failsLucas Zamboni Orioli via GitGitGadget, Jul 30, 2026
  27. 2/2 mv: reject a destination whose leading path is missing or a symlinkLucas Zamboni Orioli via GitGitGadget, Jul 30, 2026
  28. Junio C HamanoJul 30, 2026

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.