summaryrefslogtreecommitdiff
path: root/builtin/mv.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/mv.c')
-rw-r--r--builtin/mv.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/builtin/mv.c b/builtin/mv.c
index d1d43168ae..2f43877bc9 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -24,8 +24,9 @@ static const char **internal_copy_pathspec(const char *prefix,
int count, unsigned flags)
{
int i;
- const char **result = xmalloc((count + 1) * sizeof(const char *));
- memcpy(result, pathspec, count * sizeof(const char *));
+ const char **result;
+ ALLOC_ARRAY(result, count + 1);
+ COPY_ARRAY(result, pathspec, count);
result[count] = NULL;
for (i = 0; i < count; i++) {
int length = strlen(result[i]);
@@ -47,9 +48,9 @@ static const char **internal_copy_pathspec(const char *prefix,
static const char *add_slash(const char *path)
{
- int len = strlen(path);
+ size_t len = strlen(path);
if (path[len - 1] != '/') {
- char *with_slash = xmalloc(len + 2);
+ char *with_slash = xmalloc(st_add(len, 2));
memcpy(with_slash, path, len);
with_slash[len++] = '/';
with_slash[len] = 0;
@@ -103,7 +104,7 @@ static int index_range_of_same_dir(const char *src, int length,
int cmd_mv(int argc, const char **argv, const char *prefix)
{
- int i, gitmodules_modified = 0;
+ int i, flags, gitmodules_modified = 0;
int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
struct option builtin_mv_options[] = {
OPT__VERBOSE(&verbose, N_("be verbose")),
@@ -133,10 +134,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
modes = xcalloc(argc, sizeof(enum update_mode));
/*
* Keep trailing slash, needed to let
- * "git mv file no-such-dir/" error out.
+ * "git mv file no-such-dir/" error out, except in the case
+ * "git mv directory no-such-dir/".
*/
- dest_path = internal_copy_pathspec(prefix, argv + argc, 1,
- KEEP_TRAILING_SLASH);
+ flags = KEEP_TRAILING_SLASH;
+ if (argc == 1 && is_directory(argv[0]) && !is_directory(argv[1]))
+ flags = 0;
+ dest_path = internal_copy_pathspec(prefix, argv + argc, 1, flags);
submodule_gitfile = xcalloc(argc, sizeof(char *));
if (dest_path[0][0] == '\0')
@@ -251,15 +255,18 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
int pos;
if (show_only || verbose)
printf(_("Renaming %s to %s\n"), src, dst);
- if (!show_only && mode != INDEX) {
- if (rename(src, dst) < 0 && !ignore_errors)
- die_errno(_("renaming '%s' failed"), src);
- if (submodule_gitfile[i]) {
- if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
- connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
- if (!update_path_in_gitmodules(src, dst))
- gitmodules_modified = 1;
- }
+ if (show_only)
+ continue;
+ if (mode != INDEX && rename(src, dst) < 0) {
+ if (ignore_errors)
+ continue;
+ die_errno(_("renaming '%s' failed"), src);
+ }
+ if (submodule_gitfile[i]) {
+ if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
+ connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
+ if (!update_path_in_gitmodules(src, dst))
+ gitmodules_modified = 1;
}
if (mode == WORKING_DIRECTORY)