len = cp + tmp_len - name;
cp = xstrndup(name, cp - name);
upstream = branch_get(*cp ? cp : NULL);
- if (!upstream
- || !upstream->merge
- || !upstream->merge[0]->dst)
- return error("No upstream branch found for '%s'", cp);
+ /*
+ * Upstream can be NULL only if cp refers to HEAD and HEAD
+ * points to something different than a branch.
+ */
+ if (!upstream)
+ return error(_("HEAD does not point to a branch"));
+ if (!upstream->merge || !upstream->merge[0]->dst) {
+ if (!ref_exists(upstream->refname))
+ return error(_("No such branch: '%s'"), cp);
+ if (!upstream->merge)
+ return error(_("No upstream configured for branch '%s'"),
+ upstream->name);
+ return error(
+ _("Upstream branch '%s' not stored as a remote-tracking branch"),
+ upstream->merge[0]->src);
+ }
free(cp);
cp = shorten_unambiguous_ref(upstream->merge[0]->dst, 0);
strbuf_reset(buf);
static void diagnose_invalid_sha1_path(const char *prefix,
const char *filename,
const unsigned char *tree_sha1,
- const char *object_name)
+ const char *object_name,
+ int object_name_len)
{
struct stat st;
unsigned char sha1[20];
prefix = "";
if (!lstat(filename, &st))
- die("Path '%s' exists on disk, but not in '%s'.",
- filename, object_name);
+ die("Path '%s' exists on disk, but not in '%.*s'.",
+ filename, object_name_len, object_name);
if (errno == ENOENT || errno == ENOTDIR) {
char *fullname = xmalloc(strlen(filename)
+ strlen(prefix) + 1);
if (!get_tree_entry(tree_sha1, fullname,
sha1, &mode)) {
die("Path '%s' exists, but not '%s'.\n"
- "Did you mean '%s:%s' aka '%s:./%s'?",
+ "Did you mean '%.*s:%s' aka '%.*s:./%s'?",
fullname,
filename,
- object_name,
+ object_name_len, object_name,
fullname,
- object_name,
+ object_name_len, object_name,
filename);
}
- die("Path '%s' does not exist in '%s'",
- filename, object_name);
+ die("Path '%s' does not exist in '%.*s'",
+ filename, object_name_len, object_name);
}
}
}
if (*cp == ':') {
unsigned char tree_sha1[20];
- char *object_name = NULL;
- if (only_to_die) {
- object_name = xmalloc(cp-name+1);
- strncpy(object_name, name, cp-name);
- object_name[cp-name] = '\0';
- }
- if (!get_sha1_1(name, cp-name, tree_sha1, GET_SHA1_TREEISH)) {
+ int len = cp - name;
+ if (!get_sha1_1(name, len, tree_sha1, GET_SHA1_TREEISH)) {
const char *filename = cp+1;
char *new_filename = NULL;
if (new_filename)
filename = new_filename;
ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode);
- if (only_to_die) {
+ if (ret && only_to_die) {
diagnose_invalid_sha1_path(prefix, filename,
- tree_sha1, object_name);
- free(object_name);
+ tree_sha1,
+ name, len);
}
hashcpy(oc->tree, tree_sha1);
strncpy(oc->path, filename,
return ret;
} else {
if (only_to_die)
- die("Invalid object name '%s'.", object_name);
+ die("Invalid object name '%.*s'.", len, name);
}
}
return ret;