summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2013-07-14 15:35:27 +0700
committerJunio C Hamano <gitster@pobox.com>2013-07-15 10:56:06 -0700
commite4d92cdcd9450af7ae4c40de2b7c5c27a1faa138 (patch)
tree109ff87d743706a097a180954113e2036c79af03
parentf01d9820e768e7eb9eab4ad9a55a62317e0b23ad (diff)
downloadgit-e4d92cdcd9450af7ae4c40de2b7c5c27a1faa138.tar.gz
pathspec: add copy_pathspec
Because free_pathspec wants to free "items" pointer in the pathspec structure, a simple structure assignment is not enough if you want to copy an existing pathspec into another. Freeing the original will damage the copy unless a deep copy is made. Note that the strings in pathspec->items->match and the array pathspec->raw[] are still shared between the original and the copy. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/mv.c13
-rw-r--r--pathspec.c8
-rw-r--r--pathspec.h1
3 files changed, 16 insertions, 6 deletions
diff --git a/builtin/mv.c b/builtin/mv.c
index 034fec92a1..16ce99b499 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -15,8 +15,9 @@ static const char * const builtin_mv_usage[] = {
NULL
};
-static const char **copy_pathspec(const char *prefix, const char **pathspec,
- int count, int base_name)
+static const char **internal_copy_pathspec(const char *prefix,
+ const char **pathspec,
+ int count, int base_name)
{
int i;
const char **result = xmalloc((count + 1) * sizeof(const char *));
@@ -81,17 +82,17 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (read_cache() < 0)
die(_("index file corrupt"));
- source = copy_pathspec(prefix, argv, argc, 0);
+ source = internal_copy_pathspec(prefix, argv, argc, 0);
modes = xcalloc(argc, sizeof(enum update_mode));
- dest_path = copy_pathspec(prefix, argv + argc, 1, 0);
+ dest_path = internal_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, argc, 1);
+ destination = internal_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, argc, 1);
+ destination = internal_copy_pathspec(dest_path[0], argv, argc, 1);
} else {
if (argc != 1)
die("destination '%s' is not a directory", dest_path[0]);
diff --git a/pathspec.c b/pathspec.c
index 403095ba8c..8fe56cd8e9 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -249,3 +249,11 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
return NULL;
return pathspec;
}
+
+void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
+{
+ *dst = *src;
+ dst->items = xmalloc(sizeof(struct pathspec_item) * dst->nr);
+ memcpy(dst->items, src->items,
+ sizeof(struct pathspec_item) * dst->nr);
+}
diff --git a/pathspec.h b/pathspec.h
index 788406885f..a621676db8 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -18,6 +18,7 @@ struct pathspec {
};
extern int init_pathspec(struct pathspec *, const char **);
+extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
extern void free_pathspec(struct pathspec *);
extern int limit_pathspec_to_literal(void);