return retval;
}
+/*
+ * If the "reading" argument is set, this function finds out what _object_
+ * the ref points at by "reading" the ref. The ref, if it is not symbolic,
+ * has to exist, and if it is symbolic, it has to point at an existing ref,
+ * because the "read" goes through the symref to the ref it points at.
+ *
+ * The access that is not "reading" may often be "writing", but does not
+ * have to; it can be merely checking _where it leads to_. If it is a
+ * prelude to "writing" to the ref, a write to a symref that points at
+ * yet-to-be-born ref will create the real ref pointed by the symref.
+ * reading=0 allows the caller to check where such a symref leads to.
+ */
const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag)
{
int depth = MAXDEPTH;
return NULL;
git_snpath(path, sizeof(path), "%s", ref);
- /* Special case: non-existing file.
- * Not having the refs/heads/new-branch is OK
- * if we are writing into it, so is .git/HEAD
- * that points at refs/heads/master still to be
- * born. It is NOT OK if we are resolving for
- * reading.
- */
+ /* Special case: non-existing file. */
if (lstat(path, &st) < 0) {
struct ref_list *list = get_packed_refs();
while (list) {
char *ref_file;
const char *orig_ref = ref;
struct ref_lock *lock;
- struct stat st;
int last_errno = 0;
int type, lflags;
int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
+ int missing = 0;
lock = xcalloc(1, sizeof(struct ref_lock));
lock->lock_fd = -1;
orig_ref, strerror(errno));
goto error_return;
}
+ missing = is_null_sha1(lock->old_sha1);
/* When the ref did not exist and we are creating it,
* make sure there is no existing ref that is packed
* whose name begins with our refname, nor a ref whose
* name is a proper prefix of our refname.
*/
- if (is_null_sha1(lock->old_sha1) &&
+ if (missing &&
!is_refname_available(ref, NULL, get_packed_refs(), 0))
goto error_return;
lock->ref_name = xstrdup(ref);
lock->orig_ref_name = xstrdup(orig_ref);
ref_file = git_path("%s", ref);
- if (lstat(ref_file, &st) && errno == ENOENT)
+ if (missing)
lock->force_write = 1;
if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
lock->force_write = 1;
lock->lk->filename[i] = 0;
path = lock->lk->filename;
} else {
- path = git_path(refname);
+ path = git_path("%s", refname);
}
err = unlink(path);
if (err && errno != ENOENT) {