From 09d5dc32fbdfa7bfd23fe377455445dd2605c3b9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 13 Sep 2007 20:33:11 -0700 Subject: Simplify cache API Earlier, add_file_to_index() invalidated the path in the cache-tree but remove_file_from_cache() did not, and the user of the latter needed to invalidate the entry himself. This led to a few bugs due to missed invalidate calls already. This patch makes the management of cache-tree less error prone by making more invalidate calls from lower level cache API functions. The rules are: - If you are going to write the index, you should either maintain cache_tree correctly. - If you cannot, alternatively you can remove the entire cache_tree by calling cache_tree_free() before you call write_cache(). - When you modify the index, cache_tree_invalidate_path() should be called with the path you are modifying, to discard the entry from the cache-tree structure. - The following cache API functions exported from read-cache.c (and the macro whose names have "cache" instead of "index") automatically call cache_tree_invalidate_path() for you: - remove_file_from_index(); - add_file_to_index(); - add_index_entry(); You can modify the index bypassing the above API functions (e.g. find an existing cache entry from the index and modify it in place). You need to call cache_tree_invalidate_path() yourself in such a case. Signed-off-by: Junio C Hamano --- builtin-mv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 3563216aca..b95b7d286a 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -276,11 +276,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) add_file_to_cache(path, verbose); } - for (i = 0; i < deleted.nr; i++) { - const char *path = deleted.items[i].path; - remove_file_from_cache(path); - cache_tree_invalidate_path(active_cache_tree, path); - } + for (i = 0; i < deleted.nr; i++) + remove_file_from_cache(deleted.items[i].path); if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || -- cgit v1.2.3 From 182af8343c307436bb5364309aa6d4d46fa5911d Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 16 Sep 2007 00:32:36 +0200 Subject: Use xmemdupz() in many places. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- builtin-mv.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index b95b7d286a..b944651691 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -22,10 +22,7 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, for (i = 0; i < count; i++) { int length = strlen(result[i]); if (length > 0 && result[i][length - 1] == '/') { - char *without_slash = xmalloc(length); - memcpy(without_slash, result[i], length - 1); - without_slash[length - 1] = '\0'; - result[i] = without_slash; + result[i] = xmemdupz(result[i], length - 1); } if (base_name) { const char *last_slash = strrchr(result[i], '/'); -- cgit v1.2.3 From c7a20c117fedd40652d446e58b3eba7e2420fa47 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 7 Oct 2007 14:19:33 +0200 Subject: Make builtin-mv.c use parse-options Signed-off-by: Pierre Habouzit Signed-off-by: Shawn O. Pearce --- builtin-mv.c | 84 +++++++++++++++++++++++++----------------------------------- 1 file changed, 35 insertions(+), 49 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index b944651691..a3f9ad1744 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -8,9 +8,12 @@ #include "dir.h" #include "cache-tree.h" #include "path-list.h" +#include "parse-options.h" -static const char builtin_mv_usage[] = -"git-mv [-n] [-f] ( | [-k] ... )"; +static const char * const builtin_mv_usage[] = { + "git-mv [options] ... ", + NULL +}; static const char **copy_pathspec(const char *prefix, const char **pathspec, int count, int base_name) @@ -61,8 +64,14 @@ static struct lock_file lock_file; int cmd_mv(int argc, const char **argv, const char *prefix) { - int i, newfd, count; + int i, newfd; int verbose = 0, show_only = 0, force = 0, ignore_errors = 0; + struct option builtin_mv_options[] = { + OPT__DRY_RUN(&show_only), + OPT_BOOLEAN('f', NULL, &force, "force move/rename even if target exists"), + OPT_BOOLEAN('k', NULL, &ignore_errors, "skip move/rename errors"), + OPT_END(), + }; const char **source, **destination, **dest_path; enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes; struct stat st; @@ -78,52 +87,29 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die("index file corrupt"); - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; + argc = parse_options(argc, argv, builtin_mv_options, builtin_mv_usage, 0); + if (--argc < 1) + usage_with_options(builtin_mv_usage, builtin_mv_options); - if (arg[0] != '-') - break; - if (!strcmp(arg, "--")) { - i++; - break; - } - if (!strcmp(arg, "-n")) { - show_only = 1; - continue; - } - if (!strcmp(arg, "-f")) { - force = 1; - continue; - } - if (!strcmp(arg, "-k")) { - ignore_errors = 1; - continue; - } - usage(builtin_mv_usage); - } - count = argc - i - 1; - if (count < 1) - usage(builtin_mv_usage); - - source = copy_pathspec(prefix, argv + i, count, 0); - modes = xcalloc(count, sizeof(enum update_mode)); - dest_path = copy_pathspec(prefix, argv + argc - 1, 1, 0); + source = copy_pathspec(prefix, argv, argc, 0); + modes = xcalloc(argc, sizeof(enum update_mode)); + dest_path = copy_pathspec(prefix, argv + argc, 1, 0); if (dest_path[0][0] == '\0') /* special case: "." was normalized to "" */ - destination = copy_pathspec(dest_path[0], argv + i, count, 1); + destination = copy_pathspec(dest_path[0], argv, argc, 1); else if (!lstat(dest_path[0], &st) && S_ISDIR(st.st_mode)) { dest_path[0] = add_slash(dest_path[0]); - destination = copy_pathspec(dest_path[0], argv + i, count, 1); + destination = copy_pathspec(dest_path[0], argv, argc, 1); } else { - if (count != 1) - usage(builtin_mv_usage); + if (argc != 1) + usage_with_options(builtin_mv_usage, builtin_mv_options); destination = dest_path; } /* Checking */ - for (i = 0; i < count; i++) { + for (i = 0; i < argc; i++) { const char *src = source[i], *dst = destination[i]; int length, src_is_dir; const char *bad = NULL; @@ -167,13 +153,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (last - first > 0) { source = xrealloc(source, - (count + last - first) + (argc + last - first) * sizeof(char *)); destination = xrealloc(destination, - (count + last - first) + (argc + last - first) * sizeof(char *)); modes = xrealloc(modes, - (count + last - first) + (argc + last - first) * sizeof(enum update_mode)); } @@ -183,13 +169,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix) for (j = 0; j < last - first; j++) { const char *path = active_cache[first + j]->name; - source[count + j] = path; - destination[count + j] = + source[argc + j] = path; + destination[argc + j] = prefix_path(dst, dst_len, path + length); - modes[count + j] = INDEX; + modes[argc + j] = INDEX; } - count += last - first; + argc += last - first; } } else if (lstat(dst, &st) == 0) { bad = "destination exists"; @@ -216,12 +202,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (bad) { if (ignore_errors) { - if (--count > 0) { + if (--argc > 0) { memmove(source + i, source + i + 1, - (count - i) * sizeof(char *)); + (argc - i) * sizeof(char *)); memmove(destination + i, destination + i + 1, - (count - i) * sizeof(char *)); + (argc - i) * sizeof(char *)); } } else die ("%s, source=%s, destination=%s", @@ -229,7 +215,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } } - for (i = 0; i < count; i++) { + for (i = 0; i < argc; i++) { const char *src = source[i], *dst = destination[i]; enum update_mode mode = modes[i]; if (show_only || verbose) @@ -253,7 +239,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) path_list_insert(dst, &added); } - if (show_only) { + if (show_only) { show_list("Changed : ", &changed); show_list("Adding : ", &added); show_list("Deleting : ", &deleted); -- cgit v1.2.3 From 4ed7cd3ab07f7c721daf4241fe1dac306fefd1fb Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Wed, 16 Jan 2008 13:12:46 -0600 Subject: Improve use of lockfile API Remove remaining double close(2)'s. i.e. close() before commit_locked_index() or commit_lock_file(). Signed-off-by: Junio C Hamano --- builtin-mv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index a3f9ad1744..990e21355d 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -264,7 +264,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || - close(newfd) || commit_locked_index(&lock_file)) die("Unable to write new index file"); } -- cgit v1.2.3 From d089ebaad5315325d67db30176df1bbd7754fda9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 28 Jan 2008 22:44:27 -0800 Subject: setup: sanitize absolute and funny paths in get_pathspec() The prefix_path() function called from get_pathspec() is responsible for translating list of user-supplied pathspecs to list of pathspecs that is relative to the root of the work tree. When working inside a subdirectory, the user-supplied pathspecs are taken to be relative to the current subdirectory. Among special path components in pathspecs, we used to accept and interpret only "." ("the directory", meaning a no-op) and ".." ("up one level") at the beginning. Everything else was passed through as-is. For example, if you are in Documentation/ directory of the project, you can name Documentation/howto/maintain-git.txt as: howto/maintain-git.txt ../Documentation/howto/maitain-git.txt ../././Documentation/howto/maitain-git.txt but not as: howto/./maintain-git.txt $(pwd)/howto/maintain-git.txt This patch updates prefix_path() in several ways: - If the pathspec is not absolute, prefix (i.e. the current subdirectory relative to the root of the work tree, with terminating slash, if not empty) and the pathspec is concatenated first and used in the next step. Otherwise, that absolute pathspec is used in the next step. - Then special path components "." (no-op) and ".." (up one level) are interpreted to simplify the path. It is an error to have too many ".." to cause the intermediate result to step outside of the input to this step. - If the original pathspec was not absolute, the result from the previous step is the resulting "sanitized" pathspec. Otherwise, the result from the previous step is still absolute, and it is an error if it does not begin with the directory that corresponds to the root of the work tree. The directory is stripped away from the result and is returned. - In any case, the resulting pathspec in the array get_pathspec() returns omit the ones that caused errors. With this patch, the last two examples also behave as expected. Signed-off-by: Junio C Hamano --- builtin-mv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 990e21355d..94f6dd2aad 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -164,7 +164,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } dst = add_slash(dst); - dst_len = strlen(dst) - 1; + dst_len = strlen(dst); for (j = 0; j < last - first; j++) { const char *path = @@ -172,7 +172,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) source[argc + j] = path; destination[argc + j] = prefix_path(dst, dst_len, - path + length); + path + length + 1); modes[argc + j] = INDEX; } argc += last - first; -- cgit v1.2.3 From 744dacd3f5045240a304e687f3ef7135398e7865 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 3 Feb 2008 23:59:17 -0800 Subject: builtin-mv: minimum fix to avoid losing files An incorrect command "git mv subdir /outer/space" threw the subdirectory to outside of the repository and then noticed that /outer/space/subdir/ would be outside of the repository. The error checking is backwards. This fixes the issue by being careful about use of the return value of get_pathspec(). Since the implementation already has handcrafted loop to munge each path on the command line, we use prefix_path() instead. Signed-off-by: Junio C Hamano --- builtin-mv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 94f6dd2aad..68aa2a68bb 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -19,6 +19,7 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, int count, int base_name) { int i; + int len = prefix ? strlen(prefix) : 0; const char **result = xmalloc((count + 1) * sizeof(const char *)); memcpy(result, pathspec, count * sizeof(const char *)); result[count] = NULL; @@ -32,8 +33,11 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, if (last_slash) result[i] = last_slash + 1; } + result[i] = prefix_path(prefix, len, result[i]); + if (!result[i]) + exit(1); /* error already given */ } - return get_pathspec(prefix, result); + return result; } static void show_list(const char *label, struct path_list *list) -- cgit v1.2.3 From 971dfa19598324f49bd3a010ca629c91d6a0f758 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 6 Mar 2008 23:29:40 -0800 Subject: Revert part of 744dacd (builtin-mv: minimum fix to avoid losing files) When get_pathspec() was originally made absolute-path capable, we botched the interface to it, without dying inside the function when given a path that is outside the work tree, and made it the responsibility of callers to check the condition in a roundabout way. This is made unnecessary with the previous patch. Signed-off-by: Junio C Hamano --- builtin-mv.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 68aa2a68bb..94f6dd2aad 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -19,7 +19,6 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, int count, int base_name) { int i; - int len = prefix ? strlen(prefix) : 0; const char **result = xmalloc((count + 1) * sizeof(const char *)); memcpy(result, pathspec, count * sizeof(const char *)); result[count] = NULL; @@ -33,11 +32,8 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, if (last_slash) result[i] = last_slash + 1; } - result[i] = prefix_path(prefix, len, result[i]); - if (!result[i]) - exit(1); /* error already given */ } - return result; + return get_pathspec(prefix, result); } static void show_list(const char *label, struct path_list *list) -- cgit v1.2.3 From 960b8ad1b1824b1b82c2b09a000c2119f97633a0 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Mon, 12 May 2008 19:57:45 +0200 Subject: Make the exit code of add_file_to_index actually useful Update the programs which used the function (as add_file_to_cache). Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- builtin-mv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 94f6dd2aad..fb8ffb41aa 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -256,7 +256,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) for (i = 0; i < added.nr; i++) { const char *path = added.items[i].path; - add_file_to_cache(path, verbose); + if (add_file_to_cache(path, verbose)) + die("updating index entries failed"); } for (i = 0; i < deleted.nr; i++) -- cgit v1.2.3 From ef90d6d4208a5130185b04f06e5f90a5f9959fe3 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 14 May 2008 18:46:53 +0100 Subject: Provide git_config with a callback-data parameter git_config() only had a function parameter, but no callback data parameter. This assumes that all callback functions only modify global variables. With this patch, every callback gets a void * parameter, and it is hoped that this will help the libification effort. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 94f6dd2aad..3edebef45f 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -81,7 +81,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) struct path_list deleted = {NULL, 0, 0, 0}; struct path_list changed = {NULL, 0, 0, 0}; - git_config(git_default_config); + git_config(git_default_config, NULL); newfd = hold_locked_index(&lock_file, 1); if (read_cache() < 0) -- cgit v1.2.3 From 38ed1d89f759699de56004b08668e1764613f47b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 21 May 2008 12:04:34 -0700 Subject: "git-add -n -u" should not add but just report Signed-off-by: Junio C Hamano --- builtin-mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 94f6dd2aad..df9ea97744 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -256,7 +256,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) for (i = 0; i < added.nr; i++) { const char *path = added.items[i].path; - add_file_to_cache(path, verbose); + add_file_to_cache(path, verbose ? ADD_CACHE_VERBOSE : 0); } for (i = 0; i < deleted.nr; i++) -- cgit v1.2.3 From 1b1dd23f2d6a707b7077cdf6bc6d4055bd0bfb7d Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Sun, 13 Jul 2008 15:36:15 +0200 Subject: Make usage strings dash-less When you misuse a git command, you are shown the usage string. But this is currently shown in the dashed form. So if you just copy what you see, it will not work, when the dashed form is no longer supported. This patch makes git commands show the dash-less version. For shell scripts that do not specify OPTIONS_SPEC, git-sh-setup.sh generates a dash-less usage string now. Signed-off-by: Stephan Beyer Signed-off-by: Junio C Hamano --- builtin-mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 5530e11b89..ba9cedab6d 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -11,7 +11,7 @@ #include "parse-options.h" static const char * const builtin_mv_usage[] = { - "git-mv [options] ... ", + "git mv [options] ... ", NULL }; -- cgit v1.2.3 From c455c87c5cd42bbbe586b31cea1143132f3a39e4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 21 Jul 2008 19:03:49 +0100 Subject: Rename path_list to string_list The name path_list was correct for the first usage of that data structure, but it really is a general-purpose string list. $ perl -i -pe 's/path-list/string-list/g' $(git grep -l path-list) $ perl -i -pe 's/path_list/string_list/g' $(git grep -l path_list) $ git mv path-list.h string-list.h $ git mv path-list.c string-list.c $ perl -i -pe 's/has_path/has_string/g' $(git grep -l has_path) $ perl -i -pe 's/path/string/g' string-list.[ch] $ git mv Documentation/technical/api-path-list.txt \ Documentation/technical/api-string-list.txt $ perl -i -pe 's/strdup_paths/strdup_strings/g' $(git grep -l strdup_paths) ... and then fix all users of string-list to access the member "string" instead of "path". Documentation/technical/api-string-list.txt needed some rewrapping, too. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index ba9cedab6d..736a0b8bb1 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -7,7 +7,7 @@ #include "builtin.h" #include "dir.h" #include "cache-tree.h" -#include "path-list.h" +#include "string-list.h" #include "parse-options.h" static const char * const builtin_mv_usage[] = { @@ -36,13 +36,14 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, return get_pathspec(prefix, result); } -static void show_list(const char *label, struct path_list *list) +static void show_list(const char *label, struct string_list *list) { if (list->nr > 0) { int i; printf("%s", label); for (i = 0; i < list->nr; i++) - printf("%s%s", i > 0 ? ", " : "", list->items[i].path); + printf("%s%s", i > 0 ? ", " : "", + list->items[i].string); putchar('\n'); } } @@ -75,11 +76,11 @@ int cmd_mv(int argc, const char **argv, const char *prefix) const char **source, **destination, **dest_path; enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes; struct stat st; - struct path_list overwritten = {NULL, 0, 0, 0}; - struct path_list src_for_dst = {NULL, 0, 0, 0}; - struct path_list added = {NULL, 0, 0, 0}; - struct path_list deleted = {NULL, 0, 0, 0}; - struct path_list changed = {NULL, 0, 0, 0}; + struct string_list overwritten = {NULL, 0, 0, 0}; + struct string_list src_for_dst = {NULL, 0, 0, 0}; + struct string_list added = {NULL, 0, 0, 0}; + struct string_list deleted = {NULL, 0, 0, 0}; + struct string_list changed = {NULL, 0, 0, 0}; git_config(git_default_config, NULL); @@ -189,16 +190,16 @@ int cmd_mv(int argc, const char **argv, const char *prefix) " will overwrite!\n", bad); bad = NULL; - path_list_insert(dst, &overwritten); + string_list_insert(dst, &overwritten); } else bad = "Cannot overwrite"; } } else if (cache_name_pos(src, length) < 0) bad = "not under version control"; - else if (path_list_has_path(&src_for_dst, dst)) + else if (string_list_has_string(&src_for_dst, dst)) bad = "multiple sources for the same target"; else - path_list_insert(dst, &src_for_dst); + string_list_insert(dst, &src_for_dst); if (bad) { if (ignore_errors) { @@ -228,15 +229,15 @@ int cmd_mv(int argc, const char **argv, const char *prefix) continue; if (cache_name_pos(src, strlen(src)) >= 0) { - path_list_insert(src, &deleted); + string_list_insert(src, &deleted); /* destination can be a directory with 1 file inside */ - if (path_list_has_path(&overwritten, dst)) - path_list_insert(dst, &changed); + if (string_list_has_string(&overwritten, dst)) + string_list_insert(dst, &changed); else - path_list_insert(dst, &added); + string_list_insert(dst, &added); } else - path_list_insert(dst, &added); + string_list_insert(dst, &added); } if (show_only) { @@ -245,7 +246,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) show_list("Deleting : ", &deleted); } else { for (i = 0; i < changed.nr; i++) { - const char *path = changed.items[i].path; + const char *path = changed.items[i].string; int j = cache_name_pos(path, strlen(path)); struct cache_entry *ce = active_cache[j]; @@ -255,13 +256,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } for (i = 0; i < added.nr; i++) { - const char *path = added.items[i].path; + const char *path = added.items[i].string; if (add_file_to_cache(path, verbose ? ADD_CACHE_VERBOSE : 0)) die("updating index entries failed"); } for (i = 0; i < deleted.nr; i++) - remove_file_from_cache(deleted.items[i].path); + remove_file_from_cache(deleted.items[i].string); if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || -- cgit v1.2.3 From f6c52fe4e871d1d07cb7d86692ccf8cc4de54579 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Wed, 16 Jul 2008 21:11:08 +0200 Subject: git-mv: Remove dead code branch The path list builder had a branch for the case the source is not in index, but this can happen only if the source was a directory. However, in that case we have already expanded the list to the directory contents and set mode to WORKING_DIRECTORY, which is tested earlier. The patch removes the superfluous branch and adds an assert() instead. git-mv testsuite still passes. Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- builtin-mv.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 736a0b8bb1..e66fa54324 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -228,15 +228,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (mode == WORKING_DIRECTORY) continue; - if (cache_name_pos(src, strlen(src)) >= 0) { - string_list_insert(src, &deleted); - - /* destination can be a directory with 1 file inside */ - if (string_list_has_string(&overwritten, dst)) - string_list_insert(dst, &changed); - else - string_list_insert(dst, &added); - } else + assert(cache_name_pos(src, strlen(src)) >= 0); + + string_list_insert(src, &deleted); + /* destination can be a directory with 1 file inside */ + if (string_list_has_string(&overwritten, dst)) + string_list_insert(dst, &changed); + else string_list_insert(dst, &added); } -- cgit v1.2.3 From 81dc2307d0ad87a4da2e753a9d1b5586d6456eed Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Mon, 21 Jul 2008 02:25:56 +0200 Subject: git-mv: Keep moved index entries inact The rewrite of git-mv from a shell script to a builtin was perhaps a little too straightforward: the git add and git rm queues were emulated directly, which resulted in a rather complicated code and caused an inconsistent behaviour when moving dirty index entries; git mv would update the entry based on working tree state, except in case of overwrites, where the new entry would still have sha1 of the old file. This patch introduces rename_index_entry_at() into the index toolkit, which will rename an entry while removing any entries the new entry might render duplicate. This is then used in git mv instead of all the file queues, resulting in a major simplification of the code and an inevitable change in git mv -n output format. Also the code used to refuse renaming overwriting symlink with a regular file and vice versa; there is no need for that. A few new tests have been added to the testsuite to reflect this change. Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- builtin-mv.c | 65 ++++++++++-------------------------------------------------- 1 file changed, 10 insertions(+), 55 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index e66fa54324..4f65b5ae9b 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -36,18 +36,6 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, return get_pathspec(prefix, result); } -static void show_list(const char *label, struct string_list *list) -{ - if (list->nr > 0) { - int i; - printf("%s", label); - for (i = 0; i < list->nr; i++) - printf("%s%s", i > 0 ? ", " : "", - list->items[i].string); - putchar('\n'); - } -} - static const char *add_slash(const char *path) { int len = strlen(path); @@ -76,11 +64,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) const char **source, **destination, **dest_path; enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes; struct stat st; - struct string_list overwritten = {NULL, 0, 0, 0}; struct string_list src_for_dst = {NULL, 0, 0, 0}; - struct string_list added = {NULL, 0, 0, 0}; - struct string_list deleted = {NULL, 0, 0, 0}; - struct string_list changed = {NULL, 0, 0, 0}; git_config(git_default_config, NULL); @@ -185,12 +169,11 @@ int cmd_mv(int argc, const char **argv, const char *prefix) * only files can overwrite each other: * check both source and destination */ - if (S_ISREG(st.st_mode)) { + if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { fprintf(stderr, "Warning: %s;" " will overwrite!\n", bad); bad = NULL; - string_list_insert(dst, &overwritten); } else bad = "Cannot overwrite"; } @@ -219,6 +202,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) for (i = 0; i < argc; i++) { const char *src = source[i], *dst = destination[i]; enum update_mode mode = modes[i]; + int pos; if (show_only || verbose) printf("Renaming %s to %s\n", src, dst); if (!show_only && mode != INDEX && @@ -228,45 +212,16 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (mode == WORKING_DIRECTORY) continue; - assert(cache_name_pos(src, strlen(src)) >= 0); - - string_list_insert(src, &deleted); - /* destination can be a directory with 1 file inside */ - if (string_list_has_string(&overwritten, dst)) - string_list_insert(dst, &changed); - else - string_list_insert(dst, &added); + pos = cache_name_pos(src, strlen(src)); + assert(pos >= 0); + if (!show_only) + rename_cache_entry_at(pos, dst); } - if (show_only) { - show_list("Changed : ", &changed); - show_list("Adding : ", &added); - show_list("Deleting : ", &deleted); - } else { - for (i = 0; i < changed.nr; i++) { - const char *path = changed.items[i].string; - int j = cache_name_pos(path, strlen(path)); - struct cache_entry *ce = active_cache[j]; - - if (j < 0) - die ("Huh? Cache entry for %s unknown?", path); - refresh_cache_entry(ce, 0); - } - - for (i = 0; i < added.nr; i++) { - const char *path = added.items[i].string; - if (add_file_to_cache(path, verbose ? ADD_CACHE_VERBOSE : 0)) - die("updating index entries failed"); - } - - for (i = 0; i < deleted.nr; i++) - remove_file_from_cache(deleted.items[i].string); - - if (active_cache_changed) { - if (write_cache(newfd, active_cache, active_nr) || - commit_locked_index(&lock_file)) - die("Unable to write new index file"); - } + if (active_cache_changed) { + if (write_cache(newfd, active_cache, active_nr) || + commit_locked_index(&lock_file)) + die("Unable to write new index file"); } return 0; -- cgit v1.2.3 From be17262d13f5f3df5ee9635b11dad180613e9cbd Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Wed, 14 Jan 2009 18:03:22 +0100 Subject: fix handling of multiple untracked files for git mv -k The "-k" option to "git mv" should allow specifying multiple untracked files. Currently, multiple untracked files raise an assertion if they appear consecutively as arguments. Fix this by decrementing the loop index after removing one entry from the array of arguments. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- builtin-mv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 4f65b5ae9b..bce9959293 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -192,6 +192,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) memmove(destination + i, destination + i + 1, (argc - i) * sizeof(char *)); + i--; } } else die ("%s, source=%s, destination=%s", -- cgit v1.2.3 From 5aed3c6ab834367292bd7a9b0894177a07afd910 Mon Sep 17 00:00:00 2001 From: Matthieu Moy Date: Wed, 4 Feb 2009 10:32:08 +0100 Subject: builtin-mv.c: check for unversionned files before looking at the destination. The previous code was failing in the case where one moves an unversionned file to an existing destination, with mv -f: the "existing destination" was checked first, and the error was cancelled by the force flag. We now check the unrecoverable error first, which fixes the bug. Signed-off-by: Matthieu Moy Signed-off-by: Junio C Hamano --- builtin-mv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index bce9959293..01270fefdf 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -162,7 +162,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } argc += last - first; } - } else if (lstat(dst, &st) == 0) { + } else if (cache_name_pos(src, length) < 0) + bad = "not under version control"; + else if (lstat(dst, &st) == 0) { bad = "destination exists"; if (force) { /* @@ -177,9 +179,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } else bad = "Cannot overwrite"; } - } else if (cache_name_pos(src, length) < 0) - bad = "not under version control"; - else if (string_list_has_string(&src_for_dst, dst)) + } else if (string_list_has_string(&src_for_dst, dst)) bad = "multiple sources for the same target"; else string_list_insert(dst, &src_for_dst); -- cgit v1.2.3 From 377829201783b8a648e07af6ce7d747e0f45dc19 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 23 May 2009 11:53:12 -0700 Subject: parse-opts: prepare for OPT_FILENAME To give OPT_FILENAME the prefix, we pass the prefix to parse_options() which passes the prefix to parse_options_start() which sets the prefix member of parse_opts_ctx accordingly. If there isn't a prefix in the calling context, passing NULL will suffice. Signed-off-by: Stephen Boyd Signed-off-by: Junio C Hamano --- builtin-mv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 01270fefdf..8b81d4b51d 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -72,7 +72,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die("index file corrupt"); - argc = parse_options(argc, argv, builtin_mv_options, builtin_mv_usage, 0); + argc = parse_options(argc, argv, prefix, builtin_mv_options, + builtin_mv_usage, 0); if (--argc < 1) usage_with_options(builtin_mv_usage, builtin_mv_options); -- cgit v1.2.3 From d824cbba02a4061400a0e382f9bd241fbbff34f0 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Sat, 27 Jun 2009 17:58:46 +0200 Subject: Convert existing die(..., strerror(errno)) to die_errno() Change calls to die(..., strerror(errno)) to use the new die_errno(). In the process, also make slight style adjustments: at least state _something_ about the function that failed (instead of just printing the pathname), and put paths in single quotes. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- builtin-mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 8b81d4b51d..024dfebf7e 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -209,7 +209,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) printf("Renaming %s to %s\n", src, dst); if (!show_only && mode != INDEX && rename(src, dst) < 0 && !ignore_errors) - die ("renaming %s failed: %s", src, strerror(errno)); + die_errno ("renaming '%s' failed", src); if (mode == WORKING_DIRECTORY) continue; -- cgit v1.2.3 From b8f262699f6c527b13ff95a322fafc0bfbc5a232 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Tue, 30 Jun 2009 15:33:57 +0200 Subject: git-mv: fix directory separator treatment on Windows The following invocations did not work as expected on Windows: git mv foo\bar dest git mv foo\ dest The first command was interpreted as git mv foo/bar dest/foo/bar because the Windows style directory separator was not obeyed when the basename of 'foo\bar' was computed. The second command failed because the Windows style directory separator was not removed from the source directory, whereupon the lookup of the directory in the index failed. This fixes both issues by using is_dir_sep() and basename(). Signed-off-by: Johannes Sixt Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'builtin-mv.c') diff --git a/builtin-mv.c b/builtin-mv.c index 8b81d4b51d..68f47384dc 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -24,14 +24,10 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, result[count] = NULL; for (i = 0; i < count; i++) { int length = strlen(result[i]); - if (length > 0 && result[i][length - 1] == '/') { + if (length > 0 && is_dir_sep(result[i][length - 1])) result[i] = xmemdupz(result[i], length - 1); - } - if (base_name) { - const char *last_slash = strrchr(result[i], '/'); - if (last_slash) - result[i] = last_slash + 1; - } + if (base_name) + result[i] = basename((char *)result[i]); } return get_pathspec(prefix, result); } -- cgit v1.2.3