mirror of
https://github.com/git/git.git
synced 2024-11-30 13:33:44 +08:00
9e2326c7e1
Move the responsibility for normalizing prefixes from longest_ancestor_length() to its callers. Use slightly different normalizations at the two callers: In setup_git_directory_gently_1(), use the old normalization, which ignores paths that are not usable. In the next commit we will change this caller to also resolve symlinks in the paths from GIT_CEILING_DIRECTORIES as part of the normalization. In "test-path-utils longest_ancestor_length", use the old normalization, but die() if any paths are unusable. Also change t0060 to only pass normalized paths to the test program (no empty entries or non-absolute paths, strip trailing slashes from the paths, and remove tests that thereby become redundant). The point of this change is to reduce the scope of the ancestor_length tests in t0060 from testing normalization+longest_prefix to testing only mostly longest_prefix. This is necessary because when setup_git_directory_gently_1() starts resolving symlinks as part of its normalization, it will not be reasonable to do the same in the test suite, because that would make the test results depend on the contents of the root directory of the filesystem on which the test is run. HOWEVER: under Windows, bash mangles arguments that look like absolute POSIX paths into DOS paths. So we have to retain the level of normalization done by normalize_path_copy() to convert the bash-mangled DOS paths (which contain backslashes) into paths that use forward slashes. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Jeff King <peff@peff.net>
110 lines
2.8 KiB
C
110 lines
2.8 KiB
C
#include "cache.h"
|
|
#include "string-list.h"
|
|
|
|
/*
|
|
* A "string_list_each_func_t" function that normalizes an entry from
|
|
* GIT_CEILING_DIRECTORIES. If the path is unusable for some reason,
|
|
* die with an explanation.
|
|
*/
|
|
static int normalize_ceiling_entry(struct string_list_item *item, void *unused)
|
|
{
|
|
const char *ceil = item->string;
|
|
int len = strlen(ceil);
|
|
char buf[PATH_MAX+1];
|
|
|
|
if (len == 0)
|
|
die("Empty path is not supported");
|
|
if (len > PATH_MAX)
|
|
die("Path \"%s\" is too long", ceil);
|
|
if (!is_absolute_path(ceil))
|
|
die("Path \"%s\" is not absolute", ceil);
|
|
if (normalize_path_copy(buf, ceil) < 0)
|
|
die("Path \"%s\" could not be normalized", ceil);
|
|
len = strlen(buf);
|
|
if (len > 1 && buf[len-1] == '/')
|
|
die("Normalized path \"%s\" ended with slash", buf);
|
|
free(item->string);
|
|
item->string = xstrdup(buf);
|
|
return 1;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
|
|
char *buf = xmalloc(PATH_MAX + 1);
|
|
int rv = normalize_path_copy(buf, argv[2]);
|
|
if (rv)
|
|
buf = "++failed++";
|
|
puts(buf);
|
|
return 0;
|
|
}
|
|
|
|
if (argc >= 2 && !strcmp(argv[1], "real_path")) {
|
|
while (argc > 2) {
|
|
puts(real_path(argv[2]));
|
|
argc--;
|
|
argv++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (argc >= 2 && !strcmp(argv[1], "absolute_path")) {
|
|
while (argc > 2) {
|
|
puts(absolute_path(argv[2]));
|
|
argc--;
|
|
argv++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) {
|
|
int len;
|
|
struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
|
|
char *path = xstrdup(argv[2]);
|
|
|
|
/*
|
|
* We have to normalize the arguments because under
|
|
* Windows, bash mangles arguments that look like
|
|
* absolute POSIX paths or colon-separate lists of
|
|
* absolute POSIX paths into DOS paths (e.g.,
|
|
* "/foo:/foo/bar" might be converted to
|
|
* "D:\Src\msysgit\foo;D:\Src\msysgit\foo\bar"),
|
|
* whereas longest_ancestor_length() requires paths
|
|
* that use forward slashes.
|
|
*/
|
|
if (normalize_path_copy(path, path))
|
|
die("Path \"%s\" could not be normalized", argv[2]);
|
|
string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1);
|
|
filter_string_list(&ceiling_dirs, 0,
|
|
normalize_ceiling_entry, NULL);
|
|
len = longest_ancestor_length(path, &ceiling_dirs);
|
|
string_list_clear(&ceiling_dirs, 0);
|
|
free(path);
|
|
printf("%d\n", len);
|
|
return 0;
|
|
}
|
|
|
|
if (argc >= 4 && !strcmp(argv[1], "prefix_path")) {
|
|
char *prefix = argv[2];
|
|
int prefix_len = strlen(prefix);
|
|
int nongit_ok;
|
|
setup_git_directory_gently(&nongit_ok);
|
|
while (argc > 3) {
|
|
puts(prefix_path(prefix, prefix_len, argv[3]));
|
|
argc--;
|
|
argv++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) {
|
|
char *prefix = strip_path_suffix(argv[2], argv[3]);
|
|
printf("%s\n", prefix ? prefix : "(null)");
|
|
return 0;
|
|
}
|
|
|
|
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
|
|
argv[1] ? argv[1] : "(there was none)");
|
|
return 1;
|
|
}
|