From: "Lucas Zamboni Orioli via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Ben Knoble <ben.knoble@gmail.com>,
Lucas Zamboni Orioli <lucaszam0@gmail.com>
Subject: [PATCH v2 0/2] mv: report missing destination leading directory
Date: Thu, 23 Jul 2026 13:13:08 +0000 [thread overview]
Message-ID: <pull.2356.v2.git.git.1784812390.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2356.git.git.1784125963694.gitgitgadget@gmail.com>
Changes since v1:
* altered the error message to include both source and destination as
suggested by Ben Knoble
Lucas Zamboni Orioli (2):
mv: name both source and destination when rename fails
mv: check for missing destination directory before renaming
builtin/mv.c | 23 ++++++++++++++++++++++-
t/t7001-mv.sh | 14 ++++++++++++++
2 files changed, 36 insertions(+), 1 deletion(-)
base-commit: 9a0c4701dcd5725c4184599322b52933ff5005ca
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2356%2FZamboniL%2Fmv-detect-non-existing-target-folder-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2356/ZamboniL/mv-detect-non-existing-target-folder-v2
Pull-Request: https://github.com/git/git/pull/2356
Range-diff vs v1:
-: ---------- > 1: 0d67da588b mv: name both source and destination when rename fails
1: 692f44456f ! 2: 1a790e0016 mv: report missing destination leading directory
@@ Metadata
Author: Lucas Zamboni Orioli <lucaszam0@gmail.com>
## Commit message ##
- mv: report missing destination leading directory
+ mv: check for missing destination directory before renaming
- When moving a file to a destination whose leading directory does not
- exist, "git mv" fails at the rename(2) syscall with ENOENT. Because
- the error is reported via die_errno() using only the source path:
+ Moving a file into a directory that does not exist fails at rename(2)
+ with ENOENT. The checking phase already rejects a missing destination
+ directory when the destination ends in a slash, but a destination that
+ names a file inside a non-existent directory is not caught and only
+ fails later at the syscall. As a consequence "git mv -n" does not
+ detect the problem either: the dry run never reaches rename(2) and
+ reports a move that would not actually succeed.
- fatal: renaming 'src' failed: No such file or directory
+ Detect this during the checking phase. For entries that will be renamed
+ on disk, stat the destination's leading directory and, if it is
+ missing, fail with the existing "destination directory does not exist"
+ message. Guard the check with the same condition under which rename(2)
+ is invoked, so that directory moves, whose child entries are expanded
+ to paths under a not-yet-created directory, and sparse or out-of-cone
+ destinations, which are not written to the worktree, are not flagged
+ incorrectly.
- the message misleadingly blames the source, even though it is the
- destination's parent directory that is missing. A user who runs
+ This is a best-effort diagnostic rather than a guarantee: the
+ destination directory can still disappear between the check and the
+ rename(2). It fixes the common case and, unlike the syscall path,
+ lets "git mv -n" report the failure.
- git mv a/file b/does-not-exist/file
-
- is told the problem is with 'a/file', which exists, giving no hint
- that 'b/does-not-exist/' needs to be created first.
-
- The checking phase already rejects a missing destination directory
- when the destination ends in a slash, but a destination that names a
- file inside a non-existent directory is not caught and only fails
- later at rename(2). As a result "git mv -n" also fails to detect the
- problem, since the dry run never reaches the syscall and reports a
- move that would not actually succeed.
-
- Detect this during the checking phase instead: for entries that will
- be renamed on disk, stat the destination's leading directory and, if
- it is missing, fail with the existing "destination directory does not
- exist" message. Guard the check with the same condition under which
- rename(2) is invoked so that directory moves, whose child entries are
- expanded to paths under a not-yet-created directory, and sparse or
- out-of-cone destinations, which are not written to the worktree, are
- not flagged incorrectly.
-
- This gives a clear message and lets "git mv -n" report the failure.
+ Add tests covering both the error path and the dry-run detection.
Signed-off-by: Lucas Zamboni Orioli <lucaszam0@gmail.com>
--
gitgitgadget
next prev parent reply other threads:[~2026-07-23 13:13 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-15 14:32 [PATCH] mv: report missing destination leading directory Lucas Zamboni Orioli via GitGitGadget
2026-07-15 16:46 ` Ben Knoble
2026-07-22 21:32 ` Lucas Zamboni Orioli
2026-07-23 13:13 ` Lucas Zamboni Orioli via GitGitGadget [this message]
2026-07-23 13:13 ` [PATCH v2 1/2] mv: name both source and destination when rename fails Lucas Zamboni Orioli via GitGitGadget
2026-07-23 17:36 ` Junio C Hamano
2026-07-23 13:13 ` [PATCH v2 2/2] mv: check for missing destination directory before renaming Lucas Zamboni Orioli via GitGitGadget
2026-07-23 17:42 ` Junio C Hamano
2026-07-23 18:30 ` Junio C Hamano
2026-07-23 21:38 ` Lucas Zamboni Orioli
2026-07-23 22:40 ` Junio C Hamano
2026-07-23 23:28 ` Junio C Hamano
2026-07-23 21:40 ` [PATCH v3 0/2] mv: report missing destination leading directory Lucas Zamboni Orioli via GitGitGadget
2026-07-23 21:40 ` [PATCH v3 1/2] mv: name both source and destination when rename fails Lucas Zamboni Orioli via GitGitGadget
2026-07-23 21:40 ` [PATCH v3 2/2] mv: check for missing destination directory before renaming Lucas Zamboni Orioli via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.2356.v2.git.git.1784812390.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=ben.knoble@gmail.com \
--cc=git@vger.kernel.org \
--cc=lucaszam0@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox