{
unsigned char sha1[20];
unsigned mode;
- /* try a detailed diagnostic ... */
- get_sha1_with_mode_1(arg, sha1, &mode, 0, prefix);
+
+ /*
+ * Saying "'(icase)foo' does not exist in the index" when the
+ * user gave us ":(icase)foo" is just stupid. A magic pathspec
+ * begins with a colon and is followed by a non-alnum; do not
+ * let get_sha1_with_mode_1(only_to_die=1) to even trigger.
+ */
+ if (!(arg[0] == ':' && !isalnum(arg[1])))
+ /* try a detailed diagnostic ... */
+ get_sha1_with_mode_1(arg, sha1, &mode, 1, prefix);
+
/* ... or fall back the most general message. */
die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
"Use '--' to separate paths from revisions", arg);
*/
#define PATHSPEC_FROMTOP (1<<0)
-struct pathspec_magic {
+static struct pathspec_magic {
unsigned bit;
char mnemonic; /* this cannot be ':'! */
const char *name;
* the prefix part must always match literally, and a single stupid
* string cannot express such a case.
*/
-const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
+static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
{
unsigned magic = 0;
const char *copyfrom = elt;
*copyfrom && *copyfrom != ':';
copyfrom++) {
char ch = *copyfrom;
+
+ if (!is_pathspec_magic(ch))
+ break;
for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
if (pathspec_magic[i].mnemonic == ch) {
magic |= pathspec_magic[i].bit;
break;
}
if (ARRAY_SIZE(pathspec_magic) <= i)
- break;
+ die("Unimplemented pathspec magic '%c' in '%s'",
+ ch, elt);
}
if (*copyfrom == ':')
copyfrom++;
const char *slash;
struct stat st;
int fd;
- size_t len;
+ ssize_t len;
if (stat(path, &st))
return NULL;
const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
const char *worktree;
char *gitfile;
+ int offset;
if (PATH_MAX - 40 < strlen(gitdirenv))
die("'$%s' too big", GIT_DIR_ENVIRONMENT);
return NULL;
}
- if (!prefixcmp(cwd, worktree) &&
- cwd[strlen(worktree)] == '/') { /* cwd inside worktree */
+ offset = dir_inside_of(cwd, worktree);
+ if (offset >= 0) { /* cwd inside worktree? */
set_git_dir(real_path(gitdirenv));
if (chdir(worktree))
die_errno("Could not chdir to '%s'", worktree);
cwd[len++] = '/';
cwd[len] = '\0';
free(gitfile);
- return cwd + strlen(worktree) + 1;
+ return cwd + offset;
}
/* cwd outside worktree */