4
* Copyright (C) 2006 Johannes Schindelin
5
*/
6
#include "builtin.h"
7
+#include "pathspec.h"
8
#include "lockfile.h"
9
#include "dir.h"
10
#include "cache-tree.h"
20
#define DUP_BASENAME 1
21
#define KEEP_TRAILING_SLASH 2
22
22
-static const char **internal_copy_pathspec(const char *prefix,
23
- const char **pathspec,
24
- int count, unsigned flags)
23
+static const char **internal_prefix_pathspec(const char *prefix,
24
+ const char **pathspec,
25
+ int count, unsigned flags)
26
{
27
int i;
28
const char **result;
29
+ int prefixlen = prefix ? strlen(prefix) : 0;
30
ALLOC_ARRAY(result, count + 1);
29
- COPY_ARRAY(result, pathspec, count);
30
- result[count] = NULL;
31
+
32
+ /* Create an intermediate copy of the pathspec based on the flags */
33
for (i = 0; i < count; i++) {
32
- int length = strlen(result[i]);
34
+ int length = strlen(pathspec[i]);
35
int to_copy = length;
36
+ char *it;
37
while (!(flags & KEEP_TRAILING_SLASH) &&
35
- to_copy > 0 && is_dir_sep(result[i][to_copy - 1]))
38
+ to_copy > 0 && is_dir_sep(pathspec[i][to_copy - 1]))
39
to_copy--;
37
- if (to_copy != length || flags & DUP_BASENAME) {
38
- char *it = xmemdupz(result[i], to_copy);
39
- if (flags & DUP_BASENAME) {
40
- result[i] = xstrdup(basename(it));
41
- free(it);
42
- } else
43
- result[i] = it;
40
+
41
+ it = xmemdupz(pathspec[i], to_copy);
42
+ if (flags & DUP_BASENAME) {
43
+ result[i] = xstrdup(basename(it));
44
+ free(it);
45
+ } else {
46
+ result[i] = it;
47
}
48
}
46
- return get_pathspec(prefix, result);
49
+ result[count] = NULL;
50
+
51
+ /* Prefix the pathspec and free the old intermediate strings */
52
+ for (i = 0; i < count; i++) {
53
+ const char *match = prefix_path(prefix, prefixlen, result[i]);
54
+ free((char *) result[i]);
55
+ result[i] = match;
56
+ }
57
+
58
+ return result;
59
}
60
61
static const char *add_slash(const char *path)
142
if (read_cache() < 0)
143
die(_("index file corrupt"));
144
133
- source = internal_copy_pathspec(prefix, argv, argc, 0);
145
+ source = internal_prefix_pathspec(prefix, argv, argc, 0);
146
modes = xcalloc(argc, sizeof(enum update_mode));
147
/*
148
* Keep trailing slash, needed to let
152
flags = KEEP_TRAILING_SLASH;
153
if (argc == 1 && is_directory(argv[0]) && !is_directory(argv[1]))
154
flags = 0;
143
- dest_path = internal_copy_pathspec(prefix, argv + argc, 1, flags);
155
+ dest_path = internal_prefix_pathspec(prefix, argv + argc, 1, flags);
156
submodule_gitfile = xcalloc(argc, sizeof(char *));
157
158
if (dest_path[0][0] == '\0')
159
/* special case: "." was normalized to "" */
148
- destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
160
+ destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
161
else if (!lstat(dest_path[0], &st) &&
162
S_ISDIR(st.st_mode)) {
163
dest_path[0] = add_slash(dest_path[0]);
152
- destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
164
+ destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
165
} else {
166
if (argc != 1)
167
die(_("destination '%s' is not a directory"), dest_path[0]);