From: Hugo Sales <hugo@hsal.es>
To: git@vger.kernel.org
Cc: Hugo Sales <hugo@hsal.es>
Subject: [PATCH 1/3] mv: Add -p option to create parent directories
Date: Tue, 10 Oct 2023 00:34:56 +0100 [thread overview]
Message-ID: <20231009233458.1371351-2-hugo@hsal.es> (raw)
In-Reply-To: <20231009233458.1371351-1-hugo@hsal.es>
Inspired by "mkdir -p", this patch allows specifying a "-p" or
"--parents" flag which will create all non-existent directories in the
destination path before renaming the file.
This allows the user to not have to run two commands to move files to a
new directory.
Signed-off-by: Hugo Sales <hugo@hsal.es>
---
builtin/mv.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/builtin/mv.c b/builtin/mv.c
index c596515ad0..5d64d86179 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -168,7 +168,7 @@ static int empty_dir_has_sparse_contents(const char *name)
int cmd_mv(int argc, const char **argv, const char *prefix)
{
int i, flags, gitmodules_modified = 0;
- int verbose = 0, show_only = 0, force = 0, ignore_errors = 0, ignore_sparse = 0;
+ int verbose = 0, show_only = 0, force = 0, ignore_errors = 0, ignore_sparse = 0, create_parents = 0;
struct option builtin_mv_options[] = {
OPT__VERBOSE(&verbose, N_("be verbose")),
OPT__DRY_RUN(&show_only, N_("dry run")),
@@ -176,6 +176,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
PARSE_OPT_NOCOMPLETE),
OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")),
OPT_BOOL(0, "sparse", &ignore_sparse, N_("allow updating entries outside of the sparse-checkout cone")),
+ OPT_BOOL('p', "parents", &create_parents, N_("create missing parent directories")),
OPT_END(),
};
const char **source, **destination, **dest_path, **submodule_gitfile;
@@ -220,8 +221,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (dest_path[0][0] == '\0')
/* special case: "." was normalized to "" */
destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
- else if (!lstat(dest_path[0], &st) &&
- S_ISDIR(st.st_mode)) {
+ else if (create_parents ||
+ (!lstat(dest_path[0], &st) && S_ISDIR(st.st_mode))) {
destination = internal_prefix_pathspec(dst_w_slash, argv, argc, DUP_BASENAME);
} else {
if (!path_in_sparse_checkout(dst_w_slash, &the_index) &&
@@ -381,7 +382,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
bad = _("multiple sources for the same target");
goto act_on_entry;
}
- if (is_dir_sep(dst[strlen(dst) - 1])) {
+
+ if (!create_parents && is_dir_sep(dst[strlen(dst) - 1])) {
bad = _("destination directory does not exist");
goto act_on_entry;
}
@@ -459,11 +461,18 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (show_only)
continue;
if (!(mode & (INDEX | SPARSE | SKIP_WORKTREE_DIR)) &&
- !(dst_mode & (SKIP_WORKTREE_DIR | SPARSE)) &&
- rename(src, dst) < 0) {
- if (ignore_errors)
- continue;
- die_errno(_("renaming '%s' failed"), src);
+ !(dst_mode & (SKIP_WORKTREE_DIR | SPARSE))) {
+ if (create_parents && safe_create_leading_directories_const(dst) < 0) {
+ if (ignore_errors)
+ continue;
+ die_errno(_("creating parent directories for '%s' failed"), dst);
+ }
+
+ if (rename(src, dst) < 0) {
+ if (ignore_errors)
+ continue;
+ die_errno(_("renaming '%s' failed"), src);
+ }
}
if (submodule_gitfile[i]) {
if (!update_path_in_gitmodules(src, dst))
--
2.42.0
next prev parent reply other threads:[~2023-10-09 23:35 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-09 23:34 [PATCH 0/3] Add `-p' option to `git-mv', inspired by `mkdir' Hugo Sales
2023-10-09 23:34 ` Hugo Sales [this message]
2023-10-09 23:34 ` [PATCH 2/3] mv: Add tests for new -p flag Hugo Sales
2023-10-09 23:34 ` [PATCH 3/3] mv: Add documentation for new `-p' flag Hugo Sales
2023-10-10 0:39 ` [PATCH 0/3] Add `-p' option to `git-mv', inspired by `mkdir' Junio C Hamano
2023-10-10 0:59 ` Junio C Hamano
2023-10-11 12:33 ` Hugo Sales
2023-10-31 4:30 ` Junio C Hamano
2023-10-31 4:54 ` Dragan Simic
2023-10-31 5:58 ` Junio C Hamano
2023-10-31 6:38 ` Dragan Simic
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=20231009233458.1371351-2-hugo@hsal.es \
--to=hugo@hsal.es \
--cc=git@vger.kernel.org \
/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;
as well as URLs for NNTP newsgroup(s).